mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-07-18 00:43:48 +02:00
Rework multisensor plugin
This commit is contained in:
parent
3e7d72c0d3
commit
0198bc91c1
@ -32,7 +32,7 @@ PLUGIN_DIRS = \
|
||||
pushbullet \
|
||||
usbwde \
|
||||
#senic \
|
||||
#multisensor \
|
||||
multisensor \
|
||||
gpio \
|
||||
|
||||
|
||||
|
||||
@ -44,17 +44,20 @@
|
||||
|
||||
#include "plugininfo.h"
|
||||
#include "devicemanager.h"
|
||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
||||
#include "bluetooth/bluetoothlowenergymanager.h"
|
||||
#include "devicepluginmultisensor.h"
|
||||
|
||||
// http://processors.wiki.ti.com/index.php/SensorTag_User_Guide
|
||||
|
||||
DevicePluginMultiSensor::DevicePluginMultiSensor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginMultiSensor::requiredHardware() const
|
||||
void DevicePluginMultiSensor::init()
|
||||
{
|
||||
return DeviceManager::HardwareResourceBluetoothLE;
|
||||
m_measureTimer = hardwareManager()->pluginTimerManager()->registerTimer(60);
|
||||
connect(m_measureTimer, &PluginTimer::timeout, this, &DevicePluginMultiSensor::onPluginTimer);
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginMultiSensor::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||
@ -64,48 +67,35 @@ DeviceManager::DeviceError DevicePluginMultiSensor::discoverDevices(const Device
|
||||
if (deviceClassId != sensortagDeviceClassId)
|
||||
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||
|
||||
if (!discoverBluetooth())
|
||||
if (!hardwareManager()->bluetoothLowEnergyManager()->available())
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
if (!hardwareManager()->bluetoothLowEnergyManager()->enabled())
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
BluetoothDiscoveryReply *reply = hardwareManager()->bluetoothLowEnergyManager()->discoverDevices();
|
||||
connect(reply, &BluetoothDiscoveryReply::finished, this, &DevicePluginMultiSensor::onBluetoothDiscoveryFinished);
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
|
||||
void DevicePluginMultiSensor::bluetoothDiscoveryFinished(const QList<QBluetoothDeviceInfo> &deviceInfos)
|
||||
{
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
foreach (auto deviceInfo, deviceInfos) {
|
||||
if (deviceInfo.name().contains("SensorTag")) {
|
||||
if (!verifyExistingDevices(deviceInfo)) {
|
||||
DeviceDescriptor descriptor(sensortagDeviceClassId, "SensorTag", deviceInfo.address().toString());
|
||||
ParamList params;
|
||||
params.append(Param(nameParamTypeId, deviceInfo.name()));
|
||||
params.append(Param(macParamTypeId, deviceInfo.address().toString()));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit devicesDiscovered(sensortagDeviceClassId, deviceDescriptors);
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginMultiSensor::setupDevice(Device *device)
|
||||
{
|
||||
qCDebug(dcMultiSensor) << "Setting up MultiSensor" << device->name() << device->params();
|
||||
qCDebug(dcMultiSensor) << "Setting up Multi Sensor" << device->name() << device->params();
|
||||
|
||||
if (device->deviceClassId() == sensortagDeviceClassId) {
|
||||
auto address = QBluetoothAddress(device->paramValue(macParamTypeId).toString());
|
||||
auto name = device->paramValue(nameParamTypeId).toString();
|
||||
auto deviceInfo = QBluetoothDeviceInfo(address, name, 0);
|
||||
|
||||
QSharedPointer<SensorTag> tag{new SensorTag(deviceInfo, QLowEnergyController::PublicAddress, this)};
|
||||
connect(tag.data(), &SensorTag::valueChanged, this,
|
||||
[device, this](StateTypeId state, QVariant value) { device->setStateValue(state, value); });
|
||||
connect(tag.data(), &SensorTag::event, this,
|
||||
[device, this](EventTypeId event) { emit emitEvent(Event(event, device->id())); });
|
||||
m_tags.insert(tag, device);
|
||||
QBluetoothAddress address = QBluetoothAddress(device->paramValue(macParamTypeId).toString());
|
||||
QString name = device->paramValue(nameParamTypeId).toString();
|
||||
QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(address, name, 0);
|
||||
|
||||
tag->connectDevice();
|
||||
BluetoothLowEnergyDevice *bluetoothDevice = hardwareManager()->bluetoothLowEnergyManager()->registerDevice(deviceInfo, QLowEnergyController::PublicAddress);
|
||||
|
||||
SensorTag *sensor = new SensorTag(device, bluetoothDevice, this);
|
||||
connect(sensor, &SensorTag::leftKeyPressed, this, &DevicePluginMultiSensor::onSensorLeftButtonPressed);
|
||||
connect(sensor, &SensorTag::rightKeyPressed, this, &DevicePluginMultiSensor::onSensorRightButtonPressed);
|
||||
|
||||
m_sensors.insert(device, sensor);
|
||||
sensor->bluetoothDevice()->connectDevice();
|
||||
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
@ -115,16 +105,18 @@ DeviceManager::DeviceSetupStatus DevicePluginMultiSensor::setupDevice(Device *de
|
||||
|
||||
void DevicePluginMultiSensor::deviceRemoved(Device *device)
|
||||
{
|
||||
if (!m_tags.values().contains(device))
|
||||
if (!m_sensors.contains(device))
|
||||
return;
|
||||
|
||||
auto tag= m_tags.key(device);
|
||||
m_tags.remove(tag);
|
||||
SensorTag *sensor = m_sensors.value(device);
|
||||
m_sensors.remove(device);
|
||||
hardwareManager()->bluetoothLowEnergyManager()->unregisterDevice(sensor->bluetoothDevice());
|
||||
sensor->deleteLater();
|
||||
}
|
||||
|
||||
bool DevicePluginMultiSensor::verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo)
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
foreach (Device *device, m_sensors.keys()) {
|
||||
if (device->paramValue(macParamTypeId).toString() == deviceInfo.address().toString())
|
||||
return true;
|
||||
}
|
||||
@ -132,4 +124,51 @@ bool DevicePluginMultiSensor::verifyExistingDevices(const QBluetoothDeviceInfo &
|
||||
return false;
|
||||
}
|
||||
|
||||
void DevicePluginMultiSensor::onPluginTimer()
|
||||
{
|
||||
foreach (SensorTag *sensor, m_sensors) {
|
||||
sensor->measure();
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginMultiSensor::onSensorLeftButtonPressed()
|
||||
{
|
||||
SensorTag *sensor = static_cast<SensorTag *>(sender());
|
||||
emit emitEvent(Event(leftKeyEventTypeId, sensor->device()->id()));
|
||||
}
|
||||
|
||||
void DevicePluginMultiSensor::onSensorRightButtonPressed()
|
||||
{
|
||||
SensorTag *sensor = static_cast<SensorTag *>(sender());
|
||||
emit emitEvent(Event(rightKeyEventTypeId, sensor->device()->id()));
|
||||
}
|
||||
|
||||
void DevicePluginMultiSensor::onBluetoothDiscoveryFinished()
|
||||
{
|
||||
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
|
||||
if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) {
|
||||
qCWarning(dcMultiSensor()) << "Bluetooth discovery error:" << reply->error();
|
||||
reply->deleteLater();
|
||||
emit devicesDiscovered(sensortagDeviceClassId, QList<DeviceDescriptor>());
|
||||
return;
|
||||
}
|
||||
|
||||
QList<DeviceDescriptor> deviceDescriptors;
|
||||
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
||||
if (deviceInfo.name().contains("SensorTag")) {
|
||||
if (!verifyExistingDevices(deviceInfo)) {
|
||||
DeviceDescriptor descriptor(sensortagDeviceClassId, "Sensor Tag", deviceInfo.address().toString());
|
||||
ParamList params;
|
||||
params.append(Param(nameParamTypeId, deviceInfo.name()));
|
||||
params.append(Param(macParamTypeId, deviceInfo.address().toString()));
|
||||
descriptor.setParams(params);
|
||||
deviceDescriptors.append(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
emit devicesDiscovered(sensortagDeviceClassId, deviceDescriptors);
|
||||
}
|
||||
|
||||
#endif // BLUETOOTH_LE
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include <QHash>
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "devicemanager.h"
|
||||
#include "plugintimer.h"
|
||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
||||
#include "sensortag.h"
|
||||
|
||||
@ -42,16 +43,24 @@ class DevicePluginMultiSensor : public DevicePlugin
|
||||
public:
|
||||
explicit DevicePluginMultiSensor();
|
||||
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
void init() override;
|
||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||
void bluetoothDiscoveryFinished(const QList<QBluetoothDeviceInfo> &deviceInfos) override;
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
|
||||
private:
|
||||
PluginTimer *m_measureTimer = nullptr;
|
||||
QHash<Device *, SensorTag *> m_sensors;
|
||||
|
||||
bool verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo);
|
||||
|
||||
QHash<QSharedPointer<SensorTag>,QPointer<Device>> m_tags;
|
||||
private slots:
|
||||
void onPluginTimer();
|
||||
|
||||
void onSensorLeftButtonPressed();
|
||||
void onSensorRightButtonPressed();
|
||||
|
||||
void onBluetoothDiscoveryFinished();
|
||||
};
|
||||
|
||||
#endif // BLUETOOTH_LE
|
||||
|
||||
@ -8,8 +8,10 @@ TARGET = $$qtLibraryTarget(guh_devicepluginmultisensor)
|
||||
|
||||
SOURCES += \
|
||||
devicepluginmultisensor.cpp \
|
||||
#sensortag-old.cpp \
|
||||
sensortag.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginmultisensor.h \
|
||||
#sensortag-old.h \
|
||||
sensortag.h
|
||||
|
||||
337
multisensor/sensortag-old.cpp
Normal file
337
multisensor/sensortag-old.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* Copyright (C) 2016 nicc *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifdef BLUETOOTH_LE
|
||||
|
||||
#include <QPointer>
|
||||
#include <QLowEnergyService>
|
||||
#include <QtMath>
|
||||
#include "extern-plugininfo.h"
|
||||
#include "sensortag-old.h"
|
||||
|
||||
SensorTag::SensorTag(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent) :
|
||||
BluetoothLowEnergyDevice(deviceInfo, addressType, parent)
|
||||
{
|
||||
connect(this, SIGNAL(connectionStatusChanged()), this,SLOT(onConnectionStatusChanged()));
|
||||
connect(this, SIGNAL(servicesDiscoveryFinished()), this, SLOT(setupServices()));
|
||||
}
|
||||
|
||||
double SensorTag::calculateMeanValue(const QList<double> &list)
|
||||
{
|
||||
double sum = 0;
|
||||
foreach (const double &value, list)
|
||||
sum += value;
|
||||
|
||||
return sum / list.count();
|
||||
}
|
||||
|
||||
void SensorTag::setupServices()
|
||||
{
|
||||
foreach (auto id, m_services.keys()) {
|
||||
if (!controller()->services().contains(id)) {
|
||||
qCWarning(dcMultiSensor) << "Service not found for device" << name() << address().toString();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_services.value(id)) {
|
||||
qCWarning(dcMultiSensor) << "Attention! bad implementation of service handling!!";
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcMultiSensor) << "Setup service";
|
||||
|
||||
// service for temperature
|
||||
QSharedPointer<QLowEnergyService> service{controller()->createServiceObject(id, this)};
|
||||
|
||||
if (service.isNull()) {
|
||||
qCWarning(dcMultiSensor) << "Could not create service for device" << name() << address().toString();
|
||||
return;
|
||||
}
|
||||
|
||||
m_services.insert(id, service);
|
||||
|
||||
connect(service.data(), SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(onServiceError(QLowEnergyService::ServiceError)));
|
||||
connect(service.data(), &QLowEnergyService::stateChanged, this, &SensorTag::onServiceStateChanged);
|
||||
connect(service.data(), &QLowEnergyService::characteristicChanged, this, &SensorTag::onServiceCharacteristicChanged);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
connect(service.data(), &QLowEnergyService::characteristicRead, this, &SensorTag::onServiceCharacteristicChanged);
|
||||
#endif
|
||||
|
||||
service->discoverDetails();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorTag::onConnectionStatusChanged()
|
||||
{
|
||||
if (!isConnected()) {
|
||||
// delete the services, they need to be recreated and
|
||||
// rediscovered once the device will be reconnected
|
||||
foreach (QSharedPointer<QLowEnergyService> service, m_services)
|
||||
service->deleteLater();
|
||||
|
||||
emit valueChanged(connectedStateTypeId, false);
|
||||
} else {
|
||||
emit valueChanged(connectedStateTypeId, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SensorTag::onServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||
{
|
||||
QPointer<QLowEnergyService> service = qobject_cast<QLowEnergyService *>(sender());
|
||||
|
||||
switch (state) {
|
||||
case QLowEnergyService::DiscoveringServices:
|
||||
qCDebug(dcMultiSensor) << "Start discovering service" << service->serviceUuid();
|
||||
break;
|
||||
case QLowEnergyService::ServiceDiscovered:
|
||||
if (m_services.contains(service->serviceUuid())) {
|
||||
qCDebug(dcMultiSensor) << "... service discovered.";
|
||||
|
||||
auto dataId = service->serviceUuid();
|
||||
dataId.data1 += 1;
|
||||
auto sensorCharacteristic = service->characteristic(dataId);
|
||||
|
||||
if (!sensorCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor) << "Characteristic not found for device " << name() << address().toString();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto notificationDescriptor = sensorCharacteristic.descriptor(
|
||||
QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
|
||||
if (notificationDescriptor.isValid()) {
|
||||
service->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
qCDebug(dcMultiSensor) << "Measuring";
|
||||
}
|
||||
|
||||
if (service->serviceUuid().data1 == 0xffe0)
|
||||
break;
|
||||
|
||||
auto configId = service->serviceUuid();
|
||||
configId.data1 += 2;
|
||||
auto sensorConfig = service->characteristic(configId);
|
||||
|
||||
if (!sensorConfig.isValid()) {
|
||||
qCWarning(dcMultiSensor) << "Characteristic not found for device " << name() << address().toString();
|
||||
break;
|
||||
}
|
||||
|
||||
if (service->serviceUuid().data1 == 0xf000aa50) {
|
||||
service->writeCharacteristic(sensorConfig, QByteArray::fromHex("07"));
|
||||
} else {
|
||||
service->writeCharacteristic(sensorConfig, QByteArray::fromHex("01"));
|
||||
}
|
||||
|
||||
if (service->serviceUuid().data1 == 0xf000aa40) {
|
||||
service->writeCharacteristic(sensorConfig, QByteArray::fromHex("02"));
|
||||
auto calibId = service->serviceUuid();
|
||||
calibId.data1 += 3;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
service->readCharacteristic(service->characteristic(calibId));
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: initialize the states with the current value
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline quint16 buildUINT16(quint8 loByte, quint8 hiByte) {
|
||||
return ((quint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)));
|
||||
}
|
||||
|
||||
void SensorTag::onServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
{
|
||||
qCDebug(dcMultiSensor) << "Service characteristic changed" << characteristic.uuid().toString() << value.toHex();
|
||||
|
||||
auto id = characteristic.uuid();
|
||||
id.data1 -= 1;
|
||||
switch (characteristic.uuid().data1) {
|
||||
case 0xf000aa01: {
|
||||
const quint16 *data = reinterpret_cast<const quint16 *>(value.constData());
|
||||
qint16 rawTamb = data[1];
|
||||
m_temperatureValues.append((double)rawTamb / 128);
|
||||
if (m_temperatureValues.count() % 60 == 0) {
|
||||
emit valueChanged(temperatureStateTypeId, calculateMeanValue(m_temperatureValues));
|
||||
m_temperatureValues.clear();
|
||||
}
|
||||
|
||||
qint16 Vobj2 = (double)data[0];
|
||||
Vobj2 *= 0.00000015625;
|
||||
double Tdie2 = ((double)rawTamb / 128) + 273.15;
|
||||
const double S0 = 6.4E-14; // Calibration factor
|
||||
const double a1 = 1.75E-3;
|
||||
const double a2 = -1.678E-5;
|
||||
const double b0 = -2.94E-5;
|
||||
const double b1 = -5.7E-7;
|
||||
const double b2 = 4.63E-9;
|
||||
const double c2 = 13.4;
|
||||
const double Tref = 298.15;
|
||||
double S = S0*(1+a1*(Tdie2 - Tref)+a2*qPow((Tdie2 - Tref),2));
|
||||
double Vos = b0 + b1*(Tdie2 - Tref) + b2*qPow((Tdie2 - Tref),2);
|
||||
double fObj = (Vobj2 - Vos) + c2*qPow((Vobj2 - Vos),2);
|
||||
double tObj = qPow(qPow(Tdie2,4) + (fObj/S),.25);
|
||||
m_irTemperatureValues.append(tObj - 273.15);
|
||||
if (m_irTemperatureValues.count() % 60 == 0) {
|
||||
emit valueChanged(IRtemperatureStateTypeId, calculateMeanValue(m_irTemperatureValues));
|
||||
m_irTemperatureValues.clear();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0xf000aa11: {
|
||||
// TODO: evaluate movement
|
||||
|
||||
// const qint8 *data = reinterpret_cast<const qint8 *>(value.constData());
|
||||
// emit valueChanged(accelerationXStateTypeId, (double)data[0] / 64);
|
||||
// emit valueChanged(accelerationYStateTypeId, (double)data[1] / 64);
|
||||
// emit valueChanged(accelerationZStateTypeId, (double)data[2] / 64);
|
||||
break;
|
||||
}
|
||||
case 0xf000aa21: {
|
||||
const quint16 *data = reinterpret_cast<const quint16 *>(value.constData());
|
||||
quint16 rawH = data[1];
|
||||
rawH &= ~0x0003;
|
||||
m_humidityValues.append(-6.0 + 125.0/65536 * (double)rawH);
|
||||
if (m_humidityValues.count() % 60 == 0) {
|
||||
emit valueChanged(humidityStateTypeId, calculateMeanValue(m_humidityValues));
|
||||
m_humidityValues.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xf000aa31: {
|
||||
// TODO: evaluate movement
|
||||
// const qint16 *data = reinterpret_cast<const qint16 *>(value.constData());
|
||||
// emit valueChanged(magneticFieldXStateTypeId, (double)data[0] / 32.768);
|
||||
// emit valueChanged(magneticFieldYStateTypeId, (double)data[1] / 32.768);
|
||||
// emit valueChanged(magneticFieldZStateTypeId, (double)data[2] / 32.768);
|
||||
break;
|
||||
}
|
||||
case 0xf000aa41: {
|
||||
if (m_c.empty())
|
||||
break;
|
||||
const quint16 *data = reinterpret_cast<const quint16 *>(value.constData());
|
||||
quint16 Pr = data[1];
|
||||
qint16 Tr = data[0];
|
||||
// Sensitivity
|
||||
qint64 s = (qint64)m_c[2];
|
||||
qint64 val = (qint64)m_c[3] * Tr;
|
||||
s += (val >> 17);
|
||||
val = (qint64)m_c2[0] * Tr * Tr;
|
||||
s += (val >> 34);
|
||||
// Offset
|
||||
qint64 o = (qint64)m_c2[1] << 14;
|
||||
val = (qint64)m_c2[2] * Tr;
|
||||
o += (val >> 3);
|
||||
val = (qint64)m_c2[3] * Tr * Tr;
|
||||
o += (val >> 19);
|
||||
// Pressure (Pa)
|
||||
qint64 pres = ((qint64)(s * Pr) + o) >> 14;
|
||||
m_pressureValues.append((double)pres/100);
|
||||
if (m_pressureValues.count() % 60 == 0) {
|
||||
emit valueChanged(pressureStateTypeId, calculateMeanValue(m_pressureValues));
|
||||
m_pressureValues.clear();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0xf000aa43: {
|
||||
const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
|
||||
m_c.resize(4);
|
||||
m_c2.resize(4);
|
||||
m_c[0] = buildUINT16(data[0],data[1]);
|
||||
m_c[1] = buildUINT16(data[2],data[3]);
|
||||
m_c[2] = buildUINT16(data[4],data[5]);
|
||||
m_c[3] = buildUINT16(data[6],data[7]);
|
||||
m_c2[0] = buildUINT16(data[8],data[9]);
|
||||
m_c2[1] = buildUINT16(data[10],data[11]);
|
||||
m_c2[2] = buildUINT16(data[12],data[13]);
|
||||
m_c2[3] = buildUINT16(data[14],data[15]);
|
||||
break;
|
||||
}
|
||||
case 0xf000aa51: {
|
||||
// TODO: evaluate movement
|
||||
// const qint16 *data = reinterpret_cast<const qint16 *>(value.constData());
|
||||
// emit valueChanged(rotationXStateTypeId, (double)data[0] / 131.072);
|
||||
// emit valueChanged(rotationYStateTypeId, (double)data[1] / 131.072);
|
||||
// emit valueChanged(rotationZStateTypeId, (double)data[2] / 131.072);
|
||||
break;
|
||||
}
|
||||
case 0xffe1: {
|
||||
const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
|
||||
if (*data & 1)
|
||||
emit event(leftKeyEventTypeId);
|
||||
if (*data & 2)
|
||||
emit event(rightKeyEventTypeId);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SensorTag::onServiceError(const QLowEnergyService::ServiceError &error)
|
||||
{
|
||||
QString errorString;
|
||||
switch (error) {
|
||||
case QLowEnergyService::NoError:
|
||||
errorString = "No error";
|
||||
break;
|
||||
case QLowEnergyService::OperationError:
|
||||
errorString = "Operation error";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QLowEnergyService::CharacteristicReadError:
|
||||
errorString = "Characteristic read error";
|
||||
break;
|
||||
#endif
|
||||
case QLowEnergyService::CharacteristicWriteError:
|
||||
errorString = "Characteristic write error";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QLowEnergyService::DescriptorReadError:
|
||||
errorString = "Descriptor read error";
|
||||
break;
|
||||
#endif
|
||||
case QLowEnergyService::DescriptorWriteError:
|
||||
errorString = "Descriptor write error";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QLowEnergyService::UnknownError:
|
||||
errorString = "Unknown error";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errorString = "Unknown error";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
qCWarning(dcMultiSensor) << "Service of " << name() << address().toString() << ":" << errorString;
|
||||
}
|
||||
|
||||
#endif // BLUETOOTH_LE
|
||||
79
multisensor/sensortag-old.h
Normal file
79
multisensor/sensortag-old.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* Copyright (C) 2016 nicc *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SENSORTAG_H
|
||||
#define SENSORTAG_H
|
||||
|
||||
#ifdef BLUETOOTH_LE
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
#include <QLowEnergyService>
|
||||
|
||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
class SensorTag : public BluetoothLowEnergyDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SensorTag(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void valueChanged(StateTypeId state, QVariant value);
|
||||
void event(EventTypeId event);
|
||||
|
||||
private:
|
||||
QHash<QBluetoothUuid, QSharedPointer<QLowEnergyService>> m_services{
|
||||
{QBluetoothUuid(QUuid("f000aa00-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa10-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa20-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa30-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa40-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa50-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("0000ffe0-0000-1000-8000-00805f9b34fb")), QSharedPointer<QLowEnergyService>()}
|
||||
};
|
||||
|
||||
QVector<quint16> m_c;
|
||||
QVector<qint16> m_c2;
|
||||
|
||||
QList<double> m_temperatureValues;
|
||||
QList<double> m_irTemperatureValues;
|
||||
QList<double> m_humidityValues;
|
||||
QList<double> m_pressureValues;
|
||||
|
||||
double calculateMeanValue(const QList<double> &list);
|
||||
|
||||
private slots:
|
||||
void setupServices();
|
||||
void onConnectionStatusChanged();
|
||||
|
||||
// Service
|
||||
void onServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||
void onServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||
void onServiceError(const QLowEnergyService::ServiceError &error);
|
||||
};
|
||||
#endif // BLUETOOTH_LE
|
||||
|
||||
#endif // SENSORTAG_H
|
||||
@ -1,337 +1,342 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* Copyright (C) 2016 nicc *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifdef BLUETOOTH_LE
|
||||
|
||||
#include <QPointer>
|
||||
#include <QLowEnergyService>
|
||||
#include <QtMath>
|
||||
#include "extern-plugininfo.h"
|
||||
#include "sensortag.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
SensorTag::SensorTag(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent) :
|
||||
BluetoothLowEnergyDevice(deviceInfo, addressType, parent)
|
||||
SensorTag::SensorTag(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_device(device),
|
||||
m_bluetoothDevice(bluetoothDevice)
|
||||
{
|
||||
connect(this, SIGNAL(connectionStatusChanged()), this,SLOT(onConnectionStatusChanged()));
|
||||
connect(this, SIGNAL(servicesDiscoveryFinished()), this, SLOT(setupServices()));
|
||||
connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::connectedChanged, this, &SensorTag::onConnectedChanged);
|
||||
connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::servicesDiscoveryFinished, this, &SensorTag::onServiceDiscoveryFinished);
|
||||
}
|
||||
|
||||
double SensorTag::calculateMeanValue(const QList<double> &list)
|
||||
Device *SensorTag::device()
|
||||
{
|
||||
double sum = 0;
|
||||
foreach (const double &value, list)
|
||||
sum += value;
|
||||
|
||||
return sum / list.count();
|
||||
return m_device;
|
||||
}
|
||||
|
||||
void SensorTag::setupServices()
|
||||
BluetoothLowEnergyDevice *SensorTag::bluetoothDevice()
|
||||
{
|
||||
foreach (auto id, m_services.keys()) {
|
||||
if (!controller()->services().contains(id)) {
|
||||
qCWarning(dcMultiSensor) << "Service not found for device" << name() << address().toString();
|
||||
return m_bluetoothDevice;
|
||||
}
|
||||
|
||||
void SensorTag::updateInfraredValue(const QByteArray &value)
|
||||
{
|
||||
qCDebug(dcMultiSensor()) << "Infrared value" << value;
|
||||
}
|
||||
|
||||
void SensorTag::updateButtonValue(const QByteArray &value)
|
||||
{
|
||||
const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
|
||||
if (*data & 1)
|
||||
emit leftKeyPressed();
|
||||
if (*data & 2)
|
||||
emit rightKeyPressed();
|
||||
}
|
||||
|
||||
void SensorTag::updateHumidityValue(const QByteArray &value)
|
||||
{
|
||||
qCDebug(dcMultiSensor()) << "Humidity value" << value;
|
||||
}
|
||||
|
||||
void SensorTag::updatePressureValue(const QByteArray &value)
|
||||
{
|
||||
qCDebug(dcMultiSensor()) << "Pressure value" << value;
|
||||
}
|
||||
|
||||
void SensorTag::onConnectedChanged(const bool &connected)
|
||||
{
|
||||
qCDebug(dcMultiSensor()) << "Sensor" << m_bluetoothDevice->name() << m_bluetoothDevice->address().toString() << (connected ? "connected" : "disconnected");
|
||||
m_device->setStateValue(connectedStateTypeId, connected);
|
||||
|
||||
if (!connected) {
|
||||
// Clean up services
|
||||
m_infraredService->deleteLater();
|
||||
m_buttonService->deleteLater();
|
||||
m_humidityService->deleteLater();
|
||||
m_pressureService->deleteLater();
|
||||
|
||||
m_infraredService = nullptr;
|
||||
m_buttonService = nullptr;
|
||||
m_humidityService = nullptr;
|
||||
m_pressureService = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SensorTag::onServiceDiscoveryFinished()
|
||||
{
|
||||
if (!m_bluetoothDevice->serviceUuids().contains(infraredServiceUuid)) {
|
||||
qCWarning(dcMultiSensor()) << "Could not find infrared service";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_bluetoothDevice->serviceUuids().contains(accelerometerServiceUuid)) {
|
||||
qCWarning(dcMultiSensor()) << "Could not find accelereometer service";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_bluetoothDevice->serviceUuids().contains(humidityServiceUuid)) {
|
||||
qCWarning(dcMultiSensor()) << "Could not find humidity service";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_bluetoothDevice->serviceUuids().contains(magnetometerServiceUuid)) {
|
||||
qCWarning(dcMultiSensor()) << "Could not find magnetometer service";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_bluetoothDevice->serviceUuids().contains(pressureServiceUuid)) {
|
||||
qCWarning(dcMultiSensor()) << "Could not find pressure service";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_bluetoothDevice->serviceUuids().contains(gyroscopeServiceUuid)) {
|
||||
qCWarning(dcMultiSensor()) << "Could not find magnetometer service";
|
||||
return;
|
||||
}
|
||||
|
||||
// IR Temperature
|
||||
if (!m_infraredService) {
|
||||
m_infraredService = m_bluetoothDevice->controller()->createServiceObject(infraredServiceUuid, this);
|
||||
if (!m_infraredService) {
|
||||
qCWarning(dcMultiSensor()) << "Could not create infrared service.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_services.value(id)) {
|
||||
qCWarning(dcMultiSensor) << "Attention! bad implementation of service handling!!";
|
||||
connect(m_infraredService, &QLowEnergyService::stateChanged, this, &SensorTag::onInfraredServiceStateChanged);
|
||||
connect(m_infraredService, &QLowEnergyService::characteristicChanged, this, &SensorTag::onInfraredServiceCharacteristicChanged);
|
||||
|
||||
if (m_infraredService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||
m_infraredService->discoverDetails();
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons
|
||||
if (!m_buttonService) {
|
||||
m_buttonService = m_bluetoothDevice->controller()->createServiceObject(buttonServiceUuid, this);
|
||||
if (!m_buttonService) {
|
||||
qCWarning(dcMultiSensor()) << "Could not create button service.";
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcMultiSensor) << "Setup service";
|
||||
connect(m_buttonService, &QLowEnergyService::stateChanged, this, &SensorTag::onButtonServiceStateChanged);
|
||||
connect(m_buttonService, &QLowEnergyService::characteristicChanged, this, &SensorTag::onButtonServiceCharacteristicChanged);
|
||||
|
||||
// service for temperature
|
||||
QSharedPointer<QLowEnergyService> service{controller()->createServiceObject(id, this)};
|
||||
if (m_buttonService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||
m_buttonService->discoverDetails();
|
||||
}
|
||||
}
|
||||
|
||||
if (service.isNull()) {
|
||||
qCWarning(dcMultiSensor) << "Could not create service for device" << name() << address().toString();
|
||||
// Humidity
|
||||
if (!m_humidityService) {
|
||||
m_humidityService = m_bluetoothDevice->controller()->createServiceObject(humidityServiceUuid, this);
|
||||
if (!m_humidityService) {
|
||||
qCWarning(dcMultiSensor()) << "Could not create humidity service.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_services.insert(id, service);
|
||||
|
||||
connect(service.data(), SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(onServiceError(QLowEnergyService::ServiceError)));
|
||||
connect(service.data(), &QLowEnergyService::stateChanged, this, &SensorTag::onServiceStateChanged);
|
||||
connect(service.data(), &QLowEnergyService::characteristicChanged, this, &SensorTag::onServiceCharacteristicChanged);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
connect(service.data(), &QLowEnergyService::characteristicRead, this, &SensorTag::onServiceCharacteristicChanged);
|
||||
#endif
|
||||
|
||||
service->discoverDetails();
|
||||
connect(m_humidityService, &QLowEnergyService::stateChanged, this, &SensorTag::onHumidityServiceStateChanged);
|
||||
connect(m_humidityService, &QLowEnergyService::characteristicChanged, this, &SensorTag::onHumidityServiceCharacteristicChanged);
|
||||
if (m_humidityService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||
m_humidityService->discoverDetails();
|
||||
}
|
||||
}
|
||||
|
||||
// Pressure
|
||||
if (!m_pressureService) {
|
||||
m_pressureService = m_bluetoothDevice->controller()->createServiceObject(pressureServiceUuid, this);
|
||||
if (!m_pressureService) {
|
||||
qCWarning(dcMultiSensor()) << "Could not create pressure service.";
|
||||
return;
|
||||
}
|
||||
|
||||
connect(m_pressureService, &QLowEnergyService::stateChanged, this, &SensorTag::onPressureServiceStateChanged);
|
||||
connect(m_pressureService, &QLowEnergyService::characteristicChanged, this, &SensorTag::onPressureServiceCharacteristicChanged);
|
||||
if (m_pressureService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||
m_pressureService->discoverDetails();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SensorTag::onConnectionStatusChanged()
|
||||
void SensorTag::onInfraredServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||
{
|
||||
if (!isConnected()) {
|
||||
// delete the services, they need to be recreated and
|
||||
// rediscovered once the device will be reconnected
|
||||
foreach (QSharedPointer<QLowEnergyService> service, m_services)
|
||||
service->deleteLater();
|
||||
// Only continue if discovered
|
||||
if (state != QLowEnergyService::ServiceDiscovered)
|
||||
return;
|
||||
|
||||
emit valueChanged(connectedStateTypeId, false);
|
||||
} else {
|
||||
emit valueChanged(connectedStateTypeId, true);
|
||||
qCDebug(dcMultiSensor()) << "Infrared sensor service discovered.";
|
||||
|
||||
foreach (const QLowEnergyCharacteristic &characteristic, m_infraredService->characteristics()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << characteristic.name() << characteristic.uuid().toString() << characteristic.value();
|
||||
foreach (const QLowEnergyDescriptor &desciptor, characteristic.descriptors()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << desciptor.name() << desciptor.uuid().toString() << desciptor.value();
|
||||
}
|
||||
}
|
||||
|
||||
// Data characteristic
|
||||
m_infraredDataCharacteristic = m_infraredService->characteristic(QBluetoothUuid(QUuid("f000aa01-0451-4000-b000-000000000000")));
|
||||
if (!m_infraredDataCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid infrared data characteristic.";
|
||||
}
|
||||
|
||||
// Enable notifications
|
||||
QLowEnergyDescriptor notificationDescriptor = m_infraredDataCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
m_infraredService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
|
||||
|
||||
// Config characteristic
|
||||
m_infraredConfigCharacteristic = m_infraredService->characteristic(QBluetoothUuid(QUuid("f000aa02-0451-4000-b000-000000000000")));
|
||||
if (!m_infraredConfigCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid infrared configuration characteristic.";
|
||||
}
|
||||
|
||||
// Enable measuring
|
||||
m_infraredService->writeCharacteristic(m_infraredConfigCharacteristic, QByteArray::fromHex("01"));
|
||||
}
|
||||
|
||||
void SensorTag::onServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||
void SensorTag::onInfraredServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
{
|
||||
QPointer<QLowEnergyService> service = qobject_cast<QLowEnergyService *>(sender());
|
||||
if (characteristic == m_infraredDataCharacteristic) {
|
||||
updateInfraredValue(value);
|
||||
|
||||
switch (state) {
|
||||
case QLowEnergyService::DiscoveringServices:
|
||||
qCDebug(dcMultiSensor) << "Start discovering service" << service->serviceUuid();
|
||||
break;
|
||||
case QLowEnergyService::ServiceDiscovered:
|
||||
if (m_services.contains(service->serviceUuid())) {
|
||||
qCDebug(dcMultiSensor) << "... service discovered.";
|
||||
|
||||
auto dataId = service->serviceUuid();
|
||||
dataId.data1 += 1;
|
||||
auto sensorCharacteristic = service->characteristic(dataId);
|
||||
|
||||
if (!sensorCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor) << "Characteristic not found for device " << name() << address().toString();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto notificationDescriptor = sensorCharacteristic.descriptor(
|
||||
QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
|
||||
if (notificationDescriptor.isValid()) {
|
||||
service->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
qCDebug(dcMultiSensor) << "Measuring";
|
||||
}
|
||||
|
||||
if (service->serviceUuid().data1 == 0xffe0)
|
||||
break;
|
||||
|
||||
auto configId = service->serviceUuid();
|
||||
configId.data1 += 2;
|
||||
auto sensorConfig = service->characteristic(configId);
|
||||
|
||||
if (!sensorConfig.isValid()) {
|
||||
qCWarning(dcMultiSensor) << "Characteristic not found for device " << name() << address().toString();
|
||||
break;
|
||||
}
|
||||
|
||||
if (service->serviceUuid().data1 == 0xf000aa50) {
|
||||
service->writeCharacteristic(sensorConfig, QByteArray::fromHex("07"));
|
||||
} else {
|
||||
service->writeCharacteristic(sensorConfig, QByteArray::fromHex("01"));
|
||||
}
|
||||
|
||||
if (service->serviceUuid().data1 == 0xf000aa40) {
|
||||
service->writeCharacteristic(sensorConfig, QByteArray::fromHex("02"));
|
||||
auto calibId = service->serviceUuid();
|
||||
calibId.data1 += 3;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
service->readCharacteristic(service->characteristic(calibId));
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: initialize the states with the current value
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// FIXME: Disable measuring
|
||||
// m_infraredService->writeCharacteristic(m_infraredConfigCharacteristic, QByteArray::fromHex("00"));
|
||||
}
|
||||
}
|
||||
|
||||
inline quint16 buildUINT16(quint8 loByte, quint8 hiByte) {
|
||||
return ((quint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)));
|
||||
}
|
||||
|
||||
void SensorTag::onServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
void SensorTag::onButtonServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||
{
|
||||
qCDebug(dcMultiSensor) << "Service characteristic changed" << characteristic.uuid().toString() << value.toHex();
|
||||
// Only continue if discovered
|
||||
if (state != QLowEnergyService::ServiceDiscovered)
|
||||
return;
|
||||
|
||||
auto id = characteristic.uuid();
|
||||
id.data1 -= 1;
|
||||
switch (characteristic.uuid().data1) {
|
||||
case 0xf000aa01: {
|
||||
const quint16 *data = reinterpret_cast<const quint16 *>(value.constData());
|
||||
qint16 rawTamb = data[1];
|
||||
m_temperatureValues.append((double)rawTamb / 128);
|
||||
if (m_temperatureValues.count() % 60 == 0) {
|
||||
emit valueChanged(temperatureStateTypeId, calculateMeanValue(m_temperatureValues));
|
||||
m_temperatureValues.clear();
|
||||
qCDebug(dcMultiSensor()) << "Button sensor service discovered.";
|
||||
|
||||
foreach (const QLowEnergyCharacteristic &characteristic, m_buttonService->characteristics()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << characteristic.name() << characteristic.uuid().toString() << characteristic.value();
|
||||
foreach (const QLowEnergyDescriptor &desciptor, characteristic.descriptors()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << desciptor.name() << desciptor.uuid().toString() << desciptor.value();
|
||||
}
|
||||
}
|
||||
|
||||
qint16 Vobj2 = (double)data[0];
|
||||
Vobj2 *= 0.00000015625;
|
||||
double Tdie2 = ((double)rawTamb / 128) + 273.15;
|
||||
const double S0 = 6.4E-14; // Calibration factor
|
||||
const double a1 = 1.75E-3;
|
||||
const double a2 = -1.678E-5;
|
||||
const double b0 = -2.94E-5;
|
||||
const double b1 = -5.7E-7;
|
||||
const double b2 = 4.63E-9;
|
||||
const double c2 = 13.4;
|
||||
const double Tref = 298.15;
|
||||
double S = S0*(1+a1*(Tdie2 - Tref)+a2*qPow((Tdie2 - Tref),2));
|
||||
double Vos = b0 + b1*(Tdie2 - Tref) + b2*qPow((Tdie2 - Tref),2);
|
||||
double fObj = (Vobj2 - Vos) + c2*qPow((Vobj2 - Vos),2);
|
||||
double tObj = qPow(qPow(Tdie2,4) + (fObj/S),.25);
|
||||
m_irTemperatureValues.append(tObj - 273.15);
|
||||
if (m_irTemperatureValues.count() % 60 == 0) {
|
||||
emit valueChanged(IRtemperatureStateTypeId, calculateMeanValue(m_irTemperatureValues));
|
||||
m_irTemperatureValues.clear();
|
||||
}
|
||||
// Data characteristic
|
||||
m_buttonCharacteristic = m_buttonService->characteristic(QBluetoothUuid(QUuid("0000ffe1-0000-1000-8000-00805f9b34fb")));
|
||||
if (!m_buttonCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid button data characteristic.";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0xf000aa11: {
|
||||
// TODO: evaluate movement
|
||||
|
||||
// const qint8 *data = reinterpret_cast<const qint8 *>(value.constData());
|
||||
// emit valueChanged(accelerationXStateTypeId, (double)data[0] / 64);
|
||||
// emit valueChanged(accelerationYStateTypeId, (double)data[1] / 64);
|
||||
// emit valueChanged(accelerationZStateTypeId, (double)data[2] / 64);
|
||||
break;
|
||||
}
|
||||
case 0xf000aa21: {
|
||||
const quint16 *data = reinterpret_cast<const quint16 *>(value.constData());
|
||||
quint16 rawH = data[1];
|
||||
rawH &= ~0x0003;
|
||||
m_humidityValues.append(-6.0 + 125.0/65536 * (double)rawH);
|
||||
if (m_humidityValues.count() % 60 == 0) {
|
||||
emit valueChanged(humidityStateTypeId, calculateMeanValue(m_humidityValues));
|
||||
m_humidityValues.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xf000aa31: {
|
||||
// TODO: evaluate movement
|
||||
// const qint16 *data = reinterpret_cast<const qint16 *>(value.constData());
|
||||
// emit valueChanged(magneticFieldXStateTypeId, (double)data[0] / 32.768);
|
||||
// emit valueChanged(magneticFieldYStateTypeId, (double)data[1] / 32.768);
|
||||
// emit valueChanged(magneticFieldZStateTypeId, (double)data[2] / 32.768);
|
||||
break;
|
||||
}
|
||||
case 0xf000aa41: {
|
||||
if (m_c.empty())
|
||||
break;
|
||||
const quint16 *data = reinterpret_cast<const quint16 *>(value.constData());
|
||||
quint16 Pr = data[1];
|
||||
qint16 Tr = data[0];
|
||||
// Sensitivity
|
||||
qint64 s = (qint64)m_c[2];
|
||||
qint64 val = (qint64)m_c[3] * Tr;
|
||||
s += (val >> 17);
|
||||
val = (qint64)m_c2[0] * Tr * Tr;
|
||||
s += (val >> 34);
|
||||
// Offset
|
||||
qint64 o = (qint64)m_c2[1] << 14;
|
||||
val = (qint64)m_c2[2] * Tr;
|
||||
o += (val >> 3);
|
||||
val = (qint64)m_c2[3] * Tr * Tr;
|
||||
o += (val >> 19);
|
||||
// Pressure (Pa)
|
||||
qint64 pres = ((qint64)(s * Pr) + o) >> 14;
|
||||
m_pressureValues.append((double)pres/100);
|
||||
if (m_pressureValues.count() % 60 == 0) {
|
||||
emit valueChanged(pressureStateTypeId, calculateMeanValue(m_pressureValues));
|
||||
m_pressureValues.clear();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0xf000aa43: {
|
||||
const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
|
||||
m_c.resize(4);
|
||||
m_c2.resize(4);
|
||||
m_c[0] = buildUINT16(data[0],data[1]);
|
||||
m_c[1] = buildUINT16(data[2],data[3]);
|
||||
m_c[2] = buildUINT16(data[4],data[5]);
|
||||
m_c[3] = buildUINT16(data[6],data[7]);
|
||||
m_c2[0] = buildUINT16(data[8],data[9]);
|
||||
m_c2[1] = buildUINT16(data[10],data[11]);
|
||||
m_c2[2] = buildUINT16(data[12],data[13]);
|
||||
m_c2[3] = buildUINT16(data[14],data[15]);
|
||||
break;
|
||||
}
|
||||
case 0xf000aa51: {
|
||||
// TODO: evaluate movement
|
||||
// const qint16 *data = reinterpret_cast<const qint16 *>(value.constData());
|
||||
// emit valueChanged(rotationXStateTypeId, (double)data[0] / 131.072);
|
||||
// emit valueChanged(rotationYStateTypeId, (double)data[1] / 131.072);
|
||||
// emit valueChanged(rotationZStateTypeId, (double)data[2] / 131.072);
|
||||
break;
|
||||
}
|
||||
case 0xffe1: {
|
||||
const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
|
||||
if (*data & 1)
|
||||
emit event(leftKeyEventTypeId);
|
||||
if (*data & 2)
|
||||
emit event(rightKeyEventTypeId);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Enable notifications
|
||||
QLowEnergyDescriptor notificationDescriptor = m_buttonCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
m_buttonService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
}
|
||||
|
||||
void SensorTag::onServiceError(const QLowEnergyService::ServiceError &error)
|
||||
void SensorTag::onButtonServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
{
|
||||
QString errorString;
|
||||
switch (error) {
|
||||
case QLowEnergyService::NoError:
|
||||
errorString = "No error";
|
||||
break;
|
||||
case QLowEnergyService::OperationError:
|
||||
errorString = "Operation error";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QLowEnergyService::CharacteristicReadError:
|
||||
errorString = "Characteristic read error";
|
||||
break;
|
||||
#endif
|
||||
case QLowEnergyService::CharacteristicWriteError:
|
||||
errorString = "Characteristic write error";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QLowEnergyService::DescriptorReadError:
|
||||
errorString = "Descriptor read error";
|
||||
break;
|
||||
#endif
|
||||
case QLowEnergyService::DescriptorWriteError:
|
||||
errorString = "Descriptor write error";
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
case QLowEnergyService::UnknownError:
|
||||
errorString = "Unknown error";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errorString = "Unknown error";
|
||||
break;
|
||||
if (characteristic == m_buttonCharacteristic) {
|
||||
updateButtonValue(value);
|
||||
}
|
||||
|
||||
|
||||
qCWarning(dcMultiSensor) << "Service of " << name() << address().toString() << ":" << errorString;
|
||||
}
|
||||
|
||||
#endif // BLUETOOTH_LE
|
||||
void SensorTag::onHumidityServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||
{
|
||||
// Only continue if discovered
|
||||
if (state != QLowEnergyService::ServiceDiscovered)
|
||||
return;
|
||||
|
||||
qCDebug(dcMultiSensor()) << "Humidity sensor service discovered.";
|
||||
|
||||
foreach (const QLowEnergyCharacteristic &characteristic, m_humidityService->characteristics()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << characteristic.name() << characteristic.uuid().toString() << characteristic.value();
|
||||
foreach (const QLowEnergyDescriptor &desciptor, characteristic.descriptors()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << desciptor.name() << desciptor.uuid().toString() << desciptor.value();
|
||||
}
|
||||
}
|
||||
|
||||
// Data characteristic
|
||||
m_humidityDataCharacteristic = m_humidityService->characteristic(QBluetoothUuid(QUuid("f000aa21-0451-4000-b000-000000000000")));
|
||||
if (!m_humidityDataCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid humidity data characteristic.";
|
||||
}
|
||||
|
||||
// Enable notifications
|
||||
QLowEnergyDescriptor notificationDescriptor = m_humidityDataCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
m_humidityService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
|
||||
// Config characteristic
|
||||
m_humidityConfigCharacteristic = m_humidityService->characteristic(QBluetoothUuid(QUuid("f000aa22-0451-4000-b000-000000000000")));
|
||||
if (!m_humidityConfigCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid humidity configuration characteristic.";
|
||||
}
|
||||
|
||||
// Enable measuring
|
||||
m_humidityService->writeCharacteristic(m_humidityConfigCharacteristic, QByteArray::fromHex("01"));
|
||||
}
|
||||
|
||||
void SensorTag::onHumidityServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
{
|
||||
if (characteristic == m_humidityDataCharacteristic) {
|
||||
updateHumidityValue(value);
|
||||
// FIXME: Disable measuring
|
||||
// m_humidityService->writeCharacteristic(m_humidityConfigCharacteristic, QByteArray::fromHex("00"));
|
||||
}
|
||||
}
|
||||
|
||||
void SensorTag::onPressureServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||
{
|
||||
// Only continue if discovered
|
||||
if (state != QLowEnergyService::ServiceDiscovered)
|
||||
return;
|
||||
|
||||
qCDebug(dcMultiSensor()) << "Pressure sensor service discovered.";
|
||||
|
||||
foreach (const QLowEnergyCharacteristic &characteristic, m_pressureService->characteristics()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << characteristic.name() << characteristic.uuid().toString() << characteristic.value();
|
||||
foreach (const QLowEnergyDescriptor &desciptor, characteristic.descriptors()) {
|
||||
qCDebug(dcMultiSensor()) << " -->" << desciptor.name() << desciptor.uuid().toString() << desciptor.value();
|
||||
}
|
||||
}
|
||||
|
||||
// Data characteristic
|
||||
m_pressureDataCharacteristic = m_pressureService->characteristic(QBluetoothUuid(QUuid("f000aa41-0451-4000-b000-000000000000")));
|
||||
if (!m_pressureDataCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid pressure data characteristic.";
|
||||
}
|
||||
|
||||
// Enable notifications
|
||||
QLowEnergyDescriptor notificationDescriptor = m_pressureDataCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
m_pressureService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
|
||||
// Config characteristic
|
||||
m_pressureConfigCharacteristic = m_pressureService->characteristic(QBluetoothUuid(QUuid("f000aa42-0451-4000-b000-000000000000")));
|
||||
if (!m_pressureConfigCharacteristic.isValid()) {
|
||||
qCWarning(dcMultiSensor()) << "Invalid pressure configuration characteristic.";
|
||||
}
|
||||
|
||||
// Enable measuring
|
||||
m_pressureService->writeCharacteristic(m_pressureConfigCharacteristic, QByteArray::fromHex("01"));
|
||||
}
|
||||
|
||||
void SensorTag::onPressureServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
{
|
||||
if (characteristic == m_pressureDataCharacteristic) {
|
||||
updatePressureValue(value);
|
||||
// FIXME: Disable measuring
|
||||
// m_pressureService->writeCharacteristic(m_pressureConfigCharacteristic, QByteArray::fromHex("00"));
|
||||
}
|
||||
}
|
||||
|
||||
void SensorTag::measure()
|
||||
{
|
||||
if (!m_bluetoothDevice->connected())
|
||||
return;
|
||||
|
||||
// qCDebug(dcMultiSensor()) << "Measure data" << m_bluetoothDevice->name() << m_bluetoothDevice->address().toString();
|
||||
|
||||
// m_infraredService->writeCharacteristic(m_infraredConfigCharacteristic, QByteArray::fromHex("01"));
|
||||
// m_humidityService->writeCharacteristic(m_humidityConfigCharacteristic, QByteArray::fromHex("01"));
|
||||
// m_pressureService->writeCharacteristic(m_pressureConfigCharacteristic, QByteArray::fromHex("01"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,79 +1,88 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* Copyright (C) 2016 nicc *
|
||||
* *
|
||||
* This file is part of guh. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Lesser General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2.1 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SENSORTAG_H
|
||||
#define SENSORTAG_H
|
||||
|
||||
#ifdef BLUETOOTH_LE
|
||||
#include <QObject>
|
||||
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
#include <QLowEnergyService>
|
||||
|
||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
||||
#include "plugin/device.h"
|
||||
#include "extern-plugininfo.h"
|
||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
||||
|
||||
class SensorTag : public BluetoothLowEnergyDevice
|
||||
static QBluetoothUuid infraredServiceUuid = QBluetoothUuid(QUuid("f000aa00-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid accelerometerServiceUuid = QBluetoothUuid(QUuid("f000aa10-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid humidityServiceUuid = QBluetoothUuid(QUuid("f000aa20-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid magnetometerServiceUuid = QBluetoothUuid(QUuid("f000aa30-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid pressureServiceUuid = QBluetoothUuid(QUuid("f000aa40-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid gyroscopeServiceUuid = QBluetoothUuid(QUuid("f000aa50-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid testServiceUuid = QBluetoothUuid(QUuid("f000aa60-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid otaServiceUuid = QBluetoothUuid(QUuid("f000aac0-0451-4000-b000-000000000000"));
|
||||
static QBluetoothUuid buttonServiceUuid = QBluetoothUuid(QUuid("0000ffe0-0000-1000-8000-00805f9b34fb"));
|
||||
|
||||
// Currently unused services
|
||||
|
||||
class SensorTag : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SensorTag(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent = 0);
|
||||
explicit SensorTag(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void valueChanged(StateTypeId state, QVariant value);
|
||||
void event(EventTypeId event);
|
||||
Device *device();
|
||||
BluetoothLowEnergyDevice *bluetoothDevice();
|
||||
|
||||
private:
|
||||
QHash<QBluetoothUuid, QSharedPointer<QLowEnergyService>> m_services{
|
||||
{QBluetoothUuid(QUuid("f000aa00-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa10-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa20-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa30-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa40-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("f000aa50-0451-4000-b000-000000000000")), QSharedPointer<QLowEnergyService>()},
|
||||
{QBluetoothUuid(QUuid("0000ffe0-0000-1000-8000-00805f9b34fb")), QSharedPointer<QLowEnergyService>()}
|
||||
};
|
||||
Device *m_device;
|
||||
BluetoothLowEnergyDevice *m_bluetoothDevice;
|
||||
|
||||
QVector<quint16> m_c;
|
||||
QVector<qint16> m_c2;
|
||||
// Services
|
||||
QLowEnergyService *m_infraredService = nullptr;
|
||||
QLowEnergyService *m_buttonService = nullptr;
|
||||
QLowEnergyService *m_humidityService = nullptr;
|
||||
QLowEnergyService *m_pressureService = nullptr;
|
||||
QLowEnergyService *m_accelerometerService = nullptr;
|
||||
QLowEnergyService *m_magnetometerService = nullptr;
|
||||
QLowEnergyService *m_gyroscopeService = nullptr;
|
||||
|
||||
QList<double> m_temperatureValues;
|
||||
QList<double> m_irTemperatureValues;
|
||||
QList<double> m_humidityValues;
|
||||
QList<double> m_pressureValues;
|
||||
// Characteristics
|
||||
QLowEnergyCharacteristic m_infraredDataCharacteristic;
|
||||
QLowEnergyCharacteristic m_infraredConfigCharacteristic;
|
||||
QLowEnergyCharacteristic m_buttonCharacteristic;
|
||||
QLowEnergyCharacteristic m_humidityDataCharacteristic;
|
||||
QLowEnergyCharacteristic m_humidityConfigCharacteristic;
|
||||
QLowEnergyCharacteristic m_pressureDataCharacteristic;
|
||||
QLowEnergyCharacteristic m_pressureConfigCharacteristic;
|
||||
|
||||
double calculateMeanValue(const QList<double> &list);
|
||||
|
||||
void updateInfraredValue(const QByteArray &value);
|
||||
void updateButtonValue(const QByteArray &value);
|
||||
void updateHumidityValue(const QByteArray &value);
|
||||
void updatePressureValue(const QByteArray &value);
|
||||
|
||||
signals:
|
||||
void leftKeyPressed();
|
||||
void rightKeyPressed();
|
||||
|
||||
private slots:
|
||||
void setupServices();
|
||||
void onConnectionStatusChanged();
|
||||
void onConnectedChanged(const bool &connected);
|
||||
void onServiceDiscoveryFinished();
|
||||
|
||||
// Service
|
||||
void onServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||
void onServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||
void onServiceError(const QLowEnergyService::ServiceError &error);
|
||||
// Infrared sensor service
|
||||
void onInfraredServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||
void onInfraredServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||
|
||||
// Button service
|
||||
void onButtonServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||
void onButtonServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||
|
||||
// Humidity sensor service
|
||||
void onHumidityServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||
void onHumidityServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||
|
||||
// Pressure sensor service
|
||||
void onPressureServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||
void onPressureServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||
|
||||
|
||||
public slots:
|
||||
void measure();
|
||||
};
|
||||
#endif // BLUETOOTH_LE
|
||||
|
||||
#endif // SENSORTAG_H
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
|
||||
QT += network bluetooth
|
||||
QT += network bluetooth dbus
|
||||
|
||||
QMAKE_CXXFLAGS += -Werror -std=c++11 -g
|
||||
QMAKE_LFLAGS += -std=c++11
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user