LCOV - code coverage report
Current view: top level - src/cli - statuscommand.cpp (source / functions) Hit Total Coverage
Project: Dokit Lines: 72 85 84.7 %
Version: Functions: 7 8 87.5 %

          Line data    Source code
       1             : // SPDX-FileCopyrightText: 2022-2023 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         252 : StatusCommand::StatusCommand(QObject * const parent) : DeviceCommand(parent)
      23             : {
      24             : 
      25         252 : }
      26             : 
      27          90 : QStringList StatusCommand::requiredOptions(const QCommandLineParser &parser) const
      28             : {
      29         180 :     return DeviceCommand::requiredOptions(parser) + QStringList{
      30         175 :     };
      31             : }
      32             : 
      33          36 : QStringList StatusCommand::supportedOptions(const QCommandLineParser &parser) const
      34             : {
      35          36 :     return DeviceCommand::supportedOptions(parser);
      36             : }
      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          18 : QStringList StatusCommand::processOptions(const QCommandLineParser &parser)
      45             : {
      46          18 :     QStringList errors = DeviceCommand::processOptions(parser);
      47             :     if (!errors.isEmpty()) {
      48             :         return errors;
      49             :     }
      50             : 
      51             :     return errors;
      52             : }
      53             : 
      54             : /*!
      55             :  * \copybrief DeviceCommand::getService
      56             :  *
      57             :  * This override returns a pointer to a StatusService object.
      58             :  */
      59           0 : AbstractPokitService * StatusCommand::getService()
      60             : {
      61             :     Q_ASSERT(device);
      62           0 :     if (!service) {
      63           0 :         service = device->status();
      64             :         Q_ASSERT(service);
      65             :     }
      66           0 :     return service;
      67             : }
      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          18 : void StatusCommand::serviceDetailsDiscovered()
      75             : {
      76          18 :     DeviceCommand::serviceDetailsDiscovered(); // Just logs consistently.
      77          18 :     const StatusService::DeviceCharacteristics chrs = service->deviceCharacteristics();
      78          18 :     if (chrs.firmwareVersion.isNull()) {
      79          40 :         qCWarning(lc).noquote() << tr("Failed to parse device information");
      80          18 :         QCoreApplication::exit(EXIT_FAILURE);
      81             :         return;
      82             :     }
      83           0 :     outputDeviceStatus(chrs);
      84             : }
      85             : 
      86             : /*!
      87             :  * Outputs the Pokit device's details, including \a chrs, in the selected format.
      88             :  */
      89         162 : void StatusCommand::outputDeviceStatus(const StatusService::DeviceCharacteristics &chrs)
      90             : {
      91         162 :     const QString deviceName = service->deviceName();
      92         162 :     const StatusService::Status status = service->status();
      93         162 :     const std::optional<StatusService::TorchStatus> torchStatus = service->torchStatus();
      94         162 :     const std::optional<StatusService::ButtonStatus> buttonStatus = service->buttonPress();
      95         162 :     const QString statusLabel = StatusService::toString(status.deviceStatus);
      96         162 :     const QString batteryLabel = StatusService::toString(status.batteryStatus);
      97         162 :     const QString torchLabel = (torchStatus) ? StatusService::toString(*torchStatus) : QString();
      98         162 :     const QString buttonLabel = (buttonStatus) ? StatusService::toString(*buttonStatus) : QString();
      99             : 
     100         162 :     switch (format) {
     101          54 :     case OutputFormat::Csv:
     102          66 :         std::cout << qUtf8Printable(tr("device_name,device_status,firmware_version,maximum_voltage,"
     103             :                             "maximum_current,maximum_resistance,maximum_sampling_rate,"
     104             :                             "sampling_buffer_size,capability_mask,mac_address,battery_voltage,"
     105             :                             "battery_status,torch_status,button_status\n"));
     106         228 :         std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14\n")
     107             :             .arg(escapeCsvField(deviceName),statusLabel.toLower(),chrs.firmwareVersion.toString())
     108             :             .arg(chrs.maximumVoltage).arg(chrs.maximumCurrent).arg(chrs.maximumResistance)
     109             :             .arg(chrs.maximumSamplingRate).arg(chrs.samplingBufferSize).arg(chrs.capabilityMask)
     110             :             .arg(chrs.macAddress.toString()).arg(status.batteryVoltage)
     111             :             .arg(batteryLabel.toLower(), torchLabel.toLower(), buttonLabel.toLower()));
     112          54 :         break;
     113          18 :     case OutputFormat::Json: {
     114             :         QJsonObject battery{
     115          54 :             { QLatin1String("level"),  status.batteryVoltage },
     116         162 :         };
     117          54 :         if (!batteryLabel.isNull()) {
     118          81 :             battery.insert(QLatin1String("status"), batteryLabel);
     119             :         }
     120             :         QJsonObject object{
     121          12 :                 { QLatin1String("deviceName"),   deviceName },
     122         192 :                 { QLatin1String("firmwareVersion"), QJsonObject{
     123          12 :                       { QLatin1String("major"), chrs.firmwareVersion.majorVersion() },
     124          24 :                       { QLatin1String("minor"), chrs.firmwareVersion.minorVersion() },
     125         108 :                 }},
     126          66 :                 { QLatin1String("maximumVoltage"),      chrs.maximumVoltage },
     127          66 :                 { QLatin1String("maximumCurrent"),      chrs.maximumCurrent },
     128          66 :                 { QLatin1String("maximumResistance"),   chrs.maximumResistance },
     129          66 :                 { QLatin1String("maximumSamplingRate"), chrs.maximumSamplingRate },
     130          66 :                 { QLatin1String("samplingBufferSize"),  chrs.samplingBufferSize },
     131          66 :                 { QLatin1String("capabilityMask"),      chrs.capabilityMask },
     132         108 :                 { QLatin1String("macAddress"),          chrs.macAddress.toString() },
     133         192 :                 { QLatin1String("deviceStatus"), QJsonObject{
     134          54 :                       { QLatin1String("code"), (quint8)status.deviceStatus },
     135          12 :                       { QLatin1String("label"), statusLabel },
     136         108 :                 }},
     137          12 :                 { QLatin1String("battery"), battery },
     138        1050 :             };
     139          54 :         if (torchStatus) {
     140           0 :             object.insert(QStringLiteral("torchStatus"), QJsonObject{
     141           0 :                 { QLatin1String("code"), (quint8)*torchStatus },
     142           0 :                 { QLatin1String("label"), torchLabel },
     143           0 :             });
     144             :         }
     145          54 :         if (buttonStatus) {
     146           0 :             object.insert(QStringLiteral("buttonStatus"), QJsonObject{
     147           0 :                 { QLatin1String("code"), (quint8)*buttonStatus },
     148           0 :                 { QLatin1String("label"), buttonLabel },
     149           0 :             });
     150             :         }
     151         108 :         std::cout << QJsonDocument(object).toJson().toStdString();
     152          54 :     }   break;
     153          54 :     case OutputFormat::Text:
     154         120 :         std::cout << qUtf8Printable(tr("Device name:           %1\n").arg(deviceName));
     155         120 :         std::cout << qUtf8Printable(tr("Firmware version:      %1\n").arg(chrs.firmwareVersion.toString()));
     156          78 :         std::cout << qUtf8Printable(tr("Maximum voltage:       %1\n").arg(chrs.maximumVoltage));
     157          78 :         std::cout << qUtf8Printable(tr("Maximum current:       %1\n").arg(chrs.maximumCurrent));
     158          78 :         std::cout << qUtf8Printable(tr("Maximum resistance:    %1\n").arg(chrs.maximumResistance));
     159          78 :         std::cout << qUtf8Printable(tr("Maximum sampling rate: %1\n").arg(chrs.maximumSamplingRate));
     160          78 :         std::cout << qUtf8Printable(tr("Sampling buffer size:  %1\n").arg(chrs.samplingBufferSize));
     161          78 :         std::cout << qUtf8Printable(tr("Capability mask:       %1\n").arg(chrs.capabilityMask));
     162         120 :         std::cout << qUtf8Printable(tr("MAC address:           %1\n").arg(chrs.macAddress.toString()));
     163          78 :         std::cout << qUtf8Printable(tr("Device status:         %1 (%2)\n").arg(statusLabel)
     164             :             .arg((quint8)status.deviceStatus));
     165         120 :         std::cout << qUtf8Printable(tr("Battery voltage:       %1\n").arg(status.batteryVoltage));
     166         132 :         std::cout << qUtf8Printable(tr("Battery status:        %1 (%2)\n")
     167             :             .arg(batteryLabel.isNull() ? QString::fromLatin1("N/A") : batteryLabel)
     168             :             .arg((quint8)status.batteryStatus));
     169          54 :         break;
     170             :     }
     171         162 :     if (device) disconnect(); // Will exit the application once disconnected.
     172         540 : }

Generated by: LCOV version 1.14