diff --git a/debian/control b/debian/control index 37287fe..fb5ca24 100644 --- a/debian/control +++ b/debian/control @@ -260,6 +260,21 @@ Description: nymea.io plugin for genericelements This package will install the nymea.io plugin for genericelements +Package: nymea-plugin-genericinterfaces +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, + nymea-plugins-translations, +Description: nymea.io plugin for generic interfaces + 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 generic interfaces + + Package: nymea-plugin-gpio Architecture: any Depends: ${shlibs:Depends}, @@ -795,6 +810,7 @@ Depends: nymea-plugin-boblight, nymea-plugin-tcpcommander, nymea-plugin-httpcommander, nymea-plugin-genericelements, + nymea-plugin-genericinterfaces, nymea-plugin-avahimonitor, nymea-plugin-anel, nymea-plugin-gpio, diff --git a/debian/nymea-plugin-genericinterfaces.install.in b/debian/nymea-plugin-genericinterfaces.install.in new file mode 100644 index 0000000..a5e9bc1 --- /dev/null +++ b/debian/nymea-plugin-genericinterfaces.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_deviceplugingenericinterfaces.so diff --git a/genericinterfaces/deviceplugingenericinterfaces.cpp b/genericinterfaces/deviceplugingenericinterfaces.cpp new file mode 100644 index 0000000..b3535a9 --- /dev/null +++ b/genericinterfaces/deviceplugingenericinterfaces.cpp @@ -0,0 +1,176 @@ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Bernhard Trinnes . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! + \page genericinterfaces.html + \title Generic interfaces + \brief Common interfaces to test the rule engine. + + \ingroup plugins + \ingroup nymea-tests + + The generic interfaces plugin allows you create virtual buttons, which can be connected with a rule. This gives you + the possibility to execute multiple \l{Action}{Actions} with one signal. Without a rule this generic interfaces are + useless. + + \chapter Plugin properties + Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses} + and \l{Vendor}{Vendors} of this \l{DevicePlugin}. + + For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}. + + \quotefile plugins/deviceplugins/genericinterfaces/deviceplugingenericinterfaces.json +*/ + + +#include "deviceplugingenericinterfaces.h" +#include "devices/devicemanager.h" +#include "plugininfo.h" + +#include + +DevicePluginGenericInterfaces::DevicePluginGenericInterfaces() +{ +} + +Device::DeviceSetupStatus DevicePluginGenericInterfaces::setupDevice(Device *device) +{ + if (device->deviceClassId() == awningDeviceClassId) { + return Device::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == blindDeviceClassId) { + return Device::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == shutterDeviceClassId) { + return Device::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == socketDeviceClassId) { + return Device::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == lightDeviceClassId) { + return Device::DeviceSetupStatusSuccess; + } + + if (device->deviceClassId() == heatingDeviceClassId) { + return Device::DeviceSetupStatusSuccess; + } + return Device::DeviceSetupStatusFailure; +} + +Device::DeviceError DevicePluginGenericInterfaces::executeAction(Device *device, const Action &action) +{ + if (device->deviceClassId() == awningDeviceClassId) { + if (action.actionTypeId() == awningOpenActionTypeId) { + device->setStateValue(awningStatusStateTypeId, "Opening"); + device->setStateValue(awningClosingOutputStateTypeId, false); + device->setStateValue(awningOpeningOutputStateTypeId, true); + return Device::DeviceErrorNoError; + } + if (action.actionTypeId() == awningStopActionTypeId) { + device->setStateValue(awningStatusStateTypeId, "Stopped"); + device->setStateValue(awningOpeningOutputStateTypeId, false); + device->setStateValue(awningClosingOutputStateTypeId, false); + return Device::DeviceErrorNoError; + } + if (action.actionTypeId() == awningCloseActionTypeId) { + device->setStateValue(awningStatusStateTypeId, "Closing"); + device->setStateValue(awningOpeningOutputStateTypeId, false); + device->setStateValue(awningClosingOutputStateTypeId, true); + return Device::DeviceErrorNoError; + } + return Device::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == blindDeviceClassId ) { + if (action.actionTypeId() == blindOpenActionTypeId) { + device->setStateValue(blindStatusStateTypeId, "Opening"); + device->setStateValue(blindClosingOutputStateTypeId, false); + device->setStateValue(blindOpeningOutputStateTypeId, true); + return Device::DeviceErrorNoError; + } + if (action.actionTypeId() == blindStopActionTypeId) { + device->setStateValue(blindStatusStateTypeId, "Stopped"); + device->setStateValue(blindOpeningOutputStateTypeId, false); + device->setStateValue(blindClosingOutputStateTypeId, false); + return Device::DeviceErrorNoError; + } + if (action.actionTypeId() == blindCloseActionTypeId) { + device->setStateValue(blindStatusStateTypeId, "Closing"); + device->setStateValue(blindOpeningOutputStateTypeId, false); + device->setStateValue(blindClosingOutputStateTypeId, true); + return Device::DeviceErrorNoError; + } + return Device::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == shutterDeviceClassId) { + if (action.actionTypeId() == shutterOpenActionTypeId) { + device->setStateValue(shutterStatusStateTypeId, "Opening"); + device->setStateValue(shutterClosingOutputStateTypeId, false); + device->setStateValue(shutterOpeningOutputStateTypeId, true); + return Device::DeviceErrorNoError; + } + if (action.actionTypeId() == shutterStopActionTypeId) { + device->setStateValue(shutterStatusStateTypeId, "Stopped"); + device->setStateValue(shutterOpeningOutputStateTypeId, false); + device->setStateValue(shutterClosingOutputStateTypeId, false); + return Device::DeviceErrorNoError; + } + if (action.actionTypeId() == shutterCloseActionTypeId) { + device->setStateValue(shutterStatusStateTypeId, "Closing"); + device->setStateValue(shutterOpeningOutputStateTypeId, false); + device->setStateValue(shutterClosingOutputStateTypeId, true); + return Device::DeviceErrorNoError; + } + return Device::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == socketDeviceClassId) { + if (action.actionTypeId() == socketPowerActionTypeId) { + device->setStateValue(socketPowerStateTypeId, action.param(socketPowerActionPowerParamTypeId).value()); + return Device::DeviceErrorNoError; + } + return Device::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == lightDeviceClassId) { + if (action.actionTypeId() == lightPowerActionTypeId) { + device->setStateValue(lightPowerStateTypeId, action.param(lightPowerActionPowerParamTypeId).value()); + return Device::DeviceErrorNoError; + } + return Device::DeviceErrorActionTypeNotFound; + } + + if (device->deviceClassId() == heatingDeviceClassId) { + if (action.actionTypeId() == heatingPowerActionTypeId) { + device->setStateValue(heatingPowerStateTypeId, action.param(heatingPowerActionPowerParamTypeId).value()); + return Device::DeviceErrorNoError; + } + return Device::DeviceErrorActionTypeNotFound; + } + return Device::DeviceErrorDeviceClassNotFound; +} diff --git a/genericinterfaces/deviceplugingenericinterfaces.h b/genericinterfaces/deviceplugingenericinterfaces.h new file mode 100644 index 0000000..d63d500 --- /dev/null +++ b/genericinterfaces/deviceplugingenericinterfaces.h @@ -0,0 +1,44 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2019 Bernhard Trinnes . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef DEVICEPLUGINGENERICINTERFACES_H +#define DEVICEPLUGINGENERICINTERFACES_H + +#include "devices/deviceplugin.h" + +class DevicePluginGenericInterfaces : public DevicePlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "deviceplugingenericinterfaces.json") + Q_INTERFACES(DevicePlugin) + +public: + explicit DevicePluginGenericInterfaces(); + Device::DeviceSetupStatus setupDevice(Device *device) override; + +public slots: + Device::DeviceError executeAction(Device *device, const Action &action) override; + +}; + +#endif // DEVICEPLUGINGENERICINTERFACES_H diff --git a/genericinterfaces/deviceplugingenericinterfaces.json b/genericinterfaces/deviceplugingenericinterfaces.json new file mode 100644 index 0000000..98bf5f7 --- /dev/null +++ b/genericinterfaces/deviceplugingenericinterfaces.json @@ -0,0 +1,236 @@ +{ + "name": "GenericInterfaces", + "displayName": "Generic Interfaces", + "id": "b3188696-2585-4806-bf98-30ab576ce5c8", + "vendors": [ + { + "name": "nymea", + "displayName": "nymea", + "id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6", + "deviceClasses": [ + { + "id": "9e69585f-90ba-44e4-ad90-5b4bffbe345a", + "name": "awning", + "displayName": "Awning interface", + "createMethods": ["user"], + "interfaces": ["awning"], + "stateTypes": [ + { + "id": "4bb951a4-ea23-4cf0-9269-41d2c4eaf5a4", + "name": "openingOutput", + "displayName": "Opening output", + "displayNameEvent": "Opening output changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "59bfd575-709f-4e43-9726-de26e6d4ca8b", + "name": "closingOutput", + "displayName": "Closing output", + "displayNameEvent": "Closing output changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "ff6f2565-2a2e-4d34-b10f-d3f73b676399", + "name": "status", + "displayName": "Status", + "displayNameEvent": "Status changed", + "type": "QString", + "possibleValues": [ + "Opening", + "Stopped", + "Closing" + ], + "defaultValue": "Stopped" + } + ], + "actionTypes": [ + { + "id": "979e9c51-5a93-4635-85e3-01874306b229", + "name": "open", + "displayName": "Open" + }, + { + "id": "555cafe4-bd12-42c6-bab1-8cd59af6468e", + "name": "stop", + "displayName": "Stop" + }, + { + "id": "53b5ba77-9a34-4cd6-ad24-fb01fc465f98", + "name": "close", + "displayName": "Close" + } + ] + }, + { + "id": "17ee3657-6ad8-4ae2-8959-3cf66cec8d13", + "name": "blind", + "displayName": "Blind interface", + "createMethods": ["user"], + "interfaces": ["blind"], + "stateTypes": [ + { + "id": "b2dbf25c-27e5-4f7e-a57d-2ef6d087fa2b", + "name": "openingOutput", + "displayName": "Opening output", + "displayNameEvent": "Opening output changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "9b673430-572d-4a9c-85d3-dafadbe541cd", + "name": "closingOutput", + "displayName": "Closing output", + "displayNameEvent": "Closing output changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "5fdec1e0-51f6-48b9-b743-ba572504b2c1", + "name": "status", + "displayName": "Status", + "displayNameEvent": "Status changed", + "type": "QString", + "possibleValues": [ + "Opening", + "Stopped", + "Closing" + ], + "defaultValue": "Stopped" + } + ], + "actionTypes": [ + { + "id": "120dc265-dbbb-4f19-9d31-c372c23479c0", + "name": "open", + "displayName": "Open" + }, + { + "id": "1a924c9a-5dcb-4b1c-8fd6-ab101098e007", + "name": "stop", + "displayName": "Stop" + }, + { + "id": "86e9cf21-7487-47c4-b4be-4a940d7235fb", + "name": "close", + "displayName": "Close" + } + ] + }, + { + "id": "7917c2e7-d7d2-4c47-a38d-41f7dd7693d9", + "name": "shutter", + "displayName": "Shutter interface", + "createMethods": ["user"], + "interfaces": ["shutter"], + "stateTypes": [ + { + "id": "cc547728-b309-4695-b355-49748ef2521c", + "name": "openingOutput", + "displayName": "Opening output", + "displayNameEvent": "Opening output changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "1c35df0e-4c41-455f-893a-0145377952a0", + "name": "closingOutput", + "displayName": "Closing output", + "displayNameEvent": "Closing output changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "6d6e72dc-4d2b-4ec1-82c2-54405a682711", + "name": "status", + "displayName": "Status", + "displayNameEvent": "Status changed", + "type": "QString", + "possibleValues": [ + "Opening", + "Stopped", + "Closing" + ], + "defaultValue": "Stopped" + } + ], + "actionTypes": [ + { + "id": "9deb662d-2378-4345-a898-8742d41e43c1", + "name": "open", + "displayName": "Open" + }, + { + "id": "db5f3332-1f4e-4f9e-84d2-93c5d7de315c", + "name": "stop", + "displayName": "Stop" + }, + { + "id": "cf5303f1-67c7-4cef-b11c-eb9de6fc8a87", + "name": "close", + "displayName": "Close" + } + ] + }, + { + "id": "4e7261af-a27b-4446-8346-914ea59f7547", + "name": "socket", + "displayName": "Socket interface", + "createMethods": ["user"], + "interfaces": ["powersocket"], + "stateTypes": [ + { + "id": "018038d7-1d02-4b17-8fe3-babca044b087", + "name": "power", + "displayName": "Power", + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "type": "bool", + "defaultValue": false, + "writable": true + } + ] + }, + { + "id": "c50d3216-f307-4f9f-8190-4391510c385c", + "name": "light", + "displayName": "Light interface", + "createMethods": ["user"], + "interfaces": ["light"], + "stateTypes": [ + { + "id": "8b6e4a67-6522-408b-b676-8d2f09ed2d54", + "name": "power", + "displayName": "Power", + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "type": "bool", + "defaultValue": false, + "writable": true + } + ] + }, + { + "id": "392854c4-3d14-4cf8-96cd-d933526bd197", + "name": "heating", + "displayName": "Heating interface", + "createMethods": ["user"], + "interfaces": ["heating"], + "stateTypes": [ + { + "id": "409b635e-a754-4b5c-b3f0-d1c5a0fb3f03", + "name": "power", + "displayName": "Power", + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "type": "bool", + "defaultValue": false, + "writable": true + } + ] + } + ] + } + ] +} diff --git a/genericinterfaces/genericinterfaces.pro b/genericinterfaces/genericinterfaces.pro new file mode 100644 index 0000000..d66633d --- /dev/null +++ b/genericinterfaces/genericinterfaces.pro @@ -0,0 +1,12 @@ +include(../plugins.pri) + +TARGET = $$qtLibraryTarget(nymea_deviceplugingenericinterfaces) + +SOURCES += \ + deviceplugingenericinterfaces.cpp + +HEADERS += \ + deviceplugingenericinterfaces.h + + + diff --git a/genericinterfaces/translations/b3188696-2585-4806-bf98-30ab576ce5c8-en_US.ts b/genericinterfaces/translations/b3188696-2585-4806-bf98-30ab576ce5c8-en_US.ts new file mode 100644 index 0000000..f7f66d8 --- /dev/null +++ b/genericinterfaces/translations/b3188696-2585-4806-bf98-30ab576ce5c8-en_US.ts @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/nymea-plugins.pro b/nymea-plugins.pro index 75c495d..f0d5856 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -17,6 +17,7 @@ PLUGIN_DIRS = \ eq-3 \ flowercare \ genericelements \ + genericinterfaces \ gpio \ httpcommander \ intertechno \