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 : * 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 : #include "../stringliterals_p.h"
16 :
17 : #include <QCoreApplication>
18 : #include <QLoggingCategory>
19 :
20 : QTPOKIT_BEGIN_NAMESPACE
21 : DOKIT_USE_STRINGLITERALS
22 :
23 3122 : static Q_LOGGING_CATEGORY(lc, "dokit.pokit.products", QtInfoMsg); ///< Logging category for this file.
24 :
25 : namespace {
26 : class Private
27 : {
28 1680 : Q_DECLARE_TR_FUNCTIONS(PokitProducts)
29 : };
30 : }
31 :
32 : /*!
33 : * Returns \c product as user-friendly string.
34 : */
35 240 : QString toString(const PokitProduct product)
36 168 : {
37 408 : switch (product) {
38 136 : case PokitProduct::PokitMeter: return u"Pokit Meter"_s;
39 136 : case PokitProduct::PokitPro: return u"Pokit Pro"_s;
40 168 : }
41 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
42 56 : return QString();
43 168 : }
44 :
45 : /*!
46 : * Returns \c true if \a info describes a Pokit device.
47 : *
48 : * Currently, this is based on whether or not \a info's service UUIDs includes a known Pokit
49 : * Status service, but this test criteria might be swapped for something else sometime.
50 : */
51 2266 : bool isPokitProduct(const QBluetoothDeviceInfo &info)
52 1570 : {
53 4619 : return isPokitProduct(info.serviceUuids());
54 1570 : }
55 :
56 : /*!
57 : * Returns the #PokitProduct corresponding the Bluetooth device \a info.
58 : *
59 : * If \a info is not a Pokit device, then result is undefined.
60 : *
61 : * \see isPokitProduct
62 : */
63 400 : PokitProduct pokitProduct(const QBluetoothDeviceInfo &info)
64 280 : {
65 895 : return pokitProduct(info.serviceUuids());
66 280 : }
67 :
68 : /// \cond internal
69 :
70 : /*!
71 : * Returns \c true if \a serviceUuids contains a known Pokit Status service UUID.
72 : *
73 : * Currently, this is the only known way to detect a Pokit device.
74 : */
75 3706 : bool isPokitProduct(const QList<QBluetoothUuid> &serviceUuids)
76 2386 : {
77 7655 : return (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter) ||
78 6092 : serviceUuids.contains(StatusService::ServiceUuids::pokitPro));
79 2386 : }
80 :
81 :
82 : /*!
83 : * Returns \c true if \a controller describes a Pokit device.
84 : *
85 : * Currently, this is based on whether or not \a controller's service UUIDs includes a known Pokit
86 : * Status service, but this test criteria might be swapped for something else sometime.
87 : *
88 : * \see isPokitProduct
89 : */
90 480 : bool isPokitProduct(const QLowEnergyController &controller)
91 144 : {
92 786 : return isPokitProduct(controller.services());
93 144 : }
94 :
95 : /*!
96 : * Returns the #PokitProduct corresponding to the Bluetooth \a serviceUuids.
97 : *
98 : * Currently, this is based on whether or not \a servceUuids includes a known Pokit
99 : * Status service, but this test criteria might be swapped for something else sometime.
100 : *
101 : * \see isPokitProduct
102 : */
103 1200 : PokitProduct pokitProduct(const QList<QBluetoothUuid> &serviceUuids)
104 680 : {
105 1880 : if (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter)) {
106 224 : return PokitProduct::PokitMeter;
107 1336 : } else if (serviceUuids.contains(StatusService::ServiceUuids::pokitPro)) {
108 224 : return PokitProduct::PokitPro;
109 296 : } else {
110 1856 : qCWarning(lc).noquote() << Private::tr("Device is not a Pokit product");
111 995 : qCDebug(lc).noquote() << "Service UUIDs:" << serviceUuids;
112 589 : return PokitProduct::PokitMeter; // Need to fallback to something; Pokit Meter is just the lowest product.
113 232 : }
114 680 : }
115 :
116 : /*!
117 : * Returns the #PokitProduct corresponding to the Bluetooth \a controller.
118 : *
119 : * Currently, this is based on whether or not \a controller's service UUIDs includes a known Pokit
120 : * Status service, but this test criteria might be swapped for something else sometime.
121 : *
122 : * \see isPokitProduct
123 : */
124 400 : PokitProduct pokitProduct(const QLowEnergyController &controller)
125 120 : {
126 735 : return pokitProduct(controller.services());
127 120 : }
128 :
129 : /// Encapsulates convenience functions for working with capacitance ranges.
130 : namespace CapacitanceRange {
131 :
132 : /*!
133 : * Returns \a product's capacitance \a range as a human-friendly string.
134 : *
135 : * \note Since Pokit Meters do not support capacitance measurement, \a product should not be PokitProduct::PokitMeter.
136 : *
137 : * \see PokitPro::toString(const PokitPro::CapacitanceRange &range)
138 : */
139 880 : QString toString(const PokitProduct product, const quint8 range)
140 424 : {
141 1304 : switch (product) {
142 448 : case PokitProduct::PokitMeter:
143 1056 : qCWarning(lc).noquote() << Private::tr("Pokit Meter has no capacitance support");
144 128 : return QString();
145 720 : case PokitProduct::PokitPro:
146 720 : return PokitPro::toString(static_cast<PokitPro::CapacitanceRange>(range));
147 424 : }
148 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
149 56 : return QString();
150 424 : }
151 :
152 : /*!
153 : * Returns the maximum value for \a range in nanofarads, or 0 if \a range is not a known value for \a product.
154 : *
155 : * \note Since Pokit Meters do not support capacitance measurement, \a product should not be PokitProduct::PokitMeter.
156 : *
157 : * \see PokitPro::maxValue(const PokitPro::CapacitanceRange &range)
158 : */
159 400 : quint32 maxValue(const PokitProduct product, const quint8 range)
160 280 : {
161 680 : switch (product) {
162 136 : case PokitProduct::PokitMeter:
163 288 : qCWarning(lc).noquote() << Private::tr("Pokit Meter has no capacitance support");
164 65 : return 0;
165 408 : case PokitProduct::PokitPro:
166 408 : return PokitPro::maxValue(static_cast<PokitPro::CapacitanceRange>(range));
167 280 : }
168 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
169 65 : return 0;
170 280 : }
171 :
172 : }
173 :
174 : /// Encapsulates convenience functions for working with current ranges.
175 : namespace CurrentRange {
176 :
177 : /*!
178 : * Returns \a product's current \a range as a human-friendly string.
179 : *
180 : * \see PokitMeter::toString(const PokitMeter::CurrentRange &range)
181 : * \see PokitPro::toString(const PokitPro::CurrentRange &range)
182 : */
183 7920 : QString toString(const PokitProduct product, const quint8 range)
184 2856 : {
185 10776 : switch (product) {
186 9688 : case PokitProduct::PokitMeter:
187 9688 : return PokitMeter::toString(static_cast<PokitMeter::CurrentRange>(range));
188 952 : case PokitProduct::PokitPro:
189 952 : return PokitPro::toString(static_cast<PokitPro::CurrentRange>(range));
190 2856 : }
191 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
192 56 : return QString();
193 2856 : }
194 :
195 : /*!
196 : * Returns the maximum value for \a range in microamps, or 0 if \a range is not a known value for \a product.
197 : *
198 : * \see PokitMeter::maxValue(const PokitMeter::CurrentRange &range)
199 : * \see PokitPro::maxValue(const PokitPro::CurrentRange &range)
200 : */
201 1200 : quint32 maxValue(const PokitProduct product, const quint8 range)
202 840 : {
203 2040 : switch (product) {
204 952 : case PokitProduct::PokitMeter:
205 952 : return PokitMeter::maxValue(static_cast<PokitMeter::CurrentRange>(range));
206 952 : case PokitProduct::PokitPro:
207 952 : return PokitPro::maxValue(static_cast<PokitPro::CurrentRange>(range));
208 840 : }
209 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
210 65 : return 0;
211 840 : }
212 :
213 : }
214 :
215 : /// Encapsulates convenience functions for working with resistance ranges.
216 : namespace ResistanceRange {
217 :
218 : /*!
219 : * Returns \a product's current \a range as a human-friendly string.
220 : *
221 : * \see PokitMeter::toString(const PokitMeter::ResistanceRange &range)
222 : * \see PokitPro::toString(const PokitPro::ResistanceRange &range)
223 : */
224 1040 : QString toString(const PokitProduct product, const quint8 range)
225 536 : {
226 1576 : switch (product) {
227 1032 : case PokitProduct::PokitMeter:
228 1032 : return PokitMeter::toString(static_cast<PokitMeter::ResistanceRange>(range));
229 408 : case PokitProduct::PokitPro:
230 408 : return PokitPro::toString(static_cast<PokitPro::ResistanceRange>(range));
231 536 : }
232 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
233 56 : return QString();
234 536 : }
235 :
236 : /*!
237 : * Returns the maximum value for \a range in ohms, or 0 if \a range is not a known value for \a product.
238 : *
239 : * \see PokitMeter::maxValue(const PokitMeter::ResistanceRange &range)
240 : * \see PokitPro::maxValue(const PokitPro::ResistanceRange &range)
241 : */
242 560 : quint32 maxValue(const PokitProduct product, const quint8 range)
243 392 : {
244 952 : switch (product) {
245 408 : case PokitProduct::PokitMeter:
246 408 : return PokitMeter::maxValue(static_cast<PokitMeter::ResistanceRange>(range));
247 408 : case PokitProduct::PokitPro:
248 408 : return PokitPro::maxValue(static_cast<PokitPro::ResistanceRange>(range));
249 392 : }
250 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
251 65 : return 0;
252 392 : }
253 :
254 : }
255 :
256 : /// Encapsulates convenience functions for working with voltage ranges.
257 : namespace VoltageRange {
258 :
259 : /*!
260 : * Returns \a product's current \a range as a human-friendly string.
261 : *
262 : * \see PokitMeter::toString(const PokitMeter::VoltageRange &range)
263 : * \see PokitPro::toString(const PokitPro::VoltageRange &range)
264 : */
265 7920 : QString toString(const PokitProduct product, const quint8 range)
266 2856 : {
267 10776 : switch (product) {
268 9688 : case PokitProduct::PokitMeter:
269 9688 : return PokitMeter::toString(static_cast<PokitMeter::VoltageRange>(range));
270 952 : case PokitProduct::PokitPro:
271 952 : return PokitPro::toString(static_cast<PokitPro::VoltageRange>(range));
272 2856 : }
273 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
274 56 : return QString();
275 2856 : }
276 :
277 : /*!
278 : * Returns the maximum value for \a range in millivolts, or 0 if \a range is not a known value for \a product.
279 : *
280 : * \see PokitMeter::maxValue(const PokitMeter::VoltageRange &range)
281 : * \see PokitPro::maxValue(const PokitPro::VoltageRange &range)
282 : */
283 1200 : quint32 maxValue(const PokitProduct product, const quint8 range)
284 840 : {
285 2040 : switch (product) {
286 952 : case PokitProduct::PokitMeter:
287 952 : return PokitMeter::maxValue(static_cast<PokitMeter::VoltageRange>(range));
288 952 : case PokitProduct::PokitPro:
289 952 : return PokitPro::maxValue(static_cast<PokitPro::VoltageRange>(range));
290 840 : }
291 288 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
292 65 : return 0;
293 840 : }
294 :
295 : }
296 :
297 : /// \endcond
298 :
299 : QTPOKIT_END_NAMESPACE
|