Migrate senic plugin
This commit is contained in:
parent
413cd748f4
commit
cd2289563f
17
debian/control
vendored
17
debian/control
vendored
@ -446,6 +446,22 @@ Description: guh.io plugin for elgato
|
|||||||
This package will install the guh.io plugin for elgato
|
This package will install the guh.io plugin for elgato
|
||||||
|
|
||||||
|
|
||||||
|
Package: guh-plugin-senic
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends},
|
||||||
|
${misc:Depends},
|
||||||
|
guh-plugins-translations,
|
||||||
|
Description: guh.io plugin for senic
|
||||||
|
The guh daemon is a plugin based IoT (Internet of Things) server. The
|
||||||
|
server works like a translator for devices, things and services and
|
||||||
|
allows them to interact.
|
||||||
|
With the powerful rule engine you are able to connect any device available
|
||||||
|
in the system and create individual scenes and behaviors for your environment.
|
||||||
|
.
|
||||||
|
This package will install the guh.io plugin for senic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Package: guh-plugins-translations
|
Package: guh-plugins-translations
|
||||||
Section: misc
|
Section: misc
|
||||||
Architecture: all
|
Architecture: all
|
||||||
@ -479,6 +495,7 @@ Depends: guh-plugin-awattar,
|
|||||||
guh-plugin-wakeonlan,
|
guh-plugin-wakeonlan,
|
||||||
guh-plugin-wemo,
|
guh-plugin-wemo,
|
||||||
guh-plugin-elgato,
|
guh-plugin-elgato,
|
||||||
|
guh-plugin-senic
|
||||||
Description: Plugins for guh IoT server - the default plugin collection
|
Description: Plugins for guh IoT server - the default plugin collection
|
||||||
The guh daemon is a plugin based IoT (Internet of Things) server. The
|
The guh daemon is a plugin based IoT (Internet of Things) server. The
|
||||||
server works like a translator for devices, things and services and
|
server works like a translator for devices, things and services and
|
||||||
|
|||||||
@ -21,7 +21,7 @@ PLUGIN_DIRS = \
|
|||||||
tcpcommander \
|
tcpcommander \
|
||||||
kodi \
|
kodi \
|
||||||
elgato \
|
elgato \
|
||||||
#senic \
|
senic \
|
||||||
awattar \
|
awattar \
|
||||||
netatmo \
|
netatmo \
|
||||||
plantcare \
|
plantcare \
|
||||||
|
|||||||
@ -37,18 +37,23 @@
|
|||||||
\quotefile plugins/deviceplugins/senic/devicepluginsenic.json
|
\quotefile plugins/deviceplugins/senic/devicepluginsenic.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef BLUETOOTH_LE
|
|
||||||
|
|
||||||
#include "devicepluginsenic.h"
|
#include "devicepluginsenic.h"
|
||||||
#include "plugin/device.h"
|
#include "plugin/device.h"
|
||||||
#include "devicemanager.h"
|
#include "devicemanager.h"
|
||||||
#include "plugininfo.h"
|
#include "plugininfo.h"
|
||||||
|
#include "hardware/bluetoothlowenergy/bluetoothlowenergymanager.h"
|
||||||
|
|
||||||
DevicePluginSenic::DevicePluginSenic()
|
DevicePluginSenic::DevicePluginSenic()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DevicePluginSenic::init()
|
||||||
|
{
|
||||||
|
m_reconnectTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
|
||||||
|
connect(m_reconnectTimer, &PluginTimer::timeout, this, &DevicePluginSenic::onReconnectTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
DeviceManager::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
DeviceManager::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||||
{
|
{
|
||||||
Q_UNUSED(params)
|
Q_UNUSED(params)
|
||||||
@ -56,55 +61,46 @@ DeviceManager::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassI
|
|||||||
if (deviceClassId != nuimoDeviceClassId)
|
if (deviceClassId != nuimoDeviceClassId)
|
||||||
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||||
|
|
||||||
if (!discoverBluetooth())
|
if (!hardwareManager()->bluetoothLowEnergyManager()->available())
|
||||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||||
|
|
||||||
|
if (!hardwareManager()->bluetoothLowEnergyManager()->enabled())
|
||||||
|
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||||
|
|
||||||
|
BluetoothDiscoveryReply *reply = hardwareManager()->bluetoothLowEnergyManager()->discoverDevices();
|
||||||
|
connect(reply, &BluetoothDiscoveryReply::finished, this, &DevicePluginSenic::onBluetoothDiscoveryFinished);
|
||||||
|
|
||||||
return DeviceManager::DeviceErrorAsync;
|
return DeviceManager::DeviceErrorAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::DeviceSetupStatus DevicePluginSenic::setupDevice(Device *device)
|
DeviceManager::DeviceSetupStatus DevicePluginSenic::setupDevice(Device *device)
|
||||||
{
|
{
|
||||||
|
qCDebug(dcSenic()) << "Setup device" << device->name() << device->params();
|
||||||
|
|
||||||
QString name = device->paramValue(nameParamTypeId).toString();
|
QString name = device->paramValue(nameParamTypeId).toString();
|
||||||
QBluetoothAddress address = QBluetoothAddress(device->paramValue(macParamTypeId).toString());
|
QBluetoothAddress address = QBluetoothAddress(device->paramValue(macParamTypeId).toString());
|
||||||
QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(address, name, 0);
|
QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(address, name, 0);
|
||||||
|
|
||||||
Nuimo *nuimo = new Nuimo(deviceInfo, QLowEnergyController::RandomAddress, this);
|
BluetoothLowEnergyDevice *bluetoothDevice = hardwareManager()->bluetoothLowEnergyManager()->registerDevice(deviceInfo, QLowEnergyController::RandomAddress);
|
||||||
connect(nuimo, &Nuimo::availableChanged, this, &DevicePluginSenic::connectionAvailableChanged);
|
|
||||||
connect(nuimo, &Nuimo::batteryValueChaged, this, &DevicePluginSenic::onBatteryValueChanged);
|
Nuimo *nuimo = new Nuimo(device, bluetoothDevice, this);
|
||||||
connect(nuimo, &Nuimo::buttonPressed, this, &DevicePluginSenic::onButtonPressed);
|
connect(nuimo, &Nuimo::buttonPressed, this, &DevicePluginSenic::onButtonPressed);
|
||||||
connect(nuimo, &Nuimo::buttonReleased, this, &DevicePluginSenic::onButtonReleased);
|
connect(nuimo, &Nuimo::buttonReleased, this, &DevicePluginSenic::onButtonReleased);
|
||||||
connect(nuimo, &Nuimo::swipeDetected, this, &DevicePluginSenic::onSwipeDetected);
|
connect(nuimo, &Nuimo::swipeDetected, this, &DevicePluginSenic::onSwipeDetected);
|
||||||
connect(nuimo, &Nuimo::rotationValueChanged, this, &DevicePluginSenic::onRotationValueChanged);
|
connect(nuimo, &Nuimo::rotationValueChanged, this, &DevicePluginSenic::onRotationValueChanged);
|
||||||
|
|
||||||
m_nuimos.insert(nuimo, device);
|
m_nuimos.insert(nuimo, device);
|
||||||
|
nuimo->bluetoothDevice()->connectDevice();
|
||||||
nuimo->connectDevice();
|
|
||||||
|
|
||||||
return DeviceManager::DeviceSetupStatusSuccess;
|
return DeviceManager::DeviceSetupStatusSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::HardwareResources DevicePluginSenic::requiredHardware() const
|
|
||||||
{
|
|
||||||
return DeviceManager::HardwareResourceBluetoothLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceManager::DeviceError DevicePluginSenic::executeAction(Device *device, const Action &action)
|
DeviceManager::DeviceError DevicePluginSenic::executeAction(Device *device, const Action &action)
|
||||||
{
|
{
|
||||||
QPointer<Nuimo> nuimo = m_nuimos.key(device);
|
QPointer<Nuimo> nuimo = m_nuimos.key(device);
|
||||||
if (nuimo.isNull())
|
if (nuimo.isNull())
|
||||||
return DeviceManager::DeviceErrorHardwareFailure;
|
return DeviceManager::DeviceErrorHardwareFailure;
|
||||||
|
|
||||||
// reconnect action does not need available true
|
|
||||||
if (action.actionTypeId() == connectActionTypeId) {
|
|
||||||
nuimo->reconnectDevice();
|
|
||||||
return DeviceManager::DeviceErrorNoError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.actionTypeId() == disconnectActionTypeId) {
|
|
||||||
nuimo->disconnectDevice();
|
|
||||||
return DeviceManager::DeviceErrorNoError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.actionTypeId() == showLogoActionTypeId) {
|
if (action.actionTypeId() == showLogoActionTypeId) {
|
||||||
|
|
||||||
if (action.param(logoParamTypeId).value().toString() == "Guh")
|
if (action.param(logoParamTypeId).value().toString() == "Guh")
|
||||||
@ -122,25 +118,6 @@ DeviceManager::DeviceError DevicePluginSenic::executeAction(Device *device, cons
|
|||||||
return DeviceManager::DeviceErrorActionTypeNotFound;
|
return DeviceManager::DeviceErrorActionTypeNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginSenic::bluetoothDiscoveryFinished(const QList<QBluetoothDeviceInfo> &deviceInfos)
|
|
||||||
{
|
|
||||||
QList<DeviceDescriptor> deviceDescriptors;
|
|
||||||
foreach (QBluetoothDeviceInfo deviceInfo, deviceInfos) {
|
|
||||||
if (deviceInfo.name().contains("Nuimo")) {
|
|
||||||
if (!verifyExistingDevices(deviceInfo)) {
|
|
||||||
DeviceDescriptor descriptor(nuimoDeviceClassId, "Nuimo", 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(nuimoDeviceClassId, deviceDescriptors);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginSenic::deviceRemoved(Device *device)
|
void DevicePluginSenic::deviceRemoved(Device *device)
|
||||||
{
|
{
|
||||||
if (!m_nuimos.values().contains(device))
|
if (!m_nuimos.values().contains(device))
|
||||||
@ -161,20 +138,45 @@ bool DevicePluginSenic::verifyExistingDevices(const QBluetoothDeviceInfo &device
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginSenic::connectionAvailableChanged()
|
void DevicePluginSenic::onReconnectTimeout()
|
||||||
{
|
{
|
||||||
Nuimo *nuimo = static_cast<Nuimo *>(sender());
|
foreach (Nuimo *nuimo, m_nuimos.keys()) {
|
||||||
Device *device = m_nuimos.value(nuimo);
|
if (!nuimo->bluetoothDevice()->connected()) {
|
||||||
device->setStateValue(availableStateTypeId, nuimo->isAvailable());
|
nuimo->bluetoothDevice()->connectDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginSenic::onBatteryValueChanged(const uint &percentage)
|
void DevicePluginSenic::onBluetoothDiscoveryFinished()
|
||||||
{
|
{
|
||||||
Nuimo *nuimo = static_cast<Nuimo *>(sender());
|
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
|
||||||
Device *device = m_nuimos.value(nuimo);
|
if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) {
|
||||||
device->setStateValue(batteryStateTypeId, percentage);
|
qCWarning(dcSenic()) << "Bluetooth discovery error:" << reply->error();
|
||||||
|
reply->deleteLater();
|
||||||
|
emit devicesDiscovered(nuimoDeviceClassId, QList<DeviceDescriptor>());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QList<DeviceDescriptor> deviceDescriptors;
|
||||||
|
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
||||||
|
if (deviceInfo.name().contains("Nuimo")) {
|
||||||
|
if (!verifyExistingDevices(deviceInfo)) {
|
||||||
|
DeviceDescriptor descriptor(nuimoDeviceClassId, "Nuimo", 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(nuimoDeviceClassId, deviceDescriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginSenic::onButtonPressed()
|
void DevicePluginSenic::onButtonPressed()
|
||||||
{
|
{
|
||||||
Nuimo *nuimo = static_cast<Nuimo *>(sender());
|
Nuimo *nuimo = static_cast<Nuimo *>(sender());
|
||||||
@ -218,6 +220,3 @@ void DevicePluginSenic::onRotationValueChanged(const uint &value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // BLUETOOTH_LE
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,10 +23,9 @@
|
|||||||
#ifndef DEVICEPLUGINELGATO_H
|
#ifndef DEVICEPLUGINELGATO_H
|
||||||
#define DEVICEPLUGINELGATO_H
|
#define DEVICEPLUGINELGATO_H
|
||||||
|
|
||||||
#ifdef BLUETOOTH_LE
|
#include "plugintimer.h"
|
||||||
|
|
||||||
#include "plugin/deviceplugin.h"
|
#include "plugin/deviceplugin.h"
|
||||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
#include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h"
|
||||||
|
|
||||||
#include "nuimo.h"
|
#include "nuimo.h"
|
||||||
|
|
||||||
@ -40,21 +39,23 @@ class DevicePluginSenic : public DevicePlugin
|
|||||||
public:
|
public:
|
||||||
explicit DevicePluginSenic();
|
explicit DevicePluginSenic();
|
||||||
|
|
||||||
|
void init() override;
|
||||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||||
DeviceManager::HardwareResources requiredHardware() const override;
|
|
||||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||||
|
|
||||||
void bluetoothDiscoveryFinished(const QList<QBluetoothDeviceInfo> &deviceInfos);
|
|
||||||
void deviceRemoved(Device *device) override;
|
void deviceRemoved(Device *device) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<Nuimo *, Device *> m_nuimos;
|
QHash<Nuimo *, Device *> m_nuimos;
|
||||||
|
PluginTimer *m_reconnectTimer = nullptr;
|
||||||
|
|
||||||
bool verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo);
|
bool verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void connectionAvailableChanged();
|
void onReconnectTimeout();
|
||||||
void onBatteryValueChanged(const uint &percentage);
|
void onBluetoothDiscoveryFinished();
|
||||||
|
|
||||||
void onButtonPressed();
|
void onButtonPressed();
|
||||||
void onButtonReleased();
|
void onButtonReleased();
|
||||||
void onSwipeDetected(const Nuimo::SwipeDirection &direction);
|
void onSwipeDetected(const Nuimo::SwipeDirection &direction);
|
||||||
@ -62,6 +63,4 @@ private slots:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BLUETOOTH_LE
|
|
||||||
|
|
||||||
#endif // DEVICEPLUGINELGATO_H
|
#endif // DEVICEPLUGINELGATO_H
|
||||||
|
|||||||
@ -37,12 +37,36 @@
|
|||||||
"stateTypes": [
|
"stateTypes": [
|
||||||
{
|
{
|
||||||
"id": "5286976a-f5dc-4662-872a-438ac5d491cb",
|
"id": "5286976a-f5dc-4662-872a-438ac5d491cb",
|
||||||
"idName": "available",
|
"idName": "connected",
|
||||||
"name": "available",
|
"name": "Connected",
|
||||||
"eventTypeName": "available changed",
|
"eventTypeName": "Connected changed",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false
|
"defaultValue": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "5c400da4-a14e-4e0a-be9f-c82ffe7e1972",
|
||||||
|
"idName": "hardwareRevision",
|
||||||
|
"name": "Hardware revision",
|
||||||
|
"eventTypeName": "Hardware revision changed",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "-"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "edcf76c6-9fed-4c26-9853-c284cf887adb",
|
||||||
|
"idName": "firmwareRevision",
|
||||||
|
"name": "Firmware revision",
|
||||||
|
"eventTypeName": "Firmware revision changed",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "-"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "be42cbd3-12e9-44ec-8f9d-141e10d9573a",
|
||||||
|
"idName": "softwareRevision",
|
||||||
|
"name": "Software revision",
|
||||||
|
"eventTypeName": "Software revision changed",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "-"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "b5ee2465-7fa1-450b-8073-f115537d3409",
|
"id": "b5ee2465-7fa1-450b-8073-f115537d3409",
|
||||||
"idName": "battery",
|
"idName": "battery",
|
||||||
@ -67,16 +91,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"actionTypes": [
|
"actionTypes": [
|
||||||
{
|
|
||||||
"id": "bb1c46fe-5dfb-4fa3-ad89-0ba576ac780e",
|
|
||||||
"idName": "connect",
|
|
||||||
"name": "connect"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "11bf3143-34f8-42ab-9750-073040c1a7fc",
|
|
||||||
"idName": "disconnect",
|
|
||||||
"name": "disconnect"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "d44ca5b7-f8d6-4413-9d2e-cef89282c039",
|
"id": "d44ca5b7-f8d6-4413-9d2e-cef89282c039",
|
||||||
"idName": "showLogo",
|
"idName": "showLogo",
|
||||||
|
|||||||
467
senic/nuimo.cpp
467
senic/nuimo.cpp
@ -20,29 +20,38 @@
|
|||||||
* *
|
* *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#ifdef BLUETOOTH_LE
|
|
||||||
|
|
||||||
#include "nuimo.h"
|
#include "nuimo.h"
|
||||||
#include "extern-plugininfo.h"
|
#include "extern-plugininfo.h"
|
||||||
|
|
||||||
#include <QBitArray>
|
#include <QBitArray>
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
|
|
||||||
Nuimo::Nuimo(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent) :
|
static QBluetoothUuid ledMatrinxServiceUuid = QBluetoothUuid(QUuid("f29b1523-cb19-40f3-be5c-7241ecb82fd1"));
|
||||||
BluetoothLowEnergyDevice(deviceInfo, addressType, parent),
|
static QBluetoothUuid ledMatrixCharacteristicUuid = QBluetoothUuid(QUuid("f29b1524-cb19-40f3-be5c-7241ecb82fd1"));
|
||||||
m_deviceInfoService(NULL),
|
|
||||||
m_batteryService(NULL),
|
static QBluetoothUuid inputServiceUuid = QBluetoothUuid(QUuid("f29b1525-cb19-40f3-be5c-7241ecb82fd2"));
|
||||||
m_inputService(NULL),
|
static QBluetoothUuid inputSwipeCharacteristicUuid = QBluetoothUuid(QUuid("f29b1527-cb19-40f3-be5c-7241ecb82fd2"));
|
||||||
m_ledMatrixService(NULL),
|
static QBluetoothUuid inputRotationCharacteristicUuid = QBluetoothUuid(QUuid("f29b1528-cb19-40f3-be5c-7241ecb82fd2"));
|
||||||
m_isAvailable(false)
|
static QBluetoothUuid inputButtonCharacteristicUuid = QBluetoothUuid(QUuid("f29b1529-cb19-40f3-be5c-7241ecb82fd2"));
|
||||||
|
|
||||||
|
|
||||||
|
Nuimo::Nuimo(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_device(device),
|
||||||
|
m_bluetoothDevice(bluetoothDevice)
|
||||||
{
|
{
|
||||||
connect(this, SIGNAL(connectionStatusChanged()), this,SLOT(onConnectionStatusChanged()));
|
connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::connectedChanged, this, &Nuimo::onConnectedChanged);
|
||||||
connect(this, SIGNAL(servicesDiscoveryFinished()), this, SLOT(serviceScanFinished()));
|
connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::servicesDiscoveryFinished, this, &Nuimo::onServiceDiscoveryFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Nuimo::isAvailable()
|
Device *Nuimo::device()
|
||||||
{
|
{
|
||||||
return m_isAvailable;
|
return m_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
BluetoothLowEnergyDevice *Nuimo::bluetoothDevice()
|
||||||
|
{
|
||||||
|
return m_bluetoothDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nuimo::showGuhLogo()
|
void Nuimo::showGuhLogo()
|
||||||
@ -93,19 +102,11 @@ void Nuimo::showArrowDown()
|
|||||||
showMatrix(matrix, 3);
|
showMatrix(matrix, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nuimo::registerService(QLowEnergyService *service)
|
|
||||||
{
|
|
||||||
connect(service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)), this, SLOT(serviceStateChanged(QLowEnergyService::ServiceState)));
|
|
||||||
connect(service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic, QByteArray)), this, SLOT(serviceCharacteristicChanged(QLowEnergyCharacteristic, QByteArray)));
|
|
||||||
connect(service, SIGNAL(characteristicWritten(QLowEnergyCharacteristic, QByteArray)), this, SLOT(confirmedCharacteristicWritten(QLowEnergyCharacteristic, QByteArray)));
|
|
||||||
connect(service, SIGNAL(descriptorWritten(QLowEnergyDescriptor, QByteArray)), this, SLOT(confirmedDescriptorWritten(QLowEnergyDescriptor, QByteArray)));
|
|
||||||
connect(service, SIGNAL(error(QLowEnergyService::ServiceError)), this, SLOT(serviceError(QLowEnergyService::ServiceError)));
|
|
||||||
|
|
||||||
service->discoverDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Nuimo::showMatrix(const QByteArray &matrix, const int &seconds)
|
void Nuimo::showMatrix(const QByteArray &matrix, const int &seconds)
|
||||||
{
|
{
|
||||||
|
if (!m_ledMatrixService)
|
||||||
|
return;
|
||||||
|
|
||||||
QBitArray bits;
|
QBitArray bits;
|
||||||
bits.resize(81);
|
bits.resize(81);
|
||||||
for (int i = 0; i < matrix.size(); i++) {
|
for (int i = 0; i < matrix.size(); i++) {
|
||||||
@ -127,225 +128,223 @@ void Nuimo::showMatrix(const QByteArray &matrix, const int &seconds)
|
|||||||
m_ledMatrixService->writeCharacteristic(m_ledMatrixCharacteristic, bytes);
|
m_ledMatrixService->writeCharacteristic(m_ledMatrixCharacteristic, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nuimo::printService(QLowEnergyService *service)
|
||||||
void Nuimo::serviceScanFinished()
|
|
||||||
{
|
{
|
||||||
QBluetoothUuid deviceInfoUuid(QUuid("0000180A-0000-1000-8000-00805F9B34FB"));
|
foreach (const QLowEnergyCharacteristic &characteristic, service->characteristics()) {
|
||||||
QBluetoothUuid batteryUuid(QUuid("0000180F-0000-1000-8000-00805F9B34FB"));
|
qCDebug(dcSenic()) << " -->" << characteristic.name() << characteristic.uuid().toString() << characteristic.value();
|
||||||
QBluetoothUuid inputUuid(QUuid("F29B1525-CB19-40F3-BE5C-7241ECB82FD2"));
|
foreach (const QLowEnergyDescriptor &desciptor, characteristic.descriptors()) {
|
||||||
QBluetoothUuid ledMatrixUuid(QUuid("F29B1523-CB19-40F3-BE5C-7241ECB82FD1"));
|
qCDebug(dcSenic()) << " -->" << desciptor.name() << desciptor.uuid().toString() << desciptor.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nuimo::setBatteryValue(const QByteArray &data)
|
||||||
|
{
|
||||||
|
int batteryPercentage = data.toHex().toUInt(0, 16);
|
||||||
|
qCDebug(dcSenic()) << "Battery:" << batteryPercentage << "%";
|
||||||
|
|
||||||
|
device()->setStateValue(batteryStateTypeId, batteryPercentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nuimo::onConnectedChanged(const bool &connected)
|
||||||
|
{
|
||||||
|
qCDebug(dcSenic()) << m_bluetoothDevice->name() << m_bluetoothDevice->address().toString() << (connected ? "connected" : "disconnected");
|
||||||
|
m_device->setStateValue(connectedStateTypeId, connected);
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
|
// Clean up services
|
||||||
|
m_deviceInfoService->deleteLater();
|
||||||
|
m_batteryService->deleteLater();
|
||||||
|
m_ledMatrixService->deleteLater();
|
||||||
|
m_inputService->deleteLater();
|
||||||
|
|
||||||
|
m_deviceInfoService = nullptr;
|
||||||
|
m_batteryService = nullptr;
|
||||||
|
m_ledMatrixService = nullptr;
|
||||||
|
m_inputService = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nuimo::onServiceDiscoveryFinished()
|
||||||
|
{
|
||||||
qCDebug(dcSenic()) << "Service scan finised";
|
qCDebug(dcSenic()) << "Service scan finised";
|
||||||
|
|
||||||
if (!controller()->services().contains(deviceInfoUuid)) {
|
if (!m_bluetoothDevice->serviceUuids().contains(QBluetoothUuid::DeviceInformation)) {
|
||||||
qCWarning(dcSenic()) << "Device Information service not found for device" << name() << address().toString();
|
qCWarning(dcSenic()) << "Device Information service not found for device" << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller()->services().contains(batteryUuid)) {
|
if (!m_bluetoothDevice->serviceUuids().contains(QBluetoothUuid::BatteryService)) {
|
||||||
qCWarning(dcSenic()) << "Battery service not found for device" << name() << address().toString();
|
qCWarning(dcSenic()) << "Battery service not found for device" << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller()->services().contains(ledMatrixUuid)) {
|
if (!m_bluetoothDevice->serviceUuids().contains(ledMatrinxServiceUuid)) {
|
||||||
qCWarning(dcSenic()) << "Led matrix service not found for device" << name() << address().toString();
|
qCWarning(dcSenic()) << "Led matrix service not found for device" << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller()->services().contains(inputUuid)) {
|
if (!m_bluetoothDevice->serviceUuids().contains(inputServiceUuid)) {
|
||||||
qCWarning(dcSenic()) << "Input service not found for device" << name() << address().toString();
|
qCWarning(dcSenic()) << "Input service not found for device" << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isAvailable = true;
|
// Device info service
|
||||||
emit availableChanged();
|
|
||||||
|
|
||||||
// Device information
|
|
||||||
m_deviceInfoService = controller()->createServiceObject(deviceInfoUuid, this);
|
|
||||||
if (!m_deviceInfoService) {
|
if (!m_deviceInfoService) {
|
||||||
qCWarning(dcSenic()) << "Could not create device information service for device" << name() << address().toString();
|
m_deviceInfoService = m_bluetoothDevice->controller()->createServiceObject(QBluetoothUuid::DeviceInformation, this);
|
||||||
return;
|
if (!m_deviceInfoService) {
|
||||||
|
qCWarning(dcSenic()) << "Could not create device info service.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_deviceInfoService, &QLowEnergyService::stateChanged, this, &Nuimo::onDeviceInfoServiceStateChanged);
|
||||||
|
|
||||||
|
if (m_deviceInfoService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||||
|
m_deviceInfoService->discoverDetails();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Battery service
|
// Battery service
|
||||||
m_batteryService = controller()->createServiceObject(batteryUuid, this);
|
|
||||||
if (!m_batteryService) {
|
if (!m_batteryService) {
|
||||||
qCWarning(dcSenic()) << "Could not create battery service for device" << name() << address().toString();
|
m_batteryService = m_bluetoothDevice->controller()->createServiceObject(QBluetoothUuid::BatteryService, this);
|
||||||
return;
|
if (!m_batteryService) {
|
||||||
|
qCWarning(dcSenic()) << "Could not create battery service.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_batteryService, &QLowEnergyService::stateChanged, this, &Nuimo::onBatteryServiceStateChanged);
|
||||||
|
connect(m_batteryService, &QLowEnergyService::characteristicChanged, this, &Nuimo::onBatteryCharacteristicChanged);
|
||||||
|
|
||||||
|
if (m_batteryService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||||
|
m_batteryService->discoverDetails();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input service
|
// Input service
|
||||||
m_inputService = controller()->createServiceObject(inputUuid, this);
|
|
||||||
if (!m_inputService) {
|
if (!m_inputService) {
|
||||||
qCWarning(dcSenic()) << "Could not create input service for device" << name() << address().toString();
|
m_inputService = m_bluetoothDevice->controller()->createServiceObject(inputServiceUuid, this);
|
||||||
return;
|
if (!m_inputService) {
|
||||||
|
qCWarning(dcSenic()) << "Could not create input service.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_inputService, &QLowEnergyService::stateChanged, this, &Nuimo::onInputServiceStateChanged);
|
||||||
|
connect(m_inputService, &QLowEnergyService::characteristicChanged, this, &Nuimo::onInputCharacteristicChanged);
|
||||||
|
|
||||||
|
if (m_inputService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||||
|
m_inputService->discoverDetails();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Led Matrix
|
// Input service
|
||||||
m_ledMatrixService = controller()->createServiceObject(ledMatrixUuid, this);
|
|
||||||
if (!m_ledMatrixService) {
|
if (!m_ledMatrixService) {
|
||||||
qCWarning(dcSenic()) << "Could not create led matrix service for device" << name() << address().toString();
|
m_ledMatrixService = m_bluetoothDevice->controller()->createServiceObject(ledMatrinxServiceUuid, this);
|
||||||
|
if (!m_ledMatrixService) {
|
||||||
|
qCWarning(dcSenic()) << "Could not create led matrix service.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_ledMatrixService, &QLowEnergyService::stateChanged, this, &Nuimo::onLedMatrixServiceStateChanged);
|
||||||
|
|
||||||
|
if (m_ledMatrixService->state() == QLowEnergyService::DiscoveryRequired) {
|
||||||
|
m_ledMatrixService->discoverDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nuimo::onDeviceInfoServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||||
|
{
|
||||||
|
// Only continue if discovered
|
||||||
|
if (state != QLowEnergyService::ServiceDiscovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qCDebug(dcSenic()) << "Device info service discovered.";
|
||||||
|
|
||||||
|
printService(m_deviceInfoService);
|
||||||
|
|
||||||
|
device()->setStateValue(firmwareRevisionStateTypeId, QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::FirmwareRevisionString).value()));
|
||||||
|
device()->setStateValue(hardwareRevisionStateTypeId, QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::HardwareRevisionString).value()));
|
||||||
|
device()->setStateValue(softwareRevisionStateTypeId, QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::SoftwareRevisionString).value()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nuimo::onBatteryServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||||
|
{
|
||||||
|
// Only continue if discovered
|
||||||
|
if (state != QLowEnergyService::ServiceDiscovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qCDebug(dcSenic()) << "Battery service discovered.";
|
||||||
|
|
||||||
|
printService(m_batteryService);
|
||||||
|
|
||||||
|
m_batteryCharacteristic = m_batteryService->characteristic(QBluetoothUuid::BatteryLevel);
|
||||||
|
if (!m_batteryCharacteristic.isValid()) {
|
||||||
|
qCWarning(dcSenic()) << "Battery characteristc not found for device " << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerService(m_deviceInfoService);
|
// Enable notifications
|
||||||
registerService(m_batteryService);
|
QLowEnergyDescriptor notificationDescriptor = m_batteryCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||||
registerService(m_inputService);
|
m_batteryService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||||
registerService(m_ledMatrixService);
|
|
||||||
|
|
||||||
|
setBatteryValue(m_batteryCharacteristic.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nuimo::onConnectionStatusChanged()
|
void Nuimo::onBatteryCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||||
{
|
|
||||||
if (!isConnected()) {
|
|
||||||
// delete the services, they need to be recreated and
|
|
||||||
// rediscovered once the device will be reconnected
|
|
||||||
|
|
||||||
if (m_deviceInfoService) {
|
|
||||||
delete m_deviceInfoService;
|
|
||||||
m_deviceInfoService = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_batteryService) {
|
|
||||||
delete m_batteryService;
|
|
||||||
m_batteryService = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_inputService) {
|
|
||||||
delete m_inputService;
|
|
||||||
m_inputService = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_ledMatrixService) {
|
|
||||||
delete m_ledMatrixService;
|
|
||||||
m_ledMatrixService = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_isAvailable = false;
|
|
||||||
emit availableChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Nuimo::serviceStateChanged(const QLowEnergyService::ServiceState &state)
|
|
||||||
{
|
|
||||||
QLowEnergyService *service =static_cast<QLowEnergyService *>(sender());
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case QLowEnergyService::DiscoveringServices:
|
|
||||||
if (service == m_batteryService)
|
|
||||||
qCDebug(dcSenic()) << "Start discovering battery service...";
|
|
||||||
|
|
||||||
if (service == m_deviceInfoService)
|
|
||||||
qCDebug(dcSenic()) << "Start discovering device information service...";
|
|
||||||
|
|
||||||
if (service == m_inputService)
|
|
||||||
qCDebug(dcSenic()) << "Start discovering input service...";
|
|
||||||
|
|
||||||
if (service == m_ledMatrixService)
|
|
||||||
qCDebug(dcSenic()) << "Start discovering led matrix service...";
|
|
||||||
|
|
||||||
break;
|
|
||||||
case QLowEnergyService::ServiceDiscovered:
|
|
||||||
|
|
||||||
// Device information
|
|
||||||
if (service == m_deviceInfoService) {
|
|
||||||
qCDebug(dcSenic()) << "Device information service discovered";
|
|
||||||
m_deviceInfoCharacteristic = m_deviceInfoService->characteristic(QBluetoothUuid(QUuid("00002A29-0000-1000-8000-00805F9B34FB")));
|
|
||||||
if (!m_deviceInfoCharacteristic.isValid()) {
|
|
||||||
qCWarning(dcSenic()) << "Device information characteristc not found for device " << name() << address().toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcSenic()) << "Device information:" << m_deviceInfoCharacteristic.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Battery
|
|
||||||
if (service == m_batteryService) {
|
|
||||||
qCDebug(dcSenic()) << "Battery service discovered";
|
|
||||||
m_batteryCharacteristic = m_batteryService->characteristic(QBluetoothUuid(QUuid("00002A19-0000-1000-8000-00805F9B34FB")));
|
|
||||||
if (!m_batteryCharacteristic.isValid()) {
|
|
||||||
qCWarning(dcSenic()) << "Battery characteristc not found for device " << name() << address().toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int batteryPercentage = m_batteryCharacteristic.value().toHex().toUInt(0, 16);
|
|
||||||
qCDebug(dcSenic()) << "Battery:" << batteryPercentage << "%";
|
|
||||||
|
|
||||||
// Enable notification
|
|
||||||
foreach (const QLowEnergyDescriptor &descriptor, m_batteryCharacteristic.descriptors()) {
|
|
||||||
qCDebug(dcSenic()) << descriptor.name() << descriptor.uuid().toString();
|
|
||||||
m_batteryService->writeDescriptor(descriptor, QByteArray::fromHex("0100"));
|
|
||||||
}
|
|
||||||
|
|
||||||
emit batteryValueChaged(batteryPercentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input
|
|
||||||
if (service == m_inputService) {
|
|
||||||
qCDebug(dcSenic()) << "Input service discovered";
|
|
||||||
|
|
||||||
// Button
|
|
||||||
m_inputButtonCharacteristic = m_inputService->characteristic(QBluetoothUuid(QUuid("F29B1529-CB19-40F3-BE5C-7241ECB82FD2")));
|
|
||||||
if (!m_inputButtonCharacteristic.isValid()) {
|
|
||||||
qCWarning(dcSenic()) << "Button characteristc not valid for device " << name() << address().toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (const QLowEnergyDescriptor &descriptor, m_inputButtonCharacteristic.descriptors()) {
|
|
||||||
qCDebug(dcSenic()) << descriptor.name() << descriptor.uuid().toString();
|
|
||||||
m_inputService->writeDescriptor(descriptor, QByteArray::fromHex("0100"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swipe
|
|
||||||
m_inputSwipeCharacteristic = m_inputService->characteristic(QBluetoothUuid(QUuid("F29B1527-CB19-40F3-BE5C-7241ECB82FD2")));
|
|
||||||
if (!m_inputSwipeCharacteristic.isValid()) {
|
|
||||||
qCWarning(dcSenic()) << "Swipe characteristc not valid for device " << name() << address().toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (const QLowEnergyDescriptor &descriptor, m_inputSwipeCharacteristic.descriptors()) {
|
|
||||||
qCDebug(dcSenic()) << descriptor.name() << descriptor.uuid().toString();
|
|
||||||
m_inputService->writeDescriptor(descriptor, QByteArray::fromHex("0100"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swipe
|
|
||||||
m_inputRotationCharacteristic = m_inputService->characteristic(QBluetoothUuid(QUuid("F29B1528-CB19-40F3-BE5C-7241ECB82FD2")));
|
|
||||||
if (!m_inputRotationCharacteristic.isValid()) {
|
|
||||||
qCWarning(dcSenic()) << "Rotation characteristc not valid for device " << name() << address().toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const QLowEnergyDescriptor &descriptor, m_inputRotationCharacteristic.descriptors()) {
|
|
||||||
qCDebug(dcSenic()) << descriptor.name() << descriptor.uuid().toString();
|
|
||||||
m_inputService->writeDescriptor(descriptor, QByteArray::fromHex("0100"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Led Matrix
|
|
||||||
if (service == m_ledMatrixService) {
|
|
||||||
qCDebug(dcSenic()) << "Led matrix service discovered";
|
|
||||||
m_ledMatrixCharacteristic = m_ledMatrixService->characteristic(QBluetoothUuid(QUuid("F29B1524-CB19-40F3-BE5C-7241ECB82FD1")));
|
|
||||||
if (!m_ledMatrixCharacteristic.isValid()) {
|
|
||||||
qCWarning(dcSenic()) << "Led matrix characteristc not found for device " << name() << address().toString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showGuhLogo();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Nuimo::serviceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
|
||||||
{
|
{
|
||||||
if (characteristic.uuid() == m_batteryCharacteristic.uuid()) {
|
if (characteristic.uuid() == m_batteryCharacteristic.uuid()) {
|
||||||
uint batteryValue = value.toHex().toUInt(0, 16);
|
setBatteryValue(value);
|
||||||
qCDebug(dcSenic()) << "Battery:" << batteryValue;
|
}
|
||||||
emit batteryValueChaged(batteryValue);
|
}
|
||||||
|
|
||||||
|
void Nuimo::onInputServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||||
|
{
|
||||||
|
// Only continue if discovered
|
||||||
|
if (state != QLowEnergyService::ServiceDiscovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qCDebug(dcSenic()) << "Input service discovered.";
|
||||||
|
|
||||||
|
printService(m_inputService);
|
||||||
|
|
||||||
|
// Button
|
||||||
|
m_inputButtonCharacteristic = m_inputService->characteristic(inputButtonCharacteristicUuid);
|
||||||
|
if (!m_inputButtonCharacteristic.isValid()) {
|
||||||
|
qCWarning(dcSenic()) << "Input button characteristc not found for device " << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Enable notifications
|
||||||
|
QLowEnergyDescriptor notificationDescriptor = m_inputButtonCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||||
|
m_inputService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||||
|
|
||||||
|
|
||||||
|
// Swipe
|
||||||
|
m_inputSwipeCharacteristic = m_inputService->characteristic(inputSwipeCharacteristicUuid);
|
||||||
|
if (!m_inputSwipeCharacteristic.isValid()) {
|
||||||
|
qCWarning(dcSenic()) << "Input swipe characteristc not found for device " << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Enable notifications
|
||||||
|
notificationDescriptor = m_inputSwipeCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||||
|
m_inputService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||||
|
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
m_inputRotationCharacteristic = m_inputService->characteristic(inputRotationCharacteristicUuid);
|
||||||
|
if (!m_inputRotationCharacteristic.isValid()) {
|
||||||
|
qCWarning(dcSenic()) << "Input rotation characteristc not found for device " << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Enable notifications
|
||||||
|
notificationDescriptor = m_inputRotationCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||||
|
m_inputService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nuimo::onInputCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||||
|
{
|
||||||
if (characteristic.uuid() == m_inputButtonCharacteristic.uuid()) {
|
if (characteristic.uuid() == m_inputButtonCharacteristic.uuid()) {
|
||||||
bool pressed = (bool)value.toHex().toUInt(0, 16);
|
bool pressed = (bool)value.toHex().toUInt(0, 16);
|
||||||
qCDebug(dcSenic()) << "Button:" << (pressed ? "pressed": "released");
|
qCDebug(dcSenic()) << "Button:" << (pressed ? "pressed": "released");
|
||||||
@ -397,57 +396,23 @@ void Nuimo::serviceCharacteristicChanged(const QLowEnergyCharacteristic &charact
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
qCDebug(dcSenic()) << "Service characteristic changed" << characteristic.name() << value.toHex();
|
qCDebug(dcSenic()) << "Service characteristic changed" << characteristic.name() << value.toHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nuimo::confirmedCharacteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
void Nuimo::onLedMatrixServiceStateChanged(const QLowEnergyService::ServiceState &state)
|
||||||
{
|
{
|
||||||
qCDebug(dcSenic()) << characteristic.name() << value;
|
// Only continue if discovered
|
||||||
}
|
if (state != QLowEnergyService::ServiceDiscovered)
|
||||||
|
return;
|
||||||
|
|
||||||
void Nuimo::confirmedDescriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value)
|
qCDebug(dcSenic()) << "Led matrix service discovered.";
|
||||||
{
|
|
||||||
qCDebug(dcSenic()) << "Descriptor:" << descriptor.name() << "value:" << value.toHex() << "written successfully";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Nuimo::serviceError(const QLowEnergyService::ServiceError &error)
|
printService(m_ledMatrixService);
|
||||||
{
|
|
||||||
QString errorString;
|
// Led matrix
|
||||||
switch (error) {
|
m_ledMatrixCharacteristic = m_ledMatrixService->characteristic(ledMatrixCharacteristicUuid);
|
||||||
case QLowEnergyService::NoError:
|
if (!m_ledMatrixCharacteristic.isValid()) {
|
||||||
errorString = "No error";
|
qCWarning(dcSenic()) << "Led matrix characteristc not found for device " << bluetoothDevice()->name() << bluetoothDevice()->address().toString();
|
||||||
break;
|
return;
|
||||||
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(dcSenic()) << "Service error of" << name() << address().toString() << ":" << errorString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BLUETOOTH_LE
|
|
||||||
|
|||||||
@ -23,15 +23,14 @@
|
|||||||
#ifndef NUIMO_H
|
#ifndef NUIMO_H
|
||||||
#define NUIMO_H
|
#define NUIMO_H
|
||||||
|
|
||||||
#ifdef BLUETOOTH_LE
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QBluetoothUuid>
|
#include <QBluetoothUuid>
|
||||||
|
|
||||||
#include "typeutils.h"
|
#include "typeutils.h"
|
||||||
#include "bluetooth/bluetoothlowenergydevice.h"
|
#include "plugin/device.h"
|
||||||
|
#include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h"
|
||||||
|
|
||||||
class Nuimo : public BluetoothLowEnergyDevice
|
class Nuimo : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -42,19 +41,23 @@ public:
|
|||||||
SwipeDirectionDown
|
SwipeDirectionDown
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Nuimo(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent = 0);
|
explicit Nuimo(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent = nullptr);
|
||||||
|
|
||||||
bool isAvailable();
|
Device *device();
|
||||||
|
BluetoothLowEnergyDevice *bluetoothDevice();
|
||||||
|
|
||||||
void showGuhLogo();
|
void showGuhLogo();
|
||||||
void showArrowUp();
|
void showArrowUp();
|
||||||
void showArrowDown();
|
void showArrowDown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLowEnergyService *m_deviceInfoService;
|
Device *m_device = nullptr;
|
||||||
QLowEnergyService *m_batteryService;
|
BluetoothLowEnergyDevice *m_bluetoothDevice = nullptr;
|
||||||
QLowEnergyService *m_inputService;
|
|
||||||
QLowEnergyService *m_ledMatrixService;
|
QLowEnergyService *m_deviceInfoService = nullptr;
|
||||||
|
QLowEnergyService *m_batteryService = nullptr;
|
||||||
|
QLowEnergyService *m_inputService = nullptr;
|
||||||
|
QLowEnergyService *m_ledMatrixService = nullptr;
|
||||||
|
|
||||||
QLowEnergyCharacteristic m_deviceInfoCharacteristic;
|
QLowEnergyCharacteristic m_deviceInfoCharacteristic;
|
||||||
QLowEnergyCharacteristic m_batteryCharacteristic;
|
QLowEnergyCharacteristic m_batteryCharacteristic;
|
||||||
@ -63,12 +66,15 @@ private:
|
|||||||
QLowEnergyCharacteristic m_inputSwipeCharacteristic;
|
QLowEnergyCharacteristic m_inputSwipeCharacteristic;
|
||||||
QLowEnergyCharacteristic m_inputRotationCharacteristic;
|
QLowEnergyCharacteristic m_inputRotationCharacteristic;
|
||||||
|
|
||||||
bool m_isAvailable;
|
|
||||||
uint m_rotationValue;
|
uint m_rotationValue;
|
||||||
|
|
||||||
void registerService(QLowEnergyService *service);
|
|
||||||
void showMatrix(const QByteArray &matrix, const int &seconds);
|
void showMatrix(const QByteArray &matrix, const int &seconds);
|
||||||
|
|
||||||
|
void printService(QLowEnergyService *service);
|
||||||
|
|
||||||
|
// Set states
|
||||||
|
void setBatteryValue(const QByteArray &data);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void availableChanged();
|
void availableChanged();
|
||||||
void buttonPressed();
|
void buttonPressed();
|
||||||
@ -78,17 +84,19 @@ signals:
|
|||||||
void rotationValueChanged(const uint &value);
|
void rotationValueChanged(const uint &value);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void serviceScanFinished();
|
void onConnectedChanged(const bool &connected);
|
||||||
void onConnectionStatusChanged();
|
void onServiceDiscoveryFinished();
|
||||||
|
|
||||||
void serviceStateChanged(const QLowEnergyService::ServiceState &state);
|
void onDeviceInfoServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||||
void serviceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
|
||||||
void confirmedCharacteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
void onBatteryServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||||
void confirmedDescriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value);
|
void onBatteryCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||||
void serviceError(const QLowEnergyService::ServiceError &error);
|
|
||||||
|
void onInputServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||||
|
void onInputCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
|
||||||
|
|
||||||
|
void onLedMatrixServiceStateChanged(const QLowEnergyService::ServiceState &state);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BLUETOOTH_LE
|
|
||||||
|
|
||||||
#endif // NUIMO_H
|
#endif // NUIMO_H
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user