From b995c9f9bbb8ea20606fd2531bdd30386edb82d8 Mon Sep 17 00:00:00 2001 From: nymea Date: Wed, 11 Sep 2019 16:51:37 +0200 Subject: [PATCH 1/2] added counter device --- gpio/deviceplugingpio.cpp | 98 ++++++++++++++++++++++++++++------ gpio/deviceplugingpio.h | 5 +- gpio/deviceplugingpio.json | 104 ++++++++++++++++++++++++++++++++++++- 3 files changed, 187 insertions(+), 20 deletions(-) diff --git a/gpio/deviceplugingpio.cpp b/gpio/deviceplugingpio.cpp index 5a195c1f..4e848b53 100644 --- a/gpio/deviceplugingpio.cpp +++ b/gpio/deviceplugingpio.cpp @@ -27,7 +27,6 @@ DevicePluginGpio::DevicePluginGpio() { - } Device::DeviceSetupStatus DevicePluginGpio::setupDevice(Device *device) @@ -87,26 +86,55 @@ Device::DeviceSetupStatus DevicePluginGpio::setupDevice(Device *device) if (device->deviceClassId() == gpioInputBbbDeviceClassId) gpioId = device->paramValue(gpioInputBbbDeviceGpioParamTypeId).toInt(); - GpioMonitor *monior = new GpioMonitor(gpioId, this); + GpioMonitor *monitor = new GpioMonitor(gpioId, this); - if (!monior->enable()) { + if (!monitor->enable()) { qCWarning(dcGpioController()) << "Could not enable gpio monitor for device" << device->name(); return Device::DeviceSetupStatusFailure; } - connect(monior, &GpioMonitor::valueChanged, this, &DevicePluginGpio::onGpioValueChanged); + connect(monitor, &GpioMonitor::valueChanged, this, &DevicePluginGpio::onGpioValueChanged); - m_monitorDevices.insert(monior, device); + m_monitorDevices.insert(monitor, device); - if (device->deviceClassId() == gpioOutputRpiDeviceClassId) - m_raspberryPiGpioMoniors.insert(monior->gpio()->gpioNumber(), monior); + if (device->deviceClassId() == gpioInputRpiDeviceClassId) + m_raspberryPiGpioMoniors.insert(monitor->gpio()->gpioNumber(), monitor); - if (device->deviceClassId() == gpioOutputBbbDeviceClassId) - m_beagleboneBlackGpioMoniors.insert(monior->gpio()->gpioNumber(), monior); + if (device->deviceClassId() == gpioInputBbbDeviceClassId) + m_beagleboneBlackGpioMoniors.insert(monitor->gpio()->gpioNumber(), monitor); return Device::DeviceSetupStatusSuccess; } + if (device->deviceClassId() == counterRpiDeviceClassId || device->deviceClassId() == counterBbbDeviceClassId) { + + int gpioId = -1; + if (device->deviceClassId() == counterRpiDeviceClassId) + gpioId = device->paramValue(counterRpiDeviceGpioParamTypeId).toInt(); + + if (device->deviceClassId() == counterBbbDeviceClassId) + gpioId = device->paramValue(counterBbbDeviceGpioParamTypeId).toInt(); + + GpioMonitor *monitor = new GpioMonitor(gpioId, this); + + if (!monitor->enable()) { + qCWarning(dcGpioController()) << "Could not enable gpio monitor for device" << device->name(); + return Device::DeviceSetupStatusFailure; + } + + connect(monitor, &GpioMonitor::valueChanged, this, &DevicePluginGpio::onGpioValueChanged); + + m_monitorDevices.insert(monitor, device); + + if (device->deviceClassId() == counterRpiDeviceClassId) + m_raspberryPiGpioMoniors.insert(monitor->gpio()->gpioNumber(), monitor); + + if (device->deviceClassId() == counterBbbDeviceClassId) + m_beagleboneBlackGpioMoniors.insert(monitor->gpio()->gpioNumber(), monitor); + + m_counterValues.insert(device->id(), 0); + return Device::DeviceSetupStatusSuccess; + } return Device::DeviceSetupStatusSuccess; } @@ -252,6 +280,14 @@ void DevicePluginGpio::deviceRemoved(Device *device) delete monitor; } + if (m_counterValues.contains(device->id())) { + m_counterValues.remove(device->id()); + } + + if (myDevices().filterByDeviceClassId(counterRpiDeviceClassId).isEmpty() && myDevices().filterByDeviceClassId(counterBbbDeviceClassId).isEmpty()) { + hardwareManager()->pluginTimerManager()->unregisterTimer(m_counterTimer); + m_counterTimer = nullptr; + } } Device::DeviceError DevicePluginGpio::executeAction(Device *device, const Action &action) @@ -275,9 +311,9 @@ Device::DeviceError DevicePluginGpio::executeAction(Device *device, const Action // GPIO Switch power action if (deviceClass.vendorId() == raspberryPiVendorId) { - if (action.actionTypeId() == gpioOutputRpiPowerValueActionTypeId) { + if (action.actionTypeId() == gpioOutputRpiPowerActionTypeId) { bool success = false; - if (action.param(gpioOutputRpiPowerValueActionPowerValueParamTypeId).value().toBool()) { + if (action.param(gpioOutputRpiPowerActionPowerParamTypeId).value().toBool()) { success = gpio->setValue(Gpio::ValueHigh); } else { success = gpio->setValue(Gpio::ValueLow); @@ -289,14 +325,14 @@ Device::DeviceError DevicePluginGpio::executeAction(Device *device, const Action } // Set the current state - device->setStateValue(gpioOutputRpiPowerValueStateTypeId, action.param(gpioOutputRpiPowerValueActionPowerValueParamTypeId).value()); + device->setStateValue(gpioOutputRpiPowerStateTypeId, action.param(gpioOutputRpiPowerActionPowerParamTypeId).value()); return Device::DeviceErrorNoError; } } else if (deviceClass.vendorId() == beagleboneBlackVendorId) { - if (action.actionTypeId() == gpioOutputBbbPowerValueActionTypeId) { + if (action.actionTypeId() == gpioOutputBbbPowerActionTypeId) { bool success = false; - if (action.param(gpioOutputBbbPowerValueActionPowerValueParamTypeId).value().toBool()) { + if (action.param(gpioOutputBbbPowerActionPowerParamTypeId).value().toBool()) { success = gpio->setValue(Gpio::ValueHigh); } else { success = gpio->setValue(Gpio::ValueLow); @@ -308,7 +344,7 @@ Device::DeviceError DevicePluginGpio::executeAction(Device *device, const Action } // Set the current state - device->setStateValue(gpioOutputBbbPowerValueStateTypeId, action.param(gpioOutputBbbPowerValueActionPowerValueParamTypeId).value()); + device->setStateValue(gpioOutputBbbPowerStateTypeId, action.param(gpioOutputBbbPowerActionPowerParamTypeId).value()); return Device::DeviceErrorNoError; } @@ -326,10 +362,10 @@ void DevicePluginGpio::postSetupDevice(Device *device) gpio->setValue(Gpio::ValueLow); if (device->deviceClassId() == gpioOutputRpiDeviceClassId) { - device->setStateValue(gpioOutputRpiPowerValueStateTypeId, false); + device->setStateValue(gpioOutputRpiPowerStateTypeId, false); } if (device->deviceClassId() == gpioOutputBbbDeviceClassId) { - device->setStateValue(gpioOutputBbbPowerValueStateTypeId, false); + device->setStateValue(gpioOutputBbbPowerStateTypeId, false); } } @@ -344,6 +380,28 @@ void DevicePluginGpio::postSetupDevice(Device *device) device->setStateValue(gpioInputBbbPressedStateTypeId, monitor->value()); } } + + if (device->deviceClassId() == counterRpiDeviceClassId || device->deviceClassId() == counterBbbDeviceClassId) { + if (!m_counterTimer) { + m_counterTimer = hardwareManager()->pluginTimerManager()->registerTimer(1); + connect(m_counterTimer, &PluginTimer::timeout, this, [this] (){ + + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == counterRpiDeviceClassId) { + int counterValue = m_counterValues.value(device->id()); + device->setStateValue(counterRpiCounterStateTypeId, counterValue); + m_counterValues[device->id()] = 0; + } + if (device->deviceClassId() == counterBbbDeviceClassId) { + int counterValue = m_counterValues.value(device->id()); + device->setStateValue(counterBbbCounterStateTypeId, counterValue); + } + } + }); + } + + + } } QList DevicePluginGpio::raspberryPiGpioDescriptors() @@ -463,8 +521,14 @@ void DevicePluginGpio::onGpioValueChanged(const bool &value) if (device->deviceClassId() == gpioInputRpiDeviceClassId) { device->setStateValue(gpioInputRpiPressedStateTypeId, value); + //start longpresss timer } else if (device->deviceClassId() == gpioInputBbbDeviceClassId) { device->setStateValue(gpioInputBbbPressedStateTypeId, value); + //start longpress timer + } else if (device->deviceClassId() == counterRpiDeviceClassId || device->deviceClassId() == counterBbbDeviceClassId) { + if (value) { + m_counterValues[device->id()] += 1; + } } } diff --git a/gpio/deviceplugingpio.h b/gpio/deviceplugingpio.h index 8f1570e5..ea56ce08 100644 --- a/gpio/deviceplugingpio.h +++ b/gpio/deviceplugingpio.h @@ -28,6 +28,7 @@ #include "gpiodescriptor.h" #include "hardware/gpiomonitor.h" #include "devices/deviceplugin.h" +#include "plugintimer.h" class DevicePluginGpio : public DevicePlugin { @@ -44,7 +45,7 @@ public: void deviceRemoved(Device *device) override; Device::DeviceError executeAction(Device *device, const Action &action) override; - void postSetupDevice(Device *device); + void postSetupDevice(Device *device) override; private: QHash m_gpioDevices; @@ -58,6 +59,8 @@ private: QList raspberryPiGpioDescriptors(); QList beagleboneBlackGpioDescriptors(); + PluginTimer *m_counterTimer = nullptr; + QHash m_counterValues; private slots: void onGpioValueChanged(const bool &value); diff --git a/gpio/deviceplugingpio.json b/gpio/deviceplugingpio.json index 75f82704..aaaacac3 100644 --- a/gpio/deviceplugingpio.json +++ b/gpio/deviceplugingpio.json @@ -13,6 +13,7 @@ "displayName": "GPIO Output", "name": "gpioOutputRpi", "createMethods": ["discovery"], + "interfaces": ["power"], "paramTypes": [ { "id": "9eda783f-6d9f-4d39-986d-d2cbfff5a7dd", @@ -39,7 +40,7 @@ "stateTypes": [ { "id": "06843766-358e-44b0-8d52-2b46ef98459a", - "name": "powerValue", + "name": "power", "displayName": "Power", "type": "bool", "defaultValue": false, @@ -54,6 +55,7 @@ "displayName": "GPIO Input", "name": "gpioInputRpi", "createMethods": ["discovery"], + "interfaces": ["longpressbutton"], "paramTypes": [ { "id": "b45ca4a8-c67a-411c-957c-0e78e1f12c0b", @@ -86,6 +88,54 @@ "defaultValue": false, "displayNameEvent": "Pressed changed" } + ], + "eventTypes": [ + { + "id": "0df945d3-38df-4560-b42a-12b05545904d", + "name": "longPressed", + "displayName": "Long pressed" + } + ] + }, + { + "id": "75b13371-a064-47a7-bb82-e9d93a5b5027", + "displayName": "Counter", + "name": "counterRpi", + "createMethods": ["discovery"], + "interfaces": [], + "paramTypes": [ + { + "id": "a6feb722-1dc9-4262-96b0-96489507508f", + "name": "gpio", + "displayName": "GPIO", + "type": "int", + "defaultValue": -1 + }, + { + "id": "b2c194bd-1aef-4851-a290-dd45269cc592", + "name": "pin", + "displayName": "Pin number", + "type": "int", + "defaultValue": -1 + }, + { + "id": "f7b82516-ed2c-4d73-86fa-957b8b6737e4", + "name": "description", + "displayName": "Description", + "type": "QString", + "defaultValue": "-" + } + ], + "stateTypes": [ + { + "id": "891bc1ce-2f9b-4518-aed9-90e78bc2409e", + "name": "counter", + "displayName": "Counter", + "type": "int", + "defaultValue": 0, + "unit": "Herz", + "displayNameEvent": "Counter changed" + } ] } ] @@ -100,6 +150,7 @@ "displayName": "GPIO Output", "name": "gpioOutputBbb", "createMethods": ["discovery"], + "interfaces": ["power"], "paramTypes": [ { "id": "62a9596d-fc7d-4554-9f45-9803635da619", @@ -126,7 +177,7 @@ "stateTypes": [ { "id": "82b567c6-a33c-484e-b5e7-e04795498d00", - "name": "powerValue", + "name": "power", "displayName": "Power", "type": "bool", "defaultValue": false, @@ -141,6 +192,7 @@ "displayName": "GPIO Input", "name": "gpioInputBbb", "createMethods": ["discovery"], + "interfaces": ["longpressbutton"], "paramTypes": [ { "id": "20773255-4576-4c8e-8c8b-051902919761", @@ -173,6 +225,54 @@ "defaultValue": false, "displayNameEvent": "Pressed changed" } + ], + "eventTypes": [ + { + "id": "6b439e89-2cac-482a-b012-452c7c665acb", + "name": "longPressed", + "displayName": "Long pressed" + } + ] + }, + { + "id": "3e311ef1-60c4-4b0e-a2fb-186bff9bd792", + "displayName": "Counter", + "name": "counterBbb", + "createMethods": ["discovery"], + "interfaces": [], + "paramTypes": [ + { + "id": "68bc0f3b-18c3-4a60-a2df-85bc0605caec", + "name": "gpio", + "displayName": "GPIO", + "type": "int", + "defaultValue": -1 + }, + { + "id": "f9da4a22-b010-4823-9b1c-d1f422c3ad2b", + "name": "pin", + "displayName": "Pin number", + "type": "int", + "defaultValue": -1 + }, + { + "id": "cba6a527-9f5c-4c05-8602-60e0c920fd26", + "name": "description", + "displayName": "Description", + "type": "QString", + "defaultValue": "-" + } + ], + "stateTypes": [ + { + "id": "fb5181d0-644b-4ab7-afa0-b7ddc8951526", + "name": "counter", + "displayName": "Counter", + "type": "int", + "defaultValue": 0, + "unit": "Herz", + "displayNameEvent": "Counter changed" + } ] } ] From 4072d0f1fc96e1e0dfd26c3cb1c9635924f0338b Mon Sep 17 00:00:00 2001 From: nymea Date: Wed, 11 Sep 2019 18:47:40 +0200 Subject: [PATCH 2/2] added long press event --- gpio/deviceplugingpio.cpp | 60 +++++++++++++++++++++++++++++++++++--- gpio/deviceplugingpio.h | 5 +++- gpio/deviceplugingpio.json | 10 +++++++ 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/gpio/deviceplugingpio.cpp b/gpio/deviceplugingpio.cpp index 4e848b53..16246e7a 100644 --- a/gpio/deviceplugingpio.cpp +++ b/gpio/deviceplugingpio.cpp @@ -192,7 +192,6 @@ Device::DeviceError DevicePluginGpio::discoverDevices(const DeviceClassId &devic break; } } - deviceDescriptors.append(descriptor); } @@ -280,6 +279,12 @@ void DevicePluginGpio::deviceRemoved(Device *device) delete monitor; } + if (m_longPressTimers.contains(device)) { + QTimer *timer = m_longPressTimers.take(device); + timer->stop(); + timer->deleteLater(); + } + if (m_counterValues.contains(device->id())) { m_counterValues.remove(device->id()); } @@ -370,6 +375,10 @@ void DevicePluginGpio::postSetupDevice(Device *device) } if (device->deviceClassId() == gpioInputRpiDeviceClassId || device->deviceClassId() == gpioInputBbbDeviceClassId) { + QTimer *timer = new QTimer(this); + timer->setSingleShot(true); + m_longPressTimers.insert(device, timer); + GpioMonitor *monitor = m_monitorDevices.key(device); if (!monitor) return; @@ -399,8 +408,6 @@ void DevicePluginGpio::postSetupDevice(Device *device) } }); } - - } } @@ -522,9 +529,37 @@ void DevicePluginGpio::onGpioValueChanged(const bool &value) if (device->deviceClassId() == gpioInputRpiDeviceClassId) { device->setStateValue(gpioInputRpiPressedStateTypeId, value); //start longpresss timer + QTimer *timer = m_longPressTimers.value(device); + if (!timer){ + qWarning(dcGpioController()) << "Long press timer not available"; + return; + } + if (value) { + int seconds = configValue( gpioControllerPluginLongPressTimeParamTypeId).toInt(); + timer->start(seconds * 1000); + } else { + if (timer->isActive()) { + timer->stop(); + //emit timer pressed + } + } } else if (device->deviceClassId() == gpioInputBbbDeviceClassId) { device->setStateValue(gpioInputBbbPressedStateTypeId, value); - //start longpress timer + //start longpresss timer + QTimer *timer = m_longPressTimers.value(device); + if (!timer){ + qWarning(dcGpioController()) << "Long press timer not available"; + return; + } + if (value) { + int seconds = configValue( gpioControllerPluginLongPressTimeParamTypeId).toInt(); + timer->start(seconds * 1000); + } else { + if (timer->isActive()) { + timer->stop(); + //emit timer pressed + } + } } else if (device->deviceClassId() == counterRpiDeviceClassId || device->deviceClassId() == counterBbbDeviceClassId) { if (value) { m_counterValues[device->id()] += 1; @@ -532,3 +567,20 @@ void DevicePluginGpio::onGpioValueChanged(const bool &value) } } + +void DevicePluginGpio::onLongPressedTimeout() +{ + QTimer *timer = static_cast(sender()); + qCDebug(dcGpioController()) << "Button long pressed"; + timer->stop(); + Device *device = m_longPressTimers.key(timer); + if (!device) + return; + + if (device->deviceClassId() == gpioInputRpiDeviceClassId){ + emitEvent(Event(gpioInputRpiLongPressedEventTypeId, device->id())); + } else if (device->deviceClassId() == gpioInputBbbDeviceClassId){ + emitEvent(Event(gpioInputBbbLongPressedEventTypeId, device->id())); + } +} + diff --git a/gpio/deviceplugingpio.h b/gpio/deviceplugingpio.h index ea56ce08..73911bdb 100644 --- a/gpio/deviceplugingpio.h +++ b/gpio/deviceplugingpio.h @@ -30,6 +30,8 @@ #include "devices/deviceplugin.h" #include "plugintimer.h" +#include + class DevicePluginGpio : public DevicePlugin { Q_OBJECT @@ -61,10 +63,11 @@ private: QList beagleboneBlackGpioDescriptors(); PluginTimer *m_counterTimer = nullptr; QHash m_counterValues; + QHash m_longPressTimers; private slots: void onGpioValueChanged(const bool &value); - + void onLongPressedTimeout(); }; #endif // DEVICEPLUGINGPIO_H diff --git a/gpio/deviceplugingpio.json b/gpio/deviceplugingpio.json index aaaacac3..8969b43a 100644 --- a/gpio/deviceplugingpio.json +++ b/gpio/deviceplugingpio.json @@ -2,6 +2,16 @@ "displayName": "Gpio Controller", "name": "GpioController", "id": "127ead55-996a-44ac-ba82-fc3c634e018a", + "paramTypes": [ + { + "id": "bfb31f88-b481-49e1-9a0a-41b156b64efe", + "name": "longPressTime", + "displayName": "Long press time", + "type": "int", + "unit": "Seconds", + "defaultValue": 2 + } + ], "vendors": [ { "displayName": "Raspberry Pi 2/3",