Line data Source code
1 : // SPDX-FileCopyrightText: 2022-2026 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 3682 : static Q_LOGGING_CATEGORY(lc, "dokit.pokit.products", QtInfoMsg); ///< Logging category for this file.
24 :
25 : namespace {
26 : class Private
27 : {
28 2163 : Q_DECLARE_TR_FUNCTIONS(PokitProducts)
29 0 : };
30 0 : }
31 0 :
32 0 : /*!
33 0 : * Returns \c product as user-friendly string.
34 0 : */
35 309 : QString toString(const PokitProduct product)
36 384 : {
37 693 : switch (product) {
38 231 : case PokitProduct::PokitMeter: return u"Pokit Meter"_s;
39 231 : case PokitProduct::PokitPro: return u"Pokit Pro"_s;
40 384 : }
41 623 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
42 147 : return QString();
43 384 : }
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 2933 : bool isPokitProduct(const QBluetoothDeviceInfo &info)
52 3604 : {
53 8045 : return isPokitProduct(info.serviceUuids());
54 3604 : }
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 515 : PokitProduct pokitProduct(const QBluetoothDeviceInfo &info)
64 640 : {
65 1505 : return pokitProduct(info.serviceUuids());
66 640 : }
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 4787 : bool isPokitProduct(const QList<QBluetoothUuid> &serviceUuids)
76 5476 : {
77 12294 : return (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter) ||
78 10263 : serviceUuids.contains(StatusService::ServiceUuids::pokitPro));
79 5476 : }
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 618 : bool isPokitProduct(const QLowEnergyController &controller)
91 336 : {
92 1266 : return isPokitProduct(controller.services());
93 336 : }
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 1545 : PokitProduct pokitProduct(const QList<QBluetoothUuid> &serviceUuids)
104 1560 : {
105 3105 : if (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter)) {
106 512 : return PokitProduct::PokitMeter;
107 2181 : } else if (serviceUuids.contains(StatusService::ServiceUuids::pokitPro)) {
108 512 : return PokitProduct::PokitPro;
109 680 : } else {
110 2853 : qCWarning(lc).noquote() << Private::tr("Device is not a Pokit product");
111 1642 : qCDebug(lc).noquote() << "Service UUIDs:" << serviceUuids;
112 872 : return PokitProduct::PokitMeter; // Need to fallback to something; Pokit Meter is just the lowest product.
113 536 : }
114 1560 : }
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 515 : PokitProduct pokitProduct(const QLowEnergyController &controller)
125 280 : {
126 1145 : return pokitProduct(controller.services());
127 280 : }
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 1133 : QString toString(const PokitProduct product, const quint8 range)
140 976 : {
141 2109 : switch (product) {
142 708 : case PokitProduct::PokitMeter:
143 1620 : qCWarning(lc).noquote() << Private::tr("Pokit Meter has no capacitance support");
144 372 : return QString();
145 1170 : case PokitProduct::PokitPro:
146 1170 : return PokitPro::toString(static_cast<PokitPro::CapacitanceRange>(range));
147 976 : }
148 955 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
149 147 : return QString();
150 976 : }
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 515 : quint32 maxValue(const PokitProduct product, const quint8 range)
160 640 : {
161 1155 : switch (product) {
162 231 : case PokitProduct::PokitMeter:
163 459 : qCWarning(lc).noquote() << Private::tr("Pokit Meter has no capacitance support");
164 138 : return 0;
165 693 : case PokitProduct::PokitPro:
166 693 : return PokitPro::maxValue(static_cast<PokitPro::CapacitanceRange>(range));
167 640 : }
168 787 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
169 138 : return 0;
170 640 : }
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 10197 : QString toString(const PokitProduct product, const quint8 range)
184 6624 : {
185 16821 : switch (product) {
186 14973 : case PokitProduct::PokitMeter:
187 14973 : return PokitMeter::toString(static_cast<PokitMeter::CurrentRange>(range));
188 1617 : case PokitProduct::PokitPro:
189 1617 : return PokitPro::toString(static_cast<PokitPro::CurrentRange>(range));
190 6624 : }
191 3959 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
192 147 : return QString();
193 6624 : }
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 1545 : quint32 maxValue(const PokitProduct product, const quint8 range)
202 1920 : {
203 3465 : switch (product) {
204 1617 : case PokitProduct::PokitMeter:
205 1617 : return PokitMeter::maxValue(static_cast<PokitMeter::CurrentRange>(range));
206 1617 : case PokitProduct::PokitPro:
207 1617 : return PokitPro::maxValue(static_cast<PokitPro::CurrentRange>(range));
208 1920 : }
209 1607 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
210 138 : return 0;
211 1920 : }
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 1339 : QString toString(const PokitProduct product, const quint8 range)
225 1232 : {
226 2571 : switch (product) {
227 1647 : case PokitProduct::PokitMeter:
228 1647 : return PokitMeter::toString(static_cast<PokitMeter::ResistanceRange>(range));
229 693 : case PokitProduct::PokitPro:
230 693 : return PokitPro::toString(static_cast<PokitPro::ResistanceRange>(range));
231 1232 : }
232 1119 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
233 147 : return QString();
234 1232 : }
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 721 : quint32 maxValue(const PokitProduct product, const quint8 range)
243 896 : {
244 1617 : switch (product) {
245 693 : case PokitProduct::PokitMeter:
246 693 : return PokitMeter::maxValue(static_cast<PokitMeter::ResistanceRange>(range));
247 693 : case PokitProduct::PokitPro:
248 693 : return PokitPro::maxValue(static_cast<PokitPro::ResistanceRange>(range));
249 896 : }
250 951 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
251 138 : return 0;
252 896 : }
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 10197 : QString toString(const PokitProduct product, const quint8 range)
266 6624 : {
267 16821 : switch (product) {
268 14973 : case PokitProduct::PokitMeter:
269 14973 : return PokitMeter::toString(static_cast<PokitMeter::VoltageRange>(range));
270 1617 : case PokitProduct::PokitPro:
271 1617 : return PokitPro::toString(static_cast<PokitPro::VoltageRange>(range));
272 6624 : }
273 3959 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
274 147 : return QString();
275 6624 : }
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 1545 : quint32 maxValue(const PokitProduct product, const quint8 range)
284 1920 : {
285 3465 : switch (product) {
286 1617 : case PokitProduct::PokitMeter:
287 1617 : return PokitMeter::maxValue(static_cast<PokitMeter::VoltageRange>(range));
288 1617 : case PokitProduct::PokitPro:
289 1617 : return PokitPro::maxValue(static_cast<PokitPro::VoltageRange>(range));
290 1920 : }
291 1607 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
292 138 : return 0;
293 1920 : }
294 :
295 : }
296 :
297 : /// \endcond
298 :
299 : QTPOKIT_END_NAMESPACE
|