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