Line data Source code
1 : // SPDX-FileCopyrightText: 2022-2024 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 38 : 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 : /*!
59 : * \cond internal
60 : * \struct StatusService::CharacteristicUuids
61 : * \pokitApi Pokit Pro also reports the following unknown characteristics for the StatusService:
62 : * * `a59f052e-c2a1-46b6-8025-64e485c00162` - read/write
63 : * * `f89e4130-4347-45ef-b092-4f29e6f3a608` - write only
64 : * \endcond
65 : */
66 : };
67 :
68 : /// Attributes included in the `Device Characteristics` characterstic.
69 2387 : struct DeviceCharacteristics {
70 : QVersionNumber firmwareVersion; ///< Device's major and minor firmware version.
71 : quint16 maximumVoltage; ///< Device's maximum input voltage.
72 : quint16 maximumCurrent; ///< Device's maximum input current.
73 : quint16 maximumResistance; ///< Device's maximum input resistance.
74 : quint16 maximumSamplingRate; ///< Device's maximum sampling rate.
75 : quint16 samplingBufferSize; ///< Device's sampling buffer size.
76 : quint16 capabilityMask; ///< Reserved.
77 : QBluetoothAddress macAddress; ///< Device's MAC address.
78 : };
79 :
80 : /// Values supported by the `Status` attribute of the `Status` characteristic.
81 : enum class DeviceStatus : quint8 {
82 : Idle = 0, ///< Device is idle.
83 : MultimeterDcVoltage = 1, ///< Multimeter is measuring DC voltage.
84 : MultimeterAcVoltage = 2, ///< Multimeter is measuring AC voltage.
85 : MultimeterDcCurrent = 3, ///< Multimeter is measuring DC current.
86 : MultimeterAcCurrent = 4, ///< Multimeter is measuring AC current.
87 : MultimeterResistance = 5, ///< Multimeter is measuring resistance.
88 : MultimeterDiode = 6, ///< Multimeter is measuring diode.
89 : MultimeterContinuity = 7, ///< Multimeter is measuring continuity.
90 : MultimeterTemperature = 8,///< Multimeter is measuring temperature.
91 : DsoModeSampling = 9, ///< DSO is sampling.
92 : LoggerModeSampling = 10, ///< Data Logger is sampling.
93 : };
94 : static QString toString(const StatusService::DeviceStatus &status);
95 :
96 : /// Values supported by the `Battery Status` attribute of the `Status` characteristic.
97 : enum class BatteryStatus : quint8 {
98 : Low = 0, ///< Low (replace battery).
99 : Good = 1, ///< Good.
100 : };
101 : static QString toString(const StatusService::BatteryStatus &status);
102 :
103 : /// Values supported by the (undocumented) `Switch Position` attribute of the `Status` characteristic.
104 : enum class SwitchPosition : quint8 {
105 : Voltage = 0, ///< Device is switched to Voltage position.
106 : MultiMode = 1, ///< Device is switched to Resistance / Low Current / Capacitance / Diode position.
107 : HighCurrent = 2, ///< Device is switched to High Current position.
108 : };
109 : static QString toString(const StatusService::SwitchPosition &position);
110 :
111 : /// Values supported by the (undocumented) `Charging Statue` attribute of the `Status` characteristic.
112 : enum class ChargingStatus : quint8 {
113 : Discharging = 0, ///< Battery is dischargin.
114 : Charging = 1, ///< Battery is being charged.
115 : Charged = 2, ///< Battery is fully charged.
116 : };
117 : static QString toString(const StatusService::ChargingStatus &status);
118 :
119 : /// Attributes included in the `Status` characterstic.
120 : struct Status {
121 : DeviceStatus deviceStatus; ///< Current Pokit device status.
122 : float batteryVoltage; ///< Current battery voltage level.
123 : BatteryStatus batteryStatus; ///< Logical interpretation the battery voltage level.
124 : std::optional<SwitchPosition> switchPosition; ///< Position of the Pokit device's physical mode switch.
125 : std::optional<ChargingStatus> chargingStatus; ///< Current charging status, if supported by the device.
126 : };
127 :
128 : /// Values supported by the single byte of the attribute of the (undocumented) `Torch` characteristic.
129 : enum class TorchStatus : quint8 {
130 : Off = 0, ///< Torch is off.
131 : On = 1, ///< Torch is on.
132 : };
133 : static QString toString(const StatusService::TorchStatus &status);
134 :
135 : /// Values supported by the second byte of the attribute of the (undocumented) `Button Press` characteristic.
136 : enum class ButtonStatus : quint8 {
137 : Released = 0, ///< Button was released.
138 : Pressed = 1, ///< Button was pressed.
139 : Held = 2, ///< Button was held down (for typically 1,500ms).
140 : };
141 : static QString toString(const StatusService::ButtonStatus &status);
142 :
143 : StatusService(QLowEnergyController * const pokitDevice, QObject * parent = nullptr);
144 1584 : ~StatusService() = default;
145 :
146 : bool readCharacteristics() override;
147 : bool readDeviceCharacteristics();
148 : bool readStatusCharacteristic();
149 : bool readNameCharacteristic();
150 : bool readTorchCharacteristic();
151 : bool readButtonPressCharacteristic();
152 :
153 : // Device Characteristics characteristic (BLE read only).
154 : DeviceCharacteristics deviceCharacteristics() const;
155 :
156 : // Status characteristic (Meter: read, Pro: read/notify).
157 : Status status() const;
158 : bool enableStatusNotifications();
159 : bool disableStatusNotifications();
160 :
161 : // Device Name characteristic (Both read/write).
162 : QString deviceName() const;
163 : bool setDeviceName(const QString &name);
164 :
165 : // Flash LED characteristic (Meter: write only (Pro claims read/write, but fails if we try).
166 : bool flashLed();
167 :
168 : // Undocumented Torch characteristic (Pro only: read/write/notify).
169 : std::optional<TorchStatus> torchStatus() const;
170 : bool setTorchStatus(const TorchStatus status);
171 : bool enableTorchStatusNotifications();
172 : bool disableTorchStatusNotifications();
173 :
174 : // Undocumented Button Press characteristic (Pro only: read/write/notify).
175 : std::optional<ButtonStatus> buttonPress() const;
176 : bool enableButtonPressedNotifications();
177 : bool disableButtonPressedNotifications();
178 :
179 : Q_SIGNALS:
180 : void deviceCharacteristicsRead(const StatusService::DeviceCharacteristics &characteristics);
181 : void deviceNameRead(const QString &deviceName);
182 : void deviceNameWritten();
183 : void deviceStatusRead(const StatusService::Status &status);
184 : void deviceLedFlashed();
185 : void torchStatusRead(const TorchStatus &status);
186 : void torchStatusWritten();
187 : void buttonPressRead(const quint8 &unknown, const ButtonStatus status);
188 :
189 : protected:
190 : /// \cond internal
191 : StatusService(StatusServicePrivate * const d, QObject * const parent);
192 : /// \endcond
193 :
194 : private:
195 2540 : Q_DECLARE_PRIVATE(StatusService)
196 : Q_DISABLE_COPY(StatusService)
197 : friend class TestStatusService;
198 : };
199 :
200 : QTPOKIT_END_NAMESPACE
201 :
202 : #endif // QTPOKIT_STATUSSERVICE_H
|