diff --git a/genericthings/genericthings.pro b/genericthings/genericthings.pro index 126bf475..91b2c276 100644 --- a/genericthings/genericthings.pro +++ b/genericthings/genericthings.pro @@ -1,7 +1,5 @@ include(../plugins.pri) -TARGET = $$qtLibraryTarget(nymea_integrationplugingenericthings) - SOURCES += \ integrationplugingenericthings.cpp diff --git a/genericthings/integrationplugingenericthings.cpp b/genericthings/integrationplugingenericthings.cpp index 53b94785..6a177f40 100644 --- a/genericthings/integrationplugingenericthings.cpp +++ b/genericthings/integrationplugingenericthings.cpp @@ -1,4 +1,4 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright 2013 - 2020, nymea GmbH * Contact: contact@nymea.io @@ -28,28 +28,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/*! - \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{ThingClass}{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 "integrationplugingenericthings.h" #include "plugininfo.h" @@ -113,9 +91,8 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorNoError); } return info->finish(Thing::ThingErrorActionTypeNotFound); - } - if (thing->thingClassId() == blindThingClassId ) { + } else if (thing->thingClassId() == blindThingClassId ) { if (action.actionTypeId() == blindOpenActionTypeId) { thing->setStateValue(blindStatusStateTypeId, "Opening"); thing->setStateValue(blindClosingOutputStateTypeId, false); @@ -157,9 +134,100 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorNoError); } return info->finish(Thing::ThingErrorActionTypeNotFound); - } - if (thing->thingClassId() == shutterThingClassId) { + } else if (thing->thingClassId() == extendedBlindThingClassId) { + if (action.actionTypeId() == extendedBlindOpenActionTypeId) { + thing->setStateValue(extendedBlindStatusStateTypeId, "Opening"); + thing->setStateValue(extendedBlindClosingOutputStateTypeId, false); + thing->setStateValue(extendedBlindOpeningOutputStateTypeId, true); + //TODO set moving state + return info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == extendedBlindStopActionTypeId) { + thing->setStateValue(extendedBlindStatusStateTypeId, "Stopped"); + thing->setStateValue(extendedBlindOpeningOutputStateTypeId, false); + thing->setStateValue(extendedBlindClosingOutputStateTypeId, false); + return info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == extendedBlindCloseActionTypeId) { + thing->setStateValue(extendedBlindStatusStateTypeId, "Closing"); + thing->setStateValue(extendedBlindOpeningOutputStateTypeId, false); + thing->setStateValue(extendedBlindClosingOutputStateTypeId, true); + return info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == extendedBlindOpeningOutputActionTypeId) { + bool on = action.param(extendedBlindOpeningOutputActionOpeningOutputParamTypeId).value().toBool(); + thing->setStateValue(extendedBlindOpeningOutputStateTypeId, on); + if (on) { + thing->setStateValue(extendedBlindStatusStateTypeId, "Opening"); + thing->setStateValue(extendedBlindClosingOutputStateTypeId, false); + } else { + thing->setStateValue(extendedBlindStatusStateTypeId, "Stopped"); + } + info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == extendedBlindClosingOutputActionTypeId) { + bool on = action.param(extendedBlindClosingOutputActionClosingOutputParamTypeId).value().toBool(); + thing->setStateValue(extendedBlindClosingOutputStateTypeId, on); + if (on) { + thing->setStateValue(extendedBlindStatusStateTypeId, "Closing"); + thing->setStateValue(extendedBlindOpeningOutputStateTypeId, false); + } else { + thing->setStateValue(extendedBlindStatusStateTypeId, "Stopped"); + } + info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == extendedBlindPercentageActionTypeId) { + int percentage = action.param(extendedBlindPercentageActionPercentageParamTypeId).value().toBool(); + Q_UNUSED(percentage) + //TODO move to percentage + } else { + Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); + } + } else if (thing->thingClassId() == venetianBlindThingClassId) { + if (action.actionTypeId() == venetianBlindOpenActionTypeId) { + thing->setStateValue(venetianBlindStatusStateTypeId, "Opening"); + thing->setStateValue(venetianBlindClosingOutputStateTypeId, false); + thing->setStateValue(venetianBlindOpeningOutputStateTypeId, true); + //TODO set moving state + return info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == venetianBlindStopActionTypeId) { + thing->setStateValue(venetianBlindStatusStateTypeId, "Stopped"); + thing->setStateValue(venetianBlindOpeningOutputStateTypeId, false); + thing->setStateValue(venetianBlindClosingOutputStateTypeId, false); + return info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == venetianBlindCloseActionTypeId) { + thing->setStateValue(venetianBlindStatusStateTypeId, "Closing"); + thing->setStateValue(venetianBlindOpeningOutputStateTypeId, false); + thing->setStateValue(venetianBlindClosingOutputStateTypeId, true); + return info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == venetianBlindOpeningOutputActionTypeId) { + bool on = action.param(venetianBlindOpeningOutputActionOpeningOutputParamTypeId).value().toBool(); + thing->setStateValue(venetianBlindOpeningOutputStateTypeId, on); + if (on) { + thing->setStateValue(venetianBlindStatusStateTypeId, "Opening"); + thing->setStateValue(venetianBlindClosingOutputStateTypeId, false); + } else { + thing->setStateValue(venetianBlindStatusStateTypeId, "Stopped"); + } + info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == venetianBlindClosingOutputActionTypeId) { + bool on = action.param(venetianBlindClosingOutputActionClosingOutputParamTypeId).value().toBool(); + thing->setStateValue(venetianBlindClosingOutputStateTypeId, on); + if (on) { + thing->setStateValue(venetianBlindStatusStateTypeId, "Closing"); + thing->setStateValue(venetianBlindOpeningOutputStateTypeId, false); + } else { + thing->setStateValue(venetianBlindStatusStateTypeId, "Stopped"); + } + info->finish(Thing::ThingErrorNoError); + } else if (action.actionTypeId() == venetianBlindPercentageActionTypeId) { + int percentage = action.param(venetianBlindPercentageActionPercentageParamTypeId).value().toInt(); + Q_UNUSED(percentage) + //TODO move to percentage + } else if (action.actionTypeId() == venetianBlindAngleActionTypeId) { + int angle = action.param(venetianBlindAngleActionAngleParamTypeId).value().toInt(); + Q_UNUSED(angle) + //TODO move to angle + } else { + Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); + } + } else if (thing->thingClassId() == shutterThingClassId) { if (action.actionTypeId() == shutterOpenActionTypeId) { thing->setStateValue(shutterStatusStateTypeId, "Opening"); thing->setStateValue(shutterClosingOutputStateTypeId, false); @@ -201,57 +269,43 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorNoError); } return info->finish(Thing::ThingErrorActionTypeNotFound); - } - - if (thing->thingClassId() == socketThingClassId) { + } else if (thing->thingClassId() == socketThingClassId) { if (action.actionTypeId() == socketPowerActionTypeId) { thing->setStateValue(socketPowerStateTypeId, action.param(socketPowerActionPowerParamTypeId).value()); return info->finish(Thing::ThingErrorNoError); } return info->finish(Thing::ThingErrorActionTypeNotFound); - } - - if (thing->thingClassId() == lightThingClassId) { + } else if (thing->thingClassId() == lightThingClassId) { if (action.actionTypeId() == lightPowerActionTypeId) { thing->setStateValue(lightPowerStateTypeId, action.param(lightPowerActionPowerParamTypeId).value()); return info->finish(Thing::ThingErrorNoError); } return info->finish(Thing::ThingErrorActionTypeNotFound); - } - - if (thing->thingClassId() == heatingThingClassId) { + } else if (thing->thingClassId() == heatingThingClassId) { if (action.actionTypeId() == heatingPowerActionTypeId) { thing->setStateValue(heatingPowerStateTypeId, action.param(heatingPowerActionPowerParamTypeId).value()); return info->finish(Thing::ThingErrorNoError); } return info->finish(Thing::ThingErrorActionTypeNotFound); - } - - if (thing->thingClassId() == powerSwitchThingClassId) { + } else if (thing->thingClassId() == powerSwitchThingClassId) { if (action.actionTypeId() == powerSwitchPowerActionTypeId) { thing->setStateValue(powerSwitchPowerStateTypeId, action.param(powerSwitchPowerActionPowerParamTypeId).value()); info->finish(Thing::ThingErrorNoError); return; } - } - - if (thing->thingClassId() == irrigationThingClassId) { + } else if (thing->thingClassId() == irrigationThingClassId) { if (action.actionTypeId() == irrigationPowerActionTypeId) { thing->setStateValue(irrigationPowerStateTypeId, action.param(irrigationPowerActionPowerParamTypeId).value()); info->finish(Thing::ThingErrorNoError); return; } - } - - if (thing->thingClassId() == ventilationThingClassId) { + } else if (thing->thingClassId() == ventilationThingClassId) { if (action.actionTypeId() == ventilationPowerActionTypeId) { thing->setStateValue(ventilationPowerStateTypeId, action.param(ventilationPowerActionPowerParamTypeId).value()); info->finish(Thing::ThingErrorNoError); return; } - } - - if (thing->thingClassId() == temperatureSensorThingClassId) { + } else if (thing->thingClassId() == temperatureSensorThingClassId) { if (action.actionTypeId() == temperatureSensorInputActionTypeId) { double value = info->action().param(temperatureSensorInputActionInputParamTypeId).value().toDouble(); thing->setStateValue(temperatureSensorInputStateTypeId, value); @@ -264,9 +318,7 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorNoError); return; } - } - - if (thing->thingClassId() == humiditySensorThingClassId) { + } else if (thing->thingClassId() == humiditySensorThingClassId) { if (action.actionTypeId() == humiditySensorInputActionTypeId) { double value = info->action().param(humiditySensorInputActionInputParamTypeId).value().toDouble(); thing->setStateValue(humiditySensorInputStateTypeId, value); @@ -279,9 +331,7 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorNoError); return; } - } - - if (thing->thingClassId() == moistureSensorThingClassId) { + } else if (thing->thingClassId() == moistureSensorThingClassId) { if (action.actionTypeId() == moistureSensorInputActionTypeId) { double value = info->action().param(moistureSensorInputActionInputParamTypeId).value().toDouble(); thing->setStateValue(moistureSensorInputStateTypeId, value); @@ -294,9 +344,9 @@ void IntegrationPluginGenericThings::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorNoError); return; } + } else { + Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); } - - return info->finish(Thing::ThingErrorThingClassNotFound); } double IntegrationPluginGenericThings::mapDoubleValue(double value, double fromMin, double fromMax, double toMin, double toMax) diff --git a/genericthings/integrationplugingenericthings.json b/genericthings/integrationplugingenericthings.json index 838be3e7..45aee595 100644 --- a/genericthings/integrationplugingenericthings.json +++ b/genericthings/integrationplugingenericthings.json @@ -130,6 +130,181 @@ } ] }, + { + "id": "40aa9f3c-a23c-4f7f-8786-fcf3554f3e19", + "name": "extendedBlind", + "displayName": "Generic extended blind", + "createMethods": ["user"], + "interfaces": ["blind"], + "stateTypes": [ + { + "id": "e559f077-e904-4bbc-8ec3-344b814d2eab", + "name": "openingOutput", + "displayName": "Opening output", + "displayNameEvent": "Opening output changed", + "displayNameAction": "Set opening output", + "type": "bool", + "defaultValue": false, + "ioType": "digitalInput", + "writable": true + }, + { + "id": "1a4a5839-a30d-4239-a124-63bfdc74a8f6", + "name": "closingOutput", + "displayName": "Closing output", + "displayNameEvent": "Closing output changed", + "displayNameAction": "Set closing output", + "type": "bool", + "defaultValue": false, + "ioType": "digitalInput", + "writable": true + }, + { + "id": "c2354d7e-198a-43ae-aa5f-c6710010c7e1", + "name": "status", + "displayName": "Status", + "displayNameEvent": "Status changed", + "type": "QString", + "possibleValues": [ + "Opening", + "Stopped", + "Closing" + ], + "defaultValue": "Stopped" + }, + { + "id": "941d1e1f-8dd7-4493-812f-6cefefd88c2e", + "name": "moving", + "type": "bool", + "displayName": "Moving", + "displayNameEvent": "Moving changed", + "defaultValue": false + }, + { + "id": "181df603-d45f-4d3d-a358-97aa3e4ac0bd", + "name": "percentage", + "displayName": "Percentage", + "displayNameEvent": "Percentage changed", + "displayNameAction": "Set percentage", + "type": "int", + "minValue": 0, + "maxValue": 100, + "defaultValue": 0, + "writable": true + } + ], + "actionTypes": [ + { + "id": "5a7599fa-8351-4ed6-9b98-fa2f3be54304", + "name": "open", + "displayName": "Open" + }, + { + "id": "ab67e4bf-c7b6-489b-9b49-3e0a1c7d33ca", + "name": "stop", + "displayName": "Stop" + }, + { + "id": "97d6351d-7440-47f3-bdba-a31bb15368ac", + "name": "close", + "displayName": "Close" + } + ] + }, + { + "id": "e6b96ced-8d50-45da-91c8-792d364d2795", + "name": "venetianBlind", + "displayName": "Venetian blind", + "createMethods": ["user"], + "interfaces": ["blind"], + "stateTypes": [ + { + "id": "6041dacf-5303-4dc0-ba3c-7ecaa438f2dd", + "name": "openingOutput", + "displayName": "Opening output", + "displayNameEvent": "Opening output changed", + "displayNameAction": "Set opening output", + "type": "bool", + "defaultValue": false, + "ioType": "digitalInput", + "writable": true + }, + { + "id": "84dd2fa1-85fe-47f3-9e32-e6083432d39c", + "name": "closingOutput", + "displayName": "Closing output", + "displayNameEvent": "Closing output changed", + "displayNameAction": "Set closing output", + "type": "bool", + "defaultValue": false, + "ioType": "digitalInput", + "writable": true + }, + { + "id": "6fb7826e-b6d8-42f8-b712-719496046436", + "name": "status", + "displayName": "Status", + "displayNameEvent": "Status changed", + "type": "QString", + "possibleValues": [ + "Opening", + "Stopped", + "Closing" + ], + "defaultValue": "Stopped" + }, + { + "id": "6234c07e-4200-4f2c-8cbd-bff24c38c243", + "name": "moving", + "type": "bool", + "displayName": "Moving", + "displayNameEvent": "Moving changed", + "defaultValue": false + }, + { + "id": "33dc8019-336d-4d50-8d60-dff8508338ca", + "name": "percentage", + "displayName": "Percentage", + "displayNameEvent": "Percentage changed", + "displayNameAction": "Set percentage", + "type": "int", + "minValue": 0, + "maxValue": 100, + "defaultValue": 0, + "writable": true + }, + { + "id": "fcb700c4-5da8-4385-85b0-6616e807974e", + "name": "angle", + "displayName": "Angle", + "displayNameEvent": "Angle changed", + "displayNameAction": "Set angle", + "type": "int", + "unit": "Degree", + "minValue": "any", + "maxValue": "any", + "defaultValue": 0, + "writable": true + } + ], + "actionTypes": [ + { + "id": "3e728e50-3d45-4035-b215-1e604cf3159b", + "name": "open", + "displayName": "Open" + }, + { + "id": "6e3eeb5d-d7ed-4175-9795-e76451e0a00b", + "name": "stop", + "displayName": "Stop" + }, + { + "id": "1c71f050-f6cb-4929-9c9d-7c262f77c143", + "name": "close", + "displayName": "Close" + } + ] + }, { "id": "7917c2e7-d7d2-4c47-a38d-41f7dd7693d9", "name": "shutter",