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 65 : Q_OBJECT
25 0 :
26 0 : public:
27 0 : /// UUIDs of the `Pokit Status` service.
28 0 : struct QTPOKIT_EXPORT ServiceUuids {
29 0 : /// UUID of the Pokit Meter's `Pokit Status` service.
30 0 : static inline const QBluetoothUuid pokitMeter { QStringLiteral("57d3a771-267c-4394-8872-78223e92aec4") };
31 0 :
32 0 : /// UUID of the Pokit Pro's `Pokit Status` service.
33 0 : static inline const QBluetoothUuid pokitPro { QStringLiteral("57d3a771-267c-4394-8872-78223e92aec5") };
34 0 : };
35 0 :
36 0 : /// Characteristics available via the `Pokit Status` service.
37 0 : struct QTPOKIT_EXPORT CharacteristicUuids {
38 0 : /// UUID of the `Pokit Status` service's `Device Characteristics` characteristic.
39 0 : static inline const QBluetoothUuid deviceCharacteristics { QStringLiteral("6974f5e5-0e54-45c3-97dd-29e4b5fb0849") };
40 0 :
41 0 : /// UUID of the `Pokit Status` service's `Status` characteristic.
42 0 : static inline const QBluetoothUuid status { QStringLiteral("3dba36e1-6120-4706-8dfd-ed9c16e569b6") };
43 0 :
44 0 : /// UUID of the `Pokit Status` service's `Device Name` characteristic.
45 0 : static inline const QBluetoothUuid name { QStringLiteral("7f0375de-077e-4555-8f78-800494509cc3") };
46 0 :
47 0 : /// UUID of the `Pokit Status` service's `Flash LED` characteristic.
48 0 : static inline const QBluetoothUuid flashLed { QStringLiteral("ec9bb1f3-05a9-4277-8dd0-60a7896f0d6e") };
49 0 :
50 0 : /// UUID of the `Pokit Status` service's (undocumented) `Torch` characteristic.
51 0 : static inline const QBluetoothUuid torch { QStringLiteral("aaf3f6d5-43d4-4a83-9510-dff3d858d4cc") };
52 0 :
53 0 : /// UUID of the `Pokit Status` service's (undocumented) `Button Press` characteristic.
54 0 : static inline const QBluetoothUuid buttonPress { QStringLiteral("8fe5b5a9-b5b4-4a7b-8ff2-87224b970f89") };
55 0 :
56 0 : /*!
57 0 : * \cond internal
58 0 : * \struct StatusService::CharacteristicUuids
59 0 : * \pokitApi Pokit Pro also reports the following unknown characteristics for the StatusService:
60 0 : * * `a59f052e-c2a1-46b6-8025-64e485c00162` - read/write
61 0 : * * `f89e4130-4347-45ef-b092-4f29e6f3a608` - write only
62 0 : * \endcond
63 0 : */
64 0 : };
65 0 :
66 0 : /// Attributes included in the `Device Characteristics` characteristic.
67 3412 : struct DeviceCharacteristics {
68 0 : QVersionNumber firmwareVersion; ///< Device's major and minor firmware version.
69 0 : quint16 maximumVoltage; ///< Device's maximum input voltage.
70 0 : quint16 maximumCurrent; ///< Device's maximum input current.
71 0 : quint16 maximumResistance; ///< Device's maximum input resistance.
72 0 : quint16 maximumSamplingRate; ///< Device's maximum sampling rate.
73 0 : quint16 samplingBufferSize; ///< Device's sampling buffer size.
74 0 : quint16 capabilityMask; ///< Reserved.
75 0 : QBluetoothAddress macAddress; ///< Device's MAC address.
76 0 : };
77 0 :
78 0 : /// Values supported by the `Status` attribute of the `Status` characteristic.
79 0 : enum class DeviceStatus : quint8 {
80 0 : Idle = 0, ///< Device is idle.
81 0 : MultimeterDcVoltage = 1, ///< Multimeter is measuring DC voltage.
82 0 : MultimeterAcVoltage = 2, ///< Multimeter is measuring AC voltage.
83 0 : MultimeterDcCurrent = 3, ///< Multimeter is measuring DC current.
84 0 : MultimeterAcCurrent = 4, ///< Multimeter is measuring AC current.
85 0 : MultimeterResistance = 5, ///< Multimeter is measuring resistance.
86 0 : MultimeterDiode = 6, ///< Multimeter is measuring diode.
87 0 : MultimeterContinuity = 7, ///< Multimeter is measuring continuity.
88 0 : MultimeterTemperature = 8,///< Multimeter is measuring temperature.
89 0 : DsoModeSampling = 9, ///< DSO is sampling.
90 0 : LoggerModeSampling = 10, ///< Data Logger is sampling.
91 0 : };
92 0 : static QString toString(const StatusService::DeviceStatus &status);
93 0 :
94 0 : /// Values supported by the `Battery Status` attribute of the `Status` characteristic.
95 0 : enum class BatteryStatus : quint8 {
96 0 : Low = 0, ///< Low (replace battery).
97 0 : Good = 1, ///< Good.
98 0 : };
99 0 : static QString toString(const StatusService::BatteryStatus &status);
100 0 :
101 0 : /// Values supported by the (undocumented) `Switch Position` attribute of the `Status` characteristic.
102 0 : enum class SwitchPosition : quint8 {
103 0 : Voltage = 0, ///< Device is switched to Voltage position.
104 0 : MultiMode = 1, ///< Device is switched to Resistance / Low Current / Capacitance / Diode position.
105 0 : HighCurrent = 2, ///< Device is switched to High Current position.
106 0 : };
107 0 : static QString toString(const StatusService::SwitchPosition &position);
108 0 :
109 0 : /// Values supported by the (undocumented) `Charging Statue` attribute of the `Status` characteristic.
110 0 : enum class ChargingStatus : quint8 {
111 0 : Discharging = 0, ///< Battery is discharging.
112 0 : Charging = 1, ///< Battery is being charged.
113 0 : Charged = 2, ///< Battery is fully charged.
114 0 : };
115 0 : static QString toString(const StatusService::ChargingStatus &status);
116 0 :
117 0 : /// Attributes included in the `Status` characteristic.
118 0 : struct Status {
119 0 : DeviceStatus deviceStatus; ///< Current Pokit device status.
120 0 : float batteryVoltage; ///< Current battery voltage level.
121 0 : BatteryStatus batteryStatus; ///< Logical interpretation the battery voltage level.
122 0 : std::optional<SwitchPosition> switchPosition; ///< Position of the Pokit device's physical mode switch.
123 0 : std::optional<ChargingStatus> chargingStatus; ///< Current charging status, if supported by the device.
124 0 : };
125 0 :
126 0 : /// Values supported by the single byte of the attribute of the (undocumented) `Torch` characteristic.
127 0 : enum class TorchStatus : quint8 {
128 0 : Off = 0, ///< Torch is off.
129 0 : On = 1, ///< Torch is on.
130 0 : };
131 0 : static QString toString(const StatusService::TorchStatus &status);
132 0 :
133 0 : /// Values supported by the second byte of the attribute of the (undocumented) `Button Press` characteristic.
134 0 : enum class ButtonStatus : quint8 {
135 0 : Released = 0, ///< Button was released.
136 0 : Pressed = 1, ///< Button was pressed.
137 0 : Held = 2, ///< Button was held down (for typically 1,500ms).
138 0 : };
139 0 : static QString toString(const StatusService::ButtonStatus &status);
140 0 :
141 0 : StatusService(QLowEnergyController * const pokitDevice, QObject * parent = nullptr);
142 2712 : ~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 4380 : 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
|