Dokit
Internal development documentation
Loading...
Searching...
No Matches
DataLoggerServicePrivate Class Reference

The DataLoggerServicePrivate class provides private implementation for DataLoggerService. More...

Inheritance diagram for DataLoggerServicePrivate:
[legend]
Collaboration diagram for DataLoggerServicePrivate:
[legend]

Public Member Functions

 DataLoggerServicePrivate (QLowEnergyController *controller, DataLoggerService *const q)
 
- Public Member Functions inherited from AbstractPokitServicePrivate
 AbstractPokitServicePrivate (const QBluetoothUuid &serviceUuid, QLowEnergyController *controller, AbstractPokitService *const q)
 
bool createServiceObject ()
 Creates an internal service object from the internal controller.
 
QLowEnergyCharacteristic getCharacteristic (const QBluetoothUuid &uuid) const
 Get uuid characteristc from the underlying service.
 
bool readCharacteristic (const QBluetoothUuid &uuid)
 Read the uuid characteristic.
 
bool enableCharacteristicNotificatons (const QBluetoothUuid &uuid)
 Enables client (Pokit device) side notification for characteristic uuid.
 
bool disableCharacteristicNotificatons (const QBluetoothUuid &uuid)
 Disables client (Pokit device) side notification for characteristic uuid.
 
- Public Member Functions inherited from QObject
virtual const QMetaObjectmetaObject () const const
 
 QObject (QObject *parent)
 
virtual bool event (QEvent *e)
 
virtual bool eventFilter (QObject *watched, QEvent *event)
 
QString objectName () const const
 
void setObjectName (const QString &name)
 
bool isWidgetType () const const
 
bool isWindowType () const const
 
bool signalsBlocked () const const
 
bool blockSignals (bool block)
 
QThreadthread () const const
 
void moveToThread (QThread *targetThread)
 
int startTimer (int interval, Qt::TimerType timerType)
 
int startTimer (std::chrono::milliseconds time, Qt::TimerType timerType)
 
void killTimer (int id)
 
findChild (const QString &name, Qt::FindChildOptions options) const const
 
QList< T > findChildren (const QString &name, Qt::FindChildOptions options) const const
 
QList< T > findChildren (const QRegExp &regExp, Qt::FindChildOptions options) const const
 
QList< T > findChildren (const QRegularExpression &re, Qt::FindChildOptions options) const const
 
const QObjectListchildren () const const
 
void setParent (QObject *parent)
 
void installEventFilter (QObject *filterObj)
 
void removeEventFilter (QObject *obj)
 
QMetaObject::Connection connect (const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const const
 
bool disconnect (const char *signal, const QObject *receiver, const char *method) const const
 
bool disconnect (const QObject *receiver, const char *method) const const
 
void dumpObjectTree ()
 
void dumpObjectInfo ()
 
void dumpObjectTree () const const
 
void dumpObjectInfo () const const
 
bool setProperty (const char *name, const QVariant &value)
 
QVariant property (const char *name) const const
 
QList< QByteArraydynamicPropertyNames () const const
 
void destroyed (QObject *obj)
 
void objectNameChanged (const QString &objectName)
 
QObjectparent () const const
 
bool inherits (const char *className) const const
 
void deleteLater ()
 
 Q_DISABLE_COPY (Class)
 
 Q_DISABLE_MOVE (Class)
 
 Q_DISABLE_COPY_MOVE (Class)
 
qobject_cast (QObject *object)
 
qobject_cast (const QObject *object)
 
qFindChild (const QObject *obj, const QString &name)
 
QList< T > qFindChildren (const QObject *obj, const QString &name)
 
QList< T > qFindChildren (const QObject *obj, const QRegExp &regExp)
 
 Q_CLASSINFO (Name, Value)
 
 Q_INTERFACES (...)
 
 Q_PROPERTY (...)
 
 Q_ENUMS (...)
 
 Q_FLAGS (...)
 
 Q_ENUM (...)
 
 Q_FLAG (...)
 
 Q_ENUM_NS (...)
 
 Q_FLAG_NS (...)
 
 Q_OBJECT Q_OBJECT
 
 Q_GADGET Q_GADGET
 
 Q_NAMESPACE Q_NAMESPACE
 
 Q_NAMESPACE_EXPORT (EXPORT_MACRO)
 
 Q_SIGNALS Q_SIGNALS
 
 Q_SIGNAL Q_SIGNAL
 
 Q_SLOTS Q_SLOTS
 
 Q_SLOT Q_SLOT
 
 Q_EMIT Q_EMIT
 
 Q_INVOKABLE Q_INVOKABLE
 
 Q_REVISION Q_REVISION
 
 Q_SET_OBJECT_NAME (Object)
 
 QT_NO_NARROWING_CONVERSIONS_IN_CONNECT QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
 

Static Public Member Functions

static QByteArray encodeSettings (const DataLoggerService::Settings &settings, const bool updateIntervalIs32bit)
 Returns settings in the format Pokit devices expect.
 
static DataLoggerService::Metadata parseMetadata (const QByteArray &value)
 Parses the Metadata value into a DataLoggerService::Metatdata struct.
 
static DataLoggerService::Samples parseSamples (const QByteArray &value)
 Parses the Reading value into a DataLoggerService::Samples vector.
 
- Static Public Member Functions inherited from AbstractPokitServicePrivate
static Q_LOGGING_CATEGORY (lc, "pokit.ble.service", QtInfoMsg)
 Logging category.
 
static bool checkSize (const QString &label, const QByteArray &data, const int minSize, const int maxSize=-1, const bool failOnMax=false)
 Returns false if data is smaller than minSize, otherwise returns failOnMax if data is bigger than maxSize, otherwise returns true.
 
static QString toHexString (const QByteArray &data, const int maxSize=20)
 Returns up to maxSize bytes of data as a human readable hexadecimal string.
 
- Static Public Member Functions inherited from QObject
QString tr (const char *sourceText, const char *disambiguation, int n)
 
QString trUtf8 (const char *sourceText, const char *disambiguation, int n)
 
QMetaObject::Connection connect (const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
 
QMetaObject::Connection connect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type)
 
QMetaObject::Connection connect (const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
 
QMetaObject::Connection connect (const QObject *sender, PointerToMemberFunction signal, Functor functor)
 
QMetaObject::Connection connect (const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type)
 
bool disconnect (const QObject *sender, const char *signal, const QObject *receiver, const char *method)
 
bool disconnect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method)
 
bool disconnect (const QMetaObject::Connection &connection)
 
bool disconnect (const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
 

Protected Member Functions

void characteristicRead (const QLowEnergyCharacteristic &characteristic, const QByteArray &value) override
 Implements AbstractPokitServicePrivate::characteristicRead to parse value, then emit a specialised signal, for each supported characteristic.
 
void characteristicWritten (const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue) override
 Implements AbstractPokitServicePrivate::characteristicWritten to parse newValue, then emit a specialised signal, for each supported characteristic.
 
void characteristicChanged (const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue) override
 Implements AbstractPokitServicePrivate::characteristicChanged to parse newValue, then emit a specialised signal, for each supported characteristic.
 
- Protected Member Functions inherited from QObject
QObjectsender () const const
 
int senderSignalIndex () const const
 
int receivers (const char *signal) const const
 
bool isSignalConnected (const QMetaMethod &signal) const const
 
virtual void timerEvent (QTimerEvent *event)
 
virtual void childEvent (QChildEvent *event)
 
virtual void customEvent (QEvent *event)
 
virtual void connectNotify (const QMetaMethod &signal)
 
virtual void disconnectNotify (const QMetaMethod &signal)
 

Additional Inherited Members

- Public Attributes inherited from AbstractPokitServicePrivate
bool autoDiscover { true }
 Whether autodiscovery is enabled or not.
 
QLowEnergyControllercontroller { nullptr }
 BLE controller to fetch the service from.
 
std::optional< PokitProductpokitProduct
 The Pokit product controller is connected to.
 
QLowEnergyServiceservice { nullptr }
 BLE service to read/write characteristics.
 
QBluetoothUuid serviceUuid
 UUIDs for service.
 
- Public Attributes inherited from QObject
typedef QObjectList
 
- Protected Slots inherited from AbstractPokitServicePrivate
void connected ()
 Handles QLowEnergyController::connected events.
 
void discoveryFinished ()
 Handles QLowEnergyController::discoveryFinished events.
 
void errorOccurred (const QLowEnergyService::ServiceError newError)
 Handles QLowEnergyController::errorOccurred events.
 
virtual void serviceDiscovered (const QBluetoothUuid &newService)
 Handles QLowEnergyController::serviceDiscovered events.
 
void stateChanged (QLowEnergyService::ServiceState newState)
 Handles QLowEnergyController::stateChanged events.
 
- Protected Attributes inherited from AbstractPokitServicePrivate
AbstractPokitServiceq_ptr
 Internal q-pointer.
 
- Properties inherited from QObject
 objectName
 

Detailed Description

The DataLoggerServicePrivate class provides private implementation for DataLoggerService.

Definition at line 18 of file dataloggerservice_p.h.

Constructor & Destructor Documentation

◆ DataLoggerServicePrivate()

DataLoggerServicePrivate::DataLoggerServicePrivate ( QLowEnergyController * controller,
DataLoggerService *const q )
explicit

Constructs a new DataLoggerServicePrivate object with public implementation q.

Definition at line 334 of file dataloggerservice.cpp.

337{
338
339}
AbstractPokitServicePrivate(const QBluetoothUuid &serviceUuid, QLowEnergyController *controller, AbstractPokitService *const q)
QLowEnergyController * controller
BLE controller to fetch the service from.
static const QBluetoothUuid serviceUuid
UUID of the "DataLogger" service.

References AbstractPokitServicePrivate::AbstractPokitServicePrivate(), AbstractPokitServicePrivate::controller, and AbstractPokitServicePrivate::serviceUuid.

Here is the call graph for this function:

Member Function Documentation

◆ characteristicChanged()

void DataLoggerServicePrivate::characteristicChanged ( const QLowEnergyCharacteristic & characteristic,
const QByteArray & newValue )
overrideprotectedvirtual

Implements AbstractPokitServicePrivate::characteristicChanged to parse newValue, then emit a specialised signal, for each supported characteristic.

Reimplemented from AbstractPokitServicePrivate.

Definition at line 504 of file dataloggerservice.cpp.

506{
508
509 Q_Q(DataLoggerService);
511 qCWarning(lc).noquote() << tr("Settings characteristic is write-only, but somehow updated")
512 << serviceUuid << characteristic.name() << characteristic.uuid();
513 return;
514 }
515
517 Q_EMIT q->metadataRead(parseMetadata(newValue));
518 return;
519 }
520
522 Q_EMIT q->samplesRead(parseSamples(newValue));
523 return;
524 }
525
526 qCWarning(lc).noquote() << tr("Unknown characteristic notified for Data Logger service")
527 << serviceUuid << characteristic.name() << characteristic.uuid();
528}
QBluetoothUuid serviceUuid
UUIDs for service.
virtual void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue)
Handles QLowEnergyService::characteristicChanged events.
static DataLoggerService::Samples parseSamples(const QByteArray &value)
Parses the Reading value into a DataLoggerService::Samples vector.
static DataLoggerService::Metadata parseMetadata(const QByteArray &value)
Parses the Metadata value into a DataLoggerService::Metatdata struct.
QString name() const const
QBluetoothUuid uuid() const const
Q_EMITQ_EMIT
QString tr(const char *sourceText, const char *disambiguation, int n)
static const QBluetoothUuid metadata
UUID of the DataLogger service's Metadata characterstic.
static const QBluetoothUuid settings
UUID of the DataLogger service's Settings characterstic.
static const QBluetoothUuid reading
UUID of the DataLogger service's Reading characterstic.

References AbstractPokitServicePrivate::characteristicChanged(), DataLoggerService::CharacteristicUuids::metadata, QLowEnergyCharacteristic::name(), parseMetadata(), parseSamples(), QObject::Q_EMIT(), DataLoggerService::CharacteristicUuids::reading, AbstractPokitServicePrivate::serviceUuid, DataLoggerService::CharacteristicUuids::settings, QObject::tr(), and QLowEnergyCharacteristic::uuid().

Here is the call graph for this function:

◆ characteristicRead()

void DataLoggerServicePrivate::characteristicRead ( const QLowEnergyCharacteristic & characteristic,
const QByteArray & value )
overrideprotectedvirtual

Implements AbstractPokitServicePrivate::characteristicRead to parse value, then emit a specialised signal, for each supported characteristic.

Reimplemented from AbstractPokitServicePrivate.

Definition at line 442 of file dataloggerservice.cpp.

444{
446
448 qCWarning(lc).noquote() << tr("Settings characteristic is write-only, but somehow read")
449 << serviceUuid << characteristic.name() << characteristic.uuid();
450 return;
451 }
452
453 Q_Q(DataLoggerService);
455 Q_EMIT q->metadataRead(parseMetadata(value));
456 return;
457 }
458
460 qCWarning(lc).noquote() << tr("Reading characteristic is notify-only")
461 << serviceUuid << characteristic.name() << characteristic.uuid();
462 return;
463 }
464
465 qCWarning(lc).noquote() << tr("Unknown characteristic read for Data Logger service")
466 << serviceUuid << characteristic.name() << characteristic.uuid();
467}
virtual void characteristicRead(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
Handles QLowEnergyService::characteristicRead events.

References AbstractPokitServicePrivate::characteristicRead(), DataLoggerService::CharacteristicUuids::metadata, QLowEnergyCharacteristic::name(), parseMetadata(), QObject::Q_EMIT(), DataLoggerService::CharacteristicUuids::reading, AbstractPokitServicePrivate::serviceUuid, DataLoggerService::CharacteristicUuids::settings, QObject::tr(), and QLowEnergyCharacteristic::uuid().

Here is the call graph for this function:

◆ characteristicWritten()

void DataLoggerServicePrivate::characteristicWritten ( const QLowEnergyCharacteristic & characteristic,
const QByteArray & newValue )
overrideprotectedvirtual

Implements AbstractPokitServicePrivate::characteristicWritten to parse newValue, then emit a specialised signal, for each supported characteristic.

Reimplemented from AbstractPokitServicePrivate.

Definition at line 473 of file dataloggerservice.cpp.

475{
477
478 Q_Q(DataLoggerService);
480 Q_EMIT q->settingsWritten();
481 return;
482 }
483
485 qCWarning(lc).noquote() << tr("Metadata characteristic is read/notify, but somehow written")
486 << serviceUuid << characteristic.name() << characteristic.uuid();
487 return;
488 }
489
491 qCWarning(lc).noquote() << tr("Reading characteristic is notify-only, but somehow written")
492 << serviceUuid << characteristic.name() << characteristic.uuid();
493 return;
494 }
495
496 qCWarning(lc).noquote() << tr("Unknown characteristic written for Data Logger service")
497 << serviceUuid << characteristic.name() << characteristic.uuid();
498}
virtual void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue)
Handles QLowEnergyService::characteristicWritten events.

References AbstractPokitServicePrivate::characteristicWritten(), DataLoggerService::CharacteristicUuids::metadata, QLowEnergyCharacteristic::name(), QObject::Q_EMIT(), DataLoggerService::CharacteristicUuids::reading, AbstractPokitServicePrivate::serviceUuid, DataLoggerService::CharacteristicUuids::settings, QObject::tr(), and QLowEnergyCharacteristic::uuid().

Here is the call graph for this function:

◆ encodeSettings()

QByteArray DataLoggerServicePrivate::encodeSettings ( const DataLoggerService::Settings & settings,
const bool updateIntervalIs32bit )
static

Returns settings in the format Pokit devices expect.

If updateIntervalIs32bit is true then the Update Interval field will be encoded in 32-bit instead of 16.

Pokit Bluetooth API errata
For Pokit Meter, updateInterval is uint16 seconds (as per the Pokit API 1.00), however for Pokit Pro it's uint32 milliseconds, even though that's not officially documented anywhere.

Definition at line 345 of file dataloggerservice.cpp.

347{
348 static_assert(sizeof(settings.command) == 1, "Expected to be 1 byte.");
349 static_assert(sizeof(settings.arguments) == 2, "Expected to be 2 bytes.");
350 static_assert(sizeof(settings.mode) == 1, "Expected to be 1 byte.");
351 static_assert(sizeof(settings.range) == 1, "Expected to be 1 byte.");
352 static_assert(sizeof(settings.updateInterval) == 4, "Expected to be 4 bytes.");
353 static_assert(sizeof(settings.timestamp) == 4, "Expected to be 4 bytes.");
354
355 QByteArray value;
356 QDataStream stream(&value, QIODevice::WriteOnly);
357 stream.setByteOrder(QDataStream::LittleEndian);
358 stream.setFloatingPointPrecision(QDataStream::SinglePrecision); // 32-bit floats, not 64-bit.
359 stream << (quint8)settings.command << settings.arguments << (quint8)settings.mode << settings.range;
360
361 /*!
362 * \pokitApi For Pokit Meter, `updateInterval` is `uint16` seconds (as per the Pokit API 1.00),
363 * however for Pokit Pro it's `uint32` milliseconds, even though that's not officially
364 * documented anywhere.
365 */
366
367 if (!updateIntervalIs32bit) {
368 stream << (quint16)((settings.updateInterval+500)/1000) << settings.timestamp;
369 Q_ASSERT(value.size() == 11); // According to Pokit API 1.00.
370 } else {
371 stream << settings.updateInterval << settings.timestamp;
372 Q_ASSERT(value.size() == 13); // According to testing / experimentation.
373 }
374 return value;
375}
int size() const const
quint32 timestamp
Custom timestamp for start time in retrieved metadata.
quint16 arguments
Reserved to used along with command in future.
Command command
Custom operation request.
Mode mode
Desired operation mode.
quint32 updateInterval
Desired update interval in milliseconds.

References DataLoggerService::Settings::arguments, DataLoggerService::Settings::command, QDataStream::LittleEndian, DataLoggerService::Settings::mode, DataLoggerService::Settings::range, QDataStream::setByteOrder(), QDataStream::setFloatingPointPrecision(), QDataStream::SinglePrecision, QByteArray::size(), DataLoggerService::Settings::timestamp, DataLoggerService::Settings::updateInterval, and QIODevice::WriteOnly.

Referenced by DataLoggerService::setSettings().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseMetadata()

DataLoggerService::Metadata DataLoggerServicePrivate::parseMetadata ( const QByteArray & value)
static

Parses the Metadata value into a DataLoggerService::Metatdata struct.

Pokit Bluetooth API errata
For Pokit Meter, updateInterval is uint16 (as per the Pokit API 1.00), however for Pokit Pro it's uint32, even though that's not officially documented anywhere. Also note, the doc claims 'microseconds' (ie 10^-6), but clearly the value is 'milliseconds' (ie 10^-3) for Pokit Pro, and whole seconds for Pokit Meter.

Definition at line 380 of file dataloggerservice.cpp.

381{
382 DataLoggerService::Metadata metadata{
383 DataLoggerService::LoggerStatus::Error, std::numeric_limits<float>::quiet_NaN(),
385 };
386
387 // Pokit Meter: 15 bytes, Pokit Pro: 23 bytes.
388 if (!checkSize(QLatin1String("Metadata"), value, 15, 23)) {
389 return metadata;
390 }
391
392 qCDebug(lc) << value.mid(7,12).toHex(',');
393 metadata.status = static_cast<DataLoggerService::LoggerStatus>(value.at(0));
394 metadata.scale = qFromLittleEndian<float>(value.mid(1,4).constData());
395 metadata.mode = static_cast<DataLoggerService::Mode>(value.at(5));
396 metadata.range = static_cast<quint8>(value.at(6));
397
398 /*!
399 * \pokitApi For Pokit Meter, `updateInterval` is `uint16` (as per the Pokit API 1.00), however
400 * for Pokit Pro it's `uint32`, even though that's not officially documented anywhere.
401 * Also note, the doc claims 'microseconds' (ie 10^-6), but clearly the value is 'milliseconds'
402 * (ie 10^-3) for Pokit Pro, and whole seconds for Pokit Meter.
403 */
404
405 if (value.size() == 15) {
406 metadata.updateInterval = qFromLittleEndian<quint16>(value.mid(7,2).constData())*1000;
407 metadata.numberOfSamples = qFromLittleEndian<quint16>(value.mid(9,2).constData());
408 metadata.timestamp = qFromLittleEndian<quint32>(value.mid(11,4).constData());
409 } else if (value.size() == 23) {
410 metadata.updateInterval = qFromLittleEndian<quint32>(value.mid(7,4).constData());
411 metadata.numberOfSamples = qFromLittleEndian<quint16>(value.mid(11,2).constData());
412 metadata.timestamp = qFromLittleEndian<quint32>(value.mid(19,4).constData());
413 } else {
414 qCWarning(lc).noquote() << tr("Cannot decode metadata of %n byte/s: %1", nullptr, value.size())
415 .arg(toHexString(value));
416 }
417 return metadata;
418}
static QString toHexString(const QByteArray &data, const int maxSize=20)
Returns up to maxSize bytes of data as a human readable hexadecimal string.
static bool checkSize(const QString &label, const QByteArray &data, const int minSize, const int maxSize=-1, const bool failOnMax=false)
Returns false if data is smaller than minSize, otherwise returns failOnMax if data is bigger than max...
LoggerStatus
Values supported by the Status attribute of the Metadata characteristic.
@ Error
An error has occurred.
Mode
Values supported by the Mode attribute of the Settings and Metadata characteristics.
@ Idle
Make device idle.
char at(int i) const const
const char * constData() const const
QByteArray mid(int pos, int len) const const
QByteArray toHex() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const

References QString::arg(), QByteArray::at(), AbstractPokitServicePrivate::checkSize(), QByteArray::constData(), DataLoggerService::Error, DataLoggerService::Idle, QByteArray::mid(), QByteArray::size(), QByteArray::toHex(), AbstractPokitServicePrivate::toHexString(), and QObject::tr().

Referenced by characteristicChanged(), characteristicRead(), and DataLoggerService::metadata().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseSamples()

DataLoggerService::Samples DataLoggerServicePrivate::parseSamples ( const QByteArray & value)
static

Parses the Reading value into a DataLoggerService::Samples vector.

Definition at line 423 of file dataloggerservice.cpp.

424{
426 if ((value.size()%2) != 0) {
427 qCWarning(lc).noquote() << tr("Samples value has odd size %1 (should be even): %2")
428 .arg(value.size()).arg(toHexString(value));
429 return samples;
430 }
431 while ((samples.size()*2) < value.size()) {
432 samples.append(qFromLittleEndian<qint16>(value.mid(samples.size()*2,2).constData()));
433 }
434 qCDebug(lc).noquote() << tr("Read %n sample/s from %1-bytes.", nullptr, samples.size()).arg(value.size());
435 return samples;
436}
QVector< qint16 > Samples
Raw samples from the Reading characteristic.
void append(const T &value)
int size() const const

References QVector::append(), QString::arg(), QByteArray::constData(), QByteArray::mid(), QByteArray::size(), QVector::size(), AbstractPokitServicePrivate::toHexString(), and QObject::tr().

Referenced by characteristicChanged().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: