LCOV - code coverage report
Current view: top level - src/cli - loggerfetchcommand.cpp (source / functions) Hit Total Coverage
Project: Dokit Lines: 54 72 75.0 %
Version: Functions: 5 7 71.4 %

          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 "loggerfetchcommand.h"
       5             : 
       6             : #include <qtpokit/pokitdevice.h>
       7             : 
       8             : #include <QDateTime>
       9             : #include <QJsonDocument>
      10             : #include <QJsonObject>
      11             : 
      12             : #include <iostream>
      13             : 
      14             : /*!
      15             :  * \class LoggerFetchCommand
      16             :  *
      17             :  * The LoggerFetchCommand class implements the `logger` CLI command.
      18             :  */
      19             : 
      20             : /*!
      21             :  * Construct a new LoggerFetchCommand object with \a parent.
      22             :  */
      23        1386 : LoggerFetchCommand::LoggerFetchCommand(QObject * const parent) : DeviceCommand(parent)
      24             : {
      25             : 
      26        1386 : }
      27             : 
      28             : /*!
      29             :  * \copybrief DeviceCommand::getService
      30             :  *
      31             :  * This override returns a pointer to a DataLoggerService object.
      32             :  */
      33           0 : AbstractPokitService * LoggerFetchCommand::getService()
      34             : {
      35             :     Q_ASSERT(device);
      36           0 :     if (!service) {
      37           0 :         service = device->dataLogger();
      38             :         Q_ASSERT(service);
      39           0 :         connect(service, &DataLoggerService::metadataRead, this, &LoggerFetchCommand::metadataRead);
      40           0 :         connect(service, &DataLoggerService::samplesRead, this, &LoggerFetchCommand::outputSamples);
      41             :     }
      42           0 :     return service;
      43             : }
      44             : 
      45             : /*!
      46             :  * \copybrief DeviceCommand::serviceDetailsDiscovered
      47             :  *
      48             :  * This override fetches the current device's status, and outputs it in the selected format.
      49             :  */
      50           0 : void LoggerFetchCommand::serviceDetailsDiscovered()
      51             : {
      52           0 :     DeviceCommand::serviceDetailsDiscovered(); // Just logs consistently.
      53           0 :     qCInfo(lc).noquote() << tr("Fetching logger samples...");
      54           0 :     service->enableMetadataNotifications();
      55           0 :     service->enableReadingNotifications();
      56           0 :     service->fetchSamples();
      57           0 : }
      58             : 
      59             : /*!
      60             :  * Invoked when \a metadata has been received from the data logger.
      61             :  */
      62        1368 : void LoggerFetchCommand::metadataRead(const DataLoggerService::Metadata &data)
      63             : {
      64        1368 :     qCDebug(lc) << "status:" << (int)(data.status);
      65        1368 :     qCDebug(lc) << "scale:" << data.scale;
      66        1368 :     qCDebug(lc) << "mode:" << DataLoggerService::toString(data.mode) << (quint8)data.mode;
      67        1368 :     qCDebug(lc) << "range:" << DataLoggerService::toString(data.range, data.mode)
      68           0 :                             << (quint8)data.range.voltageRange;
      69        1368 :     qCDebug(lc) << "updateInterval:" << (int)data.updateInterval;
      70        1368 :     qCDebug(lc) << "numberOfSamples:" << data.numberOfSamples;
      71        1368 :     qCDebug(lc) << "timestamp:" << data.timestamp
      72           0 :                                 << QDateTime::fromSecsSinceEpoch(data.timestamp, Qt::UTC);
      73        1368 :     this->metadata = data;
      74        1368 :     this->samplesToGo = data.numberOfSamples;
      75        1368 :     this->timestamp = (quint64)data.timestamp * (quint64)1000;
      76        2736 :     qCInfo(lc).noquote() << tr("Fetching %Ln logger sample/s...", nullptr, data.numberOfSamples);
      77        1368 : }
      78             : 
      79             : /*!
      80             :  * Outputs logger \a samples in the selected ouput format.
      81             :  */
      82        1620 : void LoggerFetchCommand::outputSamples(const DataLoggerService::Samples &samples)
      83             : {
      84         360 :     QString unit;
      85        1620 :     switch (metadata.mode) {
      86         324 :     case DataLoggerService::Mode::DcVoltage: unit = QLatin1String("Vdc"); break;
      87         324 :     case DataLoggerService::Mode::AcVoltage: unit = QLatin1String("Vac"); break;
      88         324 :     case DataLoggerService::Mode::DcCurrent: unit = QLatin1String("Adc"); break;
      89         324 :     case DataLoggerService::Mode::AcCurrent: unit = QLatin1String("Aac"); break;
      90         396 :     case DataLoggerService::Mode::Temperature: unit = QString::fromUtf8("°C"); break;
      91           0 :     default:
      92           0 :         qCDebug(lc).noquote() << tr("No known unit for mode %1 \"%2\".").arg((int)metadata.mode)
      93           0 :             .arg(DataLoggerService::toString(metadata.mode));
      94             :     }
      95        2880 :     const QString range = DataLoggerService::toString(metadata.range, metadata.mode);
      96             : 
      97        9180 :     for (const qint16 &sample: samples) {
      98        7560 :         const QString timeString = (metadata.timestamp == 0) ? QString::number(timestamp)
      99        7560 :             : QDateTime::fromMSecsSinceEpoch(timestamp, Qt::UTC).toString(Qt::ISODateWithMs);
     100        7560 :         const float value = sample * metadata.scale;
     101        7560 :         switch (format) {
     102             :         case OutputFormat::Csv:
     103        2880 :             for (; showCsvHeader; showCsvHeader = false) {
     104         440 :                 std::cout << qUtf8Printable(tr("timestamp,value,unit,range\n"));
     105             :             }
     106        5600 :             std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4\n")
     107             :                 .arg(timeString).arg(value).arg(unit, range));
     108        2520 :             break;
     109         840 :         case OutputFormat::Json: {
     110             :             QJsonObject object{
     111         560 :                 { QLatin1String("timestamp"), timeString },
     112         560 :                 { QLatin1String("value"),     value },
     113         560 :                 { QLatin1String("unit"),      unit },
     114        5040 :                 { QLatin1String("mode"),      DataLoggerService::toString(metadata.mode) },
     115       20160 :             };
     116        2520 :             if (!range.isEmpty()) {
     117        3024 :                 object.insert(QLatin1String("range"), range);
     118             :             }
     119        5040 :             std::cout << QJsonDocument(object).toJson().toStdString();
     120        2520 :         }   break;
     121        2520 :         case OutputFormat::Text:
     122        5600 :             std::cout << qUtf8Printable(tr("%1 %2 %3\n").arg(timeString).arg(value).arg(unit));
     123        2520 :             break;
     124             :         }
     125        7560 :         timestamp += metadata.updateInterval;
     126        7560 :         --samplesToGo;
     127        5880 :     }
     128        1620 :     if (samplesToGo <= 0) {
     129        3780 :         qCInfo(lc).noquote() << tr("Finished fetching %Ln sample/s (with %L1 remaining).",
     130        2520 :             nullptr, metadata.numberOfSamples).arg(samplesToGo);
     131        1620 :         if (device) disconnect(); // Will exit the application once disconnected.
     132             :     }
     133        6660 : }

Generated by: LCOV version 1.14