From b8cba9df0d516f066a3fec2ad39feab42305190d Mon Sep 17 00:00:00 2001 From: Jenkins Date: Sun, 9 Dec 2018 18:56:19 +0100 Subject: [PATCH 01/35] Jenkins release build --- debian/changelog | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index f3c04da1..b23bbf76 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,14 @@ -nymea-plugins (0.10.0) UNRELEASED; urgency=medium +nymea-plugins (0.10.0) xenial; urgency=medium + [ Michael Zanetti ] + * Elgato/Avea: Fix handling white channel in set color action + * New plugin: Generic MQTT client plugin (mqttclient) + * PhilipsHue: Improve naming of hue devices using nymea's system name + and syncing to bridge + * New plugin: Sonoff-Tasmota devices plugin (tasmota) + * Netatmo: fix after upstream API change, make use of new interfaces - -- Michael Zanetti Thu, 29 Nov 2018 12:48:11 +0100 + -- Jenkins Sun, 09 Dec 2018 18:56:19 +0100 nymea-plugins (0.9.39) xenial; urgency=medium From 96e30e3c8729760f2ff616f598ff2d7c6d8b908e Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Thu, 15 Feb 2018 12:28:46 +0100 Subject: [PATCH 02/35] added initial unipi plug-in --- nymea-plugins.pro | 2 + unipi/devicepluginunipi.cpp | 392 +++++++++++++++++++++++++++++++++++ unipi/devicepluginunipi.h | 66 ++++++ unipi/devicepluginunipi.json | 224 ++++++++++++++++++++ unipi/unipi.pro | 11 + 5 files changed, 695 insertions(+) create mode 100644 unipi/devicepluginunipi.cpp create mode 100644 unipi/devicepluginunipi.h create mode 100644 unipi/devicepluginunipi.json create mode 100644 unipi/unipi.pro diff --git a/nymea-plugins.pro b/nymea-plugins.pro index 2782d88a..76d51a18 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -38,12 +38,14 @@ PLUGIN_DIRS = \ tasmota \ tcpcommander \ udpcommander \ + unipi \ unitec \ usbwde \ wakeonlan \ wemo \ ws2812 \ + CONFIG+=all message(============================================) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp new file mode 100644 index 00000000..99764251 --- /dev/null +++ b/unipi/devicepluginunipi.cpp @@ -0,0 +1,392 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2017 Bernhard Trinnes * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "devicepluginunipi.h" +#include "plugininfo.h" +#include + + + +DevicePluginUniPi::DevicePluginUniPi() +{ +} + + +void DevicePluginUniPi::init() +{ + +} + + +void DevicePluginUniPi::createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName) +{ + ParamList params; + + switch(gpioType){ + case relay : { + QList relayOutputDescriptors; + DeviceDescriptor descriptor(relayOutputDeviceClassId, "Relay Output", deviceName); + params.append(Param(relayOutputRelayNumberParamTypeId, deviceName)); + params.append(Param(relayOutputParentIdParamTypeId, parentDeviceId)); + descriptor.setParams(params); + relayOutputDescriptors.append(descriptor); + emit autoDevicesAppeared(relayOutputDeviceClassId, relayOutputDescriptors); + break; + } + + case digitalOutput : { + QList digitalOutputDescriptors; + DeviceDescriptor descriptor(digitalOutputDeviceClassId, "Digital Output", deviceName); + params.append(Param(digitalOutputDigitalOutputNumberParamTypeId, deviceName)); + params.append(Param(digitalOutputParentIdParamTypeId, parentDeviceId)); + descriptor.setParams(params); + digitalOutputDescriptors.append(descriptor); + emit autoDevicesAppeared(digitalOutputDeviceClassId, digitalOutputDescriptors); + break; + } + + case digitalInput: { + QList digitalInputDescriptors; + DeviceDescriptor descriptor(digitalInputDeviceClassId, "Digital Input", deviceName); + params.append(Param(digitalInputDigitalInputNumberParamTypeId, deviceName)); + params.append(Param(digitalInputParentIdParamTypeId, parentDeviceId)); + descriptor.setParams(params); + digitalInputDescriptors.append(descriptor); + emit autoDevicesAppeared(digitalInputDeviceClassId, digitalInputDescriptors); + break; + } + + case analogOutput: { + QList analogOutputDescriptors; + DeviceDescriptor descriptor(analogOutputDeviceClassId, "Analog Output", deviceName); + params.append(Param(analogOutputAnalogOutputNumberParamTypeId, deviceName)); + params.append(Param(analogOutputParentIdParamTypeId, parentDeviceId)); + descriptor.setParams(params); + analogOutputDescriptors.append(descriptor); + emit autoDevicesAppeared(analogOutputDeviceClassId, analogOutputDescriptors); + break; + } + + case analogInput: { + QList analogInputDescriptors; + DeviceDescriptor descriptor(analogInputDeviceClassId, "Analog Input", deviceName); + params.append(Param(analogInputAnalogInputNumberParamTypeId, deviceName)); + params.append(Param(analogInputParentIdParamTypeId, parentDeviceId)); + descriptor.setParams(params); + analogInputDescriptors.append(descriptor); + emit autoDevicesAppeared(analogInputDeviceClassId, analogInputDescriptors); + break; + } + + default: + break; + + } +} + +DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) +{ + if (device->deviceClassId() == neuronDeviceClassId) { + + int port = device->paramValue(neuronPortParamTypeId).toInt(); + + m_webSocket = new QWebSocket(); + connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); + connect(m_webSocket, &QWebSocket::disconnected, this, &DevicePluginUniPi::onWebSocketDisconnected); + + QUrl url = QUrl("ws://localhost/ws"); + url.setPort(port); + qDebug(dcUniPi()) << "Conneting to:" << url.toString(); + m_webSocket->open(url); + m_parentId = device->id(); + + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == relayOutputDeviceClassId) { + + device->setName(QString("Relay Ouput %1").arg(device->paramValue(relayOutputRelayNumberParamTypeId).toString())); + device->setParentId(device->paramValue(relayOutputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == digitalOutputDeviceClassId) { + + device->setName(QString("Digital Output %1").arg(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(digitalOutputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == digitalInputDeviceClassId) { + + device->setName(QString("Digital Input %1").arg(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(digitalInputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == analogInputDeviceClassId) { + + device->setName(QString("Analog Input %1").arg(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(analogInputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == analogOutputDeviceClassId) { + + device->setName(QString("Analog Output %1").arg(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(analogOutputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + return DeviceManager::DeviceSetupStatusFailure; +} + +void DevicePluginUniPi::postSetupDevice(Device *device) +{ + Q_UNUSED(device); +} + +DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, const Action &action) +{ + + if (device->deviceClassId() == relayOutputDeviceClassId) { + + if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { + QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); + int stateValue = action.param(relayOutputRelayStatusStateParamTypeId).value().toInt(); + + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = "relay"; + json["circuit"] = relayNumber; + json["value"] = stateValue; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(QJsonDocument::Compact); + qDebug(dcUniPi()) << "Send command" << bytes; + m_webSocket->sendBinaryMessage(bytes); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + + + if (device->deviceClassId() == digitalOutputDeviceClassId) { + if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { + int digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toInt(); + int stateValue = action.param(digitalOutputDigitalOutputStatusStateParamTypeId).value().toInt(); + + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = "do"; + json["circuit"] = digitalOutputNumber; + json["value"] = stateValue; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(); + m_webSocket->sendTextMessage(bytes); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == analogOutputDeviceClassId) { + + if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) { + int analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toInt(); + double analogValue = device->paramValue(analogOutputAnalogOutputValueStateParamTypeId).toDouble(); + + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = "ao"; + json["circuit"] = analogOutputNumber; + json["value"] = analogValue; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(); + m_webSocket->sendTextMessage(bytes); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + return DeviceManager::DeviceErrorDeviceClassNotFound; +} + + +void DevicePluginUniPi::deviceRemoved(Device *device) +{ + Q_UNUSED(device); + + m_webSocket->close(); + m_webSocket->deleteLater(); +} + + +void DevicePluginUniPi::onWebSocketConnected() +{ + qDebug(dcUniPi()) << "WebSocket connected"; + + connect(m_webSocket, &QWebSocket::textMessageReceived, + this, &DevicePluginUniPi::onWebSocketTextMessageReceived); + + QJsonObject json; + json["cmd"] = "all"; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(); + m_webSocket->sendTextMessage(bytes); +} + +void DevicePluginUniPi::onWebSocketDisconnected() +{ + qDebug(dcUniPi()) << "WebSocket disconnected"; + + //send signal device Setup was successfull +} + + +void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) +{ + QJsonArray array; + QJsonObject obj; + QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8()); + + // check validity of the document + if(!doc.isNull()) { + if(doc.isObject()) { + obj = doc.object(); + } else if (doc.isArray()){ + array = doc.array(); + }else { + qDebug(dcUniPi()) << "Document is not an object nor an array"; + } + } else { + qDebug(dcUniPi()) << "Invalid JSON"; + } + + for (int levelIndex = 0; levelIndex < array.size(); ++levelIndex) { + obj = array[levelIndex].toObject(); + + if (obj["cmd"] == "all") { + //read model number + qDebug(dcUniPi()) << message; + + } + + if (obj["dev"] == "relay") { + qDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + + bool newDevice = true; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == relayOutputDeviceClassId) { + if (obj["circuit"] == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) { + device->setStateValue(relayOutputRelayStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + newDevice = false; + break; + } + } + } + if (newDevice) { + qDebug(dcUniPi()) << "New Device detected"; + createAutoDevice(GPIOType::relay, m_parentId, obj["circuit"].toString()); + } + } + + if (obj["dev"] == "input") { + qDebug(dcUniPi()) << "Input:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + + bool newDevice = true; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == digitalInputDeviceClassId) { + if (obj["circuit"] == device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()) { + device->setStateValue(digitalInputDigitalInputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + newDevice = false; + break; + } + } + } + if (newDevice){ + //New Device detected + createAutoDevice(GPIOType::digitalInput, m_parentId, obj["circuit"].toString()); + } + } + + if (obj["dev"] == "output") { + qDebug(dcUniPi()) << "Output:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + + bool newDevice = true; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == digitalOutputDeviceClassId) { + + if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) { + device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + newDevice = false; + break; + } + } + } + if (newDevice){ + //New Device detected + createAutoDevice(GPIOType::digitalOutput, m_parentId, obj["circuit"].toString()); + } + } + + if (obj["dev"] == "ao") { + qDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + + bool newDevice = true; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == analogOutputDeviceClassId) { + + if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) { + device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble()); + newDevice = false; + break; + } + } + } + if (newDevice){ + //New Device detected + createAutoDevice(GPIOType::analogOutput, m_parentId, obj["circuit"].toString()); + } + } + + if (obj["dev"] == "ai") { + qDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + + bool newDevice = true; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == analogInputDeviceClassId) { + + if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) { + device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble()); + newDevice = false; + break; + } + } + } + if (newDevice){ + //New Device detected + createAutoDevice(GPIOType::analogInput, m_parentId, obj["circuit"].toString()); + } + } + } +} + diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h new file mode 100644 index 00000000..da7798a8 --- /dev/null +++ b/unipi/devicepluginunipi.h @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2017 Bernhard Trinnes * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef DEVICEPLUGINUNIPI_H +#define DEVICEPLUGINUNIPI_H + +#include "plugin/deviceplugin.h" +#include "devicemanager.h" +#include + +class DevicePluginUniPi : public DevicePlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginunipi.json") + Q_INTERFACES(DevicePlugin) + +public: + + explicit DevicePluginUniPi(); + + DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; + void postSetupDevice(Device *device) override; + void deviceRemoved(Device *device) override; + void init() override; + DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; + +private: + + enum GPIOType { + relay, + digitalInput, + digitalOutput, + analogInput, + analogOutput + }; + + DeviceId m_parentId; + QWebSocket *m_webSocket; + + void createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName); + +private slots: + void onWebSocketConnected(); + void onWebSocketDisconnected(); + void onWebSocketTextMessageReceived(QString message); +}; + +#endif // DEVICEPLUGINUNIPI_H diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json new file mode 100644 index 00000000..1e3da1f2 --- /dev/null +++ b/unipi/devicepluginunipi.json @@ -0,0 +1,224 @@ +{ + "displayName": "uni pi", + "name": "UniPi", + "id": "26cba644-35ae-40a6-9c48-924198893a5f", + "vendors": [ + { + "displayName": "UniPi", + "name": "unipi", + "id": "c82bfe27-d14d-40bd-b12f-ddba214b5fc5", + "deviceClasses": [ + { + "id": "f1663756-657d-4dbd-9568-e2edf513589f", + "name": "neuron", + "displayName": "Neuron", + "deviceIcon": "Gateway", + "createMethods": ["user"], + "interface": [], + "basicTags": [ + "Device", + "Gateway" + ], + "paramTypes": [ + { + "id": "5329655d-7e91-4b16-9abf-2abc82bf1b3c", + "name": "port", + "displayName": "port", + "type": "int", + "defaultValue": "8080" + } + ], + "actionTypes": [ + ], + "stateTypes": [ + ] + }, + { + "id": "58f9db7f-fd33-45af-8c98-047b67ae5267", + "name": "relayOutput", + "displayName": "Relay Output", + "deviceIcon": "Power", + "createMethods": ["auto"], + "interface": [], + "basicTags": [ + "Device" + ], + "paramTypes": [ + { + "id": "7a09e3ad-452c-4bf4-a00c-f8114ed9a7a1", + "name": "relayNumber", + "displayName": "relay number", + "type": "QString" + }, + { + "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "name": "parentId", + "displayName": "parent ID", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "f9c01e7b-0523-4cac-905a-d5b20028e021", + "name": "relayStatus", + "displayName": "relay", + "type": "bool", + "displayNameAction": "set relay", + "displayNameEvent": "relay changed", + "defaultValue": false, + "writable": true + } + ] + }, + { + "id": "0bec278a-98f1-416b-b496-6d00740f178a", + "name": "digitalInput", + "displayName": "digital input", + "deviceIcon": "Switch", + "createMethods": ["auto"], + "interface": [], + "basicTags": [ + "Sensor" + ], + "paramTypes": [ + { + "id": "9c84d9b8-fdc7-41c1-9559-08f061ffc7a6", + "name": "digitalInputNumber", + "displayName": "input number", + "type": "int" + }, + { + "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "name": "parentId", + "displayName": "parent ID", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "fa4f2764-b7ff-45e7-993b-b6af1840fd3d", + "name": "digitalInputStatus", + "displayName": "input", + "type": "bool", + "defaultValue": false, + "displayNameEvent": "input changed" + } + ] + }, + { + "id": "f3a3c5ed-461a-4ca8-930b-df3af821b9e0", + "name": "digitalOutput", + "displayName": "digital output", + "deviceIcon": "Power", + "createMethods": ["auto"], + "interface": [], + "basicTags": [ + "Device" + ], + "paramTypes": [ + { + "id": "c01d5bde-de5d-42c5-b462-79745827875a", + "name": "digitalOutputNumber", + "displayName": "input number", + "type": "QString" + }, + { + "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "name": "parentId", + "displayName": "parent ID", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "470a0e30-a170-47ed-9ed3-c41db919555f", + "name": "digitalOutputStatus", + "displayName": "digital output", + "type": "bool", + "displayNameAction": "set digital output", + "displayNameEvent": "digital output changed", + "defaultValue": false, + "writable": true + } + ] + }, + { + "id": "9094a69f-f475-4050-a345-5ab52cb19774", + "name": "analogOutput", + "displayName": "Analog Output", + "deviceIcon": "Power", + "createMethods": ["auto"], + "interface": [], + "basicTags": [ + "Device" + ], + "paramTypes": [ + { + "id": "46e606cc-67ee-4891-bc39-8fb0565c87da", + "name": "analogOutputNumber", + "displayName": "analog output number", + "type": "QString" + }, + { + "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "name": "parentId", + "displayName": "parent ID", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "6d825eb8-6d2a-4ac3-9125-9df8173116c9", + "name": "analogOutputValue", + "displayName": "analog output", + "type": "double", + "unit": "Volt", + "displayNameAction": "set analog output", + "displayNameEvent": "analog output changed", + "minValue": 0.00, + "maxValue": 10.00, + "defaultValue": 0.00, + "writable": true + } + ] + }, + { + "id": "06abd6a4-e655-4243-bc9c-9bd4ef5be2e6", + "name": "analogInput", + "displayName": "Analog Input", + "deviceIcon": "Power", + "createMethods": ["auto"], + "interface": [], + "basicTags": [ + "Sensor" + ], + "paramTypes": [ + { + "id": "cc6eb664-9fd2-457d-9d0d-0eb9703db4a2", + "name": "analogInputNumber", + "displayName": "analog input number", + "type": "QString" + }, + { + "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "name": "parentId", + "displayName": "parent ID", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "2296f575-cc53-48ef-9086-6a412abfdde5", + "name": "analogInputValue", + "displayName": "analog output", + "type": "double", + "unit": "Volt", + "displayNameEvent": "analog input changed", + "defaultValue": 0.00 + } + ] + } + ] + } + ] +} diff --git a/unipi/unipi.pro b/unipi/unipi.pro new file mode 100644 index 00000000..94d4be58 --- /dev/null +++ b/unipi/unipi.pro @@ -0,0 +1,11 @@ +include(../plugins.pri) + +TARGET = $$qtLibraryTarget(guh_devicepluginunipi) + +SOURCES += \ + devicepluginunipi.cpp \ + +HEADERS += \ + devicepluginunipi.h \ + + From 9230025a6334eb180feb0e924a10724b55ed3468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Tue, 13 Mar 2018 17:58:34 +0100 Subject: [PATCH 03/35] Migrate to nymea --- unipi/devicepluginunipi.cpp | 323 ++++++++++++++++++----------------- unipi/devicepluginunipi.h | 28 +-- unipi/devicepluginunipi.json | 103 +++++------ unipi/unipi.pro | 2 +- 4 files changed, 224 insertions(+), 232 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 99764251..5a712dc9 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -1,20 +1,23 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2017 Bernhard Trinnes * + * Copyright (C) 2018 Simon Stürz * * * - * This file is part of guh. * + * This file is part of nymea. * * * - * Guh is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, version 2 of the License. * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * * * - * Guh is distributed in the hope that it will be useful, * + * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * * * - * You should have received a copy of the GNU General Public License * - * along with guh. If not, see . * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -22,18 +25,156 @@ #include "plugininfo.h" #include - - DevicePluginUniPi::DevicePluginUniPi() { + } +DevicePluginUniPi::~DevicePluginUniPi() +{ + +} void DevicePluginUniPi::init() { } +DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) +{ + if (device->deviceClassId() == neuronDeviceClassId) { + + int port = device->paramValue(neuronPortParamTypeId).toInt(); + + m_webSocket = new QWebSocket(); + connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); + connect(m_webSocket, &QWebSocket::disconnected, this, &DevicePluginUniPi::onWebSocketDisconnected); + + QUrl url = QUrl("ws://localhost/ws"); + url.setPort(port); + qCDebug(dcUniPi()) << "Conneting to:" << url.toString(); + m_webSocket->open(url); + m_parentId = device->id(); + + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == relayOutputDeviceClassId) { + + device->setName(QString("Relay Ouput %1").arg(device->paramValue(relayOutputRelayNumberParamTypeId).toString())); + device->setParentId(device->paramValue(relayOutputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == digitalOutputDeviceClassId) { + + device->setName(QString("Digital Output %1").arg(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(digitalOutputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == digitalInputDeviceClassId) { + + device->setName(QString("Digital Input %1").arg(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(digitalInputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == analogInputDeviceClassId) { + + device->setName(QString("Analog Input %1").arg(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(analogInputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == analogOutputDeviceClassId) { + + device->setName(QString("Analog Output %1").arg(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString())); + device->setParentId(device->paramValue(analogOutputParentIdParamTypeId).toString()); + return DeviceManager::DeviceSetupStatusSuccess; + } + + return DeviceManager::DeviceSetupStatusFailure; +} + +void DevicePluginUniPi::postSetupDevice(Device *device) +{ + Q_UNUSED(device); +} + +void DevicePluginUniPi::deviceRemoved(Device *device) +{ + Q_UNUSED(device); + + m_webSocket->close(); + m_webSocket->deleteLater(); +} + +DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, const Action &action) +{ + + if (device->deviceClassId() == relayOutputDeviceClassId) { + + if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { + QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); + int stateValue = action.param(relayOutputRelayStatusStateParamTypeId).value().toInt(); + + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = "relay"; + json["circuit"] = relayNumber; + json["value"] = stateValue; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(QJsonDocument::Compact); + qCDebug(dcUniPi()) << "Send command" << bytes; + m_webSocket->sendBinaryMessage(bytes); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + + + if (device->deviceClassId() == digitalOutputDeviceClassId) { + if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { + int digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toInt(); + int stateValue = action.param(digitalOutputDigitalOutputStatusStateParamTypeId).value().toInt(); + + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = "do"; + json["circuit"] = digitalOutputNumber; + json["value"] = stateValue; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(); + m_webSocket->sendTextMessage(bytes); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == analogOutputDeviceClassId) { + + if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) { + int analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toInt(); + double analogValue = device->paramValue(analogOutputAnalogOutputValueStateParamTypeId).toDouble(); + + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = "ao"; + json["circuit"] = analogOutputNumber; + json["value"] = analogValue; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(); + m_webSocket->sendTextMessage(bytes); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + return DeviceManager::DeviceErrorDeviceClassNotFound; +} void DevicePluginUniPi::createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName) { @@ -101,147 +242,9 @@ void DevicePluginUniPi::createAutoDevice(GPIOType gpioType, DeviceId parentDevic } } -DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) -{ - if (device->deviceClassId() == neuronDeviceClassId) { - - int port = device->paramValue(neuronPortParamTypeId).toInt(); - - m_webSocket = new QWebSocket(); - connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); - connect(m_webSocket, &QWebSocket::disconnected, this, &DevicePluginUniPi::onWebSocketDisconnected); - - QUrl url = QUrl("ws://localhost/ws"); - url.setPort(port); - qDebug(dcUniPi()) << "Conneting to:" << url.toString(); - m_webSocket->open(url); - m_parentId = device->id(); - - return DeviceManager::DeviceSetupStatusSuccess; - } - - if (device->deviceClassId() == relayOutputDeviceClassId) { - - device->setName(QString("Relay Ouput %1").arg(device->paramValue(relayOutputRelayNumberParamTypeId).toString())); - device->setParentId(device->paramValue(relayOutputParentIdParamTypeId).toString()); - return DeviceManager::DeviceSetupStatusSuccess; - } - - if (device->deviceClassId() == digitalOutputDeviceClassId) { - - device->setName(QString("Digital Output %1").arg(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(digitalOutputParentIdParamTypeId).toString()); - return DeviceManager::DeviceSetupStatusSuccess; - } - - if (device->deviceClassId() == digitalInputDeviceClassId) { - - device->setName(QString("Digital Input %1").arg(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(digitalInputParentIdParamTypeId).toString()); - return DeviceManager::DeviceSetupStatusSuccess; - } - - if (device->deviceClassId() == analogInputDeviceClassId) { - - device->setName(QString("Analog Input %1").arg(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(analogInputParentIdParamTypeId).toString()); - return DeviceManager::DeviceSetupStatusSuccess; - } - - if (device->deviceClassId() == analogOutputDeviceClassId) { - - device->setName(QString("Analog Output %1").arg(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(analogOutputParentIdParamTypeId).toString()); - return DeviceManager::DeviceSetupStatusSuccess; - } - - return DeviceManager::DeviceSetupStatusFailure; -} - -void DevicePluginUniPi::postSetupDevice(Device *device) -{ - Q_UNUSED(device); -} - -DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, const Action &action) -{ - - if (device->deviceClassId() == relayOutputDeviceClassId) { - - if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { - QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); - int stateValue = action.param(relayOutputRelayStatusStateParamTypeId).value().toInt(); - - QJsonObject json; - json["cmd"] = "set"; - json["dev"] = "relay"; - json["circuit"] = relayNumber; - json["value"] = stateValue; - - QJsonDocument doc(json); - QByteArray bytes = doc.toJson(QJsonDocument::Compact); - qDebug(dcUniPi()) << "Send command" << bytes; - m_webSocket->sendBinaryMessage(bytes); - return DeviceManager::DeviceErrorNoError; - } - return DeviceManager::DeviceErrorActionTypeNotFound; - } - - - if (device->deviceClassId() == digitalOutputDeviceClassId) { - if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { - int digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toInt(); - int stateValue = action.param(digitalOutputDigitalOutputStatusStateParamTypeId).value().toInt(); - - QJsonObject json; - json["cmd"] = "set"; - json["dev"] = "do"; - json["circuit"] = digitalOutputNumber; - json["value"] = stateValue; - - QJsonDocument doc(json); - QByteArray bytes = doc.toJson(); - m_webSocket->sendTextMessage(bytes); - return DeviceManager::DeviceErrorNoError; - } - return DeviceManager::DeviceErrorActionTypeNotFound; - } - - if (device->deviceClassId() == analogOutputDeviceClassId) { - - if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) { - int analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toInt(); - double analogValue = device->paramValue(analogOutputAnalogOutputValueStateParamTypeId).toDouble(); - - QJsonObject json; - json["cmd"] = "set"; - json["dev"] = "ao"; - json["circuit"] = analogOutputNumber; - json["value"] = analogValue; - - QJsonDocument doc(json); - QByteArray bytes = doc.toJson(); - m_webSocket->sendTextMessage(bytes); - return DeviceManager::DeviceErrorNoError; - } - return DeviceManager::DeviceErrorActionTypeNotFound; - } - return DeviceManager::DeviceErrorDeviceClassNotFound; -} - - -void DevicePluginUniPi::deviceRemoved(Device *device) -{ - Q_UNUSED(device); - - m_webSocket->close(); - m_webSocket->deleteLater(); -} - - void DevicePluginUniPi::onWebSocketConnected() { - qDebug(dcUniPi()) << "WebSocket connected"; + qCDebug(dcUniPi()) << "WebSocket connected"; connect(m_webSocket, &QWebSocket::textMessageReceived, this, &DevicePluginUniPi::onWebSocketTextMessageReceived); @@ -256,7 +259,7 @@ void DevicePluginUniPi::onWebSocketConnected() void DevicePluginUniPi::onWebSocketDisconnected() { - qDebug(dcUniPi()) << "WebSocket disconnected"; + qCDebug(dcUniPi()) << "WebSocket disconnected"; //send signal device Setup was successfull } @@ -275,10 +278,10 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else if (doc.isArray()){ array = doc.array(); }else { - qDebug(dcUniPi()) << "Document is not an object nor an array"; + qCDebug(dcUniPi()) << "Document is not an object nor an array"; } } else { - qDebug(dcUniPi()) << "Invalid JSON"; + qCDebug(dcUniPi()) << "Invalid JSON"; } for (int levelIndex = 0; levelIndex < array.size(); ++levelIndex) { @@ -286,12 +289,12 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (obj["cmd"] == "all") { //read model number - qDebug(dcUniPi()) << message; + qCDebug(dcUniPi()) << message; } if (obj["dev"] == "relay") { - qDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); bool newDevice = true; foreach (Device *device, myDevices()) { @@ -304,13 +307,13 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } if (newDevice) { - qDebug(dcUniPi()) << "New Device detected"; + qCDebug(dcUniPi()) << "New Device detected"; createAutoDevice(GPIOType::relay, m_parentId, obj["circuit"].toString()); } } if (obj["dev"] == "input") { - qDebug(dcUniPi()) << "Input:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + qCDebug(dcUniPi()) << "Input:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); bool newDevice = true; foreach (Device *device, myDevices()) { @@ -329,7 +332,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "output") { - qDebug(dcUniPi()) << "Output:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + qCDebug(dcUniPi()) << "Output:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); bool newDevice = true; foreach (Device *device, myDevices()) { @@ -349,7 +352,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "ao") { - qDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); bool newDevice = true; foreach (Device *device, myDevices()) { @@ -369,7 +372,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "ai") { - qDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + qCDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); bool newDevice = true; foreach (Device *device, myDevices()) { diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index da7798a8..0827c832 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -1,20 +1,23 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2017 Bernhard Trinnes * + * Copyright (C) 2018 Simon Stürz * * * - * This file is part of guh. * + * This file is part of nymea. * * * - * Guh is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, version 2 of the License. * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * * * - * Guh is distributed in the hope that it will be useful, * + * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * * * - * You should have received a copy of the GNU General Public License * - * along with guh. If not, see . * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -29,17 +32,18 @@ class DevicePluginUniPi : public DevicePlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginunipi.json") + Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginunipi.json") Q_INTERFACES(DevicePlugin) public: explicit DevicePluginUniPi(); + ~DevicePluginUniPi(); + void init() override; DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; void postSetupDevice(Device *device) override; void deviceRemoved(Device *device) override; - void init() override; DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; private: @@ -53,7 +57,7 @@ private: }; DeviceId m_parentId; - QWebSocket *m_webSocket; + QWebSocket *m_webSocket = nullptr; void createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName); diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 1e3da1f2..7a113ff7 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -1,5 +1,5 @@ { - "displayName": "uni pi", + "displayName": "Uni pi", "name": "UniPi", "id": "26cba644-35ae-40a6-9c48-924198893a5f", "vendors": [ @@ -14,46 +14,39 @@ "displayName": "Neuron", "deviceIcon": "Gateway", "createMethods": ["user"], - "interface": [], - "basicTags": [ - "Device", - "Gateway" - ], + "interface": [ ], + "basicTags": ["Device", "Gateway"], "paramTypes": [ { "id": "5329655d-7e91-4b16-9abf-2abc82bf1b3c", "name": "port", - "displayName": "port", + "displayName": "Port", "type": "int", "defaultValue": "8080" } ], - "actionTypes": [ - ], - "stateTypes": [ - ] + "actionTypes": [ ], + "stateTypes": [ ] }, { "id": "58f9db7f-fd33-45af-8c98-047b67ae5267", "name": "relayOutput", - "displayName": "Relay Output", + "displayName": "Relay output", "deviceIcon": "Power", "createMethods": ["auto"], - "interface": [], - "basicTags": [ - "Device" - ], + "interface": [ ], + "basicTags": ["Device"], "paramTypes": [ { "id": "7a09e3ad-452c-4bf4-a00c-f8114ed9a7a1", "name": "relayNumber", - "displayName": "relay number", + "displayName": "Relay number", "type": "QString" }, { - "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "id": "84d4474b-86b4-4da1-8776-61d587cb9d0f", "name": "parentId", - "displayName": "parent ID", + "displayName": "Parent ID", "type": "QString" } ], @@ -61,10 +54,10 @@ { "id": "f9c01e7b-0523-4cac-905a-d5b20028e021", "name": "relayStatus", - "displayName": "relay", + "displayName": "Relay", + "displayNameEvent": "Relay power changed", + "displayNameAction": "Set relay power", "type": "bool", - "displayNameAction": "set relay", - "displayNameEvent": "relay changed", "defaultValue": false, "writable": true } @@ -73,13 +66,11 @@ { "id": "0bec278a-98f1-416b-b496-6d00740f178a", "name": "digitalInput", - "displayName": "digital input", + "displayName": "Digital input", "deviceIcon": "Switch", "createMethods": ["auto"], - "interface": [], - "basicTags": [ - "Sensor" - ], + "interface": [ ], + "basicTags": ["Sensor"], "paramTypes": [ { "id": "9c84d9b8-fdc7-41c1-9559-08f061ffc7a6", @@ -98,34 +89,32 @@ { "id": "fa4f2764-b7ff-45e7-993b-b6af1840fd3d", "name": "digitalInputStatus", - "displayName": "input", + "displayName": "Digital input", + "displayNameEvent": "Digital input changed", "type": "bool", - "defaultValue": false, - "displayNameEvent": "input changed" + "defaultValue": false } ] }, { "id": "f3a3c5ed-461a-4ca8-930b-df3af821b9e0", "name": "digitalOutput", - "displayName": "digital output", + "displayName": "Digital output", "deviceIcon": "Power", "createMethods": ["auto"], - "interface": [], - "basicTags": [ - "Device" - ], + "interface": [ ], + "basicTags": ["Device"], "paramTypes": [ { "id": "c01d5bde-de5d-42c5-b462-79745827875a", "name": "digitalOutputNumber", - "displayName": "input number", + "displayName": "Input number", "type": "QString" }, { - "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "id": "c697d10d-28ba-4680-9db9-094d4af7c6da", "name": "parentId", - "displayName": "parent ID", + "displayName": "Parent ID", "type": "QString" } ], @@ -134,9 +123,9 @@ "id": "470a0e30-a170-47ed-9ed3-c41db919555f", "name": "digitalOutputStatus", "displayName": "digital output", - "type": "bool", "displayNameAction": "set digital output", "displayNameEvent": "digital output changed", + "type": "bool", "defaultValue": false, "writable": true } @@ -145,24 +134,22 @@ { "id": "9094a69f-f475-4050-a345-5ab52cb19774", "name": "analogOutput", - "displayName": "Analog Output", + "displayName": "Analog output", "deviceIcon": "Power", "createMethods": ["auto"], - "interface": [], - "basicTags": [ - "Device" - ], + "interface": [ ], + "basicTags": ["Device"], "paramTypes": [ { "id": "46e606cc-67ee-4891-bc39-8fb0565c87da", "name": "analogOutputNumber", - "displayName": "analog output number", + "displayName": "Analog output number", "type": "QString" }, { - "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "id": "120ed3a4-bd76-4e86-b550-3b1f1daabfa2", "name": "parentId", - "displayName": "parent ID", + "displayName": "Parent ID", "type": "QString" } ], @@ -170,11 +157,11 @@ { "id": "6d825eb8-6d2a-4ac3-9125-9df8173116c9", "name": "analogOutputValue", - "displayName": "analog output", + "displayName": "Analog output", + "displayNameEvent": "Analog output changed", + "displayNameAction": "Set analog output", "type": "double", "unit": "Volt", - "displayNameAction": "set analog output", - "displayNameEvent": "analog output changed", "minValue": 0.00, "maxValue": 10.00, "defaultValue": 0.00, @@ -188,21 +175,19 @@ "displayName": "Analog Input", "deviceIcon": "Power", "createMethods": ["auto"], - "interface": [], - "basicTags": [ - "Sensor" - ], + "interface": [ ], + "basicTags": ["Sensor"], "paramTypes": [ { "id": "cc6eb664-9fd2-457d-9d0d-0eb9703db4a2", "name": "analogInputNumber", - "displayName": "analog input number", + "displayName": "Analog input number", "type": "QString" }, { - "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", + "id": "a4688cb3-54fa-478c-a108-d48cbb3d10e1", "name": "parentId", - "displayName": "parent ID", + "displayName": "Parent ID", "type": "QString" } ], @@ -210,10 +195,10 @@ { "id": "2296f575-cc53-48ef-9086-6a412abfdde5", "name": "analogInputValue", - "displayName": "analog output", + "displayName": "Analog input", + "displayNameEvent": "Analog input changed", "type": "double", "unit": "Volt", - "displayNameEvent": "analog input changed", "defaultValue": 0.00 } ] diff --git a/unipi/unipi.pro b/unipi/unipi.pro index 94d4be58..cac4bf40 100644 --- a/unipi/unipi.pro +++ b/unipi/unipi.pro @@ -1,6 +1,6 @@ include(../plugins.pri) -TARGET = $$qtLibraryTarget(guh_devicepluginunipi) +TARGET = $$qtLibraryTarget(nymea_devicepluginunipi) SOURCES += \ devicepluginunipi.cpp \ From 7348d3eb4a32cceceb99e1ceb4734806596976dd Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 09:53:02 +0200 Subject: [PATCH 04/35] fixed typos --- unipi/devicepluginunipi.cpp | 389 ++++++++++++++++++++++------------- unipi/devicepluginunipi.h | 14 +- unipi/devicepluginunipi.json | 182 ++++++++++------ unipi/iodescriptor.cpp | 30 +++ unipi/iodescriptor.h | 40 ++++ unipi/unipi.pro | 2 + 6 files changed, 449 insertions(+), 208 deletions(-) create mode 100644 unipi/iodescriptor.cpp create mode 100644 unipi/iodescriptor.h diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 5a712dc9..9fb6f3dd 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -42,9 +42,9 @@ void DevicePluginUniPi::init() DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) { - if (device->deviceClassId() == neuronDeviceClassId) { + if (m_webSocket == NULL) { - int port = device->paramValue(neuronPortParamTypeId).toInt(); + int port = device->paramValue(uniPiPortParamTypeId).toInt(); m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); @@ -54,49 +54,149 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) url.setPort(port); qCDebug(dcUniPi()) << "Conneting to:" << url.toString(); m_webSocket->open(url); - m_parentId = device->id(); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == relayOutputDeviceClassId) { - device->setName(QString("Relay Ouput %1").arg(device->paramValue(relayOutputRelayNumberParamTypeId).toString())); - device->setParentId(device->paramValue(relayOutputParentIdParamTypeId).toString()); + m_usedGpios.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == digitalOutputDeviceClassId) { - device->setName(QString("Digital Output %1").arg(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(digitalOutputParentIdParamTypeId).toString()); + m_usedGpios.insert(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == digitalInputDeviceClassId) { - device->setName(QString("Digital Input %1").arg(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(digitalInputParentIdParamTypeId).toString()); + m_usedGpios.insert(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogInputDeviceClassId) { - device->setName(QString("Analog Input %1").arg(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(analogInputParentIdParamTypeId).toString()); + m_usedGpios.insert(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogOutputDeviceClassId) { - device->setName(QString("Analog Output %1").arg(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString())); - device->setParentId(device->paramValue(analogOutputParentIdParamTypeId).toString()); + m_usedGpios.insert(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString(), device); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == shadingDeviceClassId) { + + m_usedGpios.insert(device->paramValue(shadingOutputUpParamTypeId).toString(), device); + m_usedGpios.insert(device->paramValue(shadingOutputDownParamTypeId).toString(), device); + return DeviceManager::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == lightDeviceClassId) { + + m_usedGpios.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } return DeviceManager::DeviceSetupStatusFailure; } +DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) +{ + Q_UNUSED(params); + + const DeviceClass deviceClass = deviceManager()->findDeviceClass(deviceClassId); + if (deviceClass.vendorId() == unipiVendorId) { + + if (deviceClassId == relayOutputDeviceClassId) { + + // Create the list of available gpios + QList deviceDescriptors; + + for (int i = 0; i < m_relais.count(); i++) { + const QString circuit = m_relais.at(i); + + // Offer only gpios which arn't in use already + if (m_usedGpios.contains(circuit)){ + continue; + } + + DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(relayOutputRelayNumberParamTypeId, circuit)); + + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); + return DeviceManager::DeviceErrorAsync; + } + + if (deviceClassId == digitalOutputDeviceClassId) { + return DeviceManager::DeviceErrorAsync; + } + + if (deviceClassId == digitalInputDeviceClassId) { + return DeviceManager::DeviceErrorAsync; + } + + if (deviceClassId == analogInputDeviceClassId) { + return DeviceManager::DeviceErrorAsync; + } + + if (deviceClassId == analogOutputDeviceClassId) { + return DeviceManager::DeviceErrorAsync; + } + + if (deviceClassId == shadingDeviceClassId) { + // Create the list of available gpios + QList deviceDescriptors; + + for (int i = 0; i < m_relais.count(); i++) { + const QString circuit = m_relais.at(i); + + // Offer only gpios which aren't in use already + if (m_usedGpios.contains(circuit)){ + continue; + } + + DeviceDescriptor descriptor(deviceClassId, QString("Up Relay %1 + Down Relay %2").arg(circuit, m_relais.at(i+1)), circuit); + ParamList parameters; + parameters.append(Param(shadingOutputUpParamTypeId, circuit)); + parameters.append(Param(shadingOutputDownParamTypeId, m_relais.at(i+1))); + parameters.append(Param(shadingOutputTypeUpParamTypeId, GPIOType::relay)); + parameters.append(Param(shadingOutputTypeDownParamTypeId, GPIOType::relay)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); + return DeviceManager::DeviceErrorAsync; + } + + if (deviceClassId == lightDeviceClassId) { + return DeviceManager::DeviceErrorAsync; + } + } + return DeviceManager::DeviceErrorDeviceClassNotFound; +} + +void DevicePluginUniPi::setOutput(const QString &circuit, const QString &type, bool value) +{ + QJsonObject json; + json["cmd"] = "set"; + json["dev"] = type; + json["circuit"] = circuit; + json["value"] = value; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(QJsonDocument::Compact); + qCDebug(dcUniPi()) << "Send command" << bytes; + m_webSocket->sendBinaryMessage(bytes); +} + void DevicePluginUniPi::postSetupDevice(Device *device) { Q_UNUSED(device); @@ -104,10 +204,12 @@ void DevicePluginUniPi::postSetupDevice(Device *device) void DevicePluginUniPi::deviceRemoved(Device *device) { - Q_UNUSED(device); + m_usedGpios.remove(m_usedGpios.key(device)); //TODO remove multible IOs associated to a single device - m_webSocket->close(); - m_webSocket->deleteLater(); + if (myDevices().isEmpty()) { + m_webSocket->close(); + m_webSocket->deleteLater(); + } } DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, const Action &action) @@ -117,7 +219,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); - int stateValue = action.param(relayOutputRelayStatusStateParamTypeId).value().toInt(); + int stateValue = action.param(relayOutputRelayStatusActionParamTypeId).value().toInt(); QJsonObject json; json["cmd"] = "set"; @@ -138,7 +240,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == digitalOutputDeviceClassId) { if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { int digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toInt(); - int stateValue = action.param(digitalOutputDigitalOutputStatusStateParamTypeId).value().toInt(); + int stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toInt(); QJsonObject json; json["cmd"] = "set"; @@ -158,7 +260,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) { int analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toInt(); - double analogValue = device->paramValue(analogOutputAnalogOutputValueStateParamTypeId).toDouble(); + double analogValue = action.param(analogOutputAnalogOutputValueActionParamTypeId).value().toDouble(); QJsonObject json; json["cmd"] = "set"; @@ -173,74 +275,38 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons } return DeviceManager::DeviceErrorActionTypeNotFound; } + + if (device->deviceClassId() == shadingDeviceClassId) { + + if (action.actionTypeId() == shadingDownActionTypeId) { + QString circuit = device->paramValue(shadingOutputDownParamTypeId).toString(); + QString type = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); + setOutput(circuit, type, false); + return DeviceManager::DeviceErrorNoError; + } + if (action.actionTypeId() == shadingUpActionTypeId) { + QString circuit = device->paramValue(shadingOutputDownParamTypeId).toString(); + QString type = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); + setOutput(circuit, type, false); + return DeviceManager::DeviceErrorNoError; + } + + if (action.actionTypeId() == shadingStopActionTypeId) { + QString circuitUp = device->paramValue(shadingOutputDownParamTypeId).toString(); + QString typeUp = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); + setOutput(circuitUp, typeUp, false); + + QString circuitDown = device->paramValue(shadingOutputDownParamTypeId).toString(); + QString typeDown = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); + setOutput(circuitDown, typeDown, false); + + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } return DeviceManager::DeviceErrorDeviceClassNotFound; } -void DevicePluginUniPi::createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName) -{ - ParamList params; - - switch(gpioType){ - case relay : { - QList relayOutputDescriptors; - DeviceDescriptor descriptor(relayOutputDeviceClassId, "Relay Output", deviceName); - params.append(Param(relayOutputRelayNumberParamTypeId, deviceName)); - params.append(Param(relayOutputParentIdParamTypeId, parentDeviceId)); - descriptor.setParams(params); - relayOutputDescriptors.append(descriptor); - emit autoDevicesAppeared(relayOutputDeviceClassId, relayOutputDescriptors); - break; - } - - case digitalOutput : { - QList digitalOutputDescriptors; - DeviceDescriptor descriptor(digitalOutputDeviceClassId, "Digital Output", deviceName); - params.append(Param(digitalOutputDigitalOutputNumberParamTypeId, deviceName)); - params.append(Param(digitalOutputParentIdParamTypeId, parentDeviceId)); - descriptor.setParams(params); - digitalOutputDescriptors.append(descriptor); - emit autoDevicesAppeared(digitalOutputDeviceClassId, digitalOutputDescriptors); - break; - } - - case digitalInput: { - QList digitalInputDescriptors; - DeviceDescriptor descriptor(digitalInputDeviceClassId, "Digital Input", deviceName); - params.append(Param(digitalInputDigitalInputNumberParamTypeId, deviceName)); - params.append(Param(digitalInputParentIdParamTypeId, parentDeviceId)); - descriptor.setParams(params); - digitalInputDescriptors.append(descriptor); - emit autoDevicesAppeared(digitalInputDeviceClassId, digitalInputDescriptors); - break; - } - - case analogOutput: { - QList analogOutputDescriptors; - DeviceDescriptor descriptor(analogOutputDeviceClassId, "Analog Output", deviceName); - params.append(Param(analogOutputAnalogOutputNumberParamTypeId, deviceName)); - params.append(Param(analogOutputParentIdParamTypeId, parentDeviceId)); - descriptor.setParams(params); - analogOutputDescriptors.append(descriptor); - emit autoDevicesAppeared(analogOutputDeviceClassId, analogOutputDescriptors); - break; - } - - case analogInput: { - QList analogInputDescriptors; - DeviceDescriptor descriptor(analogInputDeviceClassId, "Analog Input", deviceName); - params.append(Param(analogInputAnalogInputNumberParamTypeId, deviceName)); - params.append(Param(analogInputParentIdParamTypeId, parentDeviceId)); - descriptor.setParams(params); - analogInputDescriptors.append(descriptor); - emit autoDevicesAppeared(analogInputDeviceClassId, analogInputDescriptors); - break; - } - - default: - break; - - } -} void DevicePluginUniPi::onWebSocketConnected() { @@ -290,106 +356,133 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (obj["cmd"] == "all") { //read model number qCDebug(dcUniPi()) << message; - } if (obj["dev"] == "relay") { qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - bool newDevice = true; - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == relayOutputDeviceClassId) { - if (obj["circuit"] == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) { - device->setStateValue(relayOutputRelayStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); - newDevice = false; - break; + QString circuit = obj["circuit"].toString(); + bool value = QVariant(obj["value"].toInt()).toBool(); + + if (!m_relais.contains(circuit)) { + //New Device detected + m_relais.append(circuit); + } else { + + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == relayOutputDeviceClassId) { + if (circuit == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) { + device->setStateValue(relayOutputRelayStatusStateTypeId, value); + break; + } + } else if (device->deviceClassId() == shadingDeviceClassId) { + if (circuit == device->paramValue(shadingOutputUpParamTypeId).toString()) { + if (value && device->stateValue(shadingStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shadingStatusStateTypeId, "up"); + } else if (!value && device->stateValue(shadingStatusStateTypeId).toString().contains("up")) { + device->setStateValue(shadingStatusStateTypeId, "stop"); + } else { + qWarning(dcUniPi()) << "Shading" << device << "Output Up:" << value << "Status: " << device->stateValue(shadingStatusStateTypeId).toString(); + } + + break; + } + if (circuit == device->paramValue(shadingOutputDownParamTypeId).toString()) { + if (value && device->stateValue(shadingStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shadingStatusStateTypeId, "down"); + } else if (!value && device->stateValue(shadingStatusStateTypeId).toString().contains("down")) { + device->setStateValue(shadingStatusStateTypeId, "stop"); + } else { + qWarning(dcUniPi()) << "Shading" << device << "Output Down:" << value << "Status: " << device->stateValue(shadingStatusStateTypeId).toString(); + } + break; + } + + } else if (device->deviceClassId() == lightDeviceClassId) { + if (circuit == device->paramValue(lightOutputParamTypeId).toString()) { + device->setStateValue(lightStatusStateTypeId, value); + break; + } } } } - if (newDevice) { - qCDebug(dcUniPi()) << "New Device detected"; - createAutoDevice(GPIOType::relay, m_parentId, obj["circuit"].toString()); - } } if (obj["dev"] == "input") { qCDebug(dcUniPi()) << "Input:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - bool newDevice = true; - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == digitalInputDeviceClassId) { - if (obj["circuit"] == device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()) { - device->setStateValue(digitalInputDigitalInputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); - newDevice = false; - break; + if (!m_digitalInputs.contains(obj["circuit"].toString())){ + //New Device detected + m_digitalInputs.append(obj["circuit"].toString()); + } else { + + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == digitalInputDeviceClassId) { + if (obj["circuit"] == device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()) { + device->setStateValue(digitalInputDigitalInputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + break; + } } } } - if (newDevice){ - //New Device detected - createAutoDevice(GPIOType::digitalInput, m_parentId, obj["circuit"].toString()); - } } if (obj["dev"] == "output") { qCDebug(dcUniPi()) << "Output:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - bool newDevice = true; - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == digitalOutputDeviceClassId) { + if (!m_digitalOutputs.contains(obj["circuit"].toString())){ + //New Device detected + m_digitalOutputs.append(obj["circuit"].toString()); + } else { - if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) { - device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); - newDevice = false; - break; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == digitalOutputDeviceClassId) { + + if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) { + device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + break; + } } } } - if (newDevice){ - //New Device detected - createAutoDevice(GPIOType::digitalOutput, m_parentId, obj["circuit"].toString()); - } - } - if (obj["dev"] == "ao") { - qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + if (obj["dev"] == "ao") { + qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); - bool newDevice = true; - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == analogOutputDeviceClassId) { + if (!m_analogOutputs.contains(obj["circuit"].toString())){ + //New Device detected + m_analogOutputs.append(obj["circuit"].toString()); - if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) { - device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble()); - newDevice = false; - break; + } else { + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == analogOutputDeviceClassId) { + if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) { + device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble()); + break; + } + } } } } - if (newDevice){ - //New Device detected - createAutoDevice(GPIOType::analogOutput, m_parentId, obj["circuit"].toString()); - } - } - if (obj["dev"] == "ai") { - qCDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + if (obj["dev"] == "ai") { + qCDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); - bool newDevice = true; - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == analogInputDeviceClassId) { + if (!m_analogInputs.contains(obj["circuit"].toString())){ + //New Device detected + m_analogInputs.append(obj["circuit"].toString()); + } else { + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == analogInputDeviceClassId) { - if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) { - device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble()); - newDevice = false; - break; + if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) { + device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble()); + break; + } + } } } } - if (newDevice){ - //New Device detected - createAutoDevice(GPIOType::analogInput, m_parentId, obj["circuit"].toString()); - } } - } + } // end for loop } - diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 0827c832..29a4c3fc 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -45,6 +45,8 @@ public: void postSetupDevice(Device *device) override; void deviceRemoved(Device *device) override; DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; + DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; + private: @@ -56,10 +58,18 @@ private: analogOutput }; - DeviceId m_parentId; + QHash m_usedGpios; + + QList m_relais; + QList m_digitalOutputs; + QList m_digitalInputs; + QList m_analogOutputs; + QList m_analogInputs; + QList m_temperatureSensors; + QWebSocket *m_webSocket = nullptr; - void createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName); + void setOutput(const QString &circuit, const QString &type, bool value); private slots: void onWebSocketConnected(); diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 7a113ff7..5253f7af 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -1,39 +1,28 @@ { - "displayName": "Uni pi", + "displayName": "UniPi", "name": "UniPi", "id": "26cba644-35ae-40a6-9c48-924198893a5f", + "paramTypes": [ + { + "id": "5329655d-7e91-4b16-9abf-2abc82bf1b3c", + "name": "port", + "displayName": "Port", + "type": "int", + "defaultValue": "8080" + } + ], "vendors": [ { "displayName": "UniPi", "name": "unipi", "id": "c82bfe27-d14d-40bd-b12f-ddba214b5fc5", "deviceClasses": [ - { - "id": "f1663756-657d-4dbd-9568-e2edf513589f", - "name": "neuron", - "displayName": "Neuron", - "deviceIcon": "Gateway", - "createMethods": ["user"], - "interface": [ ], - "basicTags": ["Device", "Gateway"], - "paramTypes": [ - { - "id": "5329655d-7e91-4b16-9abf-2abc82bf1b3c", - "name": "port", - "displayName": "Port", - "type": "int", - "defaultValue": "8080" - } - ], - "actionTypes": [ ], - "stateTypes": [ ] - }, { "id": "58f9db7f-fd33-45af-8c98-047b67ae5267", "name": "relayOutput", "displayName": "Relay output", "deviceIcon": "Power", - "createMethods": ["auto"], + "createMethods": ["discover"], "interface": [ ], "basicTags": ["Device"], "paramTypes": [ @@ -42,12 +31,6 @@ "name": "relayNumber", "displayName": "Relay number", "type": "QString" - }, - { - "id": "84d4474b-86b4-4da1-8776-61d587cb9d0f", - "name": "parentId", - "displayName": "Parent ID", - "type": "QString" } ], "stateTypes": [ @@ -68,20 +51,14 @@ "name": "digitalInput", "displayName": "Digital input", "deviceIcon": "Switch", - "createMethods": ["auto"], + "createMethods": ["discover"], "interface": [ ], "basicTags": ["Sensor"], "paramTypes": [ { "id": "9c84d9b8-fdc7-41c1-9559-08f061ffc7a6", "name": "digitalInputNumber", - "displayName": "input number", - "type": "int" - }, - { - "id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c", - "name": "parentId", - "displayName": "parent ID", + "displayName": "Input number", "type": "QString" } ], @@ -101,20 +78,14 @@ "name": "digitalOutput", "displayName": "Digital output", "deviceIcon": "Power", - "createMethods": ["auto"], + "createMethods": ["discover"], "interface": [ ], "basicTags": ["Device"], "paramTypes": [ { "id": "c01d5bde-de5d-42c5-b462-79745827875a", "name": "digitalOutputNumber", - "displayName": "Input number", - "type": "QString" - }, - { - "id": "c697d10d-28ba-4680-9db9-094d4af7c6da", - "name": "parentId", - "displayName": "Parent ID", + "displayName": "Output number", "type": "QString" } ], @@ -136,7 +107,7 @@ "name": "analogOutput", "displayName": "Analog output", "deviceIcon": "Power", - "createMethods": ["auto"], + "createMethods": ["discover"], "interface": [ ], "basicTags": ["Device"], "paramTypes": [ @@ -145,12 +116,6 @@ "name": "analogOutputNumber", "displayName": "Analog output number", "type": "QString" - }, - { - "id": "120ed3a4-bd76-4e86-b550-3b1f1daabfa2", - "name": "parentId", - "displayName": "Parent ID", - "type": "QString" } ], "stateTypes": [ @@ -174,7 +139,7 @@ "name": "analogInput", "displayName": "Analog Input", "deviceIcon": "Power", - "createMethods": ["auto"], + "createMethods": ["discover"], "interface": [ ], "basicTags": ["Sensor"], "paramTypes": [ @@ -183,12 +148,6 @@ "name": "analogInputNumber", "displayName": "Analog input number", "type": "QString" - }, - { - "id": "a4688cb3-54fa-478c-a108-d48cbb3d10e1", - "name": "parentId", - "displayName": "Parent ID", - "type": "QString" } ], "stateTypes": [ @@ -202,6 +161,113 @@ "defaultValue": 0.00 } ] + }, + { + "id": "eadddc99-ce7d-4169-a2f9-a829fa105ad2", + "name": "shading", + "displayName": "Shading", + "deviceIcon": "Blinds", + "createMethods": ["discover"], + "interface": [ ], + "basicTags": ["Actuator"], + "paramTypes": [ + { + "id": "7878ef4b-2395-4995-b17d-b69cb7d280e1", + "name": "outputUp", + "displayName": "Output Up", + "type": "QString" + }, + { + "id": "4aa113d0-294b-403d-9dd1-ad0abe833176", + "name": "outputDown", + "displayName": "Output Down", + "type": "QString" + }, + { + "id": "a030f030-4f26-4f33-aadf-ec3c3a5141a7", + "name": "outputTypeUp", + "displayName": "Output Type Up", + "type": "QString", + "readOnly": true + }, + { + "id": "fde509c5-8db1-411b-9e71-36997c39ee6b", + "name": "outputTypeDown", + "displayName": "Output Type Down", + "type": "QString", + "readOnly": true + } + ], + "stateTypes":[ + { + "id": "b8955f33-780a-48a5-9c50-c1bccf09918f", + "name": "status", + "displayName": "Status", + "type": "QString", + "possibleValues":[ + "up", + "stop", + "down" + ], + "defaultValue": "stop" + } + ], + "actionTypes":[ + { + "id": "cc8a13ae-2a3d-440a-a127-962fb912e511", + "name": "up", + "displayName": "Up", + "type": "bool" + }, + { + "id": "19bda8bb-1a78-4f2f-9927-ff543012462e", + "name": "stop", + "displayName": "Stop", + "type": "bool" + }, + { + "id": "7dc32e36-6a5c-46e1-8507-d9283067ac21", + "name": "down", + "displayName": "Down", + "type": "bool" + } + ] + }, + { + "id": "34fc941e-3465-4618-acf6-dda9c7242e27", + "name": "light", + "displayName": "Light", + "deviceIcon": "Light", + "createMethods": ["discover"], + "interface": [""], + "basicTags": ["Actuator"], + "paramTypes": [ + { + "id": "e1375def-edd6-4886-8e87-73cf3ebc819d", + "name": "output", + "displayName": "Output", + "type": "QString" + }, + { + "id": "5853de25-94c6-4f50-95cd-f1e3ef2ebc59", + "name": "outputType", + "displayName": "Output Type", + "type": "QString", + "readOnly": true + } + ], + "stateTypes":[ + { + "id": "3d0d6abc-87b9-42af-820e-e3bc7bde1743", + "name": "status", + "displayName": "Light", + "displayNameEvent": "Light power changed", + "displayNameAction": "Set light power", + "type": "bool", + "defaultValue": false, + "writable": true + } + ] } ] } diff --git a/unipi/iodescriptor.cpp b/unipi/iodescriptor.cpp new file mode 100644 index 00000000..40f1b2fc --- /dev/null +++ b/unipi/iodescriptor.cpp @@ -0,0 +1,30 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2017 Bernhard Trinnes * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "iodescriptor.h" + +ioDescriptor::ioDescriptor(QObject *parent) : QObject(parent) +{ + +} + diff --git a/unipi/iodescriptor.h b/unipi/iodescriptor.h new file mode 100644 index 00000000..fd8d2e8f --- /dev/null +++ b/unipi/iodescriptor.h @@ -0,0 +1,40 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2017 Bernhard Trinnes * + * Copyright (C) 2018 Simon Stürz * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef IODESCRIPTOR_H +#define IODESCRIPTOR_H + +#include + +class ioDescriptor : public QObject +{ + Q_OBJECT +public: + explicit ioDescriptor(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // IODESCRIPTOR_H diff --git a/unipi/unipi.pro b/unipi/unipi.pro index cac4bf40..47076101 100644 --- a/unipi/unipi.pro +++ b/unipi/unipi.pro @@ -4,8 +4,10 @@ TARGET = $$qtLibraryTarget(nymea_devicepluginunipi) SOURCES += \ devicepluginunipi.cpp \ + iodescriptor.cpp HEADERS += \ devicepluginunipi.h \ + iodescriptor.h From 5b8abf9a3fbc784d805b12c9624602f9eb2ddd81 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 10:52:18 +0200 Subject: [PATCH 05/35] fixed interfaces for shutter and light --- unipi/devicepluginunipi.cpp | 79 ++++++++++++++++++------------------ unipi/devicepluginunipi.json | 78 +++++++++++++++++------------------ 2 files changed, 77 insertions(+), 80 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 9fb6f3dd..9e0f9f5e 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -88,10 +88,10 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) return DeviceManager::DeviceSetupStatusSuccess; } - if (device->deviceClassId() == shadingDeviceClassId) { + if (device->deviceClassId() == shutterDeviceClassId) { - m_usedGpios.insert(device->paramValue(shadingOutputUpParamTypeId).toString(), device); - m_usedGpios.insert(device->paramValue(shadingOutputDownParamTypeId).toString(), device); + m_usedGpios.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); + m_usedGpios.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } @@ -151,7 +151,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI return DeviceManager::DeviceErrorAsync; } - if (deviceClassId == shadingDeviceClassId) { + if (deviceClassId == shutterDeviceClassId) { // Create the list of available gpios QList deviceDescriptors; @@ -165,10 +165,10 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI DeviceDescriptor descriptor(deviceClassId, QString("Up Relay %1 + Down Relay %2").arg(circuit, m_relais.at(i+1)), circuit); ParamList parameters; - parameters.append(Param(shadingOutputUpParamTypeId, circuit)); - parameters.append(Param(shadingOutputDownParamTypeId, m_relais.at(i+1))); - parameters.append(Param(shadingOutputTypeUpParamTypeId, GPIOType::relay)); - parameters.append(Param(shadingOutputTypeDownParamTypeId, GPIOType::relay)); + parameters.append(Param(shutterOutputOpenParamTypeId, circuit)); + parameters.append(Param(shutterOutputCloseParamTypeId, m_relais.at(i+1))); + parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::relay)); + parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::relay)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -276,29 +276,28 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons return DeviceManager::DeviceErrorActionTypeNotFound; } - if (device->deviceClassId() == shadingDeviceClassId) { + if (device->deviceClassId() == shutterDeviceClassId) { + QString circuitOpen = device->paramValue(shutterOutputOpenParamTypeId).toString(); + QString typeOpen = device->paramValue(shutterOutputTypeOpenParamTypeId).toString(); - if (action.actionTypeId() == shadingDownActionTypeId) { - QString circuit = device->paramValue(shadingOutputDownParamTypeId).toString(); - QString type = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); - setOutput(circuit, type, false); + QString circuitClose = device->paramValue(shutterOutputCloseParamTypeId).toString(); + QString typeClose = device->paramValue(shutterOutputTypeCloseParamTypeId).toString(); + + if (action.actionTypeId() == shutterCloseActionTypeId) { + + setOutput(circuitOpen, typeOpen, false); + setOutput(circuitClose, typeClose, true); return DeviceManager::DeviceErrorNoError; } - if (action.actionTypeId() == shadingUpActionTypeId) { - QString circuit = device->paramValue(shadingOutputDownParamTypeId).toString(); - QString type = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); - setOutput(circuit, type, false); + if (action.actionTypeId() == shutterOpenActionTypeId) { + + setOutput(circuitClose, typeClose, false); + setOutput(circuitOpen, typeOpen, true); return DeviceManager::DeviceErrorNoError; } - - if (action.actionTypeId() == shadingStopActionTypeId) { - QString circuitUp = device->paramValue(shadingOutputDownParamTypeId).toString(); - QString typeUp = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); - setOutput(circuitUp, typeUp, false); - - QString circuitDown = device->paramValue(shadingOutputDownParamTypeId).toString(); - QString typeDown = device->paramValue(shadingOutputTypeDownParamTypeId).toString(); - setOutput(circuitDown, typeDown, false); + if (action.actionTypeId() == shutterStopActionTypeId) { + setOutput(circuitOpen, typeOpen, false); + setOutput(circuitClose, typeClose, false); return DeviceManager::DeviceErrorNoError; } @@ -375,32 +374,32 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(relayOutputRelayStatusStateTypeId, value); break; } - } else if (device->deviceClassId() == shadingDeviceClassId) { - if (circuit == device->paramValue(shadingOutputUpParamTypeId).toString()) { - if (value && device->stateValue(shadingStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shadingStatusStateTypeId, "up"); - } else if (!value && device->stateValue(shadingStatusStateTypeId).toString().contains("up")) { - device->setStateValue(shadingStatusStateTypeId, "stop"); + } else if (device->deviceClassId() == shutterDeviceClassId) { + if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { + if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shutterStatusStateTypeId, "open"); + } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { + device->setStateValue(shutterStatusStateTypeId, "stop"); } else { - qWarning(dcUniPi()) << "Shading" << device << "Output Up:" << value << "Status: " << device->stateValue(shadingStatusStateTypeId).toString(); + qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); } break; } - if (circuit == device->paramValue(shadingOutputDownParamTypeId).toString()) { - if (value && device->stateValue(shadingStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shadingStatusStateTypeId, "down"); - } else if (!value && device->stateValue(shadingStatusStateTypeId).toString().contains("down")) { - device->setStateValue(shadingStatusStateTypeId, "stop"); + if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { + if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shutterStatusStateTypeId, "close"); + } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) { + device->setStateValue(shutterStatusStateTypeId, "stop"); } else { - qWarning(dcUniPi()) << "Shading" << device << "Output Down:" << value << "Status: " << device->stateValue(shadingStatusStateTypeId).toString(); + qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); } break; } } else if (device->deviceClassId() == lightDeviceClassId) { if (circuit == device->paramValue(lightOutputParamTypeId).toString()) { - device->setStateValue(lightStatusStateTypeId, value); + device->setStateValue(lightPowerStateTypeId, value); break; } } diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 5253f7af..5d0bd9f3 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -22,8 +22,8 @@ "name": "relayOutput", "displayName": "Relay output", "deviceIcon": "Power", - "createMethods": ["discover"], - "interface": [ ], + "createMethods": ["discovery"], + "interfaces": [ ], "basicTags": ["Device"], "paramTypes": [ { @@ -51,8 +51,8 @@ "name": "digitalInput", "displayName": "Digital input", "deviceIcon": "Switch", - "createMethods": ["discover"], - "interface": [ ], + "createMethods": ["discovery"], + "interfaces": [ ], "basicTags": ["Sensor"], "paramTypes": [ { @@ -78,8 +78,8 @@ "name": "digitalOutput", "displayName": "Digital output", "deviceIcon": "Power", - "createMethods": ["discover"], - "interface": [ ], + "createMethods": ["discovery"], + "interfaces": [ ], "basicTags": ["Device"], "paramTypes": [ { @@ -107,8 +107,8 @@ "name": "analogOutput", "displayName": "Analog output", "deviceIcon": "Power", - "createMethods": ["discover"], - "interface": [ ], + "createMethods": ["discovery"], + "interfaces": [ ], "basicTags": ["Device"], "paramTypes": [ { @@ -139,8 +139,8 @@ "name": "analogInput", "displayName": "Analog Input", "deviceIcon": "Power", - "createMethods": ["discover"], - "interface": [ ], + "createMethods": ["discovery"], + "interfaces": [ ], "basicTags": ["Sensor"], "paramTypes": [ { @@ -164,36 +164,36 @@ }, { "id": "eadddc99-ce7d-4169-a2f9-a829fa105ad2", - "name": "shading", - "displayName": "Shading", - "deviceIcon": "Blinds", - "createMethods": ["discover"], - "interface": [ ], + "name": "shutter", + "displayName": "Shutter", + "deviceIcon": "RollerShutter", + "createMethods": ["discovery"], + "interfaces": ["shutter"], "basicTags": ["Actuator"], "paramTypes": [ { "id": "7878ef4b-2395-4995-b17d-b69cb7d280e1", - "name": "outputUp", - "displayName": "Output Up", + "name": "outputOpen", + "displayName": "Output open", "type": "QString" }, { "id": "4aa113d0-294b-403d-9dd1-ad0abe833176", - "name": "outputDown", - "displayName": "Output Down", + "name": "outputClose", + "displayName": "Output close", "type": "QString" }, { "id": "a030f030-4f26-4f33-aadf-ec3c3a5141a7", - "name": "outputTypeUp", - "displayName": "Output Type Up", + "name": "outputTypeOpen", + "displayName": "Output type open", "type": "QString", "readOnly": true }, { "id": "fde509c5-8db1-411b-9e71-36997c39ee6b", - "name": "outputTypeDown", - "displayName": "Output Type Down", + "name": "outputTypeClose", + "displayName": "Output type close", "type": "QString", "readOnly": true } @@ -203,11 +203,12 @@ "id": "b8955f33-780a-48a5-9c50-c1bccf09918f", "name": "status", "displayName": "Status", + "displayNameEvent": "Status changed", "type": "QString", "possibleValues":[ - "up", + "open", "stop", - "down" + "close" ], "defaultValue": "stop" } @@ -215,21 +216,18 @@ "actionTypes":[ { "id": "cc8a13ae-2a3d-440a-a127-962fb912e511", - "name": "up", - "displayName": "Up", - "type": "bool" + "name": "open", + "displayName": "Open" }, { "id": "19bda8bb-1a78-4f2f-9927-ff543012462e", "name": "stop", - "displayName": "Stop", - "type": "bool" + "displayName": "Stop" }, { "id": "7dc32e36-6a5c-46e1-8507-d9283067ac21", - "name": "down", - "displayName": "Down", - "type": "bool" + "name": "close", + "displayName": "Close" } ] }, @@ -237,9 +235,9 @@ "id": "34fc941e-3465-4618-acf6-dda9c7242e27", "name": "light", "displayName": "Light", - "deviceIcon": "Light", - "createMethods": ["discover"], - "interface": [""], + "deviceIcon": "LightBulb", + "createMethods": ["discovery"], + "interfaces": ["light"], "basicTags": ["Actuator"], "paramTypes": [ { @@ -259,10 +257,10 @@ "stateTypes":[ { "id": "3d0d6abc-87b9-42af-820e-e3bc7bde1743", - "name": "status", - "displayName": "Light", - "displayNameEvent": "Light power changed", - "displayNameAction": "Set light power", + "name": "power", + "displayName": "Power", + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", "type": "bool", "defaultValue": false, "writable": true From 118530bb268cb86f030a9a7b2ec10836e785b18f Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 11:15:59 +0200 Subject: [PATCH 06/35] changed discovery --- unipi/devicepluginunipi.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 9e0f9f5e..e5b0018f 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -36,15 +36,10 @@ DevicePluginUniPi::~DevicePluginUniPi() } void DevicePluginUniPi::init() -{ - -} - -DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) { if (m_webSocket == NULL) { - int port = device->paramValue(uniPiPortParamTypeId).toInt(); + int port = configValue(uniPiPortParamTypeId).toInt(); m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); @@ -54,10 +49,11 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) url.setPort(port); qCDebug(dcUniPi()) << "Conneting to:" << url.toString(); m_webSocket->open(url); - - return DeviceManager::DeviceSetupStatusSuccess; } +} +DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) +{ if (device->deviceClassId() == relayOutputDeviceClassId) { m_usedGpios.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); From e9bb76221cc56c632214a66b4b3a01bfa1b48155 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 14:22:48 +0200 Subject: [PATCH 07/35] improved light discovery --- unipi/devicepluginunipi.cpp | 117 ++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 40 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index e5b0018f..9abeb6d6 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -39,7 +39,7 @@ void DevicePluginUniPi::init() { if (m_webSocket == NULL) { - int port = configValue(uniPiPortParamTypeId).toInt(); + int port = 8080; //configValue(uniPiPortParamTypeId).toInt(); m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); @@ -108,10 +108,8 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (deviceClass.vendorId() == unipiVendorId) { if (deviceClassId == relayOutputDeviceClassId) { - // Create the list of available gpios QList deviceDescriptors; - for (int i = 0; i < m_relais.count(); i++) { const QString circuit = m_relais.at(i); @@ -119,7 +117,6 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (m_usedGpios.contains(circuit)){ continue; } - DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); ParamList parameters; parameters.append(Param(relayOutputRelayNumberParamTypeId, circuit)); @@ -151,7 +148,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI // Create the list of available gpios QList deviceDescriptors; - for (int i = 0; i < m_relais.count(); i++) { + for (int i = 0; i < (m_relais.count()-1); i++) { const QString circuit = m_relais.at(i); // Offer only gpios which aren't in use already @@ -159,10 +156,18 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI continue; } - DeviceDescriptor descriptor(deviceClassId, QString("Up Relay %1 + Down Relay %2").arg(circuit, m_relais.at(i+1)), circuit); + DeviceDescriptor descriptor(deviceClassId, QString("Opening relay %1 | Closing relay %2").arg(circuit, m_relais.at(i+1)), circuit); ParamList parameters; parameters.append(Param(shutterOutputOpenParamTypeId, circuit)); - parameters.append(Param(shutterOutputCloseParamTypeId, m_relais.at(i+1))); + for (int a = i; a < (m_relais.count()); a++) { + + const QString circuit = m_relais.at(a); + // Offer only gpios which aren't in use already + if (m_usedGpios.contains(circuit)){ + continue; + } + parameters.append(Param(shutterOutputCloseParamTypeId, m_relais.at(a))); + } parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::relay)); parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::relay)); descriptor.setParams(parameters); @@ -173,6 +178,38 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } if (deviceClassId == lightDeviceClassId) { + // Create the list of available gpios + QList deviceDescriptors; + for (int i = 0; i < m_relais.count(); i++) { + const QString circuit = m_relais.at(i); + + // Offer only gpios which arn't in use already + if (m_usedGpios.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(lightOutputParamTypeId, circuit)); + parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::relay)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + + for (int i = 0; i < m_digitalOutputs.count(); i++) { + const QString circuit = m_digitalOutputs.at(i); + + // Offer only gpios which arn't in use already + if (m_usedGpios.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Digital output %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(lightOutputParamTypeId, circuit)); + parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::digitalOutput)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } } @@ -322,7 +359,6 @@ void DevicePluginUniPi::onWebSocketDisconnected() { qCDebug(dcUniPi()) << "WebSocket disconnected"; - //send signal device Setup was successfull } @@ -440,44 +476,45 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } } + } - if (obj["dev"] == "ao") { - qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + if (obj["dev"] == "ao") { + qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); - if (!m_analogOutputs.contains(obj["circuit"].toString())){ - //New Device detected - m_analogOutputs.append(obj["circuit"].toString()); + if (!m_analogOutputs.contains(obj["circuit"].toString())){ + //New Device detected + m_analogOutputs.append(obj["circuit"].toString()); - } else { - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == analogOutputDeviceClassId) { - if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) { - device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble()); - break; - } - } - } - } - } - - if (obj["dev"] == "ai") { - qCDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); - - if (!m_analogInputs.contains(obj["circuit"].toString())){ - //New Device detected - m_analogInputs.append(obj["circuit"].toString()); - } else { - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == analogInputDeviceClassId) { - - if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) { - device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble()); - break; - } + } else { + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == analogOutputDeviceClassId) { + if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) { + device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble()); + break; } } } } } - } // end for loop + + if (obj["dev"] == "ai") { + qCDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + + if (!m_analogInputs.contains(obj["circuit"].toString())){ + //New Device detected + m_analogInputs.append(obj["circuit"].toString()); + } else { + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == analogInputDeviceClassId) { + + if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) { + device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble()); + break; + } + } + } + } + } + } } + From 2b2175f01e42d2237feaeb9e00422041b3e73209 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 14:58:35 +0200 Subject: [PATCH 08/35] improved used io handling --- unipi/devicepluginunipi.cpp | 139 +++++++++++++++++++++++++++++++----- unipi/devicepluginunipi.h | 7 +- 2 files changed, 129 insertions(+), 17 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 9abeb6d6..05540c19 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -56,44 +56,58 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) { if (device->deviceClassId() == relayOutputDeviceClassId) { - m_usedGpios.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); + m_usedRelais.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == digitalOutputDeviceClassId) { - m_usedGpios.insert(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(), device); + m_usedDigitalOutputs.insert(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == digitalInputDeviceClassId) { - m_usedGpios.insert(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString(), device); + m_usedDigitalInputs.insert(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogInputDeviceClassId) { - m_usedGpios.insert(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString(), device); + m_usedAnalogInputs.insert(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogOutputDeviceClassId) { - m_usedGpios.insert(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString(), device); + m_usedAnalogOutputs.insert(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == shutterDeviceClassId) { - m_usedGpios.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); - m_usedGpios.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); + if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) { + m_usedRelais.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); + } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); + } + + if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GPIOType::relay) { + m_usedRelais.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); + } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); + } + return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == lightDeviceClassId) { - m_usedGpios.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); + if (device->paramValue(lightOutputTypeParamTypeId) == GPIOType::relay) { + m_usedRelais.insert(device->paramValue(lightOutputParamTypeId).toString(), device); + } else if (device->paramValue(lightOutputParamTypeId) == GPIOType::digitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(lightOutputParamTypeId).toString(), device); + } return DeviceManager::DeviceSetupStatusSuccess; } @@ -108,13 +122,13 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (deviceClass.vendorId() == unipiVendorId) { if (deviceClassId == relayOutputDeviceClassId) { - // Create the list of available gpios + // Create the list of available relais QList deviceDescriptors; for (int i = 0; i < m_relais.count(); i++) { const QString circuit = m_relais.at(i); // Offer only gpios which arn't in use already - if (m_usedGpios.contains(circuit)){ + if (m_usedRelais.contains(circuit)){ continue; } DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); @@ -129,18 +143,82 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } if (deviceClassId == digitalOutputDeviceClassId) { + // Create the list of available digital outputs + QList deviceDescriptors; + for (int i = 0; i < m_digitalOutputs.count(); i++) { + const QString circuit = m_digitalOutputs.at(i); + + // Offer only gpios which arn't in use already + if (m_usedDigitalOutputs.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Digital output %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(digitalOutputDigitalOutputNumberParamTypeId, circuit)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } if (deviceClassId == digitalInputDeviceClassId) { + // Create the list of available digital inputs + QList deviceDescriptors; + for (int i = 0; i < m_digitalInputs.count(); i++) { + const QString circuit = m_digitalInputs.at(i); + + // Offer only digital inputs which arn't in use already + if (m_usedDigitalInputs.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Digital input %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(digitalInputDigitalInputNumberParamTypeId, circuit)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } if (deviceClassId == analogInputDeviceClassId) { + // Create the list of available digital inputs + QList deviceDescriptors; + for (int i = 0; i < m_analogInputs.count(); i++) { + const QString circuit = m_analogInputs.at(i); + + // Offer only analog inputs which arn't in use already + if (m_usedAnalogInputs.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Analog input %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(analogInputAnalogInputNumberParamTypeId, circuit)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } if (deviceClassId == analogOutputDeviceClassId) { + // Create the list of available digital inputs + QList deviceDescriptors; + for (int i = 0; i < m_analogOutputs.count(); i++) { + const QString circuit = m_analogOutputs.at(i); + + // Offer only digital inputs which arn't in use already + if (m_usedAnalogOutputs.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Analog Output %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(analogOutputAnalogOutputNumberParamTypeId, circuit)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } @@ -152,18 +230,18 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI const QString circuit = m_relais.at(i); // Offer only gpios which aren't in use already - if (m_usedGpios.contains(circuit)){ + if (m_usedRelais.contains(circuit)){ continue; } - DeviceDescriptor descriptor(deviceClassId, QString("Opening relay %1 | Closing relay %2").arg(circuit, m_relais.at(i+1)), circuit); + DeviceDescriptor descriptor(deviceClassId, "Roller shutter", QString("Opening relay %1 | Closing relay %2").arg(circuit, m_relais.at(i+1))); ParamList parameters; parameters.append(Param(shutterOutputOpenParamTypeId, circuit)); for (int a = i; a < (m_relais.count()); a++) { const QString circuit = m_relais.at(a); // Offer only gpios which aren't in use already - if (m_usedGpios.contains(circuit)){ + if (m_usedRelais.contains(circuit)){ continue; } parameters.append(Param(shutterOutputCloseParamTypeId, m_relais.at(a))); @@ -184,7 +262,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI const QString circuit = m_relais.at(i); // Offer only gpios which arn't in use already - if (m_usedGpios.contains(circuit)){ + if (m_usedRelais.contains(circuit)){ continue; } DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); @@ -199,7 +277,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI const QString circuit = m_digitalOutputs.at(i); // Offer only gpios which arn't in use already - if (m_usedGpios.contains(circuit)){ + if (m_usedDigitalOutputs.contains(circuit)){ continue; } DeviceDescriptor descriptor(deviceClassId, QString("Digital output %1").arg(circuit), circuit); @@ -237,7 +315,36 @@ void DevicePluginUniPi::postSetupDevice(Device *device) void DevicePluginUniPi::deviceRemoved(Device *device) { - m_usedGpios.remove(m_usedGpios.key(device)); //TODO remove multible IOs associated to a single device + if(device->deviceClassId() == relayOutputDeviceClassId) { + m_usedRelais.remove(device->paramValue(relayOutputRelayNumberParamTypeId).toString()); + } else if(device->deviceClassId() == digitalOutputDeviceClassId) { + m_usedDigitalOutputs.remove(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()); + } else if(device->deviceClassId() == digitalInputDeviceClassId) { + m_usedDigitalOutputs.remove(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()); + } else if (device->deviceClassId() == analogOutputDeviceClassId) { + m_usedDigitalOutputs.remove(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()); + } else if (device->deviceClassId() == analogInputDeviceClassId) { + m_usedDigitalOutputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()); + + } else if (device->deviceClassId() == shutterDeviceClassId) { + if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) { + m_usedRelais.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); + } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); + } + if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GPIOType::relay) { + m_usedRelais.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); + } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); + } + + } else if (device->deviceClassId() == lightDeviceClassId) { + if (device->paramValue(lightOutputTypeParamTypeId) == GPIOType::relay) { + m_usedRelais.remove(device->paramValue(lightOutputParamTypeId).toString()); + } else if (device->paramValue(lightOutputParamTypeId) == GPIOType::digitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(lightOutputParamTypeId).toString()); + } + } if (myDevices().isEmpty()) { m_webSocket->close(); diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 29a4c3fc..9db90ad0 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -58,7 +58,12 @@ private: analogOutput }; - QHash m_usedGpios; + QHash m_usedRelais; + QHash m_usedDigitalOutputs; + QHash m_usedDigitalInputs; + QHash m_usedAnalogOutputs; + QHash m_usedAnalogInputs; + QHash m_usedTemperatureSensors; QList m_relais; QList m_digitalOutputs; From d9932a882aae5bb9f0e3b1323720d883010bad9e Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 15:35:43 +0200 Subject: [PATCH 09/35] improved device detection --- unipi/devicepluginunipi.cpp | 80 +++++++++++++++++++++---------------- unipi/devicepluginunipi.h | 4 +- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 05540c19..8b330df2 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -294,11 +294,17 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI return DeviceManager::DeviceErrorDeviceClassNotFound; } -void DevicePluginUniPi::setOutput(const QString &circuit, const QString &type, bool value) +void DevicePluginUniPi::setOutput(const QString &circuit, const GPIOType &type, bool value) { QJsonObject json; json["cmd"] = "set"; - json["dev"] = type; + + if (type == GPIOType::relay) { + json["dev"] = "relay"; + } else if (type == GPIOType::relay) { + json["dev"] = "do"; //TODO check if + } + json["circuit"] = circuit; json["value"] = value; @@ -360,17 +366,8 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); int stateValue = action.param(relayOutputRelayStatusActionParamTypeId).value().toInt(); + setOutput(relayNumber, GPIOType::relay, stateValue); - QJsonObject json; - json["cmd"] = "set"; - json["dev"] = "relay"; - json["circuit"] = relayNumber; - json["value"] = stateValue; - - QJsonDocument doc(json); - QByteArray bytes = doc.toJson(QJsonDocument::Compact); - qCDebug(dcUniPi()) << "Send command" << bytes; - m_webSocket->sendBinaryMessage(bytes); return DeviceManager::DeviceErrorNoError; } return DeviceManager::DeviceErrorActionTypeNotFound; @@ -379,18 +376,10 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == digitalOutputDeviceClassId) { if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { - int digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toInt(); - int stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toInt(); + QString digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(); + bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool(); + setOutput(digitalOutputNumber, GPIOType::digitalOutput, stateValue); - QJsonObject json; - json["cmd"] = "set"; - json["dev"] = "do"; - json["circuit"] = digitalOutputNumber; - json["value"] = stateValue; - - QJsonDocument doc(json); - QByteArray bytes = doc.toJson(); - m_webSocket->sendTextMessage(bytes); return DeviceManager::DeviceErrorNoError; } return DeviceManager::DeviceErrorActionTypeNotFound; @@ -399,7 +388,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == analogOutputDeviceClassId) { if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) { - int analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toInt(); + QString analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString(); double analogValue = action.param(analogOutputAnalogOutputValueActionParamTypeId).value().toDouble(); QJsonObject json; @@ -409,7 +398,8 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons json["value"] = analogValue; QJsonDocument doc(json); - QByteArray bytes = doc.toJson(); + QByteArray bytes = doc.toJson(QJsonDocument::Compact); + qCDebug(dcUniPi()) << "Send command" << bytes; m_webSocket->sendTextMessage(bytes); return DeviceManager::DeviceErrorNoError; } @@ -418,31 +408,42 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == shutterDeviceClassId) { QString circuitOpen = device->paramValue(shutterOutputOpenParamTypeId).toString(); - QString typeOpen = device->paramValue(shutterOutputTypeOpenParamTypeId).toString(); + int typeOpen = device->paramValue(shutterOutputTypeOpenParamTypeId).toInt(); QString circuitClose = device->paramValue(shutterOutputCloseParamTypeId).toString(); - QString typeClose = device->paramValue(shutterOutputTypeCloseParamTypeId).toString(); + int typeClose = device->paramValue(shutterOutputTypeCloseParamTypeId).toInt(); if (action.actionTypeId() == shutterCloseActionTypeId) { - setOutput(circuitOpen, typeOpen, false); - setOutput(circuitClose, typeClose, true); + setOutput(circuitOpen, GPIOType(typeOpen), false); + setOutput(circuitClose, GPIOType(typeClose), true); return DeviceManager::DeviceErrorNoError; } if (action.actionTypeId() == shutterOpenActionTypeId) { - setOutput(circuitClose, typeClose, false); - setOutput(circuitOpen, typeOpen, true); + setOutput(circuitClose, GPIOType(typeClose), false); + setOutput(circuitOpen, GPIOType(typeOpen), true); return DeviceManager::DeviceErrorNoError; } if (action.actionTypeId() == shutterStopActionTypeId) { - setOutput(circuitOpen, typeOpen, false); - setOutput(circuitClose, typeClose, false); + setOutput(circuitOpen, GPIOType(typeOpen), false); + setOutput(circuitClose, GPIOType(typeClose), false); return DeviceManager::DeviceErrorNoError; } return DeviceManager::DeviceErrorActionTypeNotFound; } + + if (device->deviceClassId() == shutterDeviceClassId) { + + QString circuit = device->paramValue(lightOutputParamTypeId).toString(); + int type = device->paramValue(lightOutputTypeParamTypeId).toInt(); + bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool(); + + setOutput(circuit, GPIOType(type), stateValue); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorDeviceClassNotFound; } @@ -497,7 +498,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "relay") { - qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toInt() ; QString circuit = obj["circuit"].toString(); bool value = QVariant(obj["value"].toInt()).toBool(); @@ -608,7 +609,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) qCDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); if (!m_analogInputs.contains(obj["circuit"].toString())){ - //New Device detected + //New analog output detected m_analogInputs.append(obj["circuit"].toString()); } else { foreach (Device *device, myDevices()) { @@ -622,6 +623,15 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } } + + if (obj["dev"] == "led") { + qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + + if (!m_leds.contains(obj["circuit"].toString())){ + //New led detected + m_leds.append(obj["circuit"].toString()); + } + } } } diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 9db90ad0..d1ac8370 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -64,6 +64,7 @@ private: QHash m_usedAnalogOutputs; QHash m_usedAnalogInputs; QHash m_usedTemperatureSensors; + QHash m_usedLeds; QList m_relais; QList m_digitalOutputs; @@ -71,10 +72,11 @@ private: QList m_analogOutputs; QList m_analogInputs; QList m_temperatureSensors; + QList m_leds; QWebSocket *m_webSocket = nullptr; - void setOutput(const QString &circuit, const QString &type, bool value); + void setOutput(const QString &circuit, const GPIOType &type, bool value); private slots: void onWebSocketConnected(); From b0c141e65da397275b41c9d72801b6f8ccb9b759 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 15:45:21 +0200 Subject: [PATCH 10/35] improved device detection --- unipi/devicepluginunipi.cpp | 84 ++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 8b330df2..4d0718b9 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -498,49 +498,67 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "relay") { - qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toInt() ; + qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toString() ; QString circuit = obj["circuit"].toString(); bool value = QVariant(obj["value"].toInt()).toBool(); - if (!m_relais.contains(circuit)) { - //New Device detected - m_relais.append(circuit); - } else { + if (obj["relay_type"].toString() == "physical") { - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == relayOutputDeviceClassId) { - if (circuit == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) { - device->setStateValue(relayOutputRelayStatusStateTypeId, value); - break; - } - } else if (device->deviceClassId() == shutterDeviceClassId) { - if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { - if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "open"); - } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { - device->setStateValue(shutterStatusStateTypeId, "stop"); - } else { - qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + if (!m_relais.contains(circuit)) { + //New Device detected + m_relais.append(circuit); + } else { + + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == relayOutputDeviceClassId) { + if (circuit == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) { + device->setStateValue(relayOutputRelayStatusStateTypeId, value); + break; + } + } else if (device->deviceClassId() == shutterDeviceClassId) { + if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { + if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shutterStatusStateTypeId, "open"); + } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { + device->setStateValue(shutterStatusStateTypeId, "stop"); + } else { + qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + } + + break; + } + if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { + if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shutterStatusStateTypeId, "close"); + } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) { + device->setStateValue(shutterStatusStateTypeId, "stop"); + } else { + qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + } + break; } - break; - } - if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { - if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "close"); - } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) { - device->setStateValue(shutterStatusStateTypeId, "stop"); - } else { - qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + } else if (device->deviceClassId() == lightDeviceClassId) { + if (circuit == device->paramValue(lightOutputParamTypeId).toString()) { + device->setStateValue(lightPowerStateTypeId, value); + break; } - break; } + } + } + } else if (obj["relay_type"].toString() == "digtial") { + if (!m_digitalOutputs.contains(obj["circuit"].toString())){ + //New Device detected + m_digitalOutputs.append(obj["circuit"].toString()); + } else { - } else if (device->deviceClassId() == lightDeviceClassId) { - if (circuit == device->paramValue(lightOutputParamTypeId).toString()) { - device->setStateValue(lightPowerStateTypeId, value); - break; + foreach (Device *device, myDevices()) { + if (device->deviceClassId() == digitalOutputDeviceClassId) { + if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) { + device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + break; + } } } } From 0ab27eef57249f146d0aae8dd14bf7af5d74c7ed Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 17:41:33 +0200 Subject: [PATCH 11/35] improved device detection for digital outputs --- unipi/devicepluginunipi.cpp | 169 ++++++++++++++++++++---------------- unipi/devicepluginunipi.h | 12 ++- unipi/iodescriptor.cpp | 30 ------- unipi/iodescriptor.h | 40 --------- unipi/unipi.pro | 6 +- 5 files changed, 104 insertions(+), 153 deletions(-) delete mode 100644 unipi/iodescriptor.cpp delete mode 100644 unipi/iodescriptor.h diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 4d0718b9..e0b34515 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -32,24 +32,17 @@ DevicePluginUniPi::DevicePluginUniPi() DevicePluginUniPi::~DevicePluginUniPi() { - + hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); } void DevicePluginUniPi::init() { - if (m_webSocket == NULL) { + connectToEvok(); - int port = 8080; //configValue(uniPiPortParamTypeId).toInt(); + // Refresh timer for snapd checks + m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); + connect(m_refreshTimer, &PluginTimer::timeout, this, &DevicePluginUniPi::onRefreshTimer); - m_webSocket = new QWebSocket(); - connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); - connect(m_webSocket, &QWebSocket::disconnected, this, &DevicePluginUniPi::onWebSocketDisconnected); - - QUrl url = QUrl("ws://localhost/ws"); - url.setPort(port); - qCDebug(dcUniPi()) << "Conneting to:" << url.toString(); - m_webSocket->open(url); - } } DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) @@ -227,30 +220,59 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI QList deviceDescriptors; for (int i = 0; i < (m_relais.count()-1); i++) { - const QString circuit = m_relais.at(i); - // Offer only gpios which aren't in use already - if (m_usedRelais.contains(circuit)){ + const QString openingCircuit = m_relais.at(i); + + // Offer only relais which aren't in use already + if (m_usedRelais.contains(openingCircuit)){ continue; } - - DeviceDescriptor descriptor(deviceClassId, "Roller shutter", QString("Opening relay %1 | Closing relay %2").arg(circuit, m_relais.at(i+1))); - ParamList parameters; - parameters.append(Param(shutterOutputOpenParamTypeId, circuit)); for (int a = i; a < (m_relais.count()); a++) { - const QString circuit = m_relais.at(a); - // Offer only gpios which aren't in use already - if (m_usedRelais.contains(circuit)){ - continue; + const QString closingCircuit = m_relais.at(a); + // Offer only relais which aren't in use already + if (!m_usedRelais.contains(closingCircuit)){ + + DeviceDescriptor descriptor(deviceClassId, "Roller shutter", QString("Opening relay %1 | Closing relay %2").arg(openingCircuit, closingCircuit)); + ParamList parameters; + parameters.append(Param(shutterOutputOpenParamTypeId, openingCircuit)); + parameters.append(Param(shutterOutputCloseParamTypeId, closingCircuit)); + parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::relay)); + parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::relay)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + break; } - parameters.append(Param(shutterOutputCloseParamTypeId, m_relais.at(a))); } - parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::relay)); - parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::relay)); - descriptor.setParams(parameters); - deviceDescriptors.append(descriptor); } + + for (int i = 0; i < (m_digitalOutputs.count()-1); i++) { + + const QString openingCircuit = m_digitalOutputs.at(i); + + // Offer only relais which aren't in use already + if (m_usedDigitalOutputs.contains(openingCircuit)){ + continue; + } + for (int a = i; a < (m_digitalOutputs.count()); a++) { + + const QString closingCircuit = m_digitalOutputs.at(a); + // Offer only relais which aren't in use already + if (!m_usedDigitalOutputs.contains(closingCircuit)){ + + DeviceDescriptor descriptor(deviceClassId, "Roller shutter", QString("Opening output %1 | Closing output %2").arg(openingCircuit, closingCircuit)); + ParamList parameters; + parameters.append(Param(shutterOutputOpenParamTypeId, openingCircuit)); + parameters.append(Param(shutterOutputCloseParamTypeId, closingCircuit)); + parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::digitalOutput)); + parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::digitalOutput)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + break; + } + } + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } @@ -294,17 +316,11 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI return DeviceManager::DeviceErrorDeviceClassNotFound; } -void DevicePluginUniPi::setOutput(const QString &circuit, const GPIOType &type, bool value) +void DevicePluginUniPi::setOutput(const QString &circuit, bool value) { QJsonObject json; json["cmd"] = "set"; - - if (type == GPIOType::relay) { - json["dev"] = "relay"; - } else if (type == GPIOType::relay) { - json["dev"] = "do"; //TODO check if - } - + json["dev"] = "relay"; json["circuit"] = circuit; json["value"] = value; @@ -314,11 +330,24 @@ void DevicePluginUniPi::setOutput(const QString &circuit, const GPIOType &type, m_webSocket->sendBinaryMessage(bytes); } -void DevicePluginUniPi::postSetupDevice(Device *device) +void DevicePluginUniPi::connectToEvok() { - Q_UNUSED(device); + if (m_webSocket == NULL) { + + int port = 8080; //configValue(uniPiPortParamTypeId).toInt(); TODO + + m_webSocket = new QWebSocket(); + connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); + connect(m_webSocket, &QWebSocket::disconnected, this, &DevicePluginUniPi::onWebSocketDisconnected); + + QUrl url = QUrl("ws://localhost/ws"); + url.setPort(port); + qCDebug(dcUniPi()) << "Conneting to:" << url.toString(); + m_webSocket->open(url); + } } + void DevicePluginUniPi::deviceRemoved(Device *device) { if(device->deviceClassId() == relayOutputDeviceClassId) { @@ -338,6 +367,7 @@ void DevicePluginUniPi::deviceRemoved(Device *device) } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { m_usedDigitalOutputs.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); } + if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GPIOType::relay) { m_usedRelais.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { @@ -366,7 +396,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); int stateValue = action.param(relayOutputRelayStatusActionParamTypeId).value().toInt(); - setOutput(relayNumber, GPIOType::relay, stateValue); + setOutput(relayNumber, stateValue); return DeviceManager::DeviceErrorNoError; } @@ -378,7 +408,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { QString digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(); bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool(); - setOutput(digitalOutputNumber, GPIOType::digitalOutput, stateValue); + setOutput(digitalOutputNumber, stateValue); return DeviceManager::DeviceErrorNoError; } @@ -408,39 +438,35 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == shutterDeviceClassId) { QString circuitOpen = device->paramValue(shutterOutputOpenParamTypeId).toString(); - int typeOpen = device->paramValue(shutterOutputTypeOpenParamTypeId).toInt(); - QString circuitClose = device->paramValue(shutterOutputCloseParamTypeId).toString(); - int typeClose = device->paramValue(shutterOutputTypeCloseParamTypeId).toInt(); if (action.actionTypeId() == shutterCloseActionTypeId) { - setOutput(circuitOpen, GPIOType(typeOpen), false); - setOutput(circuitClose, GPIOType(typeClose), true); + setOutput(circuitOpen, false); + setOutput(circuitClose, true); return DeviceManager::DeviceErrorNoError; } if (action.actionTypeId() == shutterOpenActionTypeId) { - setOutput(circuitClose, GPIOType(typeClose), false); - setOutput(circuitOpen, GPIOType(typeOpen), true); + setOutput(circuitClose, false); + setOutput(circuitOpen, true); return DeviceManager::DeviceErrorNoError; } if (action.actionTypeId() == shutterStopActionTypeId) { - setOutput(circuitOpen, GPIOType(typeOpen), false); - setOutput(circuitClose, GPIOType(typeClose), false); + setOutput(circuitOpen, false); + setOutput(circuitClose, false); return DeviceManager::DeviceErrorNoError; } return DeviceManager::DeviceErrorActionTypeNotFound; } - if (device->deviceClassId() == shutterDeviceClassId) { + if (device->deviceClassId() == lightDeviceClassId) { QString circuit = device->paramValue(lightOutputParamTypeId).toString(); - int type = device->paramValue(lightOutputTypeParamTypeId).toInt(); bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool(); - setOutput(circuit, GPIOType(type), stateValue); + setOutput(circuit, stateValue); return DeviceManager::DeviceErrorNoError; } @@ -498,7 +524,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "relay") { - qCDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toString() ; + qCDebug(dcUniPi()) << "Relay:" << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toString() ; QString circuit = obj["circuit"].toString(); bool value = QVariant(obj["value"].toInt()).toBool(); @@ -519,7 +545,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else if (device->deviceClassId() == shutterDeviceClassId) { if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "open"); + device->setStateValue(shutterStatusStateTypeId, "close"); } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { device->setStateValue(shutterStatusStateTypeId, "stop"); } else { @@ -547,7 +573,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } } - } else if (obj["relay_type"].toString() == "digtial") { + } else if (obj["relay_type"].toString() == "digital") { if (!m_digitalOutputs.contains(obj["circuit"].toString())){ //New Device detected m_digitalOutputs.append(obj["circuit"].toString()); @@ -584,26 +610,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } - if (obj["dev"] == "output") { - qCDebug(dcUniPi()) << "Output:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - - if (!m_digitalOutputs.contains(obj["circuit"].toString())){ - //New Device detected - m_digitalOutputs.append(obj["circuit"].toString()); - } else { - - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == digitalOutputDeviceClassId) { - - if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) { - device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); - break; - } - } - } - } - } - if (obj["dev"] == "ao") { qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); @@ -650,6 +656,19 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) m_leds.append(obj["circuit"].toString()); } } + + if (obj["dev"] == "sensor") { + qCDebug(dcUniPi()) << "Sensor:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + + if (!m_sensors.contains(obj["circuit"].toString())){ + //New Sensor detected + m_sensors.append(obj["circuit"].toString()); + } + } } } +void DevicePluginUniPi::onRefreshTimer() +{ + connectToEvok(); +} diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index d1ac8370..e5f66564 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -27,6 +27,7 @@ #include "plugin/deviceplugin.h" #include "devicemanager.h" #include +#include "plugintimer.h" class DevicePluginUniPi : public DevicePlugin { @@ -42,7 +43,6 @@ public: void init() override; DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; - void postSetupDevice(Device *device) override; void deviceRemoved(Device *device) override; DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; @@ -63,7 +63,7 @@ private: QHash m_usedDigitalInputs; QHash m_usedAnalogOutputs; QHash m_usedAnalogInputs; - QHash m_usedTemperatureSensors; + QHash m_usedSensors; QHash m_usedLeds; QList m_relais; @@ -71,17 +71,21 @@ private: QList m_digitalInputs; QList m_analogOutputs; QList m_analogInputs; - QList m_temperatureSensors; + QList m_sensors; QList m_leds; QWebSocket *m_webSocket = nullptr; - void setOutput(const QString &circuit, const GPIOType &type, bool value); + PluginTimer *m_refreshTimer = nullptr; + + void setOutput(const QString &circuit, bool value); + void connectToEvok(); private slots: void onWebSocketConnected(); void onWebSocketDisconnected(); void onWebSocketTextMessageReceived(QString message); + void onRefreshTimer(); }; #endif // DEVICEPLUGINUNIPI_H diff --git a/unipi/iodescriptor.cpp b/unipi/iodescriptor.cpp deleted file mode 100644 index 40f1b2fc..00000000 --- a/unipi/iodescriptor.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2017 Bernhard Trinnes * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; If not, see * - * . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "iodescriptor.h" - -ioDescriptor::ioDescriptor(QObject *parent) : QObject(parent) -{ - -} - diff --git a/unipi/iodescriptor.h b/unipi/iodescriptor.h deleted file mode 100644 index fd8d2e8f..00000000 --- a/unipi/iodescriptor.h +++ /dev/null @@ -1,40 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * * - * Copyright (C) 2017 Bernhard Trinnes * - * Copyright (C) 2018 Simon Stürz * - * * - * This file is part of nymea. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Lesser General Public * - * License as published by the Free Software Foundation; either * - * version 2.1 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; If not, see * - * . * - * * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef IODESCRIPTOR_H -#define IODESCRIPTOR_H - -#include - -class ioDescriptor : public QObject -{ - Q_OBJECT -public: - explicit ioDescriptor(QObject *parent = 0); - -signals: - -public slots: -}; - -#endif // IODESCRIPTOR_H diff --git a/unipi/unipi.pro b/unipi/unipi.pro index 47076101..b107daa1 100644 --- a/unipi/unipi.pro +++ b/unipi/unipi.pro @@ -3,11 +3,9 @@ include(../plugins.pri) TARGET = $$qtLibraryTarget(nymea_devicepluginunipi) SOURCES += \ - devicepluginunipi.cpp \ - iodescriptor.cpp + devicepluginunipi.cpp HEADERS += \ - devicepluginunipi.h \ - iodescriptor.h + devicepluginunipi.h From 641c3fc62bd19240551f187c91b0fbabbb7ef76b Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 17:48:52 +0200 Subject: [PATCH 12/35] improved device detection for digital outputs --- unipi/devicepluginunipi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index e0b34515..9d974acb 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -227,7 +227,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (m_usedRelais.contains(openingCircuit)){ continue; } - for (int a = i; a < (m_relais.count()); a++) { + for (int a = (i+1); a < (m_relais.count()); a++) { const QString closingCircuit = m_relais.at(a); // Offer only relais which aren't in use already @@ -254,7 +254,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (m_usedDigitalOutputs.contains(openingCircuit)){ continue; } - for (int a = i; a < (m_digitalOutputs.count()); a++) { + for (int a = (i+1); a < (m_digitalOutputs.count()); a++) { const QString closingCircuit = m_digitalOutputs.at(a); // Offer only relais which aren't in use already From ec9232cd26fe1fc244a8582da84adc5fb3c3fb92 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 17:57:40 +0200 Subject: [PATCH 13/35] fixed a bug in used outputs allocation --- unipi/devicepluginunipi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 9d974acb..f7df2449 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -81,13 +81,13 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) { m_usedRelais.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); - } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::digitalOutput) { m_usedDigitalOutputs.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); } if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GPIOType::relay) { m_usedRelais.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); - } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::digitalOutput) { m_usedDigitalOutputs.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); } From 2307e0acc86b6e7c4f050c129f52fd031b34c8e0 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 21:47:48 +0200 Subject: [PATCH 14/35] added dimmer switch --- unipi/devicepluginunipi.cpp | 144 ++++++++++++++++++++++++++--------- unipi/devicepluginunipi.h | 8 ++ unipi/devicepluginunipi.json | 89 ++++++++++++++++++++-- unipi/dimmerswitch.cpp | 87 +++++++++++++++++++++ unipi/dimmerswitch.h | 42 ++++++++++ unipi/unipi.pro | 6 +- 6 files changed, 333 insertions(+), 43 deletions(-) create mode 100644 unipi/dimmerswitch.cpp create mode 100644 unipi/dimmerswitch.h diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index f7df2449..e61358bd 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -104,6 +104,17 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) return DeviceManager::DeviceSetupStatusSuccess; } + if (device->deviceClassId() == dimmerSwitchDeviceClassId) { + m_usedDigitalInputs.insert(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString(), device); + DimmerSwitch* dimmerSwitch = new DimmerSwitch(this); + + connect(dimmerSwitch, &DimmerSwitch::pressed, this, &DevicePluginUniPi::onDimmerSwitchPressed); + connect(dimmerSwitch, &DimmerSwitch::longPressed, this, &DevicePluginUniPi::onDimmerSwitchLongPressed); + connect(dimmerSwitch, &DimmerSwitch::doublePressed, this, &DevicePluginUniPi::onDimmerSwitchDoublePressed); + connect(dimmerSwitch, &DimmerSwitch::dimValueChanged, this, &DevicePluginUniPi::onDimmerSwitchDimValueChanged); + m_dimmerSwitches.insert(dimmerSwitch, device); + } + return DeviceManager::DeviceSetupStatusFailure; } @@ -287,7 +298,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (m_usedRelais.contains(circuit)){ continue; } - DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); + DeviceDescriptor descriptor(deviceClassId, "Light", QString("Relay %1").arg(circuit)); ParamList parameters; parameters.append(Param(lightOutputParamTypeId, circuit)); parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::relay)); @@ -302,7 +313,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (m_usedDigitalOutputs.contains(circuit)){ continue; } - DeviceDescriptor descriptor(deviceClassId, QString("Digital output %1").arg(circuit), circuit); + DeviceDescriptor descriptor(deviceClassId, "Light", QString("Digital output %1").arg(circuit)); ParamList parameters; parameters.append(Param(lightOutputParamTypeId, circuit)); parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::digitalOutput)); @@ -312,6 +323,26 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } + + if (deviceClassId == dimmerSwitchDeviceClassId) { + // Create the list of available digital inputs + QList deviceDescriptors; + for (int i = 0; i < m_digitalInputs.count(); i++) { + const QString circuit = m_digitalInputs.at(i); + + // Offer only digital inputs which arn't in use already + if (m_usedDigitalInputs.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, "Dimmer switch", QString("Digital Input %1").arg(circuit)); + ParamList parameters; + parameters.append(Param(digitalInputDigitalInputNumberParamTypeId, circuit)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); + return DeviceManager::DeviceErrorAsync; + } } return DeviceManager::DeviceErrorDeviceClassNotFound; } @@ -355,11 +386,11 @@ void DevicePluginUniPi::deviceRemoved(Device *device) } else if(device->deviceClassId() == digitalOutputDeviceClassId) { m_usedDigitalOutputs.remove(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()); } else if(device->deviceClassId() == digitalInputDeviceClassId) { - m_usedDigitalOutputs.remove(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()); + m_usedDigitalInputs.remove(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()); } else if (device->deviceClassId() == analogOutputDeviceClassId) { - m_usedDigitalOutputs.remove(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()); + m_usedAnalogOutputs.remove(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()); } else if (device->deviceClassId() == analogInputDeviceClassId) { - m_usedDigitalOutputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()); + m_usedAnalogInputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()); } else if (device->deviceClassId() == shutterDeviceClassId) { if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) { @@ -380,6 +411,9 @@ void DevicePluginUniPi::deviceRemoved(Device *device) } else if (device->paramValue(lightOutputParamTypeId) == GPIOType::digitalOutput) { m_usedDigitalOutputs.remove(device->paramValue(lightOutputParamTypeId).toString()); } + } else if (device->deviceClassId() == dimmerSwitchDeviceClassId) { + m_usedDigitalInputs.remove(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString()); + m_dimmerSwitches.remove(m_dimmerSwitches.key(device)); } if (myDevices().isEmpty()) { @@ -393,9 +427,9 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == relayOutputDeviceClassId) { - if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) { + if (action.actionTypeId() == relayOutputPowerActionTypeId) { QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); - int stateValue = action.param(relayOutputRelayStatusActionParamTypeId).value().toInt(); + int stateValue = action.param(relayOutputPowerActionParamTypeId).value().toInt(); setOutput(relayNumber, stateValue); return DeviceManager::DeviceErrorNoError; @@ -403,11 +437,10 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons return DeviceManager::DeviceErrorActionTypeNotFound; } - if (device->deviceClassId() == digitalOutputDeviceClassId) { - if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) { + if (action.actionTypeId() == digitalOutputPowerActionTypeId) { QString digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(); - bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool(); + bool stateValue = action.param(digitalOutputPowerActionParamTypeId).value().toBool(); setOutput(digitalOutputNumber, stateValue); return DeviceManager::DeviceErrorNoError; @@ -464,7 +497,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == lightDeviceClassId) { QString circuit = device->paramValue(lightOutputParamTypeId).toString(); - bool stateValue = action.param(digitalOutputDigitalOutputStatusActionParamTypeId).value().toBool(); + bool stateValue = action.param(digitalOutputPowerActionParamTypeId).value().toBool(); setOutput(circuit, stateValue); return DeviceManager::DeviceErrorNoError; @@ -535,13 +568,10 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) //New Device detected m_relais.append(circuit); } else { - - foreach (Device *device, myDevices()) { + if (m_usedRelais.contains(circuit)) { + Device *device = m_usedRelais.value(circuit); if (device->deviceClassId() == relayOutputDeviceClassId) { - if (circuit == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) { - device->setStateValue(relayOutputRelayStatusStateTypeId, value); - break; - } + device->setStateValue(relayOutputPowerStateTypeId, value); } else if (device->deviceClassId() == shutterDeviceClassId) { if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { @@ -551,8 +581,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else { qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); } - - break; } if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { @@ -566,10 +594,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } else if (device->deviceClassId() == lightDeviceClassId) { - if (circuit == device->paramValue(lightOutputParamTypeId).toString()) { - device->setStateValue(lightPowerStateTypeId, value); - break; - } + device->setStateValue(lightPowerStateTypeId, value); } } } @@ -578,13 +603,32 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) //New Device detected m_digitalOutputs.append(obj["circuit"].toString()); } else { - - foreach (Device *device, myDevices()) { + if (m_usedDigitalOutputs.contains(obj["circuit"].toString())) { + Device *device = m_usedDigitalOutputs.value(obj["circuit"].toString()); if (device->deviceClassId() == digitalOutputDeviceClassId) { - if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) { - device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); + device->setStateValue(digitalOutputPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); + } else if (device->deviceClassId() == shutterDeviceClassId) { + if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { + if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shutterStatusStateTypeId, "close"); + } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { + device->setStateValue(shutterStatusStateTypeId, "stop"); + } else { + qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + } + } + if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { + if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(shutterStatusStateTypeId, "close"); + } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) { + device->setStateValue(shutterStatusStateTypeId, "stop"); + } else { + qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + } break; } + } else if (device->deviceClassId() == lightDeviceClassId) { + device->setStateValue(lightPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); } } } @@ -598,13 +642,15 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) //New Device detected m_digitalInputs.append(obj["circuit"].toString()); } else { - - foreach (Device *device, myDevices()) { + if (m_usedDigitalInputs.contains(obj["circuit"].toString())) { + bool value = QVariant(obj["value"].toInt()).toBool(); + Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == digitalInputDeviceClassId) { - if (obj["circuit"] == device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()) { - device->setStateValue(digitalInputDigitalInputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool()); - break; - } + device->setStateValue(digitalInputDigitalInputStatusStateTypeId, value); + } else if (device->deviceClassId() == dimmerSwitchDeviceClassId) { + device->setStateValue(dimmerSwitchStatusStateTypeId, value); + DimmerSwitch *dimmerSwitch = m_dimmerSwitches.key(device); + dimmerSwitch->setPower(value); } } } @@ -648,7 +694,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } - if (obj["dev"] == "led") { + if (obj["dev"] == "led") { //TODO cant discover leds without toggling it from another client qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); if (!m_leds.contains(obj["circuit"].toString())){ @@ -657,7 +703,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } - if (obj["dev"] == "sensor") { + if (obj["dev"] == "sensor") { //TODO not yet implemented qCDebug(dcUniPi()) << "Sensor:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); if (!m_sensors.contains(obj["circuit"].toString())){ @@ -672,3 +718,31 @@ void DevicePluginUniPi::onRefreshTimer() { connectToEvok(); } + +void DevicePluginUniPi::onDimmerSwitchPressed() +{ + DimmerSwitch *dimmerSwitch = static_cast(sender()); + Device *device = m_dimmerSwitches.value(dimmerSwitch); + emit emitEvent(Event(dimmerSwitchPressedEventTypeId, device->id())); +} + +void DevicePluginUniPi::onDimmerSwitchLongPressed() +{ + DimmerSwitch *dimmerSwitch = static_cast(sender()); + Device *device = m_dimmerSwitches.value(dimmerSwitch); + emit emitEvent(Event(dimmerSwitchLongPressedEventTypeId, device->id())); +} + +void DevicePluginUniPi::onDimmerSwitchDoublePressed() +{ + DimmerSwitch *dimmerSwitch = static_cast(sender()); + Device *device = m_dimmerSwitches.value(dimmerSwitch); + emit emitEvent(Event(dimmerSwitchDoublePressedEventTypeId, device->id())); +} + +void DevicePluginUniPi::onDimmerSwitchDimValueChanged(int dimValue) +{ + DimmerSwitch *dimmerSwitch = static_cast(sender()); + Device *device = m_dimmerSwitches.value(dimmerSwitch); + device->setStateValue(dimmerSwitchDimValueStateTypeId, dimValue); +} diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index e5f66564..6e1ee629 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -28,6 +28,7 @@ #include "devicemanager.h" #include #include "plugintimer.h" +#include "dimmerswitch.h" class DevicePluginUniPi : public DevicePlugin { @@ -66,6 +67,8 @@ private: QHash m_usedSensors; QHash m_usedLeds; + QHash m_dimmerSwitches; + QList m_relais; QList m_digitalOutputs; QList m_digitalInputs; @@ -86,6 +89,11 @@ private slots: void onWebSocketDisconnected(); void onWebSocketTextMessageReceived(QString message); void onRefreshTimer(); + + void onDimmerSwitchPressed(); + void onDimmerSwitchLongPressed(); + void onDimmerSwitchDoublePressed(); + void onDimmerSwitchDimValueChanged(int dimValue); }; #endif // DEVICEPLUGINUNIPI_H diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 5d0bd9f3..655bb873 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -23,7 +23,7 @@ "displayName": "Relay output", "deviceIcon": "Power", "createMethods": ["discovery"], - "interfaces": [ ], + "interfaces": ["power"], "basicTags": ["Device"], "paramTypes": [ { @@ -36,8 +36,8 @@ "stateTypes": [ { "id": "f9c01e7b-0523-4cac-905a-d5b20028e021", - "name": "relayStatus", - "displayName": "Relay", + "name": "power", + "displayName": "Power", "displayNameEvent": "Relay power changed", "displayNameAction": "Set relay power", "type": "bool", @@ -73,13 +73,66 @@ } ] }, + { + "id": "71e03d00-1b62-412b-b55d-ab90ad2eddff", + "name": "dimmerSwitch", + "displayName": "Dimmer switch", + "deviceIcon": "Switch", + "createMethods": ["discovery"], + "interfaces": ["longpressbutton"], + "basicTags": ["Sensor"], + "paramTypes": [ + { + "id": "2344dedb-3e21-4f59-a016-0fc6233a38ac", + "name": "inputNumber", + "displayName": "Input number", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "b39a84ff-45c8-4ec1-b3a9-b99aeefc7221", + "name": "status", + "displayName": "Digital input", + "displayNameEvent": "Digital input changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "3e566b7c-11e6-4e97-9d9f-9636c465639e", + "name": "dimValue", + "displayName": "Dim value", + "displayNameEvent": "Dim value changed", + "type": "int", + "defaultValue": 0, + "unit": "Percentage" + } + ], + "eventTypes": [ + { + "id": "44be91cd-cbeb-477b-bb8c-6a6d4f9aaaf3", + "name": "pressed", + "displayName": "Pressed" + }, + { + "id": "a4748afe-dcd6-45ea-8574-7b9c0e925f35", + "name": "longPressed", + "displayName": "Long pressed" + }, + { + "id": "7e7b36f5-b871-43a3-a7f0-6cef1e550ad7", + "name": "doublePressed", + "displayName": "Double pressed" + } + ] + }, { "id": "f3a3c5ed-461a-4ca8-930b-df3af821b9e0", "name": "digitalOutput", "displayName": "Digital output", "deviceIcon": "Power", "createMethods": ["discovery"], - "interfaces": [ ], + "interfaces": ["power"], "basicTags": ["Device"], "paramTypes": [ { @@ -92,8 +145,8 @@ "stateTypes": [ { "id": "470a0e30-a170-47ed-9ed3-c41db919555f", - "name": "digitalOutputStatus", - "displayName": "digital output", + "name": "power", + "displayName": "Power", "displayNameAction": "set digital output", "displayNameEvent": "digital output changed", "type": "bool", @@ -266,6 +319,30 @@ "writable": true } ] + }, + { + "id": "fe3d7d2f-3cee-4f2b-b6f8-4381ff1a2825", + "name": "temperatureSensor", + "displayName": "1-Wire Temperature Sensor", + "deviceIcon": "Thermometer", + "createMethods": ["discovery"], + "interfaces": ["temperaturesensor"], + "basicTags": ["Actuator"], + "paramTypes": [ + { + } + ], + "stateTypes":[ + { + "id": "a11e8108-d16e-4972-820a-f3611ba6fe24", + "name": "temperature", + "displayName": "Temperature", + "displayNameEvent": "Temperature changed", + "type": "double", + "defaultValue": 0, + "unit": "DegreeCelsius" + } + ] } ] } diff --git a/unipi/dimmerswitch.cpp b/unipi/dimmerswitch.cpp new file mode 100644 index 00000000..b2dd6354 --- /dev/null +++ b/unipi/dimmerswitch.cpp @@ -0,0 +1,87 @@ +#include "dimmerswitch.h" + +DimmerSwitch::DimmerSwitch(QObject *parent) : QObject(parent) +{ + m_longPressedTimer = new QTimer(this); + m_longPressedTimer->setSingleShot(true); + connect(m_longPressedTimer, SIGNAL(timeout()), this, SLOT(onLongPressedTimeout())); + + m_doublePressedTimer = new QTimer(this); + m_doublePressedTimer->setSingleShot(true); + + m_dimmerTimer = new QTimer(this); + connect(m_dimmerTimer, SIGNAL(timeout()), this, SLOT(onDimmerTimeout())); +} + +DimmerSwitch::~DimmerSwitch() +{ + m_longPressedTimer->deleteLater(); + m_doublePressedTimer->deleteLater(); + m_dimmerTimer->deleteLater(); +} + +void DimmerSwitch::setPower(const bool power) +{ + if (m_power == power) { + return; + } + + m_power = power; + if(power){ + m_dimmerTimer->start(150); + m_longPressedTimer->start(2000); + + if (m_doublePressedTimer->isActive()) { + m_doublePressedTimer->stop(); + emit doublePressed(); + } else { + m_doublePressedTimer->start(1000); + emit pressed(); + } + + } else { + m_dimmerTimer->stop(); + m_longPressedTimer->stop(); + } +} + +bool DimmerSwitch::getPower() +{ + return m_power; +} + +void DimmerSwitch::setDimValue(const int dimValue) +{ + m_dimValue = dimValue; + emit dimValueChanged(m_dimValue); +} + +int DimmerSwitch::getDimValue() +{ + return m_dimValue; +} + +void DimmerSwitch::onDimmerTimeout() +{ + if (m_countingUp) { + m_dimValue += 3; + if(m_dimValue >= 100) { + m_dimValue = 100; + m_countingUp = false; + } + } else { + m_dimValue -= 3; + if(m_dimValue <= 0) { + m_dimValue = 0; + m_countingUp = true; + } + } + emit dimValueChanged(m_dimValue); +} + +void DimmerSwitch::onLongPressedTimeout() +{ + emit longPressed(); +} + + diff --git a/unipi/dimmerswitch.h b/unipi/dimmerswitch.h new file mode 100644 index 00000000..06c106bb --- /dev/null +++ b/unipi/dimmerswitch.h @@ -0,0 +1,42 @@ +#ifndef DIMMERSWITCH_H +#define DIMMERSWITCH_H + +#include +#include + +class DimmerSwitch : public QObject +{ + Q_OBJECT +public: + explicit DimmerSwitch(QObject *parent = 0); + ~DimmerSwitch(); + + void setPower(const bool power); + bool getPower(); + void setDimValue(const int dimValue); + int getDimValue(); + + QTimer *m_doublePressedTimer = nullptr; + QTimer *m_longPressedTimer = nullptr; + QTimer *m_dimmerTimer = nullptr; + +private: + bool m_power; + int m_dimValue = 0; + bool m_countingUp = true; + bool m_powerWasLow = false; //flag to indicate the power was low within the double pressed time frame + + +signals: + void pressed(); + void longPressed(); + void doublePressed(); + void dimValueChanged(int dimValue); + +private slots: + void onLongPressedTimeout(); + void onDimmerTimeout(); + +}; + +#endif // DIMMERSWITCH_H diff --git a/unipi/unipi.pro b/unipi/unipi.pro index b107daa1..60a45796 100644 --- a/unipi/unipi.pro +++ b/unipi/unipi.pro @@ -3,9 +3,11 @@ include(../plugins.pri) TARGET = $$qtLibraryTarget(nymea_devicepluginunipi) SOURCES += \ - devicepluginunipi.cpp + devicepluginunipi.cpp \ + dimmerswitch.cpp HEADERS += \ - devicepluginunipi.h + devicepluginunipi.h \ + dimmerswitch.h From d975f791f9464b6e55bd8d91fe75953c2f853b89 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 22:50:59 +0200 Subject: [PATCH 15/35] fixed dimmer setup bug --- unipi/devicepluginunipi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index e61358bd..3f4ec75b 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -113,6 +113,7 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) connect(dimmerSwitch, &DimmerSwitch::doublePressed, this, &DevicePluginUniPi::onDimmerSwitchDoublePressed); connect(dimmerSwitch, &DimmerSwitch::dimValueChanged, this, &DevicePluginUniPi::onDimmerSwitchDimValueChanged); m_dimmerSwitches.insert(dimmerSwitch, device); + return DeviceManager::DeviceSetupStatusSuccess; } return DeviceManager::DeviceSetupStatusFailure; @@ -336,7 +337,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, "Dimmer switch", QString("Digital Input %1").arg(circuit)); ParamList parameters; - parameters.append(Param(digitalInputDigitalInputNumberParamTypeId, circuit)); + parameters.append(Param(dimmerSwitchInputNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } From 301b1fbfa818249331971af23e909a9b6436c53e Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 12 Jun 2018 23:11:48 +0200 Subject: [PATCH 16/35] improved dimmer switch behaviour --- unipi/dimmerswitch.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/unipi/dimmerswitch.cpp b/unipi/dimmerswitch.cpp index b2dd6354..d6440f1f 100644 --- a/unipi/dimmerswitch.cpp +++ b/unipi/dimmerswitch.cpp @@ -28,7 +28,7 @@ void DimmerSwitch::setPower(const bool power) m_power = power; if(power){ - m_dimmerTimer->start(150); + m_dimmerTimer->start(250); m_longPressedTimer->start(2000); if (m_doublePressedTimer->isActive()) { @@ -63,20 +63,23 @@ int DimmerSwitch::getDimValue() void DimmerSwitch::onDimmerTimeout() { - if (m_countingUp) { - m_dimValue += 3; - if(m_dimValue >= 100) { - m_dimValue = 100; - m_countingUp = false; - } - } else { - m_dimValue -= 3; - if(m_dimValue <= 0) { - m_dimValue = 0; - m_countingUp = true; + if(!m_longPressedTimer->isActive()) { + if (m_countingUp) { + m_dimValue += 5; + if(m_dimValue >= 100) { + m_dimValue = 100; + m_countingUp = false; + } + } else { + m_dimValue -= 5; + if(m_dimValue <= 0) { + m_dimValue = 0; + m_countingUp = true; + } } + emit dimValueChanged(m_dimValue); } - emit dimValueChanged(m_dimValue); + } void DimmerSwitch::onLongPressedTimeout() From 5569fc44069f8797e74f292b4f9de83e0182578a Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Fri, 22 Jun 2018 10:58:10 +0200 Subject: [PATCH 17/35] added unipi plug-in debian installer --- debian/control | 16 ++++++++++++++++ debian/copyright | 5 +++-- debian/nymea-plugin-unipi.install.in | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 debian/nymea-plugin-unipi.install.in diff --git a/debian/control b/debian/control index a0c0bbde..eb2fb6ea 100644 --- a/debian/control +++ b/debian/control @@ -681,6 +681,21 @@ Description: nymea.io plugin for remote ssh connection This package will install the nymea.io plugin for remote ssh connection +Package: nymea-plugin-unipi +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, + nymea-plugins-translations, +Description: nymea.io plugin for remote ssh connection + The nymea 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 nymea.io plugin for unipi devices + + Package: nymea-plugins-translations Section: misc Architecture: all @@ -720,6 +735,7 @@ Depends: nymea-plugin-awattar, nymea-plugin-elgato, nymea-plugin-senic, nymea-plugin-keba, + nymea-plugin-unipi, Replaces: guh-plugins Description: Plugins for nymea IoT server - the default plugin collection The nymea daemon is a plugin based IoT (Internet of Things) server. The diff --git a/debian/copyright b/debian/copyright index ee080ae0..e0309381 100644 --- a/debian/copyright +++ b/debian/copyright @@ -36,9 +36,10 @@ License: LGPL-2.1 Copyright: 2016, Bernhard Trinnes Files: plantcare/* + unipi/* License: LGPL-2.1 -Copyright: 2016-2017, Simon Stürz - 2016, Bernhard Trinnes +Copyright: 2016-2018, Simon Stürz + 2016-2018, Bernhard Trinnes Files: pushbullet/* usbwde/* diff --git a/debian/nymea-plugin-unipi.install.in b/debian/nymea-plugin-unipi.install.in new file mode 100644 index 00000000..c8a07bf7 --- /dev/null +++ b/debian/nymea-plugin-unipi.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_devicepluginunipi.so From 873ab05c007fdfc5ecb03ae492813dfa41a63e27 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Fri, 22 Jun 2018 11:25:05 +0200 Subject: [PATCH 18/35] added translation file --- .../26cba644-35ae-40a6-9c48-924198893a5f-en_US.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 unipi/translations/26cba644-35ae-40a6-9c48-924198893a5f-en_US.ts diff --git a/unipi/translations/26cba644-35ae-40a6-9c48-924198893a5f-en_US.ts b/unipi/translations/26cba644-35ae-40a6-9c48-924198893a5f-en_US.ts new file mode 100644 index 00000000..f7f66d85 --- /dev/null +++ b/unipi/translations/26cba644-35ae-40a6-9c48-924198893a5f-en_US.ts @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 1e2e4dab95cc40450f0ba720c79848f1494ce084 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Fri, 22 Jun 2018 15:47:38 +0200 Subject: [PATCH 19/35] clean-up unipi code and implement inline comments from reviewer --- unipi/devicepluginunipi.cpp | 58 ++++++++++++++++-------------------- unipi/devicepluginunipi.h | 12 ++++---- unipi/devicepluginunipi.json | 24 --------------- 3 files changed, 32 insertions(+), 62 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 3f4ec75b..eed0b922 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -39,7 +39,6 @@ void DevicePluginUniPi::init() { connectToEvok(); - // Refresh timer for snapd checks m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); connect(m_refreshTimer, &PluginTimer::timeout, this, &DevicePluginUniPi::onRefreshTimer); @@ -79,15 +78,15 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) if (device->deviceClassId() == shutterDeviceClassId) { - if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) { + if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::Relay) { m_usedRelais.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); - } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { m_usedDigitalOutputs.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); } - if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GPIOType::relay) { + if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GpioType::Relay) { m_usedRelais.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); - } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { m_usedDigitalOutputs.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); } @@ -96,9 +95,9 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) if (device->deviceClassId() == lightDeviceClassId) { - if (device->paramValue(lightOutputTypeParamTypeId) == GPIOType::relay) { + if (device->paramValue(lightOutputTypeParamTypeId) == GpioType::Relay) { m_usedRelais.insert(device->paramValue(lightOutputParamTypeId).toString(), device); - } else if (device->paramValue(lightOutputParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(lightOutputParamTypeId) == GpioType::DigitalOutput) { m_usedDigitalOutputs.insert(device->paramValue(lightOutputParamTypeId).toString(), device); } return DeviceManager::DeviceSetupStatusSuccess; @@ -193,7 +192,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI for (int i = 0; i < m_analogInputs.count(); i++) { const QString circuit = m_analogInputs.at(i); - // Offer only analog inputs which arn't in use already + // Offer only analog inputs which aren't in use already if (m_usedAnalogInputs.contains(circuit)){ continue; } @@ -249,8 +248,8 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI ParamList parameters; parameters.append(Param(shutterOutputOpenParamTypeId, openingCircuit)); parameters.append(Param(shutterOutputCloseParamTypeId, closingCircuit)); - parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::relay)); - parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::relay)); + parameters.append(Param(shutterOutputTypeOpenParamTypeId, GpioType::Relay)); + parameters.append(Param(shutterOutputTypeCloseParamTypeId, GpioType::Relay)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); break; @@ -276,8 +275,8 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI ParamList parameters; parameters.append(Param(shutterOutputOpenParamTypeId, openingCircuit)); parameters.append(Param(shutterOutputCloseParamTypeId, closingCircuit)); - parameters.append(Param(shutterOutputTypeOpenParamTypeId, GPIOType::digitalOutput)); - parameters.append(Param(shutterOutputTypeCloseParamTypeId, GPIOType::digitalOutput)); + parameters.append(Param(shutterOutputTypeOpenParamTypeId, GpioType::DigitalOutput)); + parameters.append(Param(shutterOutputTypeCloseParamTypeId, GpioType::DigitalOutput)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); break; @@ -302,7 +301,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI DeviceDescriptor descriptor(deviceClassId, "Light", QString("Relay %1").arg(circuit)); ParamList parameters; parameters.append(Param(lightOutputParamTypeId, circuit)); - parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::relay)); + parameters.append(Param(lightOutputTypeParamTypeId, GpioType::Relay)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -317,7 +316,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI DeviceDescriptor descriptor(deviceClassId, "Light", QString("Digital output %1").arg(circuit)); ParamList parameters; parameters.append(Param(lightOutputParamTypeId, circuit)); - parameters.append(Param(lightOutputTypeParamTypeId, GPIOType::digitalOutput)); + parameters.append(Param(lightOutputTypeParamTypeId, GpioType::DigitalOutput)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -366,7 +365,7 @@ void DevicePluginUniPi::connectToEvok() { if (m_webSocket == NULL) { - int port = 8080; //configValue(uniPiPortParamTypeId).toInt(); TODO + int port = 8080; //configValue(uniPiPortParamTypeId).toInt(); //FIXME plugin configuration loading currently not possible in init m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); @@ -394,27 +393,29 @@ void DevicePluginUniPi::deviceRemoved(Device *device) m_usedAnalogInputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()); } else if (device->deviceClassId() == shutterDeviceClassId) { - if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GPIOType::relay) { + if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::Relay) { m_usedRelais.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); - } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(shutterOutputOpenParamTypeId) == GpioType::DigitalOutput) { m_usedDigitalOutputs.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); } - if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GPIOType::relay) { + if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GpioType::Relay) { m_usedRelais.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); - } else if (device->paramValue(shutterOutputOpenParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(shutterOutputOpenParamTypeId) == GpioType::DigitalOutput) { m_usedDigitalOutputs.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); } } else if (device->deviceClassId() == lightDeviceClassId) { - if (device->paramValue(lightOutputTypeParamTypeId) == GPIOType::relay) { + if (device->paramValue(lightOutputTypeParamTypeId) == GpioType::Relay) { m_usedRelais.remove(device->paramValue(lightOutputParamTypeId).toString()); - } else if (device->paramValue(lightOutputParamTypeId) == GPIOType::digitalOutput) { + } else if (device->paramValue(lightOutputParamTypeId) == GpioType::DigitalOutput) { m_usedDigitalOutputs.remove(device->paramValue(lightOutputParamTypeId).toString()); } } else if (device->deviceClassId() == dimmerSwitchDeviceClassId) { m_usedDigitalInputs.remove(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString()); - m_dimmerSwitches.remove(m_dimmerSwitches.key(device)); + DimmerSwitch *dimmerSwitch = m_dimmerSwitches.key(device); + m_dimmerSwitches.remove(dimmerSwitch); + dimmerSwitch->deleteLater(); } if (myDevices().isEmpty()) { @@ -425,6 +426,8 @@ void DevicePluginUniPi::deviceRemoved(Device *device) DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, const Action &action) { + if (m_webSocket->state() != QAbstractSocket::ConnectedState) + return DeviceManager::DeviceErrorHardwareNotAvailable; if (device->deviceClassId() == relayOutputDeviceClassId) { @@ -695,7 +698,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } - if (obj["dev"] == "led") { //TODO cant discover leds without toggling it from another client + if (obj["dev"] == "led") { //TODO can't discover leds without toggling it from another client qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); if (!m_leds.contains(obj["circuit"].toString())){ @@ -703,15 +706,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) m_leds.append(obj["circuit"].toString()); } } - - if (obj["dev"] == "sensor") { //TODO not yet implemented - qCDebug(dcUniPi()) << "Sensor:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - - if (!m_sensors.contains(obj["circuit"].toString())){ - //New Sensor detected - m_sensors.append(obj["circuit"].toString()); - } - } } } diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 6e1ee629..6c47d445 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -51,12 +51,12 @@ public: private: - enum GPIOType { - relay, - digitalInput, - digitalOutput, - analogInput, - analogOutput + enum GpioType { + Relay, + DigitalInput, + DigitalOutput, + AnalogInput, + AnalogOutput }; QHash m_usedRelais; diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 655bb873..d2730a26 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -319,30 +319,6 @@ "writable": true } ] - }, - { - "id": "fe3d7d2f-3cee-4f2b-b6f8-4381ff1a2825", - "name": "temperatureSensor", - "displayName": "1-Wire Temperature Sensor", - "deviceIcon": "Thermometer", - "createMethods": ["discovery"], - "interfaces": ["temperaturesensor"], - "basicTags": ["Actuator"], - "paramTypes": [ - { - } - ], - "stateTypes":[ - { - "id": "a11e8108-d16e-4972-820a-f3611ba6fe24", - "name": "temperature", - "displayName": "Temperature", - "displayNameEvent": "Temperature changed", - "type": "double", - "defaultValue": 0, - "unit": "DegreeCelsius" - } - ] } ] } From a72fabf28f413325605fd424bcad5508150aa787 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 9 Oct 2018 13:21:43 +0200 Subject: [PATCH 20/35] minor bugfixes --- unipi/devicepluginunipi.cpp | 130 ++++++++++++++++++----------------- unipi/devicepluginunipi.json | 16 ++--- 2 files changed, 75 insertions(+), 71 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index eed0b922..09dade9d 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -76,18 +76,18 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) return DeviceManager::DeviceSetupStatusSuccess; } - if (device->deviceClassId() == shutterDeviceClassId) { + if (device->deviceClassId() == blindDeviceClassId) { - if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::Relay) { - m_usedRelais.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); - } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.insert(device->paramValue(shutterOutputOpenParamTypeId).toString(), device); + if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::Relay) { + m_usedRelais.insert(device->paramValue(blindOutputOpenParamTypeId).toString(), device); + } else if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(blindOutputOpenParamTypeId).toString(), device); } - if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GpioType::Relay) { - m_usedRelais.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); - } else if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.insert(device->paramValue(shutterOutputCloseParamTypeId).toString(), device); + if (device->paramValue(blindOutputTypeCloseParamTypeId) == GpioType::Relay) { + m_usedRelais.insert(device->paramValue(blindOutputCloseParamTypeId).toString(), device); + } else if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(blindOutputCloseParamTypeId).toString(), device); } return DeviceManager::DeviceSetupStatusSuccess; @@ -121,6 +121,11 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) { Q_UNUSED(params); + qSort(m_relais); + qSort(m_digitalOutputs); + qSort(m_digitalInputs); + qSort(m_analogInputs); + qSort(m_analogOutputs); const DeviceClass deviceClass = deviceManager()->findDeviceClass(deviceClassId); if (deviceClass.vendorId() == unipiVendorId) { @@ -226,10 +231,9 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI return DeviceManager::DeviceErrorAsync; } - if (deviceClassId == shutterDeviceClassId) { + if (deviceClassId == blindDeviceClassId) { // Create the list of available gpios QList deviceDescriptors; - for (int i = 0; i < (m_relais.count()-1); i++) { const QString openingCircuit = m_relais.at(i); @@ -244,12 +248,12 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI // Offer only relais which aren't in use already if (!m_usedRelais.contains(closingCircuit)){ - DeviceDescriptor descriptor(deviceClassId, "Roller shutter", QString("Opening relay %1 | Closing relay %2").arg(openingCircuit, closingCircuit)); + DeviceDescriptor descriptor(deviceClassId, "Blind", QString("Opening relay %1 | Closing relay %2").arg(openingCircuit, closingCircuit)); ParamList parameters; - parameters.append(Param(shutterOutputOpenParamTypeId, openingCircuit)); - parameters.append(Param(shutterOutputCloseParamTypeId, closingCircuit)); - parameters.append(Param(shutterOutputTypeOpenParamTypeId, GpioType::Relay)); - parameters.append(Param(shutterOutputTypeCloseParamTypeId, GpioType::Relay)); + parameters.append(Param(blindOutputOpenParamTypeId, openingCircuit)); + parameters.append(Param(blindOutputCloseParamTypeId, closingCircuit)); + parameters.append(Param(blindOutputTypeOpenParamTypeId, GpioType::Relay)); + parameters.append(Param(blindOutputTypeCloseParamTypeId, GpioType::Relay)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); break; @@ -271,12 +275,12 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI // Offer only relais which aren't in use already if (!m_usedDigitalOutputs.contains(closingCircuit)){ - DeviceDescriptor descriptor(deviceClassId, "Roller shutter", QString("Opening output %1 | Closing output %2").arg(openingCircuit, closingCircuit)); + DeviceDescriptor descriptor(deviceClassId, "Blind", QString("Opening output %1 | Closing output %2").arg(openingCircuit, closingCircuit)); ParamList parameters; - parameters.append(Param(shutterOutputOpenParamTypeId, openingCircuit)); - parameters.append(Param(shutterOutputCloseParamTypeId, closingCircuit)); - parameters.append(Param(shutterOutputTypeOpenParamTypeId, GpioType::DigitalOutput)); - parameters.append(Param(shutterOutputTypeCloseParamTypeId, GpioType::DigitalOutput)); + parameters.append(Param(blindOutputOpenParamTypeId, openingCircuit)); + parameters.append(Param(blindOutputCloseParamTypeId, closingCircuit)); + parameters.append(Param(blindOutputTypeOpenParamTypeId, GpioType::DigitalOutput)); + parameters.append(Param(blindOutputTypeCloseParamTypeId, GpioType::DigitalOutput)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); break; @@ -392,17 +396,17 @@ void DevicePluginUniPi::deviceRemoved(Device *device) } else if (device->deviceClassId() == analogInputDeviceClassId) { m_usedAnalogInputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()); - } else if (device->deviceClassId() == shutterDeviceClassId) { - if (device->paramValue(shutterOutputTypeOpenParamTypeId) == GpioType::Relay) { - m_usedRelais.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); - } else if (device->paramValue(shutterOutputOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.remove(device->paramValue(shutterOutputOpenParamTypeId).toString()); + } else if (device->deviceClassId() == blindDeviceClassId) { + if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::Relay) { + m_usedRelais.remove(device->paramValue(blindOutputOpenParamTypeId).toString()); + } else if (device->paramValue(blindOutputOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(blindOutputOpenParamTypeId).toString()); } - if (device->paramValue(shutterOutputTypeCloseParamTypeId) == GpioType::Relay) { - m_usedRelais.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); - } else if (device->paramValue(shutterOutputOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.remove(device->paramValue(shutterOutputCloseParamTypeId).toString()); + if (device->paramValue(blindOutputTypeCloseParamTypeId) == GpioType::Relay) { + m_usedRelais.remove(device->paramValue(blindOutputCloseParamTypeId).toString()); + } else if (device->paramValue(blindOutputOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(blindOutputCloseParamTypeId).toString()); } } else if (device->deviceClassId() == lightDeviceClassId) { @@ -473,23 +477,23 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons return DeviceManager::DeviceErrorActionTypeNotFound; } - if (device->deviceClassId() == shutterDeviceClassId) { - QString circuitOpen = device->paramValue(shutterOutputOpenParamTypeId).toString(); - QString circuitClose = device->paramValue(shutterOutputCloseParamTypeId).toString(); + if (device->deviceClassId() == blindDeviceClassId) { + QString circuitOpen = device->paramValue(blindOutputOpenParamTypeId).toString(); + QString circuitClose = device->paramValue(blindOutputCloseParamTypeId).toString(); - if (action.actionTypeId() == shutterCloseActionTypeId) { + if (action.actionTypeId() == blindCloseActionTypeId) { setOutput(circuitOpen, false); setOutput(circuitClose, true); return DeviceManager::DeviceErrorNoError; } - if (action.actionTypeId() == shutterOpenActionTypeId) { + if (action.actionTypeId() == blindOpenActionTypeId) { setOutput(circuitClose, false); setOutput(circuitOpen, true); return DeviceManager::DeviceErrorNoError; } - if (action.actionTypeId() == shutterStopActionTypeId) { + if (action.actionTypeId() == blindStopActionTypeId) { setOutput(circuitOpen, false); setOutput(circuitClose, false); @@ -501,7 +505,7 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == lightDeviceClassId) { QString circuit = device->paramValue(lightOutputParamTypeId).toString(); - bool stateValue = action.param(digitalOutputPowerActionParamTypeId).value().toBool(); + bool stateValue = action.param(lightPowerActionParamTypeId).value().toBool(); setOutput(circuit, stateValue); return DeviceManager::DeviceErrorNoError; @@ -576,23 +580,23 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) Device *device = m_usedRelais.value(circuit); if (device->deviceClassId() == relayOutputDeviceClassId) { device->setStateValue(relayOutputPowerStateTypeId, value); - } else if (device->deviceClassId() == shutterDeviceClassId) { - if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { - if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "close"); - } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { - device->setStateValue(shutterStatusStateTypeId, "stop"); + } else if (device->deviceClassId() == blindDeviceClassId) { + if (circuit == device->paramValue(blindOutputOpenParamTypeId).toString()) { + if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + device->setStateValue(blindStatusStateTypeId, "opening"); + } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { + device->setStateValue(blindStatusStateTypeId, "stopped"); } else { - qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + qWarning(dcUniPi()) << "Blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); } } - if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { - if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "close"); - } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) { - device->setStateValue(shutterStatusStateTypeId, "stop"); + if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { + if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + device->setStateValue(blindStatusStateTypeId, "closing"); + } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { + device->setStateValue(blindStatusStateTypeId, "stopped"); } else { - qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + qWarning(dcUniPi()) << "Blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); } break; } @@ -611,23 +615,23 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) Device *device = m_usedDigitalOutputs.value(obj["circuit"].toString()); if (device->deviceClassId() == digitalOutputDeviceClassId) { device->setStateValue(digitalOutputPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); - } else if (device->deviceClassId() == shutterDeviceClassId) { - if (circuit == device->paramValue(shutterOutputOpenParamTypeId).toString()) { - if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "close"); - } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("open")) { - device->setStateValue(shutterStatusStateTypeId, "stop"); + } else if (device->deviceClassId() == blindDeviceClassId) { + if (circuit == device->paramValue(blindOutputOpenParamTypeId).toString()) { + if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(blindStatusStateTypeId, "open"); + } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("open")) { + device->setStateValue(blindStatusStateTypeId, "stop"); } else { - qWarning(dcUniPi()) << "shutter" << device << "Output open:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + qWarning(dcUniPi()) << "blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); } } - if (circuit == device->paramValue(shutterOutputCloseParamTypeId).toString()) { - if (value && device->stateValue(shutterStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(shutterStatusStateTypeId, "close"); - } else if (!value && device->stateValue(shutterStatusStateTypeId).toString().contains("close")) { - device->setStateValue(shutterStatusStateTypeId, "stop"); + if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { + if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stop")) { + device->setStateValue(blindStatusStateTypeId, "close"); + } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("close")) { + device->setStateValue(blindStatusStateTypeId, "stop"); } else { - qWarning(dcUniPi()) << "shutter" << device << "Output close:" << value << "Status: " << device->stateValue(shutterStatusStateTypeId).toString(); + qWarning(dcUniPi()) << "blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); } break; } diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index d2730a26..bcc4cc72 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -217,11 +217,11 @@ }, { "id": "eadddc99-ce7d-4169-a2f9-a829fa105ad2", - "name": "shutter", - "displayName": "Shutter", - "deviceIcon": "RollerShutter", + "name": "blind", + "displayName": "Blind", + "deviceIcon": "Blinds", "createMethods": ["discovery"], - "interfaces": ["shutter"], + "interfaces": ["blind"], "basicTags": ["Actuator"], "paramTypes": [ { @@ -259,11 +259,11 @@ "displayNameEvent": "Status changed", "type": "QString", "possibleValues":[ - "open", - "stop", - "close" + "opening", + "stopped", + "closing" ], - "defaultValue": "stop" + "defaultValue": "stopped" } ], "actionTypes":[ From cc5fc910a3edac50062789b7cdcb613f598827aa Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 9 Oct 2018 13:37:53 +0200 Subject: [PATCH 21/35] minor fixes --- unipi/devicepluginunipi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 09dade9d..245d6645 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -369,7 +369,8 @@ void DevicePluginUniPi::connectToEvok() { if (m_webSocket == NULL) { - int port = 8080; //configValue(uniPiPortParamTypeId).toInt(); //FIXME plugin configuration loading currently not possible in init + int port = 8080; + //configValue(uniPiPortParamTypeId).toInt(); //FIXME plugin configuration loading currently not possible in init m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); From 838937a875ca557995e7d2d76f8076496e0e1ab2 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 9 Oct 2018 19:59:23 +0200 Subject: [PATCH 22/35] fixed issue in blind state --- unipi/devicepluginunipi.cpp | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 245d6645..3f6d58ca 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -589,6 +589,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(blindStatusStateTypeId, "stopped"); } else { qWarning(dcUniPi()) << "Blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + device->setStateValue(blindStatusStateTypeId, "stopped"); } } if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { @@ -598,8 +599,8 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(blindStatusStateTypeId, "stopped"); } else { qWarning(dcUniPi()) << "Blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + device->setStateValue(blindStatusStateTypeId, "stopped"); } - break; } } else if (device->deviceClassId() == lightDeviceClassId) { @@ -618,21 +619,23 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(digitalOutputPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); } else if (device->deviceClassId() == blindDeviceClassId) { if (circuit == device->paramValue(blindOutputOpenParamTypeId).toString()) { - if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(blindStatusStateTypeId, "open"); - } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("open")) { - device->setStateValue(blindStatusStateTypeId, "stop"); - } else { + if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + device->setStateValue(blindStatusStateTypeId, "opening"); + } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { + device->setStateValue(blindStatusStateTypeId, "stopped"); + } else { qWarning(dcUniPi()) << "blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + device->setStateValue(blindStatusStateTypeId, "stopped"); } } if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { - if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stop")) { - device->setStateValue(blindStatusStateTypeId, "close"); - } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("close")) { - device->setStateValue(blindStatusStateTypeId, "stop"); + if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + device->setStateValue(blindStatusStateTypeId, "closing"); + } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { + device->setStateValue(blindStatusStateTypeId, "stopped"); } else { qWarning(dcUniPi()) << "blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + device->setStateValue(blindStatusStateTypeId, "stopped"); } break; } @@ -665,6 +668,16 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } + + if (obj["dev"] == "led") { //TODO can't discover leds without toggling it from another client + qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); + + if (!m_leds.contains(obj["circuit"].toString())){ + //New led detected + m_leds.append(obj["circuit"].toString()); + } + } + if (obj["dev"] == "ao") { qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); @@ -702,15 +715,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } } - - if (obj["dev"] == "led") { //TODO can't discover leds without toggling it from another client - qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - - if (!m_leds.contains(obj["circuit"].toString())){ - //New led detected - m_leds.append(obj["circuit"].toString()); - } - } } } From 49cc41f4730b3ee84e1cdc87a23a07db2bd55f26 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 9 Oct 2018 20:02:55 +0200 Subject: [PATCH 23/35] fixed issue in blind state --- unipi/devicepluginunipi.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 3f6d58ca..501a66e5 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -637,7 +637,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) qWarning(dcUniPi()) << "blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); device->setStateValue(blindStatusStateTypeId, "stopped"); } - break; } } else if (device->deviceClassId() == lightDeviceClassId) { device->setStateValue(lightPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); From 85a4ccafc34765968351107da604873913734d6c Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 9 Oct 2018 20:47:00 +0200 Subject: [PATCH 24/35] still fixing an issue with the blind state --- unipi/devicepluginunipi.cpp | 71 +++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 501a66e5..1a9a9e1e 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -583,23 +583,45 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(relayOutputPowerStateTypeId, value); } else if (device->deviceClassId() == blindDeviceClassId) { if (circuit == device->paramValue(blindOutputOpenParamTypeId).toString()) { - if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { - device->setStateValue(blindStatusStateTypeId, "opening"); - } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { - device->setStateValue(blindStatusStateTypeId, "stopped"); + if (value) { + if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + device->setStateValue(blindStatusStateTypeId, "opening"); + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { + //error both relais are on + qWarning(dcUniPi()) << "Blind" << device->name() << "Critical state - Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + device->setStateValue(blindStatusStateTypeId, "stopped"); + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { + //state unchanged + } } else { - qWarning(dcUniPi()) << "Blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); - device->setStateValue(blindStatusStateTypeId, "stopped"); + if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + // state unchanged + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { + // state unchanged + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { + device->setStateValue(blindStatusStateTypeId, "stopped"); + } } } if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { - if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { - device->setStateValue(blindStatusStateTypeId, "closing"); - } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { - device->setStateValue(blindStatusStateTypeId, "stopped"); + if (value) { + if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + device->setStateValue(blindStatusStateTypeId, "closing"); + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { + //state unchanged + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { + //error both relais are on + qWarning(dcUniPi()) << "Blind" << device->name() << "Critical state - Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + device->setStateValue(blindStatusStateTypeId, "stopped"); + } } else { - qWarning(dcUniPi()) << "Blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); - device->setStateValue(blindStatusStateTypeId, "stopped"); + if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { + // state unchanged + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { + device->setStateValue(blindStatusStateTypeId, "stopped"); + } else if (device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { + // state unchanged + } } } @@ -623,7 +645,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(blindStatusStateTypeId, "opening"); } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { device->setStateValue(blindStatusStateTypeId, "stopped"); - } else { + } else { qWarning(dcUniPi()) << "blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); device->setStateValue(blindStatusStateTypeId, "stopped"); } @@ -667,7 +689,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } - if (obj["dev"] == "led") { //TODO can't discover leds without toggling it from another client qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); @@ -683,14 +704,13 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (!m_analogOutputs.contains(obj["circuit"].toString())){ //New Device detected m_analogOutputs.append(obj["circuit"].toString()); - } else { - foreach (Device *device, myDevices()) { + if (m_usedAnalogOutputs.contains(obj["circuit"].toString())) { + double value = QVariant(obj["value"]).toDouble(); + Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); + if (device->deviceClassId() == analogOutputDeviceClassId) { - if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) { - device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble()); - break; - } + device->setStateValue(analogOutputAnalogOutputValueStateTypeId, value); } } } @@ -703,13 +723,12 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) //New analog output detected m_analogInputs.append(obj["circuit"].toString()); } else { - foreach (Device *device, myDevices()) { - if (device->deviceClassId() == analogInputDeviceClassId) { + if (m_usedAnalogInputs.contains(obj["circuit"].toString())) { + double value = QVariant(obj["value"]).toDouble(); + Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); - if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) { - device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble()); - break; - } + if (device->deviceClassId() == analogInputDeviceClassId) { + device->setStateValue(analogInputAnalogInputValueStateTypeId, value); } } } From 1aa1e425284a7fdfb3e7ace78fd12585d18d9042 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 9 Oct 2018 20:56:07 +0200 Subject: [PATCH 25/35] unipi blinds state now fixed --- unipi/devicepluginunipi.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 1a9a9e1e..cfeb85fe 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -587,9 +587,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { device->setStateValue(blindStatusStateTypeId, "opening"); } else if (device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { - //error both relais are on - qWarning(dcUniPi()) << "Blind" << device->name() << "Critical state - Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); - device->setStateValue(blindStatusStateTypeId, "stopped"); + device->setStateValue(blindStatusStateTypeId, "opening"); } else if (device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { //state unchanged } @@ -610,9 +608,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else if (device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { //state unchanged } else if (device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { - //error both relais are on - qWarning(dcUniPi()) << "Blind" << device->name() << "Critical state - Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); - device->setStateValue(blindStatusStateTypeId, "stopped"); + device->setStateValue(blindStatusStateTypeId, "closing"); } } else { if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { From c38e15c54071c44a49246aa6517820d6878d9dfa Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Wed, 14 Nov 2018 10:45:48 +0100 Subject: [PATCH 26/35] added port config --- unipi/devicepluginunipi.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index cfeb85fe..2a8a8689 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -367,10 +367,9 @@ void DevicePluginUniPi::setOutput(const QString &circuit, bool value) void DevicePluginUniPi::connectToEvok() { - if (m_webSocket == NULL) { + if ((m_webSocket == NULL) || !m_webSocket) { - int port = 8080; - //configValue(uniPiPortParamTypeId).toInt(); //FIXME plugin configuration loading currently not possible in init + int port = configValue(uniPiPortParamTypeId).toInt(); m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); From a06b7363e368a461baed2f2857ec4adbed9a0198 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Thu, 6 Dec 2018 17:48:40 +0100 Subject: [PATCH 27/35] updated to new nymea naming convention --- unipi/devicepluginunipi.cpp | 148 +++++++++++++++++------------------ unipi/devicepluginunipi.json | 16 ++-- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 2a8a8689..f5236559 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -48,46 +48,46 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) { if (device->deviceClassId() == relayOutputDeviceClassId) { - m_usedRelais.insert(device->paramValue(relayOutputRelayNumberParamTypeId).toString(), device); + m_usedRelais.insert(device->paramValue(relayOutputDeviceNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == digitalOutputDeviceClassId) { - m_usedDigitalOutputs.insert(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(), device); + m_usedDigitalOutputs.insert(device->paramValue(digitalOutputDeviceNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == digitalInputDeviceClassId) { - m_usedDigitalInputs.insert(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString(), device); + m_usedDigitalInputs.insert(device->paramValue(digitalInputDeviceNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogInputDeviceClassId) { - m_usedAnalogInputs.insert(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString(), device); + m_usedAnalogInputs.insert(device->paramValue(analogInputDeviceInputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogOutputDeviceClassId) { - m_usedAnalogOutputs.insert(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString(), device); + m_usedAnalogOutputs.insert(device->paramValue(analogOutputDeviceOutputNumberParamTypeId).toString(), device); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == blindDeviceClassId) { - if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::Relay) { - m_usedRelais.insert(device->paramValue(blindOutputOpenParamTypeId).toString(), device); - } else if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.insert(device->paramValue(blindOutputOpenParamTypeId).toString(), device); + if (device->paramValue(blindDeviceOutputTypeOpenParamTypeId) == GpioType::Relay) { + m_usedRelais.insert(device->paramValue(blindDeviceOutputOpenParamTypeId).toString(), device); + } else if (device->paramValue(blindDeviceOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(blindDeviceOutputOpenParamTypeId).toString(), device); } - if (device->paramValue(blindOutputTypeCloseParamTypeId) == GpioType::Relay) { - m_usedRelais.insert(device->paramValue(blindOutputCloseParamTypeId).toString(), device); - } else if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.insert(device->paramValue(blindOutputCloseParamTypeId).toString(), device); + if (device->paramValue(blindDeviceOutputTypeCloseParamTypeId) == GpioType::Relay) { + m_usedRelais.insert(device->paramValue(blindDeviceOutputCloseParamTypeId).toString(), device); + } else if (device->paramValue(blindDeviceOutputTypeOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(blindDeviceOutputCloseParamTypeId).toString(), device); } return DeviceManager::DeviceSetupStatusSuccess; @@ -95,16 +95,16 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) if (device->deviceClassId() == lightDeviceClassId) { - if (device->paramValue(lightOutputTypeParamTypeId) == GpioType::Relay) { - m_usedRelais.insert(device->paramValue(lightOutputParamTypeId).toString(), device); - } else if (device->paramValue(lightOutputParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.insert(device->paramValue(lightOutputParamTypeId).toString(), device); + if (device->paramValue(lightDeviceOutputTypeParamTypeId) == GpioType::Relay) { + m_usedRelais.insert(device->paramValue(lightDeviceOutputParamTypeId).toString(), device); + } else if (device->paramValue(lightDeviceOutputParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.insert(device->paramValue(lightDeviceOutputParamTypeId).toString(), device); } return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == dimmerSwitchDeviceClassId) { - m_usedDigitalInputs.insert(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString(), device); + m_usedDigitalInputs.insert(device->paramValue(dimmerSwitchDeviceInputNumberParamTypeId).toString(), device); DimmerSwitch* dimmerSwitch = new DimmerSwitch(this); connect(dimmerSwitch, &DimmerSwitch::pressed, this, &DevicePluginUniPi::onDimmerSwitchPressed); @@ -142,7 +142,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, QString("Relay %1").arg(circuit), circuit); ParamList parameters; - parameters.append(Param(relayOutputRelayNumberParamTypeId, circuit)); + parameters.append(Param(relayOutputDeviceNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); @@ -163,7 +163,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, QString("Digital output %1").arg(circuit), circuit); ParamList parameters; - parameters.append(Param(digitalOutputDigitalOutputNumberParamTypeId, circuit)); + parameters.append(Param(digitalOutputDeviceNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -183,7 +183,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, QString("Digital input %1").arg(circuit), circuit); ParamList parameters; - parameters.append(Param(digitalInputDigitalInputNumberParamTypeId, circuit)); + parameters.append(Param(digitalInputDeviceNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -203,7 +203,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, QString("Analog input %1").arg(circuit), circuit); ParamList parameters; - parameters.append(Param(analogInputAnalogInputNumberParamTypeId, circuit)); + parameters.append(Param(analogInputDeviceInputNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -223,7 +223,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, QString("Analog Output %1").arg(circuit), circuit); ParamList parameters; - parameters.append(Param(analogOutputAnalogOutputNumberParamTypeId, circuit)); + parameters.append(Param(analogOutputDeviceOutputNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -250,10 +250,10 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI DeviceDescriptor descriptor(deviceClassId, "Blind", QString("Opening relay %1 | Closing relay %2").arg(openingCircuit, closingCircuit)); ParamList parameters; - parameters.append(Param(blindOutputOpenParamTypeId, openingCircuit)); - parameters.append(Param(blindOutputCloseParamTypeId, closingCircuit)); - parameters.append(Param(blindOutputTypeOpenParamTypeId, GpioType::Relay)); - parameters.append(Param(blindOutputTypeCloseParamTypeId, GpioType::Relay)); + parameters.append(Param(blindDeviceOutputOpenParamTypeId, openingCircuit)); + parameters.append(Param(blindDeviceOutputCloseParamTypeId, closingCircuit)); + parameters.append(Param(blindDeviceOutputTypeOpenParamTypeId, GpioType::Relay)); + parameters.append(Param(blindDeviceOutputTypeCloseParamTypeId, GpioType::Relay)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); break; @@ -277,10 +277,10 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI DeviceDescriptor descriptor(deviceClassId, "Blind", QString("Opening output %1 | Closing output %2").arg(openingCircuit, closingCircuit)); ParamList parameters; - parameters.append(Param(blindOutputOpenParamTypeId, openingCircuit)); - parameters.append(Param(blindOutputCloseParamTypeId, closingCircuit)); - parameters.append(Param(blindOutputTypeOpenParamTypeId, GpioType::DigitalOutput)); - parameters.append(Param(blindOutputTypeCloseParamTypeId, GpioType::DigitalOutput)); + parameters.append(Param(blindDeviceOutputOpenParamTypeId, openingCircuit)); + parameters.append(Param(blindDeviceOutputCloseParamTypeId, closingCircuit)); + parameters.append(Param(blindDeviceOutputTypeOpenParamTypeId, GpioType::DigitalOutput)); + parameters.append(Param(blindDeviceOutputTypeCloseParamTypeId, GpioType::DigitalOutput)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); break; @@ -304,8 +304,8 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, "Light", QString("Relay %1").arg(circuit)); ParamList parameters; - parameters.append(Param(lightOutputParamTypeId, circuit)); - parameters.append(Param(lightOutputTypeParamTypeId, GpioType::Relay)); + parameters.append(Param(lightDeviceOutputParamTypeId, circuit)); + parameters.append(Param(lightDeviceOutputTypeParamTypeId, GpioType::Relay)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -319,8 +319,8 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, "Light", QString("Digital output %1").arg(circuit)); ParamList parameters; - parameters.append(Param(lightOutputParamTypeId, circuit)); - parameters.append(Param(lightOutputTypeParamTypeId, GpioType::DigitalOutput)); + parameters.append(Param(lightDeviceOutputParamTypeId, circuit)); + parameters.append(Param(lightDeviceOutputTypeParamTypeId, GpioType::DigitalOutput)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -340,7 +340,7 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI } DeviceDescriptor descriptor(deviceClassId, "Dimmer switch", QString("Digital Input %1").arg(circuit)); ParamList parameters; - parameters.append(Param(dimmerSwitchInputNumberParamTypeId, circuit)); + parameters.append(Param(dimmerSwitchDeviceInputNumberParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -369,7 +369,7 @@ void DevicePluginUniPi::connectToEvok() { if ((m_webSocket == NULL) || !m_webSocket) { - int port = configValue(uniPiPortParamTypeId).toInt(); + int port = configValue(uniPiPluginPortParamTypeId).toInt(); m_webSocket = new QWebSocket(); connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected); @@ -386,37 +386,37 @@ void DevicePluginUniPi::connectToEvok() void DevicePluginUniPi::deviceRemoved(Device *device) { if(device->deviceClassId() == relayOutputDeviceClassId) { - m_usedRelais.remove(device->paramValue(relayOutputRelayNumberParamTypeId).toString()); + m_usedRelais.remove(device->paramValue(relayOutputDeviceNumberParamTypeId).toString()); } else if(device->deviceClassId() == digitalOutputDeviceClassId) { - m_usedDigitalOutputs.remove(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()); + m_usedDigitalOutputs.remove(device->paramValue(digitalOutputDeviceNumberParamTypeId).toString()); } else if(device->deviceClassId() == digitalInputDeviceClassId) { - m_usedDigitalInputs.remove(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()); + m_usedDigitalInputs.remove(device->paramValue(digitalInputDeviceNumberParamTypeId).toString()); } else if (device->deviceClassId() == analogOutputDeviceClassId) { - m_usedAnalogOutputs.remove(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()); + m_usedAnalogOutputs.remove(device->paramValue(analogOutputDeviceOutputNumberParamTypeId).toString()); } else if (device->deviceClassId() == analogInputDeviceClassId) { - m_usedAnalogInputs.remove(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()); + m_usedAnalogInputs.remove(device->paramValue(analogInputDeviceInputNumberParamTypeId).toString()); } else if (device->deviceClassId() == blindDeviceClassId) { - if (device->paramValue(blindOutputTypeOpenParamTypeId) == GpioType::Relay) { - m_usedRelais.remove(device->paramValue(blindOutputOpenParamTypeId).toString()); - } else if (device->paramValue(blindOutputOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.remove(device->paramValue(blindOutputOpenParamTypeId).toString()); + if (device->paramValue(blindDeviceOutputTypeOpenParamTypeId) == GpioType::Relay) { + m_usedRelais.remove(device->paramValue(blindDeviceOutputOpenParamTypeId).toString()); + } else if (device->paramValue(blindDeviceOutputOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(blindDeviceOutputOpenParamTypeId).toString()); } - if (device->paramValue(blindOutputTypeCloseParamTypeId) == GpioType::Relay) { - m_usedRelais.remove(device->paramValue(blindOutputCloseParamTypeId).toString()); - } else if (device->paramValue(blindOutputOpenParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.remove(device->paramValue(blindOutputCloseParamTypeId).toString()); + if (device->paramValue(blindDeviceOutputTypeCloseParamTypeId) == GpioType::Relay) { + m_usedRelais.remove(device->paramValue(blindDeviceOutputCloseParamTypeId).toString()); + } else if (device->paramValue(blindDeviceOutputOpenParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(blindDeviceOutputCloseParamTypeId).toString()); } } else if (device->deviceClassId() == lightDeviceClassId) { - if (device->paramValue(lightOutputTypeParamTypeId) == GpioType::Relay) { - m_usedRelais.remove(device->paramValue(lightOutputParamTypeId).toString()); - } else if (device->paramValue(lightOutputParamTypeId) == GpioType::DigitalOutput) { - m_usedDigitalOutputs.remove(device->paramValue(lightOutputParamTypeId).toString()); + if (device->paramValue(lightDeviceOutputTypeParamTypeId) == GpioType::Relay) { + m_usedRelais.remove(device->paramValue(lightDeviceOutputParamTypeId).toString()); + } else if (device->paramValue(lightDeviceOutputParamTypeId) == GpioType::DigitalOutput) { + m_usedDigitalOutputs.remove(device->paramValue(lightDeviceOutputParamTypeId).toString()); } } else if (device->deviceClassId() == dimmerSwitchDeviceClassId) { - m_usedDigitalInputs.remove(device->paramValue(dimmerSwitchInputNumberParamTypeId).toString()); + m_usedDigitalInputs.remove(device->paramValue(dimmerSwitchDeviceInputNumberParamTypeId).toString()); DimmerSwitch *dimmerSwitch = m_dimmerSwitches.key(device); m_dimmerSwitches.remove(dimmerSwitch); dimmerSwitch->deleteLater(); @@ -436,8 +436,8 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == relayOutputDeviceClassId) { if (action.actionTypeId() == relayOutputPowerActionTypeId) { - QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString(); - int stateValue = action.param(relayOutputPowerActionParamTypeId).value().toInt(); + QString relayNumber = device->paramValue(relayOutputDeviceNumberParamTypeId).toString(); + int stateValue = action.param(relayOutputPowerActionPowerParamTypeId).value().toInt(); setOutput(relayNumber, stateValue); return DeviceManager::DeviceErrorNoError; @@ -447,8 +447,8 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == digitalOutputDeviceClassId) { if (action.actionTypeId() == digitalOutputPowerActionTypeId) { - QString digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString(); - bool stateValue = action.param(digitalOutputPowerActionParamTypeId).value().toBool(); + QString digitalOutputNumber = device->paramValue(digitalOutputDeviceNumberParamTypeId).toString(); + bool stateValue = action.param(digitalOutputPowerActionPowerParamTypeId).value().toBool(); setOutput(digitalOutputNumber, stateValue); return DeviceManager::DeviceErrorNoError; @@ -458,9 +458,9 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == analogOutputDeviceClassId) { - if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) { - QString analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString(); - double analogValue = action.param(analogOutputAnalogOutputValueActionParamTypeId).value().toDouble(); + if (action.actionTypeId() == analogOutputOutputValueActionTypeId) { + QString analogOutputNumber = device->paramValue(analogOutputDeviceOutputNumberParamTypeId).toString(); + double analogValue = action.param(analogOutputOutputValueActionOutputValueParamTypeId).value().toDouble(); QJsonObject json; json["cmd"] = "set"; @@ -478,8 +478,8 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons } if (device->deviceClassId() == blindDeviceClassId) { - QString circuitOpen = device->paramValue(blindOutputOpenParamTypeId).toString(); - QString circuitClose = device->paramValue(blindOutputCloseParamTypeId).toString(); + QString circuitOpen = device->paramValue(blindDeviceOutputOpenParamTypeId).toString(); + QString circuitClose = device->paramValue(blindDeviceOutputCloseParamTypeId).toString(); if (action.actionTypeId() == blindCloseActionTypeId) { @@ -504,8 +504,8 @@ DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, cons if (device->deviceClassId() == lightDeviceClassId) { - QString circuit = device->paramValue(lightOutputParamTypeId).toString(); - bool stateValue = action.param(lightPowerActionParamTypeId).value().toBool(); + QString circuit = device->paramValue(lightDeviceOutputParamTypeId).toString(); + bool stateValue = action.param(lightPowerActionPowerParamTypeId).value().toBool(); setOutput(circuit, stateValue); return DeviceManager::DeviceErrorNoError; @@ -570,7 +570,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) QString circuit = obj["circuit"].toString(); bool value = QVariant(obj["value"].toInt()).toBool(); - if (obj["relay_type"].toString() == "physical") { + if ((obj["relay_type"].toString() == "physical") || (obj["relay_type"].toString() == "")) { if (!m_relais.contains(circuit)) { //New Device detected @@ -581,7 +581,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (device->deviceClassId() == relayOutputDeviceClassId) { device->setStateValue(relayOutputPowerStateTypeId, value); } else if (device->deviceClassId() == blindDeviceClassId) { - if (circuit == device->paramValue(blindOutputOpenParamTypeId).toString()) { + if (circuit == device->paramValue(blindDeviceOutputOpenParamTypeId).toString()) { if (value) { if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { device->setStateValue(blindStatusStateTypeId, "opening"); @@ -600,7 +600,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } } - if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { + if (circuit == device->paramValue(blindDeviceOutputCloseParamTypeId).toString()) { if (value) { if (device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { device->setStateValue(blindStatusStateTypeId, "closing"); @@ -635,7 +635,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (device->deviceClassId() == digitalOutputDeviceClassId) { device->setStateValue(digitalOutputPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); } else if (device->deviceClassId() == blindDeviceClassId) { - if (circuit == device->paramValue(blindOutputOpenParamTypeId).toString()) { + if (circuit == device->paramValue(blindDeviceOutputOpenParamTypeId).toString()) { if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { device->setStateValue(blindStatusStateTypeId, "opening"); } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { @@ -645,7 +645,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) device->setStateValue(blindStatusStateTypeId, "stopped"); } } - if (circuit == device->paramValue(blindOutputCloseParamTypeId).toString()) { + if (circuit == device->paramValue(blindDeviceOutputCloseParamTypeId).toString()) { if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { device->setStateValue(blindStatusStateTypeId, "closing"); } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { @@ -674,7 +674,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) bool value = QVariant(obj["value"].toInt()).toBool(); Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == digitalInputDeviceClassId) { - device->setStateValue(digitalInputDigitalInputStatusStateTypeId, value); + device->setStateValue(digitalInputInputStatusStateTypeId, value); } else if (device->deviceClassId() == dimmerSwitchDeviceClassId) { device->setStateValue(dimmerSwitchStatusStateTypeId, value); DimmerSwitch *dimmerSwitch = m_dimmerSwitches.key(device); @@ -705,7 +705,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == analogOutputDeviceClassId) { - device->setStateValue(analogOutputAnalogOutputValueStateTypeId, value); + device->setStateValue(analogOutputOutputValueStateTypeId, value); } } } @@ -723,7 +723,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == analogInputDeviceClassId) { - device->setStateValue(analogInputAnalogInputValueStateTypeId, value); + device->setStateValue(analogInputInputValueStateTypeId, value); } } } diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index bcc4cc72..fce53c9f 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -28,7 +28,7 @@ "paramTypes": [ { "id": "7a09e3ad-452c-4bf4-a00c-f8114ed9a7a1", - "name": "relayNumber", + "name": "number", "displayName": "Relay number", "type": "QString" } @@ -57,7 +57,7 @@ "paramTypes": [ { "id": "9c84d9b8-fdc7-41c1-9559-08f061ffc7a6", - "name": "digitalInputNumber", + "name": "number", "displayName": "Input number", "type": "QString" } @@ -65,7 +65,7 @@ "stateTypes": [ { "id": "fa4f2764-b7ff-45e7-993b-b6af1840fd3d", - "name": "digitalInputStatus", + "name": "inputStatus", "displayName": "Digital input", "displayNameEvent": "Digital input changed", "type": "bool", @@ -137,7 +137,7 @@ "paramTypes": [ { "id": "c01d5bde-de5d-42c5-b462-79745827875a", - "name": "digitalOutputNumber", + "name": "number", "displayName": "Output number", "type": "QString" } @@ -166,7 +166,7 @@ "paramTypes": [ { "id": "46e606cc-67ee-4891-bc39-8fb0565c87da", - "name": "analogOutputNumber", + "name": "outputNumber", "displayName": "Analog output number", "type": "QString" } @@ -174,7 +174,7 @@ "stateTypes": [ { "id": "6d825eb8-6d2a-4ac3-9125-9df8173116c9", - "name": "analogOutputValue", + "name": "outputValue", "displayName": "Analog output", "displayNameEvent": "Analog output changed", "displayNameAction": "Set analog output", @@ -198,7 +198,7 @@ "paramTypes": [ { "id": "cc6eb664-9fd2-457d-9d0d-0eb9703db4a2", - "name": "analogInputNumber", + "name": "inputNumber", "displayName": "Analog input number", "type": "QString" } @@ -206,7 +206,7 @@ "stateTypes": [ { "id": "2296f575-cc53-48ef-9086-6a412abfdde5", - "name": "analogInputValue", + "name": "inputValue", "displayName": "Analog input", "displayNameEvent": "Analog input changed", "type": "double", From c794a99d5e87ee4fb73a45e58d73f23e6cf55c2d Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Thu, 6 Dec 2018 19:02:15 +0100 Subject: [PATCH 28/35] added 1-Wire temperature sensor --- unipi/devicepluginunipi.cpp | 50 ++++++++++++++++++++++++++++++++++-- unipi/devicepluginunipi.h | 4 +-- unipi/devicepluginunipi.json | 39 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index f5236559..ff8a6b59 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -115,6 +115,11 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) return DeviceManager::DeviceSetupStatusSuccess; } + if (device->deviceClassId() == temperatureSensorDeviceClassId) { + + m_usedTemperatureSensors.insert(device->paramValue(temperatureSensorDeviceAddressParamTypeId).toString(), device); + return DeviceManager::DeviceSetupStatusSuccess; + } return DeviceManager::DeviceSetupStatusFailure; } @@ -347,6 +352,27 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI emit devicesDiscovered(deviceClassId, deviceDescriptors); return DeviceManager::DeviceErrorAsync; } + + if (deviceClassId == temperatureSensorDeviceClassId) { + // Create the list of available temperature sensor + QList deviceDescriptors; + for (int i = 0; i < m_temperatureSensors.count(); i++) { + const QString circuit = m_temperatureSensors.at(i); + + // Offer only temperature sensors which aren't in use already + if (m_usedTemperatureSensors.contains(circuit)){ + continue; + } + DeviceDescriptor descriptor(deviceClassId, QString("Temperature Sensor %1").arg(circuit), circuit); + ParamList parameters; + parameters.append(Param(temperatureSensorDeviceAddressParamTypeId, circuit)); + parameters.append(Param(temperatureSensorDeviceTypeParamTypeId, circuit)); + descriptor.setParams(parameters); + deviceDescriptors.append(descriptor); + } + emit devicesDiscovered(deviceClassId, deviceDescriptors); + return DeviceManager::DeviceErrorAsync; + } } return DeviceManager::DeviceErrorDeviceClassNotFound; } @@ -420,8 +446,11 @@ void DevicePluginUniPi::deviceRemoved(Device *device) DimmerSwitch *dimmerSwitch = m_dimmerSwitches.key(device); m_dimmerSwitches.remove(dimmerSwitch); dimmerSwitch->deleteLater(); + } else if (device->deviceClassId() == temperatureSensorDeviceClassId) { + m_usedTemperatureSensors.remove(device->paramValue(temperatureSensorDeviceAddressParamTypeId).toString()); } + if (myDevices().isEmpty()) { m_webSocket->close(); m_webSocket->deleteLater(); @@ -702,7 +731,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else { if (m_usedAnalogOutputs.contains(obj["circuit"].toString())) { double value = QVariant(obj["value"]).toDouble(); - Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); + Device *device = m_usedAnalogOutputs.value(obj["circuit"].toString()); if (device->deviceClassId() == analogOutputDeviceClassId) { device->setStateValue(analogOutputOutputValueStateTypeId, value); @@ -720,7 +749,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else { if (m_usedAnalogInputs.contains(obj["circuit"].toString())) { double value = QVariant(obj["value"]).toDouble(); - Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); + Device *device = m_usedAnalogInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == analogInputDeviceClassId) { device->setStateValue(analogInputInputValueStateTypeId, value); @@ -728,6 +757,23 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } } + + if (obj["dev"] == "temp") { + qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + if (!m_temperatureSensors.contains(obj["circuit"].toString())){ + //New temperature sensor detected + m_temperatureSensors.append(obj["circuit"].toString()); + } else { + if (m_usedTemperatureSensors.contains(obj["circuit"].toString())) { + double value = QVariant(obj["value"]).toDouble(); + Device *device = m_usedTemperatureSensors.value(obj["circuit"].toString()); + + if (device->deviceClassId() == temperatureSensorDeviceClassId) { + device->setStateValue(temperatureSensorTemperatureStateTypeId, value); + } + } + } + } } } diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 6c47d445..3161d806 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -64,7 +64,7 @@ private: QHash m_usedDigitalInputs; QHash m_usedAnalogOutputs; QHash m_usedAnalogInputs; - QHash m_usedSensors; + QHash m_usedTemperatureSensors; QHash m_usedLeds; QHash m_dimmerSwitches; @@ -74,7 +74,7 @@ private: QList m_digitalInputs; QList m_analogOutputs; QList m_analogInputs; - QList m_sensors; + QList m_temperatureSensors; QList m_leds; QWebSocket *m_webSocket = nullptr; diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index fce53c9f..85a09309 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -319,6 +319,45 @@ "writable": true } ] + }, + { + "id": "4f0b3cfd-603a-47ec-9719-2db7eeae1143", + "name": "temperatureSensor", + "displayName": "Temperature sensor", + "deviceIcon": "Temperature", + "createMethods": ["discovery"], + "interfaces": ["temperaturesensor", "connectable"], + "paramTypes": [ + { + "id": "9dd8f7e9-a24c-4a67-82cd-1e25e911cf5d", + "name": "type", + "displayName": "Type", + "type": "QString" + }, + { + "id": "4684cee2-674e-4aa4-823d-096bd49f18ee", + "name": "address", + "displayName": "Address", + "type": "QString" + } + ], + "stateTypes":[ + { + "id": "7641d379-b832-40fc-a29b-7d32bba79236", + "name": "connected", + "displayName": "Connected", + "type": "bool", + "defaultValue": false + }, + { + "id": "7fd10e94-f11d-4084-8d03-414fd5592b6a", + "displayName": "Temperature", + "displayNameEvent": "Temperature changed", + "name": "temperature", + "type": "double", + "defaultValue": 0.00 + } + ] } ] } From 15863c509333af13af1423f2a54a40a2c689ecc3 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Thu, 6 Dec 2018 19:11:49 +0100 Subject: [PATCH 29/35] unipi fixed json for temp sensor --- unipi/devicepluginunipi.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 85a09309..18502ce8 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -324,7 +324,7 @@ "id": "4f0b3cfd-603a-47ec-9719-2db7eeae1143", "name": "temperatureSensor", "displayName": "Temperature sensor", - "deviceIcon": "Temperature", + "deviceIcon": "Thermometer", "createMethods": ["discovery"], "interfaces": ["temperaturesensor", "connectable"], "paramTypes": [ @@ -346,6 +346,7 @@ "id": "7641d379-b832-40fc-a29b-7d32bba79236", "name": "connected", "displayName": "Connected", + "displayNameEvent": "Connection changed", "type": "bool", "defaultValue": false }, From bc1b046991fced952bdadb02faa96993689eef95 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Thu, 6 Dec 2018 20:06:21 +0100 Subject: [PATCH 30/35] unipi fixed parsing of json objects --- unipi/devicepluginunipi.cpp | 48 +++++++++++++++++------------------- unipi/devicepluginunipi.h | 1 + unipi/devicepluginunipi.json | 6 ----- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index ff8a6b59..e723b022 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -61,12 +61,14 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) if (device->deviceClassId() == digitalInputDeviceClassId) { m_usedDigitalInputs.insert(device->paramValue(digitalInputDeviceNumberParamTypeId).toString(), device); + requestAllData(); return DeviceManager::DeviceSetupStatusSuccess; } if (device->deviceClassId() == analogInputDeviceClassId) { m_usedAnalogInputs.insert(device->paramValue(analogInputDeviceInputNumberParamTypeId).toString(), device); + requestAllData(); return DeviceManager::DeviceSetupStatusSuccess; } @@ -118,8 +120,10 @@ DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) if (device->deviceClassId() == temperatureSensorDeviceClassId) { m_usedTemperatureSensors.insert(device->paramValue(temperatureSensorDeviceAddressParamTypeId).toString(), device); + requestAllData(); return DeviceManager::DeviceSetupStatusSuccess; } + return DeviceManager::DeviceSetupStatusFailure; } @@ -363,10 +367,9 @@ DeviceManager::DeviceError DevicePluginUniPi::discoverDevices(const DeviceClassI if (m_usedTemperatureSensors.contains(circuit)){ continue; } - DeviceDescriptor descriptor(deviceClassId, QString("Temperature Sensor %1").arg(circuit), circuit); + DeviceDescriptor descriptor(deviceClassId, "Temperature Sensor", circuit); ParamList parameters; parameters.append(Param(temperatureSensorDeviceAddressParamTypeId, circuit)); - parameters.append(Param(temperatureSensorDeviceTypeParamTypeId, circuit)); descriptor.setParams(parameters); deviceDescriptors.append(descriptor); } @@ -551,12 +554,7 @@ void DevicePluginUniPi::onWebSocketConnected() connect(m_webSocket, &QWebSocket::textMessageReceived, this, &DevicePluginUniPi::onWebSocketTextMessageReceived); - QJsonObject json; - json["cmd"] = "all"; - - QJsonDocument doc(json); - QByteArray bytes = doc.toJson(); - m_webSocket->sendTextMessage(bytes); + requestAllData(); } void DevicePluginUniPi::onWebSocketDisconnected() @@ -565,19 +563,27 @@ void DevicePluginUniPi::onWebSocketDisconnected() } +void DevicePluginUniPi::requestAllData() +{ + QJsonObject json; + json["cmd"] = "all"; + + QJsonDocument doc(json); + QByteArray bytes = doc.toJson(); + m_webSocket->sendTextMessage(bytes); +} void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) { QJsonArray array; - QJsonObject obj; QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8()); // check validity of the document if(!doc.isNull()) { if(doc.isObject()) { - obj = doc.object(); + array.append(doc.object()); } else if (doc.isArray()){ - array = doc.array(); + array = doc.array();; }else { qCDebug(dcUniPi()) << "Document is not an object nor an array"; } @@ -586,13 +592,9 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } for (int levelIndex = 0; levelIndex < array.size(); ++levelIndex) { + QJsonObject obj; obj = array[levelIndex].toObject(); - if (obj["cmd"] == "all") { - //read model number - qCDebug(dcUniPi()) << message; - } - if (obj["dev"] == "relay") { qCDebug(dcUniPi()) << "Relay:" << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toString() ; @@ -713,15 +715,6 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } - if (obj["dev"] == "led") { //TODO can't discover leds without toggling it from another client - qCDebug(dcUniPi()) << "Led:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt(); - - if (!m_leds.contains(obj["circuit"].toString())){ - //New led detected - m_leds.append(obj["circuit"].toString()); - } - } - if (obj["dev"] == "ao") { qCDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); @@ -759,17 +752,20 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "temp") { - qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"].toString() << "Address:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); if (!m_temperatureSensors.contains(obj["circuit"].toString())){ //New temperature sensor detected m_temperatureSensors.append(obj["circuit"].toString()); } else { + //Updating states of already added temperature sensor if (m_usedTemperatureSensors.contains(obj["circuit"].toString())) { double value = QVariant(obj["value"]).toDouble(); + bool connected = QVariant(obj["lost"]).toBool(); Device *device = m_usedTemperatureSensors.value(obj["circuit"].toString()); if (device->deviceClassId() == temperatureSensorDeviceClassId) { device->setStateValue(temperatureSensorTemperatureStateTypeId, value); + device->setStateValue(temperatureSensorConnectedStateTypeId, connected); } } } diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 3161d806..1ff4e4a9 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -81,6 +81,7 @@ private: PluginTimer *m_refreshTimer = nullptr; + void requestAllData(); void setOutput(const QString &circuit, bool value); void connectToEvok(); diff --git a/unipi/devicepluginunipi.json b/unipi/devicepluginunipi.json index 18502ce8..b6db4aec 100644 --- a/unipi/devicepluginunipi.json +++ b/unipi/devicepluginunipi.json @@ -328,12 +328,6 @@ "createMethods": ["discovery"], "interfaces": ["temperaturesensor", "connectable"], "paramTypes": [ - { - "id": "9dd8f7e9-a24c-4a67-82cd-1e25e911cf5d", - "name": "type", - "displayName": "Type", - "type": "QString" - }, { "id": "4684cee2-674e-4aa4-823d-096bd49f18ee", "name": "address", From 7fb4168716e051c31d36b632b4247da1c4c59396 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Thu, 6 Dec 2018 20:22:25 +0100 Subject: [PATCH 31/35] unipi fixed device initialisation --- unipi/devicepluginunipi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index e723b022..2745cb84 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -408,6 +408,8 @@ void DevicePluginUniPi::connectToEvok() url.setPort(port); qCDebug(dcUniPi()) << "Conneting to:" << url.toString(); m_webSocket->open(url); + } else { + requestAllData(); } } @@ -752,7 +754,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "temp") { - qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"].toString() << "Address:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble(); + qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"].toString() << "Address:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble() << "Connected:" << ~(QVariant(obj["lost"]).toBool()); if (!m_temperatureSensors.contains(obj["circuit"].toString())){ //New temperature sensor detected m_temperatureSensors.append(obj["circuit"].toString()); @@ -760,7 +762,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) //Updating states of already added temperature sensor if (m_usedTemperatureSensors.contains(obj["circuit"].toString())) { double value = QVariant(obj["value"]).toDouble(); - bool connected = QVariant(obj["lost"]).toBool(); + bool connected = ~(QVariant(obj["lost"]).toBool()); Device *device = m_usedTemperatureSensors.value(obj["circuit"].toString()); if (device->deviceClassId() == temperatureSensorDeviceClassId) { From 553884268f43895c96c192d9348d90a706ae1173 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Fri, 7 Dec 2018 16:27:53 +0100 Subject: [PATCH 32/35] unipi minor bug fix --- unipi/devicepluginunipi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 2745cb84..8381ed5a 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -754,7 +754,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } if (obj["dev"] == "temp") { - qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"].toString() << "Address:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble() << "Connected:" << ~(QVariant(obj["lost"]).toBool()); + qCDebug(dcUniPi()) << "Temperature Sensor:" << obj["typ"].toString() << "Address:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble() << "Connected:" << !(QVariant(obj["lost"]).toBool()); if (!m_temperatureSensors.contains(obj["circuit"].toString())){ //New temperature sensor detected m_temperatureSensors.append(obj["circuit"].toString()); @@ -762,7 +762,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) //Updating states of already added temperature sensor if (m_usedTemperatureSensors.contains(obj["circuit"].toString())) { double value = QVariant(obj["value"]).toDouble(); - bool connected = ~(QVariant(obj["lost"]).toBool()); + bool connected = !(QVariant(obj["lost"]).toBool()); Device *device = m_usedTemperatureSensors.value(obj["circuit"].toString()); if (device->deviceClassId() == temperatureSensorDeviceClassId) { From 858dda9c88ce847f638e5421f74b8f3dcae2d628 Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Fri, 7 Dec 2018 16:55:17 +0100 Subject: [PATCH 33/35] moved unipi to maker packages --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index eb2fb6ea..8b33459e 100644 --- a/debian/control +++ b/debian/control @@ -735,7 +735,6 @@ Depends: nymea-plugin-awattar, nymea-plugin-elgato, nymea-plugin-senic, nymea-plugin-keba, - nymea-plugin-unipi, Replaces: guh-plugins Description: Plugins for nymea IoT server - the default plugin collection The nymea daemon is a plugin based IoT (Internet of Things) server. The @@ -759,6 +758,7 @@ Depends: nymea-plugin-commandlauncher, nymea-plugin-gpio, nymea-plugin-mqttclient, nymea-plugin-remotessh, + nymea-plugin-unipi, Replaces: guh-plugins-maker Description: Plugins for nymea IoT server - Meta package for makers, tinkers and hackers The nymea daemon is a plugin based IoT (Internet of Things) server. The From 2a3d924a68c457ed0ded43a407fcb9b4889a698f Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Fri, 7 Dec 2018 17:23:04 +0100 Subject: [PATCH 34/35] unipi improved json check --- unipi/devicepluginunipi.cpp | 32 ++++++++++++++++++++------------ unipi/devicepluginunipi.h | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 8381ed5a..1e771c5b 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -575,10 +575,17 @@ void DevicePluginUniPi::requestAllData() m_webSocket->sendTextMessage(bytes); } -void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) +void DevicePluginUniPi::onWebSocketTextMessageReceived(const QString &message) { QJsonArray array; - QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8()); + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error); + + + if(error.error != QJsonParseError::NoError) { + qCWarning(dcUniPi) << "failed to parse data" << message << ":" << error.errorString(); + return; + } // check validity of the document if(!doc.isNull()) { @@ -591,6 +598,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } } else { qCDebug(dcUniPi()) << "Invalid JSON"; + return; } for (int levelIndex = 0; levelIndex < array.size(); ++levelIndex) { @@ -601,7 +609,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) qCDebug(dcUniPi()) << "Relay:" << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt() << "Relay Type:" << obj["relay_type"].toString() ; QString circuit = obj["circuit"].toString(); - bool value = QVariant(obj["value"].toInt()).toBool(); + bool value = obj["value"].toBool(); if ((obj["relay_type"].toString() == "physical") || (obj["relay_type"].toString() == "")) { @@ -666,7 +674,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) if (m_usedDigitalOutputs.contains(obj["circuit"].toString())) { Device *device = m_usedDigitalOutputs.value(obj["circuit"].toString()); if (device->deviceClassId() == digitalOutputDeviceClassId) { - device->setStateValue(digitalOutputPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); + device->setStateValue(digitalOutputPowerStateTypeId, obj["value"].toBool()); } else if (device->deviceClassId() == blindDeviceClassId) { if (circuit == device->paramValue(blindDeviceOutputOpenParamTypeId).toString()) { if (value && device->stateValue(blindStatusStateTypeId).toString().contains("stopped")) { @@ -674,7 +682,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("opening")) { device->setStateValue(blindStatusStateTypeId, "stopped"); } else { - qWarning(dcUniPi()) << "blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + qCWarning(dcUniPi()) << "blind" << device << "Output open:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); device->setStateValue(blindStatusStateTypeId, "stopped"); } } @@ -684,12 +692,12 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else if (!value && device->stateValue(blindStatusStateTypeId).toString().contains("closing")) { device->setStateValue(blindStatusStateTypeId, "stopped"); } else { - qWarning(dcUniPi()) << "blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); + qCWarning(dcUniPi()) << "blind" << device << "Output close:" << value << "Status: " << device->stateValue(blindStatusStateTypeId).toString(); device->setStateValue(blindStatusStateTypeId, "stopped"); } } } else if (device->deviceClassId() == lightDeviceClassId) { - device->setStateValue(lightPowerStateTypeId, QVariant(obj["value"].toInt()).toBool()); + device->setStateValue(lightPowerStateTypeId, obj["value"].toBool()); } } } @@ -704,7 +712,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) m_digitalInputs.append(obj["circuit"].toString()); } else { if (m_usedDigitalInputs.contains(obj["circuit"].toString())) { - bool value = QVariant(obj["value"].toInt()).toBool(); + bool value = obj["value"].toBool(); Device *device = m_usedDigitalInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == digitalInputDeviceClassId) { device->setStateValue(digitalInputInputStatusStateTypeId, value); @@ -725,7 +733,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) m_analogOutputs.append(obj["circuit"].toString()); } else { if (m_usedAnalogOutputs.contains(obj["circuit"].toString())) { - double value = QVariant(obj["value"]).toDouble(); + double value = obj["value"].toDouble(); Device *device = m_usedAnalogOutputs.value(obj["circuit"].toString()); if (device->deviceClassId() == analogOutputDeviceClassId) { @@ -743,7 +751,7 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) m_analogInputs.append(obj["circuit"].toString()); } else { if (m_usedAnalogInputs.contains(obj["circuit"].toString())) { - double value = QVariant(obj["value"]).toDouble(); + double value = obj["value"].toDouble(); Device *device = m_usedAnalogInputs.value(obj["circuit"].toString()); if (device->deviceClassId() == analogInputDeviceClassId) { @@ -761,8 +769,8 @@ void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message) } else { //Updating states of already added temperature sensor if (m_usedTemperatureSensors.contains(obj["circuit"].toString())) { - double value = QVariant(obj["value"]).toDouble(); - bool connected = !(QVariant(obj["lost"]).toBool()); + double value = obj["value"].toDouble(); + bool connected = !(obj["lost"]).toBool(); Device *device = m_usedTemperatureSensors.value(obj["circuit"].toString()); if (device->deviceClassId() == temperatureSensorDeviceClassId) { diff --git a/unipi/devicepluginunipi.h b/unipi/devicepluginunipi.h index 1ff4e4a9..a9ee8982 100644 --- a/unipi/devicepluginunipi.h +++ b/unipi/devicepluginunipi.h @@ -88,7 +88,7 @@ private: private slots: void onWebSocketConnected(); void onWebSocketDisconnected(); - void onWebSocketTextMessageReceived(QString message); + void onWebSocketTextMessageReceived(const QString &message); void onRefreshTimer(); void onDimmerSwitchPressed(); From 4856be758037693b1c1429c932c9d9e5bab14b5f Mon Sep 17 00:00:00 2001 From: Bernhard Trinnes Date: Tue, 11 Dec 2018 15:08:37 +0100 Subject: [PATCH 35/35] unipi moved timer init to first device setup --- unipi/devicepluginunipi.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/unipi/devicepluginunipi.cpp b/unipi/devicepluginunipi.cpp index 1e771c5b..05fe779a 100644 --- a/unipi/devicepluginunipi.cpp +++ b/unipi/devicepluginunipi.cpp @@ -37,15 +37,17 @@ DevicePluginUniPi::~DevicePluginUniPi() void DevicePluginUniPi::init() { - connectToEvok(); - - m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); - connect(m_refreshTimer, &PluginTimer::timeout, this, &DevicePluginUniPi::onRefreshTimer); - } DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device) { + connectToEvok(); + + if(myDevices().empty()) { + m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); + connect(m_refreshTimer, &PluginTimer::timeout, this, &DevicePluginUniPi::onRefreshTimer); + } + if (device->deviceClassId() == relayOutputDeviceClassId) { m_usedRelais.insert(device->paramValue(relayOutputDeviceNumberParamTypeId).toString(), device);