LCOV - code coverage report
Current view: top level - src/cli - statuscommand.cpp (source / functions) Coverage Total Hit
Project: Dokit Lines: 73.3 % 146 107
Version: Functions: 86.7 % 15 13

            Line data    Source code
       1              : // SPDX-FileCopyrightText: 2022-2025 Paul Colby <git@colby.id.au>
       2              : // SPDX-License-Identifier: LGPL-3.0-or-later
       3              : 
       4              : #include "statuscommand.h"
       5              : 
       6              : #include <qtpokit/pokitdevice.h>
       7              : 
       8              : #include <QJsonDocument>
       9              : #include <QJsonObject>
      10              : 
      11              : #include <iostream>
      12              : 
      13              : /*!
      14              :  * \class StatusCommand
      15              :  *
      16              :  * The StatusCommand class implements the `status` CLI command.
      17              :  */
      18              : 
      19              : /*!
      20              :  * Construct a new StatusCommand object with \a parent.
      21              :  */
      22          798 : StatusCommand::StatusCommand(QObject * const parent) : DeviceCommand(parent)
      23          358 : {
      24              : 
      25          918 : }
      26              : 
      27          200 : QStringList StatusCommand::requiredOptions(const QCommandLineParser &parser) const
      28          235 : {
      29          635 :     return DeviceCommand::requiredOptions(parser) + QStringList{
      30          585 :     };
      31          235 : }
      32              : 
      33           80 : QStringList StatusCommand::supportedOptions(const QCommandLineParser &parser) const
      34           94 : {
      35          174 :     return DeviceCommand::supportedOptions(parser);
      36           94 : }
      37              : 
      38              : /*!
      39              :  * \copybrief DeviceCommand::processOptions
      40              :  *
      41              :  * This implementation extends DeviceCommand::processOptions to process additional CLI options
      42              :  * supported (or required) by this command.
      43              :  */
      44           40 : QStringList StatusCommand::processOptions(const QCommandLineParser &parser)
      45           47 : {
      46           87 :     QStringList errors = DeviceCommand::processOptions(parser);
      47           47 :     if (!errors.isEmpty()) {
      48            0 :         return errors;
      49            0 :     }
      50              : 
      51           47 :     return errors;
      52           47 : }
      53              : 
      54              : /*!
      55              :  * \copybrief DeviceCommand::getService
      56              :  *
      57              :  * This override returns a pointer to a StatusService object.
      58              :  */
      59            0 : AbstractPokitService * StatusCommand::getService()
      60            0 : {
      61            0 :     Q_ASSERT(device);
      62            0 :     if (!service) {
      63            0 :         service = device->status();
      64            0 :         Q_ASSERT(service);
      65            0 :     }
      66            0 :     return service;
      67            0 : }
      68              : 
      69              : /*!
      70              :  * \copybrief DeviceCommand::serviceDetailsDiscovered
      71              :  *
      72              :  * This override fetches the current device's status, and outputs it in the selected format.
      73              :  */
      74           40 : void StatusCommand::serviceDetailsDiscovered()
      75           17 : {
      76           57 :     DeviceCommand::serviceDetailsDiscovered(); // Just logs consistently.
      77           57 :     const StatusService::DeviceCharacteristics chrs = service->deviceCharacteristics();
      78           57 :     if (chrs.firmwareVersion.isNull()) {
      79          124 :         qCWarning(lc).noquote() << tr("Failed to parse device information");
      80           57 :         QCoreApplication::exit(EXIT_FAILURE);
      81           17 :         return;
      82           17 :     }
      83            0 :     outputDeviceStatus(chrs);
      84            0 : }
      85              : 
      86              : /*!
      87              :  * Outputs the Pokit device's details, including \a chrs, in the selected format.
      88              :  */
      89          360 : void StatusCommand::outputDeviceStatus(const StatusService::DeviceCharacteristics &chrs)
      90          153 : {
      91          513 :     const QString deviceName = service->deviceName();
      92          513 :     const StatusService::Status status = service->status();
      93          513 :     const std::optional<StatusService::TorchStatus> torchStatus = service->torchStatus();
      94          513 :     const std::optional<StatusService::ButtonStatus> buttonStatus = service->buttonPress();
      95          513 :     const QString statusLabel = StatusService::toString(status.deviceStatus);
      96          513 :     const QString batteryLabel = StatusService::toString(status.batteryStatus);
      97          513 :     const QString switchLabel = status.switchPosition ? StatusService::toString(*status.switchPosition) : QString();
      98          513 :     const QString chargingLabel = status.chargingStatus ? StatusService::toString(*status.chargingStatus) : QString();
      99          513 :     const QString torchLabel = (torchStatus) ? StatusService::toString(*torchStatus) : QString();
     100          513 :     const QString buttonLabel = (buttonStatus) ? StatusService::toString(*buttonStatus) : QString();
     101              : 
     102          513 :     switch (format) {
     103          171 :     case OutputFormat::Csv:
     104          222 :         std::cout << qUtf8Printable(tr("device_name,device_status,firmware_version,maximum_voltage,"
     105           51 :                             "maximum_current,maximum_resistance,maximum_sampling_rate,"
     106           51 :                             "sampling_buffer_size,capability_mask,mac_address,battery_voltage,"
     107           51 :                             "battery_status,torch_status,button_status,switch_position,charging_status\n"));
     108          690 :         std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15,%16\n")
     109           51 :             .arg(escapeCsvField(deviceName),statusLabel.toLower(),chrs.firmwareVersion.toString())
     110           51 :             .arg(chrs.maximumVoltage).arg(chrs.maximumCurrent).arg(chrs.maximumResistance)
     111           51 :             .arg(chrs.maximumSamplingRate).arg(chrs.samplingBufferSize).arg(chrs.capabilityMask)
     112           51 :             .arg(chrs.macAddress.toString()).arg(status.batteryVoltage)
     113           51 :             .arg(batteryLabel.toLower(), torchLabel.toLower(), buttonLabel.toLower(), switchLabel.toLower(),
     114           51 :                  chargingLabel.toLower()));
     115          171 :         break;
     116          171 :     case OutputFormat::Json: {
     117           51 :         QJsonObject battery{
     118          171 :             { QLatin1String("level"),  status.batteryVoltage },
     119          423 :         };
     120          171 :         if (!batteryLabel.isNull()) {
     121          231 :             battery.insert(QLatin1String("status"), batteryLabel);
     122           51 :         }
     123           51 :         QJsonObject object{
     124          102 :                 { QLatin1String("deviceName"),   deviceName },
     125          495 :                 { QLatin1String("firmwareVersion"), QJsonObject{
     126          153 :                       { QLatin1String("major"), chrs.firmwareVersion.majorVersion() },
     127          153 :                       { QLatin1String("minor"), chrs.firmwareVersion.minorVersion() },
     128          339 :                 }},
     129          222 :                 { QLatin1String("maximumVoltage"),      chrs.maximumVoltage },
     130          222 :                 { QLatin1String("maximumCurrent"),      chrs.maximumCurrent },
     131          222 :                 { QLatin1String("maximumResistance"),   chrs.maximumResistance },
     132          222 :                 { QLatin1String("maximumSamplingRate"), chrs.maximumSamplingRate },
     133          222 :                 { QLatin1String("samplingBufferSize"),  chrs.samplingBufferSize },
     134          222 :                 { QLatin1String("capabilityMask"),      chrs.capabilityMask },
     135          291 :                 { QLatin1String("macAddress"),          chrs.macAddress.toString() },
     136          495 :                 { QLatin1String("deviceStatus"), QJsonObject{
     137          222 :                       { QLatin1String("code"), (quint8)status.deviceStatus },
     138          102 :                       { QLatin1String("label"), statusLabel },
     139          339 :                 }},
     140          102 :                 { QLatin1String("battery"), battery },
     141         1830 :             };
     142          171 :         if (torchStatus) {
     143            0 :             object.insert(QStringLiteral("torchStatus"), QJsonObject{
     144            0 :                 { QLatin1String("code"), (quint8)*torchStatus },
     145            0 :                 { QLatin1String("label"), torchLabel },
     146            0 :             });
     147            0 :         }
     148          171 :         if (buttonStatus) {
     149            0 :             object.insert(QStringLiteral("buttonStatus"), QJsonObject{
     150            0 :                 { QLatin1String("code"), (quint8)*buttonStatus },
     151            0 :                 { QLatin1String("label"), buttonLabel },
     152            0 :             });
     153            0 :         }
     154          171 :         if (status.switchPosition) {
     155            0 :             object.insert(QStringLiteral("switchStatus"), QJsonObject{
     156            0 :                 { QLatin1String("code"), (quint8)*status.switchPosition },
     157            0 :                 { QLatin1String("label"), switchLabel },
     158            0 :             });
     159            0 :         }
     160          171 :         if (status.chargingStatus) {
     161            0 :             object.insert(QStringLiteral("chargingStatus"), QJsonObject{
     162            0 :                 { QLatin1String("code"), (quint8)*status.chargingStatus },
     163            0 :                 { QLatin1String("label"), chargingLabel },
     164            0 :             });
     165            0 :         }
     166          291 :         std::cout << QJsonDocument(object).toJson().toStdString();
     167          171 :     }   break;
     168          171 :     case OutputFormat::Text:
     169          342 :         std::cout << qUtf8Printable(tr("Device name:           %1\n").arg(deviceName));
     170          348 :         std::cout << qUtf8Printable(tr("Firmware version:      %1\n").arg(chrs.firmwareVersion.toString()));
     171          273 :         std::cout << qUtf8Printable(tr("Maximum voltage:       %1\n").arg(chrs.maximumVoltage));
     172          273 :         std::cout << qUtf8Printable(tr("Maximum current:       %1\n").arg(chrs.maximumCurrent));
     173          273 :         std::cout << qUtf8Printable(tr("Maximum resistance:    %1\n").arg(chrs.maximumResistance));
     174          273 :         std::cout << qUtf8Printable(tr("Maximum sampling rate: %1\n").arg(chrs.maximumSamplingRate));
     175          273 :         std::cout << qUtf8Printable(tr("Sampling buffer size:  %1\n").arg(chrs.samplingBufferSize));
     176          273 :         std::cout << qUtf8Printable(tr("Capability mask:       %1\n").arg(chrs.capabilityMask));
     177          348 :         std::cout << qUtf8Printable(tr("MAC address:           %1\n").arg(chrs.macAddress.toString()));
     178          273 :         std::cout << qUtf8Printable(tr("Device status:         %1 (%2)\n").arg(statusLabel)
     179           51 :             .arg((quint8)status.deviceStatus));
     180          342 :         std::cout << qUtf8Printable(tr("Battery voltage:       %1\n").arg(status.batteryVoltage));
     181          393 :         std::cout << qUtf8Printable(tr("Battery status:        %1 (%2)\n")
     182           51 :             .arg(batteryLabel.isNull() ? QString::fromLatin1("N/A") : batteryLabel)
     183           51 :             .arg((quint8)status.batteryStatus));
     184          171 :         if (status.switchPosition) {
     185            0 :             std::cout << qUtf8Printable(tr("Switch position:       %1 (%2)\n")
     186            0 :                 .arg(switchLabel).arg((quint8)*status.switchPosition));
     187            0 :         }
     188          171 :         if (status.chargingStatus) {
     189            0 :             std::cout << qUtf8Printable(tr("Charging status:       %1 (%2)\n")
     190            0 :                 .arg(chargingLabel).arg((quint8)*status.chargingStatus));
     191            0 :         }
     192           51 :         break;
     193          153 :     }
     194          513 :     if (device) disconnect(); // Will exit the application once disconnected.
     195         2421 : }
        

Generated by: LCOV version 2.2-1