LCOV - code coverage report
Current view: top level - src/lib - pokitproducts.cpp (source / functions) Hit Total Coverage
Project: Dokit Lines: 91 91 100.0 %
Version: Functions: 16 16 100.0 %

          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             : /*!
       5             :  * \file
       6             :  * Defines the #PokitProduct helper functions.
       7             :  */
       8             : 
       9             : #include <qtpokit/pokitmeter.h>
      10             : #include <qtpokit/pokitpro.h>
      11             : #include <qtpokit/pokitproducts.h>
      12             : #include <qtpokit/statusservice.h>
      13             : 
      14             : #include "pokitproducts_p.h"
      15             : 
      16             : #include <QCoreApplication>
      17             : #include <QLoggingCategory>
      18             : 
      19         819 : static Q_LOGGING_CATEGORY(lc, "dokit.pokit.products", QtInfoMsg); ///< Logging category for this file.
      20             : 
      21             : QTPOKIT_BEGIN_NAMESPACE
      22             : 
      23             : /*!
      24             :  * Returns \c product as user-friendly string.
      25             :  */
      26          54 : QString toString(const PokitProduct product)
      27             : {
      28          54 :     switch (product) {
      29          18 :     case PokitProduct::PokitMeter: return QStringLiteral("Pokit Meter");
      30          18 :     case PokitProduct::PokitPro:   return QStringLiteral("Pokit Pro");
      31             :     }
      32          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("PokitProducts",
      33          28 :         "Unknown PokitProduct value: %1", "toString").arg((int)product);
      34             :     return QString();
      35             : }
      36             : 
      37             : /*!
      38             :  * Returns \c true if \a info describes a Pokit device.
      39             :  *
      40             :  * Currently, this is based on whether or not \a info's service UUIDs includes a known Pokit
      41             :  * Status service, but this test criteria might be swapped for something else sometime.
      42             :  */
      43         492 : bool isPokitProduct(const QBluetoothDeviceInfo &info)
      44             : {
      45         608 :     return isPokitProduct(info.serviceUuids());
      46             : }
      47             : 
      48             : /*!
      49             :  * Returns the #PokitProduct corresponding the Bluetotoh device \a info.
      50             :  *
      51             :  * If \a info is not a Pokit device, then result is undefined.
      52             :  *
      53             :  * \see isPokitProduct
      54             :  */
      55          90 : PokitProduct pokitProduct(const QBluetoothDeviceInfo &info)
      56             : {
      57         110 :     return pokitProduct(info.serviceUuids());
      58             : }
      59             : 
      60             : /// \cond internal
      61             : 
      62             : /*!
      63             :  * Returns \c true if \a serviceUuids contains a known Pokit Status service UUID.
      64             :  *
      65             :  * \todo The Pokit Android app does this by distinguishing between these two advertiserd services:
      66             :  * "00001800-0000-1000-8000-00805f9b34fb" Meter
      67             :  * "0000180a-0000-1000-8000-00805f9b34fb" Pro
      68             :  * Of course, these are the QBluetoothUuid::ServiceClassUuid::GenericAccess and
      69             :  * QBluetoothUuid::ServiceClassUuid::GenericAttribute services.
      70             :  *
      71             :  * Currently, this is the only known way to detect a Pokit device.
      72             :  */
      73         816 : bool isPokitProduct(const QList<QBluetoothUuid> &serviceUuids)
      74             : {
      75        1342 :     return (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter) ||
      76         816 :             serviceUuids.contains(StatusService::ServiceUuids::pokitPro));
      77             : }
      78             : 
      79             : 
      80             : /*!
      81             :  * Returns \c true if \a controller describes a Pokit device.
      82             :  *
      83             :  * Currently, this is based on whether or not \a controller's service UUIDs includes a known Pokit
      84             :  * Status service, but this test criteria might be swapped for something else sometime.
      85             :  *
      86             :  * \see isPokitProduct
      87             :  */
      88         108 : bool isPokitProduct(const QLowEnergyController &controller)
      89             : {
      90         132 :     return isPokitProduct(controller.services());
      91             : }
      92             : 
      93             : /*!
      94             :  * Returns the #PokitProduct corresponding to the Bluetooth \a serviceUuids.
      95             :  *
      96             :  * Currently, this is based on whether or not \a servceUuids includes a known Pokit
      97             :  * Status service, but this test criteria might be swapped for something else sometime.
      98             :  *
      99             :  * \see isPokitProduct
     100             :  */
     101         270 : PokitProduct pokitProduct(const QList<QBluetoothUuid> &serviceUuids)
     102             : {
     103         270 :     if (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter)) {
     104             :         return PokitProduct::PokitMeter;
     105         198 :     } else if (serviceUuids.contains(StatusService::ServiceUuids::pokitPro)) {
     106             :         return PokitProduct::PokitPro;
     107             :     } else {
     108         252 :         qCWarning(lc).noquote()
     109         154 :             << QCoreApplication::translate("PokitProducts", "Device is not a Pokit product", "pokitProduct");
     110         126 :         qCDebug(lc).noquote() << "Service UUIDs:" << serviceUuids;
     111         126 :         return PokitProduct::PokitMeter; // Need to fallback to something; Pokit Meter is just the lowest product.
     112             :     }
     113             : }
     114             : 
     115             : /*!
     116             :  * Returns the #PokitProduct corresponding to the Bluetooth \a controller.
     117             :  *
     118             :  * Currently, this is based on whether or not \a controller's service UUIDs includes a known Pokit
     119             :  * Status service, but this test criteria might be swapped for something else sometime.
     120             :  *
     121             :  * \see isPokitProduct
     122             :  */
     123          90 : PokitProduct pokitProduct(const QLowEnergyController &controller)
     124             : {
     125         110 :     return pokitProduct(controller.services());
     126             : }
     127             : 
     128             : QTPOKIT_END_NAMESPACE
     129             : 
     130             : /// Encapsulates convenience functions for working with capacitance ranges.
     131             : namespace CapacitanceRange {
     132             : 
     133             : /*!
     134             :  *  Returns \a product's capacitance \a range as a human-friendly string.
     135             :  *
     136             :  *  \note Since Pokit Meters do not support capacitance measurement, \a product should not be PokitProduct::PokitMeter.
     137             :  *
     138             :  *  \see PokitPro::toString(const PokitPro::CapacitanceRange &range)
     139             :  */
     140         198 : QString toString(const PokitProduct product, const quint8 range)
     141             : {
     142         198 :     switch (product) {
     143          72 :     case PokitProduct::PokitMeter:
     144         144 :         qCWarning(lc).noquote()
     145          88 :             << QCoreApplication::translate("PokitProducts", "Pokit Meter has no capacitance support", "toString");
     146             :         return QString();
     147         108 :     case PokitProduct::PokitPro:
     148         108 :         return PokitPro::toString(static_cast<PokitPro::CapacitanceRange>(range));
     149             :     }
     150          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("CapacitanceRange",
     151          28 :         "Unknown PokitProduct value: %1", "toString").arg((int)product);
     152             :     return QString();
     153             : }
     154             : 
     155             : /*!
     156             :  *  Returns the maximum value for \a product's \a range in (integer) nanofarads, or the string "Auto".
     157             :  *  If \a range is not a known valid value, then an null QVariant is returned.
     158             :  *
     159             :  *  \note Since Pokit Meters do not support capacitance measurement, \a product should not be PokitProduct::PokitMeter.
     160             :  *
     161             :  *  \see PokitPro::maxValue(const PokitPro::CapacitanceRange &range)
     162             :  */
     163          90 : QVariant maxValue(const PokitProduct product, const quint8 range)
     164             : {
     165          90 :     switch (product) {
     166          18 :     case PokitProduct::PokitMeter:
     167          36 :         qCWarning(lc).noquote()
     168          22 :             << QCoreApplication::translate("PokitProducts", "Pokit Meter has no capacitance support", "toString");
     169             :         return QVariant();
     170          54 :     case PokitProduct::PokitPro:
     171          54 :         return PokitPro::maxValue(static_cast<PokitPro::CapacitanceRange>(range));
     172             :     }
     173          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("CapacitanceRange",
     174          28 :         "Unknown PokitProduct value: %1", "maxValue").arg((int)product);
     175             :     return QVariant();
     176             : }
     177             : 
     178             : }
     179             : 
     180             : /// Encapsulates convenience functions for working with current ranges.
     181             : namespace CurrentRange {
     182             : 
     183             : /*!
     184             :  *  Returns \a product's current \a range as a human-friendly string.
     185             :  *
     186             :  *  \see PokitMeter::toString(const PokitMeter::CurrentRange &range)
     187             :  *  \see PokitPro::toString(const PokitPro::CurrentRange &range)
     188             :  */
     189        1782 : QString toString(const PokitProduct product, const quint8 range)
     190             : {
     191        1782 :     switch (product) {
     192        1638 :     case PokitProduct::PokitMeter:
     193        1638 :         return PokitMeter::toString(static_cast<PokitMeter::CurrentRange>(range));
     194         126 :     case PokitProduct::PokitPro:
     195         126 :         return PokitPro::toString(static_cast<PokitPro::CurrentRange>(range));
     196             :     }
     197          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("CurrentRange",
     198          28 :         "Unknown PokitProduct value: %1", "toString").arg((int)product);
     199             :     return QString();
     200             : }
     201             : 
     202             : /*!
     203             :  *  Returns the maximum value for \a product's \a range in (integer) microamps, or the string "Auto".
     204             :  *  If \a range is not a known valid value, then an null QVariant is returned.
     205             :  *
     206             :  *  \see PokitMeter::maxValue(const PokitMeter::CurrentRange &range)
     207             :  *  \see PokitPro::maxValue(const PokitPro::CurrentRange &range)
     208             :  */
     209         270 : QVariant maxValue(const PokitProduct product, const quint8 range)
     210             : {
     211         270 :     switch (product) {
     212         126 :     case PokitProduct::PokitMeter:
     213         126 :         return PokitMeter::maxValue(static_cast<PokitMeter::CurrentRange>(range));
     214         126 :     case PokitProduct::PokitPro:
     215         126 :         return PokitPro::maxValue(static_cast<PokitPro::CurrentRange>(range));
     216             :     }
     217          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("CurrentRange",
     218          28 :         "Unknown PokitProduct value: %1", "maxValue").arg((int)product);
     219             :     return QVariant();
     220             : }
     221             : 
     222             : }
     223             : 
     224             : /// Encapsulates convenience functions for working with resistance ranges.
     225             : namespace ResistanceRange {
     226             : 
     227             : /*!
     228             :  *  Returns \a product's current \a range as a human-friendly string.
     229             :  *
     230             :  *  \see PokitMeter::toString(const PokitMeter::ResistanceRange &range)
     231             :  *  \see PokitPro::toString(const PokitPro::ResistanceRange &range)
     232             :  */
     233         234 : QString toString(const PokitProduct product, const quint8 range)
     234             : {
     235         234 :     switch (product) {
     236         162 :     case PokitProduct::PokitMeter:
     237         162 :         return PokitMeter::toString(static_cast<PokitMeter::ResistanceRange>(range));
     238          54 :     case PokitProduct::PokitPro:
     239          54 :         return PokitPro::toString(static_cast<PokitPro::ResistanceRange>(range));
     240             :     }
     241          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("ResistanceRange",
     242          28 :         "Unknown PokitProduct value: %1", "toString").arg((int)product);
     243             :     return QString();
     244             : }
     245             : 
     246             : /*!
     247             :  *  Returns the maximum value for \a product's \a range in (integer) ohms, or the string "Auto".
     248             :  *  If \a range is not a known valid value, then an null QVariant is returned.
     249             :  *
     250             :  *  \see PokitMeter::maxValue(const PokitMeter::ResistanceRange &range)
     251             :  *  \see PokitPro::maxValue(const PokitPro::ResistanceRange &range)
     252             :  */
     253         126 : QVariant maxValue(const PokitProduct product, const quint8 range)
     254             : {
     255         126 :     switch (product) {
     256          54 :     case PokitProduct::PokitMeter:
     257          54 :         return PokitMeter::maxValue(static_cast<PokitMeter::ResistanceRange>(range));
     258          54 :     case PokitProduct::PokitPro:
     259          54 :         return PokitPro::maxValue(static_cast<PokitPro::ResistanceRange>(range));
     260             :     }
     261          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("ResistanceRange",
     262          28 :         "Unknown PokitProduct value: %1", "maxValue").arg((int)product);
     263             :     return QVariant();
     264             : }
     265             : 
     266             : }
     267             : 
     268             : /// Encapsulates convenience functions for working with voltage ranges.
     269             : namespace VoltageRange {
     270             : 
     271             : /*!
     272             :  *  Returns \a product's current \a range as a human-friendly string.
     273             :  *
     274             :  *  \see PokitMeter::toString(const PokitMeter::VoltageRange &range)
     275             :  *  \see PokitPro::toString(const PokitPro::VoltageRange &range)
     276             :  */
     277        1782 : QString toString(const PokitProduct product, const quint8 range)
     278             : {
     279        1782 :     switch (product) {
     280        1638 :     case PokitProduct::PokitMeter:
     281        1638 :         return PokitMeter::toString(static_cast<PokitMeter::VoltageRange>(range));
     282         126 :     case PokitProduct::PokitPro:
     283         126 :         return PokitPro::toString(static_cast<PokitPro::VoltageRange>(range));
     284             :     }
     285          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("VoltageRange",
     286          28 :         "Unknown PokitProduct value: %1", "toString").arg((int)product);
     287             :     return QString();
     288             : }
     289             : 
     290             : /*!
     291             :  *  Returns the maximum value for \a product's \a range in (integer) millivolts, or the string "Auto".
     292             :  *  If \a range is not a known valid value, then an null QVariant is returned.
     293             :  *
     294             :  *  \see PokitMeter::maxValue(const PokitMeter::VoltageRange &range)
     295             :  *  \see PokitPro::maxValue(const PokitPro::VoltageRange &range)
     296             :  */
     297         270 : QVariant maxValue(const PokitProduct product, const quint8 range)
     298             : {
     299         270 :     switch (product) {
     300         126 :     case PokitProduct::PokitMeter:
     301         126 :         return PokitMeter::maxValue(static_cast<PokitMeter::VoltageRange>(range));
     302         126 :     case PokitProduct::PokitPro:
     303         126 :         return PokitPro::maxValue(static_cast<PokitPro::VoltageRange>(range));
     304             :     }
     305          56 :     qCWarning(lc).noquote() << QCoreApplication::translate("VoltageRange",
     306          28 :         "Unknown PokitProduct value: %1", "maxValue").arg((int)product);
     307             :     return QVariant();
     308             : }
     309             : 
     310             : }
     311             : 
     312             : /// \endcond

Generated by: LCOV version 1.14