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 2548 : static Q_LOGGING_CATEGORY(lc, "dokit.pokit.products", QtInfoMsg); ///< Logging category for this file.
24 :
25 : namespace {
26 : class Private
27 : {
28 1470 : 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 210 : QString toString(const PokitProduct product)
36 333 : {
37 543 : switch (product) {
38 181 : case PokitProduct::PokitMeter: return u"Pokit Meter"_s;
39 181 : case PokitProduct::PokitPro: return u"Pokit Pro"_s;
40 333 : }
41 433 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
42 111 : return QString();
43 333 : }
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 1994 : bool isPokitProduct(const QBluetoothDeviceInfo &info)
52 3111 : {
53 5975 : return isPokitProduct(info.serviceUuids());
54 3111 : }
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 350 : PokitProduct pokitProduct(const QBluetoothDeviceInfo &info)
64 555 : {
65 1135 : return pokitProduct(info.serviceUuids());
66 555 : }
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 3254 : bool isPokitProduct(const QList<QBluetoothUuid> &serviceUuids)
76 4599 : {
77 9077 : return (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter) ||
78 7853 : serviceUuids.contains(StatusService::ServiceUuids::pokitPro));
79 4599 : }
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 420 : bool isPokitProduct(const QLowEnergyController &controller)
91 156 : {
92 756 : return isPokitProduct(controller.services());
93 156 : }
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 1050 : PokitProduct pokitProduct(const QList<QBluetoothUuid> &serviceUuids)
104 1240 : {
105 2290 : if (serviceUuids.contains(StatusService::ServiceUuids::pokitMeter)) {
106 444 : return PokitProduct::PokitMeter;
107 1566 : } else if (serviceUuids.contains(StatusService::ServiceUuids::pokitPro)) {
108 444 : return PokitProduct::PokitPro;
109 522 : } else {
110 1892 : qCWarning(lc).noquote() << Private::tr("Device is not a Pokit product");
111 1080 : qCDebug(lc).noquote() << "Service UUIDs:" << serviceUuids;
112 604 : return PokitProduct::PokitMeter; // Need to fallback to something; Pokit Meter is just the lowest product.
113 352 : }
114 1240 : }
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 350 : PokitProduct pokitProduct(const QLowEnergyController &controller)
125 130 : {
126 710 : return pokitProduct(controller.services());
127 130 : }
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 770 : QString toString(const PokitProduct product, const quint8 range)
140 711 : {
141 1481 : switch (product) {
142 469 : case PokitProduct::PokitMeter:
143 1069 : qCWarning(lc).noquote() << Private::tr("Pokit Meter has no capacitance support");
144 189 : return QString();
145 831 : case PokitProduct::PokitPro:
146 831 : return PokitPro::toString(static_cast<PokitPro::CapacitanceRange>(range));
147 711 : }
148 535 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
149 111 : return QString();
150 711 : }
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 350 : quint32 maxValue(const PokitProduct product, const quint8 range)
160 555 : {
161 905 : switch (product) {
162 181 : case PokitProduct::PokitMeter:
163 331 : qCWarning(lc).noquote() << Private::tr("Pokit Meter has no capacitance support");
164 119 : return 0;
165 543 : case PokitProduct::PokitPro:
166 543 : return PokitPro::maxValue(static_cast<PokitPro::CapacitanceRange>(range));
167 555 : }
168 535 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
169 119 : return 0;
170 555 : }
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 6930 : QString toString(const PokitProduct product, const quint8 range)
184 3849 : {
185 10779 : switch (product) {
186 9331 : case PokitProduct::PokitMeter:
187 9331 : return PokitMeter::toString(static_cast<PokitMeter::CurrentRange>(range));
188 1267 : case PokitProduct::PokitPro:
189 1267 : return PokitPro::toString(static_cast<PokitPro::CurrentRange>(range));
190 3849 : }
191 1045 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
192 111 : return QString();
193 3849 : }
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 1050 : quint32 maxValue(const PokitProduct product, const quint8 range)
202 1665 : {
203 2715 : switch (product) {
204 1267 : case PokitProduct::PokitMeter:
205 1267 : return PokitMeter::maxValue(static_cast<PokitMeter::CurrentRange>(range));
206 1267 : case PokitProduct::PokitPro:
207 1267 : return PokitPro::maxValue(static_cast<PokitPro::CurrentRange>(range));
208 1665 : }
209 1045 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
210 119 : return 0;
211 1665 : }
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 910 : QString toString(const PokitProduct product, const quint8 range)
225 933 : {
226 1843 : switch (product) {
227 1119 : case PokitProduct::PokitMeter:
228 1119 : return PokitMeter::toString(static_cast<PokitMeter::ResistanceRange>(range));
229 543 : case PokitProduct::PokitPro:
230 543 : return PokitPro::toString(static_cast<PokitPro::ResistanceRange>(range));
231 933 : }
232 637 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
233 111 : return QString();
234 933 : }
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 490 : quint32 maxValue(const PokitProduct product, const quint8 range)
243 777 : {
244 1267 : switch (product) {
245 543 : case PokitProduct::PokitMeter:
246 543 : return PokitMeter::maxValue(static_cast<PokitMeter::ResistanceRange>(range));
247 543 : case PokitProduct::PokitPro:
248 543 : return PokitPro::maxValue(static_cast<PokitPro::ResistanceRange>(range));
249 777 : }
250 637 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
251 119 : return 0;
252 777 : }
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 6930 : QString toString(const PokitProduct product, const quint8 range)
266 3849 : {
267 10779 : switch (product) {
268 9331 : case PokitProduct::PokitMeter:
269 9331 : return PokitMeter::toString(static_cast<PokitMeter::VoltageRange>(range));
270 1267 : case PokitProduct::PokitPro:
271 1267 : return PokitPro::toString(static_cast<PokitPro::VoltageRange>(range));
272 3849 : }
273 1045 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
274 111 : return QString();
275 3849 : }
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 1050 : quint32 maxValue(const PokitProduct product, const quint8 range)
284 1665 : {
285 2715 : switch (product) {
286 1267 : case PokitProduct::PokitMeter:
287 1267 : return PokitMeter::maxValue(static_cast<PokitMeter::VoltageRange>(range));
288 1267 : case PokitProduct::PokitPro:
289 1267 : return PokitPro::maxValue(static_cast<PokitPro::VoltageRange>(range));
290 1665 : }
291 1045 : qCWarning(lc).noquote() << Private::tr("Unknown PokitProduct value: %1").arg((int)product);
292 119 : return 0;
293 1665 : }
294 :
295 : }
296 :
297 : /// \endcond
298 :
299 : QTPOKIT_END_NAMESPACE
|