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 : * Declares the StatusService class. 7 : */ 8 : 9 : #ifndef QTPOKIT_STATUSSERVICE_H 10 : #define QTPOKIT_STATUSSERVICE_H 11 : 12 : #include "abstractpokitservice.h" 13 : 14 : #include <QBluetoothAddress> 15 : #include <QBluetoothUuid> 16 : #include <QVersionNumber> 17 : 18 : #include <optional> 19 : 20 : QTPOKIT_BEGIN_NAMESPACE 21 : 22 : class StatusServicePrivate; 23 : 24 : class QTPOKIT_EXPORT StatusService : public AbstractPokitService 25 : { 26 19 : Q_OBJECT 27 : 28 : public: 29 : /// UUIDs of the `Pokit Status` service. 30 : struct QTPOKIT_EXPORT ServiceUuids { 31 : /// UUID of the Pokit Meter's `Pokit Status` service. 32 : static inline const QBluetoothUuid pokitMeter { QStringLiteral("57d3a771-267c-4394-8872-78223e92aec4") }; 33 : 34 : /// UUID of the Pokit Pro's `Pokit Status` service. 35 : static inline const QBluetoothUuid pokitPro { QStringLiteral("57d3a771-267c-4394-8872-78223e92aec5") }; 36 : }; 37 : 38 : /// Characteristics available via the `Pokit Status` service. 39 : struct QTPOKIT_EXPORT CharacteristicUuids { 40 : /// UUID of the `Pokit Status` service's `Device Characteristics` characterstic. 41 : static inline const QBluetoothUuid deviceCharacteristics { QStringLiteral("6974f5e5-0e54-45c3-97dd-29e4b5fb0849") }; 42 : 43 : /// UUID of the `Pokit Status` service's `Status` characterstic. 44 : static inline const QBluetoothUuid status { QStringLiteral("3dba36e1-6120-4706-8dfd-ed9c16e569b6") }; 45 : 46 : /// UUID of the `Pokit Status` service's `Device Name` characterstic. 47 : static inline const QBluetoothUuid name { QStringLiteral("7f0375de-077e-4555-8f78-800494509cc3") }; 48 : 49 : /// UUID of the `Pokit Status` service's `Flash LED` characterstic. 50 : static inline const QBluetoothUuid flashLed { QStringLiteral("ec9bb1f3-05a9-4277-8dd0-60a7896f0d6e") }; 51 : 52 : /// UUID of the `Pokit Status` service's (undocumented) `Torch` characterstic. 53 : static inline const QBluetoothUuid torch { QStringLiteral("aaf3f6d5-43d4-4a83-9510-dff3d858d4cc") }; 54 : 55 : /// UUID of the `Pokit Status` service's (undocumented) `Button Press` characterstic. 56 : static inline const QBluetoothUuid buttonPress { QStringLiteral("8fe5b5a9-b5b4-4a7b-8ff2-87224b970f89") }; 57 : 58 : // Pokit Pro also reports an unknown "a59f052e-c2a1-46b6-8025-64e485c00162" characteristic. 59 : }; 60 : 61 : /// Attributes included in the `Device Characteristics` characterstic. 62 1290 : struct DeviceCharacteristics { 63 : QVersionNumber firmwareVersion; ///< Device's major and minor firmware version. 64 : quint16 maximumVoltage; ///< Device's maximum input voltage. 65 : quint16 maximumCurrent; ///< Device's maximum input current. 66 : quint16 maximumResistance; ///< Device's maximum input resistance. 67 : quint16 maximumSamplingRate; ///< Device's maximum sampling rate. 68 : quint16 samplingBufferSize; ///< Device's sampling buffer size. 69 : quint16 capabilityMask; ///< Reserved. 70 : QBluetoothAddress macAddress; ///< Device's MAC address. 71 : }; 72 : 73 : /// Values supported by the `Status` attribute of the `Status` characteristic. 74 : enum class DeviceStatus : quint8 { 75 : Idle = 0, ///< Device is idle. 76 : MultimeterDcVoltage = 1, ///< Multimeter is measuring DC voltage. 77 : MultimeterAcVoltage = 2, ///< Multimeter is measuring AC voltage. 78 : MultimeterDcCurrent = 3, ///< Multimeter is measuring DC current. 79 : MultimeterAcCurrent = 4, ///< Multimeter is measuring AC current. 80 : MultimeterResistance = 5, ///< Multimeter is measuring resistance. 81 : MultimeterDiode = 6, ///< Multimeter is measuring diode. 82 : MultimeterContinuity = 7, ///< Multimeter is measuring continuity. 83 : MultimeterTemperature = 8,///< Multimeter is measuring temperature. 84 : DsoModeSampling = 9, ///< DSO is sampling. 85 : LoggerModeSampling = 10, ///< Data Logger is sampling. 86 : }; 87 : static QString toString(const StatusService::DeviceStatus &status); 88 : 89 : /// Values supported by the `Battery Status` attribute of the `Status` characteristic. 90 : enum class BatteryStatus : quint8 { 91 : Low = 0, ///< Low (replace battery). 92 : Good = 1, ///< Good. 93 : }; 94 : static QString toString(const StatusService::BatteryStatus &status); 95 : 96 : /// Values supported by the (undocumented) `Switch Position` attribute of the `Status` characteristic. 97 : enum class SwitchPosition : quint8 { 98 : Voltage = 0, ///< Device is switched to Voltage position. 99 : MultiMode = 1, ///< Device is switched to Resistance / Low Current / Capacitance / Diode position. 100 : HighCurrent = 2, ///< Device is switched to High Current position. 101 : }; 102 : static QString toString(const StatusService::SwitchPosition &position); 103 : 104 : /// Values supported by the (undocumented) `Charging Statue` attribute of the `Status` characteristic. 105 : enum class ChargingStatus : quint8 { 106 : Discharging = 0, ///< Battery is dischargin. 107 : Charging = 1, ///< Battery is being charged. 108 : Charged = 2, ///< Battery is fully charged. 109 : }; 110 : static QString toString(const StatusService::ChargingStatus &status); 111 : 112 : /// Attributes included in the `Status` characterstic. 113 : struct Status { 114 : DeviceStatus deviceStatus; ///< Current Pokit device status. 115 : float batteryVoltage; ///< Current battery voltage level. 116 : BatteryStatus batteryStatus; ///< Logical interpretation the battery voltage level. 117 : std::optional<SwitchPosition> switchPosition; ///< Position of the Pokit device's physical mode switch. 118 : std::optional<ChargingStatus> chargingStatus; ///< Current charging status, if supported by the device. 119 : }; 120 : 121 : /// Values supported by the single byte of the attribute of the (undocumented) `Torch` characteristic. 122 : enum class TorchStatus : quint8 { 123 : Off = 0, ///< Torch is off. 124 : On = 1, ///< Torch is on. 125 : }; 126 : static QString toString(const StatusService::TorchStatus &status); 127 : 128 : /// Values supported by the second byte of the attribute of the (undocumented) `Button Press` characteristic. 129 : enum class ButtonStatus : quint8 { 130 : Released = 0, ///< Button was released. 131 : Pressed = 1, ///< Button was pressed. 132 : Held = 2, ///< Button was held down (for typically 1,500ms). 133 : }; 134 : static QString toString(const StatusService::ButtonStatus &status); 135 : 136 : StatusService(QLowEnergyController * const pokitDevice, QObject * parent = nullptr); 137 : ~StatusService() override; 138 : 139 : bool readCharacteristics() override; 140 : bool readDeviceCharacteristics(); 141 : bool readStatusCharacteristic(); 142 : bool readNameCharacteristic(); 143 : bool readTorchCharacteristic(); 144 : bool readButtonPressCharacteristic(); 145 : 146 : // Device Characteristics characteristic (BLE read only). 147 : DeviceCharacteristics deviceCharacteristics() const; 148 : 149 : // Status characteristic (Meter: read, Pro: read/notify). 150 : Status status() const; 151 : bool enableStatusNotifications(); 152 : bool disableStatusNotifications(); 153 : 154 : // Device Name characteristic (Both read/write). 155 : QString deviceName() const; 156 : bool setDeviceName(const QString &name); 157 : 158 : // Flash LED characteristic (Meter: write only (Pro claims read/write, but fails if we try). 159 : bool flashLed(); 160 : 161 : // Undocumented Torch characteristic (Pro only: read/write/notify). 162 : std::optional<TorchStatus> torchStatus() const; 163 : bool setTorchStatus(const TorchStatus status); 164 : bool enableTorchStatusNotifications(); 165 : bool disableTorchStatusNotifications(); 166 : 167 : // Undocumented Button Press characteristic (Pro only: read/write/notify). 168 : std::optional<ButtonStatus> buttonPress() const; 169 : bool enableButtonPressedNotifications(); 170 : bool disableButtonPressedNotifications(); 171 : 172 : Q_SIGNALS: 173 : void deviceCharacteristicsRead(const StatusService::DeviceCharacteristics &characteristics); 174 : void deviceNameRead(const QString &deviceName); 175 : void deviceNameWritten(); 176 : void deviceStatusRead(const StatusService::Status &status); 177 : void deviceLedFlashed(); 178 : void torchStatusRead(const TorchStatus &status); 179 : void torchStatusWritten(); 180 : void buttonPressRead(const quint8 &unknown, const ButtonStatus status); 181 : 182 : protected: 183 : /// \cond internal 184 : StatusService(StatusServicePrivate * const d, QObject * const parent); 185 : /// \endcond 186 : 187 : private: 188 1280 : Q_DECLARE_PRIVATE(StatusService) 189 : Q_DISABLE_COPY(StatusService) 190 : friend class TestStatusService; 191 : }; 192 : 193 : QTPOKIT_END_NAMESPACE 194 : 195 : #endif // QTPOKIT_STATUSSERVICE_H