Merge PR #138: Fix senic

This commit is contained in:
Jenkins 2019-09-02 18:02:05 +02:00
commit 310ad71d91
5 changed files with 307 additions and 87 deletions

View File

@ -32,10 +32,12 @@ DevicePluginSenic::DevicePluginSenic()
void DevicePluginSenic::init() void DevicePluginSenic::init()
{ {
m_reconnectTimer = hardwareManager()->pluginTimerManager()->registerTimer(10); // Initialize plugin configurations
connect(m_reconnectTimer, &PluginTimer::timeout, this, &DevicePluginSenic::onReconnectTimeout); m_autoSymbolMode = configValue(senicPluginAutoSymbolsParamTypeId).toBool();
connect(this, &DevicePluginSenic::configValueChanged, this, &DevicePluginSenic::onPluginConfigurationChanged);
} }
Device::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params) Device::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{ {
Q_UNUSED(params) Q_UNUSED(params)
@ -55,28 +57,39 @@ Device::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassId &devi
return Device::DeviceErrorAsync; return Device::DeviceErrorAsync;
} }
Device::DeviceSetupStatus DevicePluginSenic::setupDevice(Device *device) Device::DeviceSetupStatus DevicePluginSenic::setupDevice(Device *device)
{ {
if (!m_reconnectTimer) {
m_reconnectTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_reconnectTimer, &PluginTimer::timeout, this, &DevicePluginSenic::onReconnectTimeout);
}
qCDebug(dcSenic()) << "Setup device" << device->name() << device->params(); qCDebug(dcSenic()) << "Setup device" << device->name() << device->params();
QString name = device->paramValue(nuimoDeviceNameParamTypeId).toString();
QBluetoothAddress address = QBluetoothAddress(device->paramValue(nuimoDeviceMacParamTypeId).toString()); QBluetoothAddress address = QBluetoothAddress(device->paramValue(nuimoDeviceMacParamTypeId).toString());
QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(address, name, 0); QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(address, device->name(), 0);
BluetoothLowEnergyDevice *bluetoothDevice = hardwareManager()->bluetoothLowEnergyManager()->registerDevice(deviceInfo, QLowEnergyController::RandomAddress); BluetoothLowEnergyDevice *bluetoothDevice = hardwareManager()->bluetoothLowEnergyManager()->registerDevice(deviceInfo, QLowEnergyController::RandomAddress);
Nuimo *nuimo = new Nuimo(device, bluetoothDevice, this); Nuimo *nuimo = new Nuimo(bluetoothDevice, this);
nuimo->setLongPressTime(configValue(senicPluginLongPressTimeParamTypeId).toInt());
connect(nuimo, &Nuimo::deviceInitializationFinished, this, &DevicePluginSenic::onDeviceInitializationFinished);
connect(nuimo, &Nuimo::buttonPressed, this, &DevicePluginSenic::onButtonPressed); connect(nuimo, &Nuimo::buttonPressed, this, &DevicePluginSenic::onButtonPressed);
connect(nuimo, &Nuimo::buttonReleased, this, &DevicePluginSenic::onButtonReleased); connect(nuimo, &Nuimo::buttonLongPressed, this, &DevicePluginSenic::onButtonLongPressed);
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);
connect(nuimo, &Nuimo::connectedChanged, this, &DevicePluginSenic::onConnectedChanged);
connect(nuimo, &Nuimo::deviceInformationChanged, this, &DevicePluginSenic::onDeviceInformationChanged);
connect(nuimo, &Nuimo::batteryValueChanged, this, &DevicePluginSenic::onBatteryValueChanged);
m_nuimos.insert(nuimo, device); m_nuimos.insert(nuimo, device);
nuimo->bluetoothDevice()->connectDevice(); nuimo->bluetoothDevice()->connectDevice();
return Device::DeviceSetupStatusSuccess; return Device::DeviceSetupStatusAsync;
} }
Device::DeviceError DevicePluginSenic::executeAction(Device *device, const Action &action) Device::DeviceError DevicePluginSenic::executeAction(Device *device, const Action &action)
{ {
QPointer<Nuimo> nuimo = m_nuimos.key(device); QPointer<Nuimo> nuimo = m_nuimos.key(device);
@ -104,9 +117,17 @@ Device::DeviceError DevicePluginSenic::executeAction(Device *device, const Actio
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Stop") if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Stop")
nuimo->showImage(Nuimo::MatrixTypeStop); nuimo->showImage(Nuimo::MatrixTypeStop);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Music") if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Music")
nuimo->showImage(Nuimo::MatrixTypeStop); nuimo->showImage(Nuimo::MatrixTypeMusic);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Heart") if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Heart")
nuimo->showImage(Nuimo::MatrixTypeHeart); nuimo->showImage(Nuimo::MatrixTypeHeart);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Next")
nuimo->showImage(Nuimo::MatrixTypeNext);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Previous")
nuimo->showImage(Nuimo::MatrixTypePrevious);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Circle")
nuimo->showImage(Nuimo::MatrixTypeCircle);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Light")
nuimo->showImage(Nuimo::MatrixTypeLight);
return Device::DeviceErrorNoError; return Device::DeviceErrorNoError;
} }
@ -114,6 +135,7 @@ Device::DeviceError DevicePluginSenic::executeAction(Device *device, const Actio
return Device::DeviceErrorActionTypeNotFound; return Device::DeviceErrorActionTypeNotFound;
} }
void DevicePluginSenic::deviceRemoved(Device *device) void DevicePluginSenic::deviceRemoved(Device *device)
{ {
if (!m_nuimos.values().contains(device)) if (!m_nuimos.values().contains(device))
@ -121,19 +143,17 @@ void DevicePluginSenic::deviceRemoved(Device *device)
Nuimo *nuimo = m_nuimos.key(device); Nuimo *nuimo = m_nuimos.key(device);
m_nuimos.take(nuimo); m_nuimos.take(nuimo);
delete nuimo;
}
bool DevicePluginSenic::verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo) hardwareManager()->bluetoothLowEnergyManager()->unregisterDevice(nuimo->bluetoothDevice());
{ nuimo->deleteLater();
foreach (Device *device, myDevices()) {
if (device->paramValue(nuimoDeviceMacParamTypeId).toString() == deviceInfo.address().toString()) if (myDevices().isEmpty()) {
return true; hardwareManager()->pluginTimerManager()->unregisterTimer(m_reconnectTimer);
m_reconnectTimer = nullptr;
} }
return false;
} }
void DevicePluginSenic::onReconnectTimeout() void DevicePluginSenic::onReconnectTimeout()
{ {
foreach (Nuimo *nuimo, m_nuimos.keys()) { foreach (Nuimo *nuimo, m_nuimos.keys()) {
@ -143,48 +163,80 @@ void DevicePluginSenic::onReconnectTimeout()
} }
} }
void DevicePluginSenic::onBluetoothDiscoveryFinished() void DevicePluginSenic::onBluetoothDiscoveryFinished()
{ {
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender()); BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
reply->deleteLater();
if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) { if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) {
qCWarning(dcSenic()) << "Bluetooth discovery error:" << reply->error(); qCWarning(dcSenic()) << "Bluetooth discovery error:" << reply->error();
reply->deleteLater();
emit devicesDiscovered(nuimoDeviceClassId, QList<DeviceDescriptor>()); emit devicesDiscovered(nuimoDeviceClassId, QList<DeviceDescriptor>());
return; return;
} }
QList<DeviceDescriptor> deviceDescriptors; QList<DeviceDescriptor> deviceDescriptors;
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) { foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
if (deviceInfo.name().contains("Nuimo")) { if (deviceInfo.name().contains("Nuimo")) {
if (!verifyExistingDevices(deviceInfo)) { DeviceDescriptor descriptor(nuimoDeviceClassId, "Nuimo", deviceInfo.name() + " (" + deviceInfo.address().toString() + ")");
DeviceDescriptor descriptor(nuimoDeviceClassId, "Nuimo", deviceInfo.address().toString()); ParamList params;
ParamList params;
params.append(Param(nuimoDeviceNameParamTypeId, deviceInfo.name())); foreach (Device *existingDevice, myDevices()) {
params.append(Param(nuimoDeviceMacParamTypeId, deviceInfo.address().toString())); if (existingDevice->paramValue(nuimoDeviceMacParamTypeId).toString() == deviceInfo.address().toString()) {
descriptor.setParams(params); descriptor.setDeviceId(existingDevice->id());
deviceDescriptors.append(descriptor); break;
}
} }
params.append(Param(nuimoDeviceMacParamTypeId, deviceInfo.address().toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
} }
} }
reply->deleteLater();
emit devicesDiscovered(nuimoDeviceClassId, deviceDescriptors); emit devicesDiscovered(nuimoDeviceClassId, deviceDescriptors);
} }
void DevicePluginSenic::onDeviceInitializationFinished()
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
if (!device->setupComplete()) {
emit deviceSetupFinished(device, Device::DeviceSetupStatusSuccess);
}
}
void DevicePluginSenic::onConnectedChanged(bool connected)
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
device->setStateValue(nuimoConnectedStateTypeId, connected);
}
void DevicePluginSenic::onButtonPressed() void DevicePluginSenic::onButtonPressed()
{ {
Nuimo *nuimo = static_cast<Nuimo *>(sender()); Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo); Device *device = m_nuimos.value(nuimo);
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, ""))); emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
if (m_autoSymbolMode) {
nuimo->showImage(Nuimo::MatrixTypeCircle);
}
} }
void DevicePluginSenic::onButtonReleased()
void DevicePluginSenic::onButtonLongPressed()
{ {
// TODO: user timer for detekt long pressed (if needed) Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
emitEvent(Event(nuimoLongPressedEventTypeId, device->id()));
if (m_autoSymbolMode) {
nuimo->showImage(Nuimo::MatrixTypeFilledCircle);
}
} }
void DevicePluginSenic::onSwipeDetected(const Nuimo::SwipeDirection &direction) void DevicePluginSenic::onSwipeDetected(const Nuimo::SwipeDirection &direction)
{ {
Nuimo *nuimo = static_cast<Nuimo *>(sender()); Nuimo *nuimo = static_cast<Nuimo *>(sender());
@ -204,8 +256,26 @@ void DevicePluginSenic::onSwipeDetected(const Nuimo::SwipeDirection &direction)
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, ""))); emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
break; break;
} }
if (m_autoSymbolMode) {
switch (direction) {
case Nuimo::SwipeDirectionLeft:
nuimo->showImage(Nuimo::MatrixType::MatrixTypeLeft);
break;
case Nuimo::SwipeDirectionRight:
nuimo->showImage(Nuimo::MatrixType::MatrixTypeRight);
break;
case Nuimo::SwipeDirectionUp:
nuimo->showImage(Nuimo::MatrixType::MatrixTypeUp);
break;
case Nuimo::SwipeDirectionDown:
nuimo->showImage(Nuimo::MatrixType::MatrixTypeDown);
break;
}
}
} }
void DevicePluginSenic::onRotationValueChanged(const uint &value) void DevicePluginSenic::onRotationValueChanged(const uint &value)
{ {
Nuimo *nuimo = static_cast<Nuimo *>(sender()); Nuimo *nuimo = static_cast<Nuimo *>(sender());
@ -214,3 +284,44 @@ void DevicePluginSenic::onRotationValueChanged(const uint &value)
} }
void DevicePluginSenic::onDeviceInformationChanged(const QString &firmwareRevision, const QString &hardwareRevision, const QString &softwareRevision)
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
device->setStateValue(nuimoFirmwareRevisionStateTypeId, firmwareRevision);
device->setStateValue(nuimoHardwareRevisionStateTypeId, hardwareRevision);
device->setStateValue(nuimoSoftwareRevisionStateTypeId, softwareRevision);
}
void DevicePluginSenic::onPluginConfigurationChanged(const ParamTypeId &paramTypeId, const QVariant &value)
{
qCDebug(dcSenic()) << "Plugin configuration changed";
// Check auto symbol mode
if (paramTypeId == senicPluginAutoSymbolsParamTypeId) {
qCDebug(dcSenic()) << "Auto symbol mode" << (value.toBool() ? "enabled." : "disabled.");
m_autoSymbolMode = value.toBool();
}
if (paramTypeId == senicPluginLongPressTimeParamTypeId) {
qCDebug(dcSenic()) << "Long press time" << value.toInt();
foreach(Nuimo *nuimo, m_nuimos.keys()) {
nuimo->setLongPressTime(value.toInt());
}
}
}
void DevicePluginSenic::onBatteryValueChanged(const uint &percentage)
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
device->setStateValue(nuimoBatteryLevelStateTypeId, percentage);
if (percentage < 20) {
device->setStateValue(nuimoBatteryCriticalStateTypeId, true);
} else {
device->setStateValue(nuimoBatteryCriticalStateTypeId, false);
}
}

View File

@ -49,18 +49,21 @@ public:
private: private:
QHash<Nuimo *, Device *> m_nuimos; QHash<Nuimo *, Device *> m_nuimos;
PluginTimer *m_reconnectTimer = nullptr; PluginTimer *m_reconnectTimer = nullptr;
bool m_autoSymbolMode = true;
bool verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo);
private slots: private slots:
void onPluginConfigurationChanged(const ParamTypeId &paramTypeId, const QVariant &value);
void onReconnectTimeout(); void onReconnectTimeout();
void onBluetoothDiscoveryFinished(); void onBluetoothDiscoveryFinished();
void onDeviceInitializationFinished();
void onConnectedChanged(bool connected);
void onBatteryValueChanged(const uint &percentage);
void onButtonPressed(); void onButtonPressed();
void onButtonReleased(); void onButtonLongPressed();
void onSwipeDetected(const Nuimo::SwipeDirection &direction); void onSwipeDetected(const Nuimo::SwipeDirection &direction);
void onRotationValueChanged(const uint &value); void onRotationValueChanged(const uint &value);
void onDeviceInformationChanged(const QString &firmwareRevision, const QString &hardwareRevision, const QString &softwareRevision);
}; };
#endif // DEVICEPLUGINSENIC_H #endif // DEVICEPLUGINSENIC_H

View File

@ -2,6 +2,22 @@
"displayName": "Senic", "displayName": "Senic",
"id": "413e9d77-335f-4ecf-abbc-8f2a8a399c39", "id": "413e9d77-335f-4ecf-abbc-8f2a8a399c39",
"name": "Senic", "name": "Senic",
"paramTypes": [
{
"id": "ba3d4269-940b-42ee-8c73-1e1bdea329c2",
"name": "autoSymbols",
"displayName": "Automatically display symbols",
"type": "bool",
"defaultValue": true
},
{
"id": "f9900dfe-310b-462b-b09d-a999df441075",
"name": "longPressTime",
"displayName": "Long press time",
"type": "int",
"defaultValue": 2000
}
],
"vendors": [ "vendors": [
{ {
"displayName": "Senic", "displayName": "Senic",
@ -13,19 +29,12 @@
"name": "nuimo", "name": "nuimo",
"displayName": "Nuimo", "displayName": "Nuimo",
"createMethods": ["discovery"], "createMethods": ["discovery"],
"interfaces": [ "simplemultibutton", "connectable"], "interfaces": ["simplemultibutton", "longpressbutton", "connectable", "batterylevel"],
"paramTypes": [ "paramTypes": [
{
"id": "db67d1e6-26fa-44ed-ad55-c6aef45ea2ea",
"name": "name",
"displayName": "name",
"type": "QString",
"inputType": "TextLine"
},
{ {
"id": "71553f6a-2ed4-4896-bb7b-52e7dca948b2", "id": "71553f6a-2ed4-4896-bb7b-52e7dca948b2",
"name": "mac", "name": "mac",
"displayName": "mac address", "displayName": "Mac address",
"type": "QString", "type": "QString",
"inputType": "MacAddress" "inputType": "MacAddress"
} }
@ -63,11 +72,19 @@
"type": "QString", "type": "QString",
"defaultValue": "-" "defaultValue": "-"
}, },
{
"id": "aabd660f-b0c5-49f6-b7b0-6ba8e0a8cfcd",
"name": "batteryCritical",
"displayName": "Battery critical",
"displayNameEvent": "Battery critical changed",
"type": "bool",
"defaultValue": true
},
{ {
"id": "b5ee2465-7fa1-450b-8073-f115537d3409", "id": "b5ee2465-7fa1-450b-8073-f115537d3409",
"name": "battery", "name": "batteryLevel",
"displayName": "battery", "displayName": "Battery",
"displayNameEvent": "battery changed", "displayNameEvent": "Battery changed",
"type": "int", "type": "int",
"minValue": 0, "minValue": 0,
"maxValue": 100, "maxValue": 100,
@ -77,8 +94,8 @@
{ {
"id": "69a5f495-5452-434b-8fb8-b73d992c5446", "id": "69a5f495-5452-434b-8fb8-b73d992c5446",
"name": "rotation", "name": "rotation",
"displayName": "rotation", "displayName": "Rotation",
"displayNameEvent": "rotation changed", "displayNameEvent": "Rotation changed",
"type": "int", "type": "int",
"minValue": 0, "minValue": 0,
"maxValue": 100, "maxValue": 100,
@ -95,7 +112,7 @@
{ {
"id": "a8f72c37-9cb5-4885-a7e4-b2b396f8e4cd", "id": "a8f72c37-9cb5-4885-a7e4-b2b396f8e4cd",
"name": "logo", "name": "logo",
"displayName": "logo", "displayName": "Logo",
"type": "QString", "type": "QString",
"defaultValue": "Heart", "defaultValue": "Heart",
"allowedValues": [ "allowedValues": [
@ -107,7 +124,11 @@
"Pause", "Pause",
"Stop", "Stop",
"Music", "Music",
"Heart" "Heart",
"Next",
"Previous",
"Circle",
"Light"
] ]
} }
] ]
@ -127,6 +148,11 @@
"allowedValues": ["•", "←", "↑", "→", "↓"] "allowedValues": ["•", "←", "↑", "→", "↓"]
} }
] ]
},
{
"id": "a2f4add5-f76a-4dca-ae68-4107533bee0e",
"name": "longPressed",
"displayName": "Button long pressed"
} }
] ]
} }

View File

@ -35,19 +35,20 @@ static QBluetoothUuid inputRotationCharacteristicUuid = QBluetoothUuid(QUuid("
static QBluetoothUuid inputButtonCharacteristicUuid = QBluetoothUuid(QUuid("f29b1529-cb19-40f3-be5c-7241ecb82fd2")); static QBluetoothUuid inputButtonCharacteristicUuid = QBluetoothUuid(QUuid("f29b1529-cb19-40f3-be5c-7241ecb82fd2"));
Nuimo::Nuimo(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent) : Nuimo::Nuimo(BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent) :
QObject(parent), QObject(parent),
m_device(device),
m_bluetoothDevice(bluetoothDevice) m_bluetoothDevice(bluetoothDevice)
{ {
connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::connectedChanged, this, &Nuimo::onConnectedChanged); connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::connectedChanged, this, &Nuimo::onConnectedChanged);
connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::servicesDiscoveryFinished, this, &Nuimo::onServiceDiscoveryFinished); connect(m_bluetoothDevice, &BluetoothLowEnergyDevice::servicesDiscoveryFinished, this, &Nuimo::onServiceDiscoveryFinished);
if (!m_longPressTimer) {
m_longPressTimer = new QTimer(this);
m_longPressTimer->setSingleShot(true);
}
connect(m_longPressTimer, &QTimer::timeout, this, &Nuimo::onLongPressTimer);
} }
Device *Nuimo::device()
{
return m_device;
}
BluetoothLowEnergyDevice *Nuimo::bluetoothDevice() BluetoothLowEnergyDevice *Nuimo::bluetoothDevice()
{ {
@ -176,13 +177,81 @@ void Nuimo::showImage(const Nuimo::MatrixType &matrixType)
" * "); " * ");
time = 5; time = 5;
break; break;
default: case MatrixTypeNext:
matrix = QByteArray(
" "
" * ** "
" ** ** "
" *** ** "
" ****** "
" *** ** "
" ** ** "
" * ** "
" ");
time = 5;
break;
case MatrixTypePrevious:
matrix = QByteArray(
" "
" ** * "
" ** ** "
" ** *** "
" ****** "
" ** *** "
" ** ** "
" ** * "
" ");
time = 5;
break;
case MatrixTypeCircle:
matrix = QByteArray(
" "
" "
" *** "
" * * "
" * * "
" * * "
" *** "
" "
" ");
time = 5;
break;
case MatrixTypeFilledCircle:
matrix = QByteArray(
" "
" "
" *** "
" ***** "
" ***** "
" ***** "
" *** "
" "
" ");
time = 5;
break;
case MatrixTypeLight:
matrix = QByteArray(
" "
" *** "
" * * "
" * * "
" * * "
" *** "
" *** "
" *** "
" * ");
time = 5;
break; break;
} }
showMatrix(matrix, time); showMatrix(matrix, time);
} }
void Nuimo::setLongPressTime(int milliSeconds)
{
m_longPressTime = milliSeconds;
}
void Nuimo::showMatrix(const QByteArray &matrix, const int &seconds) void Nuimo::showMatrix(const QByteArray &matrix, const int &seconds)
{ {
if (!m_ledMatrixService) if (!m_ledMatrixService)
@ -219,18 +288,19 @@ void Nuimo::printService(QLowEnergyService *service)
} }
} }
void Nuimo::setBatteryValue(const QByteArray &data) void Nuimo::onLongPressTimer()
{ {
int batteryPercentage = data.toHex().toUInt(0, 16); emit buttonLongPressed();
qCDebug(dcSenic()) << "Battery:" << batteryPercentage << "%";
device()->setStateValue(nuimoBatteryStateTypeId, batteryPercentage);
} }
void Nuimo::onConnectedChanged(const bool &connected) void Nuimo::onConnectedChanged(const bool &connected)
{ {
qCDebug(dcSenic()) << m_bluetoothDevice->name() << m_bluetoothDevice->address().toString() << (connected ? "connected" : "disconnected"); qCDebug(dcSenic()) << m_bluetoothDevice->name() << m_bluetoothDevice->address().toString() << (connected ? "connected" : "disconnected");
m_device->setStateValue(nuimoConnectedStateTypeId, connected);
m_longPressTimer->stop();
emit connectedChanged(connected);
if (!connected) { if (!connected) {
// Clean up services // Clean up services
@ -332,7 +402,7 @@ void Nuimo::onServiceDiscoveryFinished()
m_ledMatrixService->discoverDetails(); m_ledMatrixService->discoverDetails();
} }
} }
emit deviceInitializationFinished();
} }
void Nuimo::onDeviceInfoServiceStateChanged(const QLowEnergyService::ServiceState &state) void Nuimo::onDeviceInfoServiceStateChanged(const QLowEnergyService::ServiceState &state)
@ -344,11 +414,11 @@ void Nuimo::onDeviceInfoServiceStateChanged(const QLowEnergyService::ServiceStat
qCDebug(dcSenic()) << "Device info service discovered."; qCDebug(dcSenic()) << "Device info service discovered.";
printService(m_deviceInfoService); printService(m_deviceInfoService);
QString firmware = QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::FirmwareRevisionString).value());
QString hardware = QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::HardwareRevisionString).value());
QString software = QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::SoftwareRevisionString).value());
device()->setStateValue(nuimoFirmwareRevisionStateTypeId, QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::FirmwareRevisionString).value())); emit deviceInformationChanged(firmware, hardware, software);
device()->setStateValue(nuimoHardwareRevisionStateTypeId, QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::HardwareRevisionString).value()));
device()->setStateValue(nuimoSoftwareRevisionStateTypeId, QString::fromUtf8(m_deviceInfoService->characteristic(QBluetoothUuid::SoftwareRevisionString).value()));
} }
void Nuimo::onBatteryServiceStateChanged(const QLowEnergyService::ServiceState &state) void Nuimo::onBatteryServiceStateChanged(const QLowEnergyService::ServiceState &state)
@ -371,13 +441,15 @@ void Nuimo::onBatteryServiceStateChanged(const QLowEnergyService::ServiceState &
QLowEnergyDescriptor notificationDescriptor = m_batteryCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); QLowEnergyDescriptor notificationDescriptor = m_batteryCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
m_batteryService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100")); m_batteryService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
setBatteryValue(m_batteryCharacteristic.value()); uint batteryPercentage = m_batteryCharacteristic.value().toHex().toUInt(nullptr, 16);
emit batteryValueChanged(batteryPercentage);
} }
void Nuimo::onBatteryCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) void Nuimo::onBatteryCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
{ {
if (characteristic.uuid() == m_batteryCharacteristic.uuid()) { if (characteristic.uuid() == m_batteryCharacteristic.uuid()) {
setBatteryValue(value); uint batteryPercentage = value.toHex().toUInt(nullptr, 16);
emit batteryValueChanged(batteryPercentage);
} }
} }
@ -427,18 +499,22 @@ void Nuimo::onInputServiceStateChanged(const QLowEnergyService::ServiceState &st
void Nuimo::onInputCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value) 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(nullptr, 16);
qCDebug(dcSenic()) << "Button:" << (pressed ? "pressed": "released"); qCDebug(dcSenic()) << "Button:" << (pressed ? "pressed": "released");
if (pressed) { if (pressed) {
emit buttonPressed(); m_longPressTimer->start(m_longPressTime);
} else { } else {
emit buttonReleased(); if (m_longPressTimer->isActive()) {
m_longPressTimer->stop();
emit buttonPressed();
}
// else the time run out and has the long pressed event emittted
} }
return; return;
} }
if (characteristic.uuid() == m_inputSwipeCharacteristic.uuid()) { if (characteristic.uuid() == m_inputSwipeCharacteristic.uuid()) {
quint8 swipe = (quint8)value.toHex().toUInt(0, 16); quint8 swipe = (quint8)value.toHex().toUInt(nullptr, 16);
switch (swipe) { switch (swipe) {
case 0: case 0:
qCDebug(dcSenic()) << "Swipe: Left"; qCDebug(dcSenic()) << "Swipe: Left";

View File

@ -24,10 +24,10 @@
#define NUIMO_H #define NUIMO_H
#include <QObject> #include <QObject>
#include <QTimer>
#include <QBluetoothUuid> #include <QBluetoothUuid>
#include "typeutils.h" #include "typeutils.h"
#include "devices/device.h"
#include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h" #include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h"
class Nuimo : public QObject class Nuimo : public QObject
@ -50,18 +50,21 @@ public:
MatrixTypePause, MatrixTypePause,
MatrixTypeStop, MatrixTypeStop,
MatrixTypeMusic, MatrixTypeMusic,
MatrixTypeHeart MatrixTypeHeart,
MatrixTypeNext,
MatrixTypePrevious,
MatrixTypeCircle,
MatrixTypeFilledCircle,
MatrixTypeLight
}; };
explicit Nuimo(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent = nullptr); explicit Nuimo(BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent = nullptr);
Device *device();
BluetoothLowEnergyDevice *bluetoothDevice(); BluetoothLowEnergyDevice *bluetoothDevice();
void showImage(const MatrixType &matrixType); void showImage(const MatrixType &matrixType);
void setLongPressTime(int milliSeconds);
private: private:
Device *m_device = nullptr;
BluetoothLowEnergyDevice *m_bluetoothDevice = nullptr; BluetoothLowEnergyDevice *m_bluetoothDevice = nullptr;
QLowEnergyService *m_deviceInfoService = nullptr; QLowEnergyService *m_deviceInfoService = nullptr;
@ -77,21 +80,22 @@ private:
QLowEnergyCharacteristic m_inputRotationCharacteristic; QLowEnergyCharacteristic m_inputRotationCharacteristic;
uint m_rotationValue; uint m_rotationValue;
QTimer *m_longPressTimer = nullptr;
int m_longPressTime = 2000; //default value 2 seconds
void showMatrix(const QByteArray &matrix, const int &seconds); void showMatrix(const QByteArray &matrix, const int &seconds);
void printService(QLowEnergyService *service); void printService(QLowEnergyService *service);
void onLongPressTimer();
// Set states
void setBatteryValue(const QByteArray &data);
signals: signals:
void availableChanged(); void connectedChanged(bool connected);
void buttonPressed(); void buttonPressed();
void buttonReleased(); void buttonLongPressed();
void batteryValueChaged(const uint &percentage); void batteryValueChanged(const uint &percentage);
void swipeDetected(const SwipeDirection &direction); void swipeDetected(const SwipeDirection &direction);
void rotationValueChanged(const uint &value); void rotationValueChanged(const uint &value);
void deviceInformationChanged(const QString &firmwareRevision, const QString &hardwareRevision, const QString &softwareRevision);
void deviceInitializationFinished();
private slots: private slots:
void onConnectedChanged(const bool &connected); void onConnectedChanged(const bool &connected);