diff --git a/plugins/deviceplugins/senic/devicepluginsenic.cpp b/plugins/deviceplugins/senic/devicepluginsenic.cpp index 7b008460..2645ad91 100644 --- a/plugins/deviceplugins/senic/devicepluginsenic.cpp +++ b/plugins/deviceplugins/senic/devicepluginsenic.cpp @@ -26,7 +26,6 @@ \ingroup plugins \ingroup guh-plugins - \chapter Plugin properties Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses} and \l{Vendor}{Vendors} of this \l{DevicePlugin}. @@ -72,6 +71,8 @@ DeviceManager::DeviceSetupStatus DevicePluginSenic::setupDevice(Device *device) connect(nuimo, &Nuimo::batteryValueChaged, this, &DevicePluginSenic::onBatteryValueChanged); connect(nuimo, &Nuimo::buttonPressed, this, &DevicePluginSenic::onButtonPressed); connect(nuimo, &Nuimo::buttonReleased, this, &DevicePluginSenic::onButtonReleased); + connect(nuimo, &Nuimo::swipeDetected, this, &DevicePluginSenic::onSwipeDetected); + connect(nuimo, &Nuimo::rotationValueChanged, this, &DevicePluginSenic::onRotationValueChanged); m_nuimos.insert(nuimo, device); @@ -103,11 +104,19 @@ DeviceManager::DeviceError DevicePluginSenic::executeAction(Device *device, cons } if (action.actionTypeId() == showLogoActionTypeId) { - nuimo->showGuhLogo(); + + if (action.param("logo").value().toString() == "Guh") + nuimo->showGuhLogo(); + + if (action.param("logo").value().toString() == "Arrow up") + nuimo->showArrowUp(); + + if (action.param("logo").value().toString() == "Arrow down") + nuimo->showArrowDown(); + return DeviceManager::DeviceErrorNoError; } - return DeviceManager::DeviceErrorActionTypeNotFound; } @@ -176,6 +185,36 @@ void DevicePluginSenic::onButtonReleased() // TODO: user timer for detekt long pressed (if needed) } +void DevicePluginSenic::onSwipeDetected(const Nuimo::SwipeDirection &direction) +{ + Nuimo *nuimo = static_cast(sender()); + Device *device = m_nuimos.value(nuimo); + + switch (direction) { + case Nuimo::SwipeDirectionLeft: + emitEvent(Event(swipeLeftEventTypeId, device->id())); + break; + case Nuimo::SwipeDirectionRight: + emitEvent(Event(swipeRightEventTypeId, device->id())); + break; + case Nuimo::SwipeDirectionUp: + emitEvent(Event(swipeUpEventTypeId, device->id())); + break; + case Nuimo::SwipeDirectionDown: + emitEvent(Event(swipeDownEventTypeId, device->id())); + break; + default: + break; + } +} + +void DevicePluginSenic::onRotationValueChanged(const uint &value) +{ + Nuimo *nuimo = static_cast(sender()); + Device *device = m_nuimos.value(nuimo); + device->setStateValue(rotationStateTypeId, value); +} + #endif // BLUETOOTH_LE diff --git a/plugins/deviceplugins/senic/devicepluginsenic.h b/plugins/deviceplugins/senic/devicepluginsenic.h index ff3a12a8..0fa3b172 100644 --- a/plugins/deviceplugins/senic/devicepluginsenic.h +++ b/plugins/deviceplugins/senic/devicepluginsenic.h @@ -55,6 +55,8 @@ private slots: void onBatteryValueChanged(const uint &percentage); void onButtonPressed(); void onButtonReleased(); + void onSwipeDetected(const Nuimo::SwipeDirection &direction); + void onRotationValueChanged(const uint &value); }; diff --git a/plugins/deviceplugins/senic/devicepluginsenic.json b/plugins/deviceplugins/senic/devicepluginsenic.json index 745ce161..ad305c0e 100644 --- a/plugins/deviceplugins/senic/devicepluginsenic.json +++ b/plugins/deviceplugins/senic/devicepluginsenic.json @@ -50,6 +50,17 @@ "maxValue": 100, "unit": "Percentage", "defaultValue": 0 + }, + { + "id": "69a5f495-5452-434b-8fb8-b73d992c5446", + "idName": "rotation", + "name": "rotation", + "index": 2, + "type": "int", + "minValue": 0, + "maxValue": 100, + "unit": "Percentage", + "defaultValue": 0 } ], "actionTypes": [ @@ -69,7 +80,20 @@ "id": "d44ca5b7-f8d6-4413-9d2e-cef89282c039", "idName": "showLogo", "index": 2, - "name": "show logo" + "name": "Show logo", + "paramTypes": [ + { + "name": "logo", + "type": "QString", + "index": 0, + "defaultValue": "Guh", + "allowedValues": [ + "Guh", + "Arrow up", + "Arrow down" + ] + } + ] } ], "eventTypes": [ @@ -77,19 +101,31 @@ "id": "5b9e08e8-7a6c-4311-9db6-82547847708c", "idName": "clicked", "name": "clicked", - "index": "0" + "index": 0 }, { "id": "2be36aa0-e2fe-4192-81c5-cf0bb7f08dd4", "idName": "swipeLeft", "name": "Swipe left", - "index": "1" + "index": 1 }, { "id": "81fb61ab-6d3d-4c1b-85fe-3dbd5c8dead7", "idName": "swipeRight", "name": "Swipe right", - "index": "2" + "index": 2 + }, + { + "id": "ab5c575b-b265-491c-93ca-ad9212374bc1", + "idName": "swipeUp", + "name": "Swipe up", + "index": 3 + }, + { + "id": "4d97cf28-1030-4a30-bed5-411102dd4b9b", + "idName": "swipeDown", + "name": "Swipe down", + "index": 4 } ] } diff --git a/plugins/deviceplugins/senic/nuimo.cpp b/plugins/deviceplugins/senic/nuimo.cpp index 6028d893..f630aae9 100644 --- a/plugins/deviceplugins/senic/nuimo.cpp +++ b/plugins/deviceplugins/senic/nuimo.cpp @@ -24,6 +24,7 @@ #include "extern-plugininfo.h" #include +#include Nuimo::Nuimo(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent) : BluetoothLowEnergyDevice(deviceInfo, addressType, parent), @@ -45,35 +46,49 @@ bool Nuimo::isAvailable() void Nuimo::showGuhLogo() { QByteArray matrix( - " " - " * " - " ** ** " - " **** " - " ** " - " * " - " * " - " * " - " "); + " " + " * " + " ** " + " *** ** " + " ***** " + " ** " + " ** " + " * " + " "); - QBitArray bits; - bits.resize(81); - for (int i = 0; i < matrix.size(); i++) { - if (matrix.at(i) != ' ') { - bits[i] = true; - } - } + showMatrix(matrix, 10); +} - QByteArray bytes; - bytes.resize(bits.count() / 8+1); - bytes.fill(0); - // Convert from QBitArray to QByteArray - for(int b = 0; b < bits.count(); ++b) - bytes[b / 8] = (bytes.at(b / 8) | ((bits[b] ? 1 : 0) << (b % 8))); +void Nuimo::showArrowUp() +{ + QByteArray matrix( + " * " + " *** " + " * * * " + " * * * " + "* * *" + " * " + " * " + " * " + " * "); - bytes.append(QByteArray::fromHex("FF")); - bytes.append(QByteArray::fromHex("AA")); + showMatrix(matrix, 3); +} - m_ledMatrixService->writeCharacteristic(m_ledMatrixCharacteristic, bytes); +void Nuimo::showArrowDown() +{ + QByteArray matrix( + " * " + " * " + " * " + " * " + "* * *" + " * * * " + " * * * " + " *** " + " * "); + + showMatrix(matrix, 3); } void Nuimo::registerService(QLowEnergyService *service) @@ -87,6 +102,29 @@ void Nuimo::registerService(QLowEnergyService *service) service->discoverDetails(); } +void Nuimo::showMatrix(const QByteArray &matrix, const int &seconds) +{ + QBitArray bits; + bits.resize(81); + for (int i = 0; i < matrix.size(); i++) { + if (matrix.at(i) != ' ') { + bits[i] = true; + } + } + + QByteArray bytes; + bytes.resize(bits.count() / 8 + 1); + bytes.fill(0); + // Convert from QBitArray to QByteArray + for(int b = 0; b < bits.count(); ++b) + bytes[b / 8] = (bytes.at(b / 8) | ((bits[b] ? 1 : 0) << (b % 8))); + + bytes.append(QByteArray::fromHex("FF")); + quint8 time = quint8(seconds * 10); + bytes.append((char)time); + m_ledMatrixService->writeCharacteristic(m_ledMatrixCharacteristic, bytes); +} + void Nuimo::serviceScanFinished() { @@ -192,18 +230,18 @@ void Nuimo::serviceStateChanged(const QLowEnergyService::ServiceState &state) switch (state) { case QLowEnergyService::DiscoveringServices: - if (service == m_batteryService) { + if (service == m_batteryService) qCDebug(dcSenic()) << "Start discovering battery service..."; - } - if (service == m_deviceInfoService) { + + if (service == m_deviceInfoService) qCDebug(dcSenic()) << "Start discovering device information service..."; - } - if (service == m_inputService) { + + if (service == m_inputService) qCDebug(dcSenic()) << "Start discovering input service..."; - } - if (service == m_inputService) { + + if (service == m_ledMatrixService) qCDebug(dcSenic()) << "Start discovering led matrix service..."; - } + break; case QLowEnergyService::ServiceDiscovered: @@ -243,19 +281,43 @@ void Nuimo::serviceStateChanged(const QLowEnergyService::ServiceState &state) // 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 found for device " << name() << address().toString(); + 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_inputButtonCharacteristic.descriptors()) { + foreach (const QLowEnergyDescriptor &descriptor, m_inputRotationCharacteristic.descriptors()) { qCDebug(dcSenic()) << descriptor.name() << descriptor.uuid().toString(); m_inputService->writeDescriptor(descriptor, QByteArray::fromHex("0100")); } } - // Input + // Led Matrix if (service == m_ledMatrixService) { qCDebug(dcSenic()) << "Led matrix service discovered"; m_ledMatrixCharacteristic = m_ledMatrixService->characteristic(QBluetoothUuid(QUuid("F29B1524-CB19-40F3-BE5C-7241ECB82FD1"))); @@ -293,6 +355,47 @@ void Nuimo::serviceCharacteristicChanged(const QLowEnergyCharacteristic &charact return; } + if (characteristic.uuid() == m_inputSwipeCharacteristic.uuid()) { + quint8 swipe = (quint8)value.toHex().toUInt(0, 16); + switch (swipe) { + case 0: + qCDebug(dcSenic()) << "Swipe: Left"; + emit swipeDetected(SwipeDirectionLeft); + break; + case 1: + qCDebug(dcSenic()) << "Swipe: Right"; + emit swipeDetected(SwipeDirectionRight); + break; + case 2: + qCDebug(dcSenic()) << "Swipe: Up"; + emit swipeDetected(SwipeDirectionUp); + break; + case 3: + qCDebug(dcSenic()) << "Swipe: Down"; + emit swipeDetected(SwipeDirectionDown); + break; + default: + break; + } + return; + } + + if (characteristic.uuid() == m_inputRotationCharacteristic.uuid()) { + qint16 intValue = qFromLittleEndian((uchar *)value.constData()); + qCDebug(dcSenic()) << "Rotation" << value.toHex() << intValue; + int finalValue = m_rotationValue + qRound(intValue / 10.0); + if (finalValue <= 0) { + m_rotationValue = 0; + } else if (finalValue >= 100) { + m_rotationValue = 100; + } else { + m_rotationValue = finalValue; + } + emit rotationValueChanged(m_rotationValue); + return; + } + + qCDebug(dcSenic()) << "Service characteristic changed" << characteristic.name() << value.toHex(); } diff --git a/plugins/deviceplugins/senic/nuimo.h b/plugins/deviceplugins/senic/nuimo.h index a2ba166d..b844c41b 100644 --- a/plugins/deviceplugins/senic/nuimo.h +++ b/plugins/deviceplugins/senic/nuimo.h @@ -33,11 +33,20 @@ class Nuimo : public BluetoothLowEnergyDevice { Q_OBJECT public: + enum SwipeDirection { + SwipeDirectionLeft, + SwipeDirectionRight, + SwipeDirectionUp, + SwipeDirectionDown + }; + explicit Nuimo(const QBluetoothDeviceInfo &deviceInfo, const QLowEnergyController::RemoteAddressType &addressType, QObject *parent = 0); bool isAvailable(); void showGuhLogo(); + void showArrowUp(); + void showArrowDown(); private: QLowEnergyService *m_deviceInfoService; @@ -47,18 +56,24 @@ private: QLowEnergyCharacteristic m_deviceInfoCharacteristic; QLowEnergyCharacteristic m_batteryCharacteristic; - QLowEnergyCharacteristic m_inputButtonCharacteristic; QLowEnergyCharacteristic m_ledMatrixCharacteristic; + QLowEnergyCharacteristic m_inputButtonCharacteristic; + QLowEnergyCharacteristic m_inputSwipeCharacteristic; + QLowEnergyCharacteristic m_inputRotationCharacteristic; bool m_isAvailable; + uint m_rotationValue; void registerService(QLowEnergyService *service); + void showMatrix(const QByteArray &matrix, const int &seconds); signals: void availableChanged(); void buttonPressed(); void buttonReleased(); void batteryValueChaged(const uint &percentage); + void swipeDetected(const SwipeDirection &direction); + void rotationValueChanged(const uint &value); private slots: void serviceScanFinished();