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