LCOV - code coverage report
Current view: top level - src/cli - loggerfetchcommand.cpp (source / functions) Hit Total Coverage
Project: Dokit Lines: 54 70 77.1 %
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:"           << service->toString(data.range, data.mode) << data.range;
      68        1368 :     qCDebug(lc) << "updateInterval:"  << (int)data.updateInterval;
      69        1368 :     qCDebug(lc) << "numberOfSamples:" << data.numberOfSamples;
      70        1368 :     qCDebug(lc) << "timestamp:"       << data.timestamp << QDateTime::fromSecsSinceEpoch(data.timestamp, Qt::UTC);
      71        1368 :     this->metadata = data;
      72        1368 :     this->samplesToGo = data.numberOfSamples;
      73        1368 :     this->timestamp = (quint64)data.timestamp * (quint64)1000;
      74        2736 :     qCInfo(lc).noquote() << tr("Fetching %Ln logger sample/s...", nullptr, data.numberOfSamples);
      75        1368 : }
      76             : 
      77             : /*!
      78             :  * Outputs logger \a samples in the selected ouput format.
      79             :  */
      80        1620 : void LoggerFetchCommand::outputSamples(const DataLoggerService::Samples &samples)
      81             : {
      82         360 :     QString unit;
      83        1620 :     switch (metadata.mode) {
      84         324 :     case DataLoggerService::Mode::DcVoltage: unit = QLatin1String("Vdc"); break;
      85         324 :     case DataLoggerService::Mode::AcVoltage: unit = QLatin1String("Vac"); break;
      86         324 :     case DataLoggerService::Mode::DcCurrent: unit = QLatin1String("Adc"); break;
      87         324 :     case DataLoggerService::Mode::AcCurrent: unit = QLatin1String("Aac"); break;
      88         396 :     case DataLoggerService::Mode::Temperature: unit = QString::fromUtf8("°C"); break;
      89           0 :     default:
      90           0 :         qCDebug(lc).noquote() << tr(R"(No known unit for mode %1 "%2".)").arg((int)metadata.mode)
      91           0 :             .arg(DataLoggerService::toString(metadata.mode));
      92             :     }
      93        2880 :     const QString range = service->toString(metadata.range, metadata.mode);
      94             : 
      95        9180 :     for (const qint16 &sample: samples) {
      96        7560 :         const QString timeString = (metadata.timestamp == 0) ? QString::number(timestamp)
      97        7560 :             : QDateTime::fromMSecsSinceEpoch(timestamp, Qt::UTC).toString(Qt::ISODateWithMs);
      98        7560 :         const float value = sample * metadata.scale;
      99        7560 :         switch (format) {
     100             :         case OutputFormat::Csv:
     101        2880 :             for (; showCsvHeader; showCsvHeader = false) {
     102         440 :                 std::cout << qUtf8Printable(tr("timestamp,value,unit,range\n"));
     103             :             }
     104        5600 :             std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4\n")
     105             :                 .arg(timeString).arg(value).arg(unit, range));
     106        2520 :             break;
     107         840 :         case OutputFormat::Json: {
     108             :             QJsonObject object{
     109         560 :                 { QLatin1String("timestamp"), timeString },
     110         560 :                 { QLatin1String("value"),     value },
     111         560 :                 { QLatin1String("unit"),      unit },
     112        5040 :                 { QLatin1String("mode"),      DataLoggerService::toString(metadata.mode) },
     113       20160 :             };
     114        2520 :             if (!range.isEmpty()) {
     115        3024 :                 object.insert(QLatin1String("range"), range);
     116             :             }
     117        5040 :             std::cout << QJsonDocument(object).toJson().toStdString();
     118        2520 :         }   break;
     119        2520 :         case OutputFormat::Text:
     120        5600 :             std::cout << qUtf8Printable(tr("%1 %2 %3\n").arg(timeString).arg(value).arg(unit));
     121        2520 :             break;
     122             :         }
     123        7560 :         timestamp += metadata.updateInterval;
     124        7560 :         --samplesToGo;
     125        5880 :     }
     126        1620 :     if (samplesToGo <= 0) {
     127        3780 :         qCInfo(lc).noquote() << tr("Finished fetching %Ln sample/s (with %L1 remaining).",
     128        2520 :             nullptr, metadata.numberOfSamples).arg(samplesToGo);
     129        1620 :         if (device) disconnect(); // Will exit the application once disconnected.
     130             :     }
     131        6660 : }

Generated by: LCOV version 1.14