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 \