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: 85.7 % 7 6

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

Generated by: LCOV version 2.3.1-1