Dokit
Internal development documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
calibrationservice.cpp
Go to the documentation of this file.
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 CalibrationService and CalibrationServicePrivate classes.
7 */
8
11
12#include <QtEndian>
13
15
16/*!
17 * \class CalibrationService
18 *
19 * The CalibrationService class accesses the `Calibrartion` service of Pokit devices.
20 */
21
22
23/*!
24 * Constructs a new Pokit service with \a parent.
25 */
27 : AbstractPokitService(new CalibrationServicePrivate(controller, this), parent)
28{
29
30}
31
32/*!
33 * \cond internal
34 * Constructs a new Pokit service with \a parent, and private implementation \a d.
35 */
37 CalibrationServicePrivate * const d, QObject * const parent)
38 : AbstractPokitService(d, parent)
39{
40
41}
42/// \endcond
43
44/*!
45 * \copybrief AbstractPokitService::readCharacteristics
46 *
47 * This implementation always returns `true`, since the Calibration service provides no *readable*
48 * characteristics (they're all write-only).
49 */
51{
53 qCDebug(d->lc).noquote() << tr("Ignoring read request; the Calibration service is write-only.");
54 return true;
55}
56
57/*!
58 * Calibrates the Pokit device's temperature to \a ambientTemperature.
59 *
60 * Returns `true` if the write request was successfully queued, `false` otherwise.
61 *
62 * Emits temperatureCalibrated() if/when the \a name has been set.
63 */
64bool CalibrationService::calibrateTemperature(const float ambientTemperature)
65{
66 static_assert(sizeof(float) == 4, "Pokit devices expect 32-bit floats");
67 Q_D(const CalibrationService);
68 const QLowEnergyCharacteristic characteristic =
69 d->getCharacteristic(CharacteristicUuids::temperature);
70 if (!characteristic.isValid()) {
71 return false;
72 }
73
74 const QByteArray newValue = CalibrationServicePrivate::encodeTemperature(ambientTemperature);
75 qCDebug(d->lc).noquote() << tr("Writing new temperature %1 (0x%2).")
76 .arg(ambientTemperature).arg(QLatin1String(newValue.toHex()));
77 d->service->writeCharacteristic(characteristic, newValue);
78 return (d->service->error() != QLowEnergyService::ServiceError::CharacteristicWriteError);
79}
80
81/*!
82 * \fn CalibrationService::temperatureCalibrated
83 *
84 * This signal is emitted when the `Temperature` characteristic has been written successfully.
85 *
86 * \see calibrateTemperature
87 */
88
89/*!
90 * \cond internal
91 * \class CalibrationServicePrivate
92 *
93 * The CalibrationServicePrivate class provides private implementation for CalibrationService.
94 */
95
96/*!
97 * \internal
98 * Constructs a new CalibrationServicePrivate object with public implementation \a q.
99 */
106
107/*!
108 * Returns \a value in a format Pokit devices expect. Specifically, this just encodes \a value as
109 * a 32-bit float in litte-endian byte order.
110 */
112{
113 static_assert(sizeof(value) == 4, "Pokit devices expect 32-bit floats");
114 QByteArray bytes(sizeof(float), '\0');
115 qToLittleEndian<float>(value, bytes.data());
116 return bytes;
117}
118
119/*!
120 * Implements AbstractPokitServicePrivate::characteristicWritten to parse \a newValue, then emit a
121 * specialised signal, for each supported \a characteristic.
122 */
124 const QByteArray &newValue)
125{
127
130 Q_EMIT q->temperatureCalibrated();
131 return;
132 }
133
134 qCWarning(lc).noquote() << tr("Unknown characteristic written for Calibration service")
135 << serviceUuid << characteristic.name() << characteristic.uuid();
136}
137
138/// \endcond
139
Declares the CalibrationService class.
Declares the CalibrationServicePrivate class.
QBluetoothUuid serviceUuid
UUIDs for service.
AbstractPokitServicePrivate(const QBluetoothUuid &serviceUuid, QLowEnergyController *controller, AbstractPokitService *const q)
virtual void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue)
Handles QLowEnergyService::characteristicWritten events.
QLowEnergyController * controller
BLE controller to fetch the service from.
The CalibrationServicePrivate class provides private implementation for CalibrationService.
CalibrationServicePrivate(QLowEnergyController *controller, CalibrationService *const q)
static QByteArray encodeTemperature(const float value)
Returns value in a format Pokit devices expect.
void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue) override
Implements AbstractPokitServicePrivate::characteristicWritten to parse newValue, then emit a speciali...
The CalibrationService class accesses the Calibrartion service of Pokit devices.
bool calibrateTemperature(const float ambientTemperature)
Calibrates the Pokit device's temperature to ambientTemperature.
CalibrationService(QLowEnergyController *const pokitDevice, QObject *parent=nullptr)
Constructs a new Pokit service with parent.
bool readCharacteristics() override
Read all characteristics.
char * data()
QByteArray toHex() const const
bool isValid() const const
QString name() const const
QBluetoothUuid uuid() const const
QObject(QObject *parent)
Q_EMITQ_EMIT
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
#define QTPOKIT_BEGIN_NAMESPACE
Macro for starting the QtPokit library's top-most namespace (if one is defined).
#define QTPOKIT_END_NAMESPACE
Macro for ending the QtPokit library's top-most namespace (if one is defined).
static const QBluetoothUuid temperature
UUID of the Calibration service's Temperature characteristic.