From 54299c043e1c30263120f46f9e68279a43250883 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Sun, 4 Apr 2021 19:58:23 +0200 Subject: [PATCH] somfytahoma: Add support for awnings --- somfytahoma/README.md | 6 +- somfytahoma/integrationpluginsomfytahoma.cpp | 61 ++++- somfytahoma/integrationpluginsomfytahoma.json | 72 +++++ ...be1c1-daa8-4e21-9e85-b2372ab1a450-en_US.ts | 250 +++++++++++------- 4 files changed, 287 insertions(+), 102 deletions(-) diff --git a/somfytahoma/README.md b/somfytahoma/README.md index d78154bd..08591b31 100644 --- a/somfytahoma/README.md +++ b/somfytahoma/README.md @@ -17,6 +17,6 @@ entering your personal username + password for the Somfy TaHoma API. ## Supported devices -Currently this plugin supports all roller shutters, blinds and garage -door drives that are connectable to the TaHoma gateway. These are Somfy iO -devices as well as RTS devices. +Currently this plugin supports all roller shutters, blinds, garage +door and awning drives that are connectable to the TaHoma gateway. These are +Somfy iO devices as well as RTS devices. diff --git a/somfytahoma/integrationpluginsomfytahoma.cpp b/somfytahoma/integrationpluginsomfytahoma.cpp index fc7f89ca..a0826d2d 100644 --- a/somfytahoma/integrationpluginsomfytahoma.cpp +++ b/somfytahoma/integrationpluginsomfytahoma.cpp @@ -119,6 +119,16 @@ void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info) descriptor.setParams(ParamList() << Param(garagedoorThingDeviceUrlParamTypeId, deviceUrl)); unknownDevices.append(descriptor); } + } else if (type == QStringLiteral("Awning")) { + Thing *thing = myThings().findByParams(ParamList() << Param(awningThingDeviceUrlParamTypeId, deviceUrl)); + if (thing) { + qCDebug(dcSomfyTahoma()) << "Found existing awning:" << label << deviceUrl; + } else { + qCInfo(dcSomfyTahoma()) << "Found new awning:" << label << deviceUrl; + ThingDescriptor descriptor(awningThingClassId, label, QString(), accountId); + descriptor.setParams(ParamList() << Param(awningThingDeviceUrlParamTypeId, deviceUrl)); + unknownDevices.append(descriptor); + } } else { qCInfo(dcSomfyTahoma()) << "Found unsupperted Somfy device:" << label << type << deviceUrl; } @@ -134,7 +144,8 @@ void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info) else if (info->thing()->thingClassId() == gatewayThingClassId || info->thing()->thingClassId() == rollershutterThingClassId || info->thing()->thingClassId() == venetianblindThingClassId || - info->thing()->thingClassId() == garagedoorThingClassId) { + info->thing()->thingClassId() == garagedoorThingClassId || + info->thing()->thingClassId() == awningThingClassId) { info->finish(Thing::ThingErrorNoError); } } @@ -156,9 +167,10 @@ void IntegrationPluginSomfyTahoma::postSetupThing(Thing *thing) deviceUrl = QUrl(thing->paramValue(rollershutterThingDeviceUrlParamTypeId).toString()); } else if (thing->thingClassId() == venetianblindThingClassId) { deviceUrl = QUrl(thing->paramValue(venetianblindThingDeviceUrlParamTypeId).toString()); - } - else if (thing->thingClassId() == garagedoorThingClassId) { - deviceUrl = QUrl(thing->paramValue(garagedoorThingDeviceUrlParamTypeId).toString()); + } else if (thing->thingClassId() == garagedoorThingClassId) { + deviceUrl = QUrl(thing->paramValue(garagedoorThingDeviceUrlParamTypeId).toString()); + } else if (thing->thingClassId() == awningThingClassId) { + deviceUrl = QUrl(thing->paramValue(awningThingDeviceUrlParamTypeId).toString()); } if (!deviceUrl.isEmpty()) { Thing *gateway = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, deviceUrl.host())); @@ -274,6 +286,12 @@ void IntegrationPluginSomfyTahoma::handleEvents(const QVariantList &eventList) thing->setStateValue(garagedoorMovingStateTypeId, true); things.append(thing); } + thing = myThings().findByParams(ParamList() << Param(awningThingDeviceUrlParamTypeId, action.toMap()["deviceURL"])); + if (thing) { + thing->setStateValue(awningMovingStateTypeId, true); + things.append(thing); + continue; + } } qCDebug(dcSomfyTahoma()) << "ExecutionRegisteredEvent" << eventMap["execId"]; m_currentExecutions.insert(eventMap["execId"].toString(), things); @@ -287,6 +305,8 @@ void IntegrationPluginSomfyTahoma::handleEvents(const QVariantList &eventList) thing->setStateValue(venetianblindMovingStateTypeId, false); } else if (thing->thingClassId() == garagedoorThingClassId) { thing->setStateValue(garagedoorMovingStateTypeId, false); + } else if (thing->thingClassId() == awningThingClassId) { + thing->setStateValue(awningMovingStateTypeId, false); } } @@ -395,6 +415,23 @@ void IntegrationPluginSomfyTahoma::updateThingStates(const QString &deviceUrl, c } return; } + thing = myThings().findByParams(ParamList() << Param(awningThingDeviceUrlParamTypeId, deviceUrl)); + if (thing) { + foreach (const QVariant &stateVariant, stateList) { + QVariantMap stateMap = stateVariant.toMap(); + if (stateMap["name"] == "core:DeploymentState") { + thing->setStateValue(awningPercentageStateTypeId, stateMap["value"]); + } else if (stateMap["name"] == "core:StatusState") { + thing->setStateValue(awningConnectedStateTypeId, stateMap["value"] == "available"); + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("connected", stateMap["value"] == "available"); + pluginStorage()->endGroup(); + } else if (stateMap["name"] == "core:RSSILevelState") { + thing->setStateValue(awningSignalStrengthStateTypeId, stateMap["value"]); + } + } + return; + } } void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info) @@ -448,6 +485,18 @@ void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info) } else if (info->action().actionTypeId() == garagedoorStopActionTypeId) { actionName = "stop"; } + } else if (info->thing()->thingClassId() == awningThingClassId) { + deviceUrl = info->thing()->paramValue(awningThingDeviceUrlParamTypeId).toString(); + if (info->action().actionTypeId() == awningPercentageActionTypeId) { + actionName = "setDeployment"; + actionParameters = { info->action().param(awningPercentageActionPercentageParamTypeId).value().toInt() }; + } else if (info->action().actionTypeId() == awningOpenActionTypeId) { + actionName = "deploy"; + } else if (info->action().actionTypeId() == awningCloseActionTypeId) { + actionName = "undeploy"; + } else if (info->action().actionTypeId() == awningStopActionTypeId) { + actionName = "stop"; + } } if (!actionName.isEmpty()) { @@ -492,6 +541,8 @@ void IntegrationPluginSomfyTahoma::markDisconnected(Thing *thing) thing->setStateValue(venetianblindConnectedStateTypeId, false); } else if (thing->thingClassId() == garagedoorThingClassId) { thing->setStateValue(garagedoorConnectedStateTypeId, false); + } else if (thing->thingClassId() == awningThingClassId) { + thing->setStateValue(awningConnectedStateTypeId, false); } foreach (Thing *child, myThings().filterByParentId(thing->id())) { markDisconnected(child); @@ -510,6 +561,8 @@ void IntegrationPluginSomfyTahoma::restoreChildConnectedState(Thing *thing) thing->setStateValue(venetianblindConnectedStateTypeId, pluginStorage()->value("connected").toBool()); } else if (thing->thingClassId() == garagedoorThingClassId) { thing->setStateValue(garagedoorConnectedStateTypeId, pluginStorage()->value("connected").toBool()); + } else if (thing->thingClassId() == awningThingClassId) { + thing->setStateValue(awningConnectedStateTypeId, pluginStorage()->value("connected").toBool()); } } pluginStorage()->endGroup(); diff --git a/somfytahoma/integrationpluginsomfytahoma.json b/somfytahoma/integrationpluginsomfytahoma.json index 5aeb7886..9f163629 100644 --- a/somfytahoma/integrationpluginsomfytahoma.json +++ b/somfytahoma/integrationpluginsomfytahoma.json @@ -304,6 +304,78 @@ "displayName": "Close" } ] + }, + { + "id": "d3a3bb40-4b2d-4bdc-989f-5254f03b4c90", + "name": "awning", + "displayName": "Awning", + "createMethods": ["auto"], + "interfaces": ["extendedawning", "wirelessconnectable"], + "paramTypes": [ + { + "id": "ca60f12e-b9da-427a-a149-195922399fd5", + "displayName": "Device URL", + "name": "deviceUrl", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "c409cb9b-82ef-4f59-ae89-eb783d4ebe97", + "name": "percentage", + "displayName": "Percentage", + "type": "int", + "unit": "Percentage", + "displayNameEvent": "Percentage changed", + "writable": true, + "displayNameAction": "Set percentage", + "defaultValue": 0 + }, + { + "id": "2507ac5a-9658-42cb-80f6-73f673c32771", + "name": "moving", + "type": "bool", + "defaultValue": false, + "displayName": "Moving", + "displayNameEvent": "Moving changed" + }, + { + "id": "b2ad6f4a-c507-45c3-a951-b344603cc3fc", + "name": "signalStrength", + "displayName": "Signal strength", + "type": "uint", + "unit": "Percentage", + "displayNameEvent": "Signal strength changed", + "minValue": 0, + "maxValue": 100, + "defaultValue": 0 + }, + { + "id": "8f972969-10dd-4954-9c8b-de56070a6668", + "name": "connected", + "displayName": "Connected", + "type": "bool", + "displayNameEvent": "Connetion state changed", + "defaultValue": false + } + ], + "actionTypes": [ + { + "id": "9612954c-02cb-4159-9a29-f36eaf1c7f6a", + "name": "open", + "displayName": "Open" + }, + { + "id": "33bec73b-4d15-493a-b553-bcee32c40ee1", + "name": "stop", + "displayName": "Stop" + }, + { + "id": "20cae53b-f36d-425b-b937-3e46519893a3", + "name": "close", + "displayName": "Close" + } + ] } ] } diff --git a/somfytahoma/translations/4e8be1c1-daa8-4e21-9e85-b2372ab1a450-en_US.ts b/somfytahoma/translations/4e8be1c1-daa8-4e21-9e85-b2372ab1a450-en_US.ts index 782040dc..33318542 100644 --- a/somfytahoma/translations/4e8be1c1-daa8-4e21-9e85-b2372ab1a450-en_US.ts +++ b/somfytahoma/translations/4e8be1c1-daa8-4e21-9e85-b2372ab1a450-en_US.ts @@ -18,9 +18,9 @@ SomfyTahoma - - - + + + Angle The name of the ParamType (ThingClass: venetianblind, ActionType: angle, ID: {079c7a80-8a1c-4fd7-b40c-6800120c70fb}) ---------- @@ -30,17 +30,26 @@ The name of the StateType ({079c7a80-8a1c-4fd7-b40c-6800120c70fb}) of ThingClass - + Angle changed The name of the EventType ({079c7a80-8a1c-4fd7-b40c-6800120c70fb}) of ThingClass venetianblind - - - + + Awning + The name of the ThingClass ({d3a3bb40-4b2d-4bdc-989f-5254f03b4c90}) + + + + + + + Close - The name of the ActionType ({1e6552e3-8eb0-4070-b9cf-13fd13671eef}) of ThingClass garagedoor + The name of the ActionType ({20cae53b-f36d-425b-b937-3e46519893a3}) of ThingClass awning +---------- +The name of the ActionType ({1e6552e3-8eb0-4070-b9cf-13fd13671eef}) of ThingClass garagedoor ---------- The name of the ActionType ({1a9707e7-9d64-4237-b150-234edcfed12a}) of ThingClass venetianblind ---------- @@ -48,18 +57,24 @@ The name of the ActionType ({baf377c6-9fba-44cf-9f14-af0101f874b5}) of ThingClas - - - - - - - - - - + + + + + + + + + + + + Connected - The name of the ParamType (ThingClass: garagedoor, EventType: connected, ID: {5a32cbd3-bc1c-4724-ae53-9f36cb75bf84}) + The name of the ParamType (ThingClass: awning, EventType: connected, ID: {8f972969-10dd-4954-9c8b-de56070a6668}) +---------- +The name of the StateType ({8f972969-10dd-4954-9c8b-de56070a6668}) of ThingClass awning +---------- +The name of the ParamType (ThingClass: garagedoor, EventType: connected, ID: {5a32cbd3-bc1c-4724-ae53-9f36cb75bf84}) ---------- The name of the StateType ({5a32cbd3-bc1c-4724-ae53-9f36cb75bf84}) of ThingClass garagedoor ---------- @@ -81,13 +96,16 @@ The name of the StateType ({10ebf650-a93a-4ee3-945b-fba10d4e35a5}) of ThingClass - - - - - + + + + + + Connetion state changed - The name of the EventType ({5a32cbd3-bc1c-4724-ae53-9f36cb75bf84}) of ThingClass garagedoor + The name of the EventType ({8f972969-10dd-4954-9c8b-de56070a6668}) of ThingClass awning +---------- +The name of the EventType ({5a32cbd3-bc1c-4724-ae53-9f36cb75bf84}) of ThingClass garagedoor ---------- The name of the EventType ({57361115-edbe-49fb-9847-408b571d3108}) of ThingClass venetianblind ---------- @@ -99,11 +117,14 @@ The name of the EventType ({10ebf650-a93a-4ee3-945b-fba10d4e35a5}) of ThingClass - - - + + + + Device URL - The name of the ParamType (ThingClass: garagedoor, Type: thing, ID: {974710eb-5da4-4b3e-8c4f-ba60e8af31b3}) + The name of the ParamType (ThingClass: awning, Type: thing, ID: {ca60f12e-b9da-427a-a149-195922399fd5}) +---------- +The name of the ParamType (ThingClass: garagedoor, Type: thing, ID: {974710eb-5da4-4b3e-8c4f-ba60e8af31b3}) ---------- The name of the ParamType (ThingClass: venetianblind, Type: thing, ID: {e2541b7b-fbfa-4659-87b1-35d8993714c9}) ---------- @@ -111,20 +132,20 @@ The name of the ParamType (ThingClass: rollershutter, Type: thing, ID: {b3d20d6a - + Garage Door The name of the ThingClass ({cb206d74-b13c-4466-98c6-070b19ebd23a}) - + Gateway Id The name of the ParamType (ThingClass: gateway, Type: thing, ID: {e321a7d6-6dcb-4a37-baf1-c7008f2d5bdb}) - - + + Logged in The name of the ParamType (ThingClass: tahoma, EventType: loggedIn, ID: {97fefa85-db79-4efd-8d83-4a15d72996e1}) ---------- @@ -132,20 +153,26 @@ The name of the StateType ({97fefa85-db79-4efd-8d83-4a15d72996e1}) of ThingClass - + Login state changed The name of the EventType ({97fefa85-db79-4efd-8d83-4a15d72996e1}) of ThingClass tahoma - - - - - - + + + + + + + + Moving - The name of the ParamType (ThingClass: garagedoor, EventType: moving, ID: {07175175-f95d-4cd9-a398-9aab8232c2a9}) + The name of the ParamType (ThingClass: awning, EventType: moving, ID: {2507ac5a-9658-42cb-80f6-73f673c32771}) +---------- +The name of the StateType ({2507ac5a-9658-42cb-80f6-73f673c32771}) of ThingClass awning +---------- +The name of the ParamType (ThingClass: garagedoor, EventType: moving, ID: {07175175-f95d-4cd9-a398-9aab8232c2a9}) ---------- The name of the StateType ({07175175-f95d-4cd9-a398-9aab8232c2a9}) of ThingClass garagedoor ---------- @@ -159,11 +186,14 @@ The name of the StateType ({fa9446ba-da30-4d49-8fb6-f410ecc7dba0}) of ThingClass - - - + + + + Moving changed - The name of the EventType ({07175175-f95d-4cd9-a398-9aab8232c2a9}) of ThingClass garagedoor + The name of the EventType ({2507ac5a-9658-42cb-80f6-73f673c32771}) of ThingClass awning +---------- +The name of the EventType ({07175175-f95d-4cd9-a398-9aab8232c2a9}) of ThingClass garagedoor ---------- The name of the EventType ({48d5de0a-11ab-4801-94e4-a1dd458c341d}) of ThingClass venetianblind ---------- @@ -171,11 +201,14 @@ The name of the EventType ({fa9446ba-da30-4d49-8fb6-f410ecc7dba0}) of ThingClass - - - + + + + Open - The name of the ActionType ({5738edd9-a1d1-4031-8505-85a919afe6f7}) of ThingClass garagedoor + The name of the ActionType ({9612954c-02cb-4159-9a29-f36eaf1c7f6a}) of ThingClass awning +---------- +The name of the ActionType ({5738edd9-a1d1-4031-8505-85a919afe6f7}) of ThingClass garagedoor ---------- The name of the ActionType ({004e7294-59e6-498b-a0aa-e58eaeefdf2b}) of ThingClass venetianblind ---------- @@ -183,17 +216,26 @@ The name of the ActionType ({a0460180-e799-4bc6-83ba-11731ef124a3}) of ThingClas - - - - - - - - - + + + + + + + + + + + + Percentage - The name of the ParamType (ThingClass: garagedoor, ActionType: percentage, ID: {284816aa-842b-4a86-bb4e-ef5353b76762}) + The name of the ParamType (ThingClass: awning, ActionType: percentage, ID: {c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) +---------- +The name of the ParamType (ThingClass: awning, EventType: percentage, ID: {c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) +---------- +The name of the StateType ({c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) of ThingClass awning +---------- +The name of the ParamType (ThingClass: garagedoor, ActionType: percentage, ID: {284816aa-842b-4a86-bb4e-ef5353b76762}) ---------- The name of the ParamType (ThingClass: garagedoor, EventType: percentage, ID: {284816aa-842b-4a86-bb4e-ef5353b76762}) ---------- @@ -213,11 +255,14 @@ The name of the StateType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass - - - + + + + Percentage changed - The name of the EventType ({284816aa-842b-4a86-bb4e-ef5353b76762}) of ThingClass garagedoor + The name of the EventType ({c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) of ThingClass awning +---------- +The name of the EventType ({284816aa-842b-4a86-bb4e-ef5353b76762}) of ThingClass garagedoor ---------- The name of the EventType ({77ca50db-42a7-4434-83e2-8b5fc4438924}) of ThingClass venetianblind ---------- @@ -225,23 +270,26 @@ The name of the EventType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass - + Roller Shutter The name of the ThingClass ({6b187fe0-a987-462d-90ac-c48efc0d0fc0}) - + Set angle The name of the ActionType ({079c7a80-8a1c-4fd7-b40c-6800120c70fb}) of ThingClass venetianblind - - - + + + + Set percentage - The name of the ActionType ({284816aa-842b-4a86-bb4e-ef5353b76762}) of ThingClass garagedoor + The name of the ActionType ({c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) of ThingClass awning +---------- +The name of the ActionType ({284816aa-842b-4a86-bb4e-ef5353b76762}) of ThingClass garagedoor ---------- The name of the ActionType ({77ca50db-42a7-4434-83e2-8b5fc4438924}) of ThingClass venetianblind ---------- @@ -249,14 +297,20 @@ The name of the ActionType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClas - - - - - - + + + + + + + + Signal strength - The name of the ParamType (ThingClass: garagedoor, EventType: signalStrength, ID: {0a194091-3073-4912-9d84-f1d52c8534bd}) + The name of the ParamType (ThingClass: awning, EventType: signalStrength, ID: {b2ad6f4a-c507-45c3-a951-b344603cc3fc}) +---------- +The name of the StateType ({b2ad6f4a-c507-45c3-a951-b344603cc3fc}) of ThingClass awning +---------- +The name of the ParamType (ThingClass: garagedoor, EventType: signalStrength, ID: {0a194091-3073-4912-9d84-f1d52c8534bd}) ---------- The name of the StateType ({0a194091-3073-4912-9d84-f1d52c8534bd}) of ThingClass garagedoor ---------- @@ -270,11 +324,14 @@ The name of the StateType ({67594d96-47a2-4360-a1b8-79e4f22f9ed0}) of ThingClass - - - + + + + Signal strength changed - The name of the EventType ({0a194091-3073-4912-9d84-f1d52c8534bd}) of ThingClass garagedoor + The name of the EventType ({b2ad6f4a-c507-45c3-a951-b344603cc3fc}) of ThingClass awning +---------- +The name of the EventType ({0a194091-3073-4912-9d84-f1d52c8534bd}) of ThingClass garagedoor ---------- The name of the EventType ({aee4f4e3-3445-441d-bdbb-631b0c5db942}) of ThingClass venetianblind ---------- @@ -282,20 +339,20 @@ The name of the EventType ({67594d96-47a2-4360-a1b8-79e4f22f9ed0}) of ThingClass - + Somfy The name of the vendor ({4e42a22a-ccfb-4677-89e3-f7fa16bf6be0}) - + Somfy Tahoma The name of the plugin SomfyTahoma ({4e8be1c1-daa8-4e21-9e85-b2372ab1a450}) - - + + State The name of the ParamType (ThingClass: garagedoor, EventType: state, ID: {12af28f1-475e-4d05-9bbb-adbb86dcd69c}) ---------- @@ -303,17 +360,20 @@ The name of the StateType ({12af28f1-475e-4d05-9bbb-adbb86dcd69c}) of ThingClass - + State changed The name of the EventType ({12af28f1-475e-4d05-9bbb-adbb86dcd69c}) of ThingClass garagedoor - - - + + + + Stop - The name of the ActionType ({75e345b8-0a25-4ba6-ba83-f2611252f87f}) of ThingClass garagedoor + The name of the ActionType ({33bec73b-4d15-493a-b553-bcee32c40ee1}) of ThingClass awning +---------- +The name of the ActionType ({75e345b8-0a25-4ba6-ba83-f2611252f87f}) of ThingClass garagedoor ---------- The name of the ActionType ({31b07407-65ef-4fd1-880b-b5d9f69a9d07}) of ThingClass venetianblind ---------- @@ -321,20 +381,20 @@ The name of the ActionType ({cbccf714-1188-4ac9-9c91-17fe2c99acb3}) of ThingClas - + Tahoma Account The name of the ThingClass ({fedd72b8-547d-4e4f-b73e-71344a8ba0c1}) - + Tahoma Gateway The name of the ThingClass ({6c09e0b9-f0cc-4dea-9994-9e039eff78f1}) - - + + User display name The name of the ParamType (ThingClass: tahoma, EventType: userDisplayName, ID: {75609987-be60-4932-94f6-ead791b5fa58}) ---------- @@ -342,13 +402,13 @@ The name of the StateType ({75609987-be60-4932-94f6-ead791b5fa58}) of ThingClass - + User display name changed The name of the EventType ({75609987-be60-4932-94f6-ead791b5fa58}) of ThingClass tahoma - + Venetian Blind The name of the ThingClass ({c7160205-d864-4194-b418-060fff60f0cb})