From 54299c043e1c30263120f46f9e68279a43250883 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Sun, 4 Apr 2021 19:58:23 +0200 Subject: [PATCH 1/3] 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}) From 52435b27fc44562aa579e234145432737c3443b7 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Sun, 4 Apr 2021 20:20:49 +0200 Subject: [PATCH 2/3] somfytahoma: Add support for dimmable lights --- somfytahoma/README.md | 4 +- somfytahoma/integrationpluginsomfytahoma.cpp | 46 ++- somfytahoma/integrationpluginsomfytahoma.json | 59 ++++ ...be1c1-daa8-4e21-9e85-b2372ab1a450-en_US.ts | 283 +++++++++++------- 4 files changed, 285 insertions(+), 107 deletions(-) diff --git a/somfytahoma/README.md b/somfytahoma/README.md index 08591b31..08542194 100644 --- a/somfytahoma/README.md +++ b/somfytahoma/README.md @@ -18,5 +18,5 @@ entering your personal username + password for the Somfy TaHoma API. ## Supported 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. +door, awning drives and lights 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 a0826d2d..f220b4ca 100644 --- a/somfytahoma/integrationpluginsomfytahoma.cpp +++ b/somfytahoma/integrationpluginsomfytahoma.cpp @@ -129,6 +129,16 @@ void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info) descriptor.setParams(ParamList() << Param(awningThingDeviceUrlParamTypeId, deviceUrl)); unknownDevices.append(descriptor); } + } else if (type == QStringLiteral("Light") && (deviceUrl.startsWith("io"))) { + Thing *thing = myThings().findByParams(ParamList() << Param(lightThingDeviceUrlParamTypeId, deviceUrl)); + if (thing) { + qCDebug(dcSomfyTahoma()) << "Found existing light:" << label << deviceUrl; + } else { + qCInfo(dcSomfyTahoma()) << "Found new light:" << label << deviceUrl; + ThingDescriptor descriptor(lightThingClassId, label, QString(), accountId); + descriptor.setParams(ParamList() << Param(lightThingDeviceUrlParamTypeId, deviceUrl)); + unknownDevices.append(descriptor); + } } else { qCInfo(dcSomfyTahoma()) << "Found unsupperted Somfy device:" << label << type << deviceUrl; } @@ -145,7 +155,8 @@ void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info) info->thing()->thingClassId() == rollershutterThingClassId || info->thing()->thingClassId() == venetianblindThingClassId || info->thing()->thingClassId() == garagedoorThingClassId || - info->thing()->thingClassId() == awningThingClassId) { + info->thing()->thingClassId() == awningThingClassId || + info->thing()->thingClassId() == lightThingClassId) { info->finish(Thing::ThingErrorNoError); } } @@ -171,6 +182,8 @@ void IntegrationPluginSomfyTahoma::postSetupThing(Thing *thing) deviceUrl = QUrl(thing->paramValue(garagedoorThingDeviceUrlParamTypeId).toString()); } else if (thing->thingClassId() == awningThingClassId) { deviceUrl = QUrl(thing->paramValue(awningThingDeviceUrlParamTypeId).toString()); + } else if (thing->thingClassId() == lightThingClassId) { + deviceUrl = QUrl(thing->paramValue(lightThingDeviceUrlParamTypeId).toString()); } if (!deviceUrl.isEmpty()) { Thing *gateway = myThings().findByParams(ParamList() << Param(gatewayThingGatewayIdParamTypeId, deviceUrl.host())); @@ -432,6 +445,25 @@ void IntegrationPluginSomfyTahoma::updateThingStates(const QString &deviceUrl, c } return; } + thing = myThings().findByParams(ParamList() << Param(lightThingDeviceUrlParamTypeId, deviceUrl)); + if (thing) { + foreach (const QVariant &stateVariant, stateList) { + QVariantMap stateMap = stateVariant.toMap(); + if (stateMap["name"] == "core:OnOffState") { + thing->setStateValue(lightPowerStateTypeId, stateMap["value"] == "on"); + } else if (stateMap["name"] == "core:LightIntensityState") { + thing->setStateValue(lightBrightnessStateTypeId, stateMap["value"]); + } else if (stateMap["name"] == "core:StatusState") { + thing->setStateValue(lightConnectedStateTypeId, stateMap["value"] == "available"); + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("connected", stateMap["value"] == "available"); + pluginStorage()->endGroup(); + } else if (stateMap["name"] == "core:RSSILevelState") { + thing->setStateValue(lightSignalStrengthStateTypeId, stateMap["value"]); + } + } + return; + } } void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info) @@ -497,6 +529,14 @@ void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info) } else if (info->action().actionTypeId() == awningStopActionTypeId) { actionName = "stop"; } + } else if (info->thing()->thingClassId() == lightThingClassId) { + deviceUrl = info->thing()->paramValue(lightThingDeviceUrlParamTypeId).toString(); + if (info->action().actionTypeId() == lightPowerActionTypeId) { + actionName = info->action().param(lightPowerActionPowerParamTypeId).value().toBool() ? "on" : "off"; + } else if (info->action().actionTypeId() == lightBrightnessActionTypeId) { + actionName = "setIntensity"; + actionParameters = { info->action().param(lightBrightnessActionBrightnessParamTypeId).value().toInt() }; + } } if (!actionName.isEmpty()) { @@ -543,6 +583,8 @@ void IntegrationPluginSomfyTahoma::markDisconnected(Thing *thing) thing->setStateValue(garagedoorConnectedStateTypeId, false); } else if (thing->thingClassId() == awningThingClassId) { thing->setStateValue(awningConnectedStateTypeId, false); + } else if (thing->thingClassId() == lightThingClassId) { + thing->setStateValue(lightConnectedStateTypeId, false); } foreach (Thing *child, myThings().filterByParentId(thing->id())) { markDisconnected(child); @@ -563,6 +605,8 @@ void IntegrationPluginSomfyTahoma::restoreChildConnectedState(Thing *thing) thing->setStateValue(garagedoorConnectedStateTypeId, pluginStorage()->value("connected").toBool()); } else if (thing->thingClassId() == awningThingClassId) { thing->setStateValue(awningConnectedStateTypeId, pluginStorage()->value("connected").toBool()); + } else if (thing->thingClassId() == lightThingClassId) { + thing->setStateValue(lightConnectedStateTypeId, pluginStorage()->value("connected").toBool()); } } pluginStorage()->endGroup(); diff --git a/somfytahoma/integrationpluginsomfytahoma.json b/somfytahoma/integrationpluginsomfytahoma.json index 9f163629..4d22246d 100644 --- a/somfytahoma/integrationpluginsomfytahoma.json +++ b/somfytahoma/integrationpluginsomfytahoma.json @@ -376,6 +376,65 @@ "displayName": "Close" } ] + }, + { + "id": "e569a3cc-6e79-4e24-af35-c5fa327a7314", + "name": "light", + "displayName": "Light", + "createMethods": ["auto"], + "interfaces": ["dimmablelight", "wirelessconnectable"], + "paramTypes": [ + { + "id": "9cd2e0f2-a02f-478a-9358-6ff0f5aba9f5", + "displayName": "Device URL", + "name": "deviceUrl", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "1b51ce68-1f7e-4f06-b68d-bfca2d61b353", + "name": "brightness", + "displayName": "Brightness", + "type": "int", + "unit": "Percentage", + "displayNameEvent": "Brightness changed", + "writable": true, + "displayNameAction": "Set brightness", + "minValue": 0, + "maxValue": 100, + "defaultValue": 0 + }, + { + "id": "654ddcdf-b0b7-4c38-a70d-878f0f3857a5", + "name": "power", + "type": "bool", + "displayName": "Power", + "displayNameEvent": "Power changed", + "writable": true, + "displayNameAction": "Set power", + "defaultValue": false + }, + { + "id": "cfaa5533-d26e-4545-9f44-6567c9d7888a", + "name": "signalStrength", + "displayName": "Signal strength", + "type": "uint", + "unit": "Percentage", + "displayNameEvent": "Signal strength changed", + "minValue": 0, + "maxValue": 100, + "defaultValue": 0 + }, + { + "id": "fb8dcd84-70ad-4f3e-97c4-93296608e33d", + "name": "connected", + "displayName": "Connected", + "type": "bool", + "displayNameEvent": "Connetion state changed", + "defaultValue": false + } + ] } ] } 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 33318542..61c319bc 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,22 +30,40 @@ 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}) - - - - + + + + Brightness + The name of the ParamType (ThingClass: light, ActionType: brightness, ID: {1b51ce68-1f7e-4f06-b68d-bfca2d61b353}) +---------- +The name of the ParamType (ThingClass: light, EventType: brightness, ID: {1b51ce68-1f7e-4f06-b68d-bfca2d61b353}) +---------- +The name of the StateType ({1b51ce68-1f7e-4f06-b68d-bfca2d61b353}) of ThingClass light + + + + + Brightness changed + The name of the EventType ({1b51ce68-1f7e-4f06-b68d-bfca2d61b353}) of ThingClass light + + + + + + + Close The name of the ActionType ({20cae53b-f36d-425b-b937-3e46519893a3}) of ThingClass awning ---------- @@ -57,20 +75,26 @@ The name of the ActionType ({baf377c6-9fba-44cf-9f14-af0101f874b5}) of ThingClas - - - - - - - - - - + + + + + + + + + + + + Connected - The name of the ParamType (ThingClass: awning, EventType: connected, ID: {8f972969-10dd-4954-9c8b-de56070a6668}) + The name of the ParamType (ThingClass: light, EventType: connected, ID: {fb8dcd84-70ad-4f3e-97c4-93296608e33d}) +---------- +The name of the StateType ({fb8dcd84-70ad-4f3e-97c4-93296608e33d}) of ThingClass light +---------- +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 ---------- @@ -96,14 +120,17 @@ The name of the StateType ({10ebf650-a93a-4ee3-945b-fba10d4e35a5}) of ThingClass - - - - - - + + + + + + + Connetion state changed - The name of the EventType ({8f972969-10dd-4954-9c8b-de56070a6668}) of ThingClass awning + The name of the EventType ({fb8dcd84-70ad-4f3e-97c4-93296608e33d}) of ThingClass light +---------- +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 ---------- @@ -117,12 +144,15 @@ The name of the EventType ({10ebf650-a93a-4ee3-945b-fba10d4e35a5}) of ThingClass - - - - + + + + + Device URL - The name of the ParamType (ThingClass: awning, Type: thing, ID: {ca60f12e-b9da-427a-a149-195922399fd5}) + The name of the ParamType (ThingClass: light, Type: thing, ID: {9cd2e0f2-a02f-478a-9358-6ff0f5aba9f5}) +---------- +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}) ---------- @@ -132,20 +162,26 @@ 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}) - - + + Light + The name of the ThingClass ({e569a3cc-6e79-4e24-af35-c5fa327a7314}) + + + + + Logged in The name of the ParamType (ThingClass: tahoma, EventType: loggedIn, ID: {97fefa85-db79-4efd-8d83-4a15d72996e1}) ---------- @@ -153,20 +189,20 @@ 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: awning, EventType: moving, ID: {2507ac5a-9658-42cb-80f6-73f673c32771}) ---------- @@ -186,10 +222,10 @@ The name of the StateType ({fa9446ba-da30-4d49-8fb6-f410ecc7dba0}) of ThingClass - - - - + + + + Moving changed The name of the EventType ({2507ac5a-9658-42cb-80f6-73f673c32771}) of ThingClass awning ---------- @@ -201,10 +237,10 @@ The name of the EventType ({fa9446ba-da30-4d49-8fb6-f410ecc7dba0}) of ThingClass - - - - + + + + Open The name of the ActionType ({9612954c-02cb-4159-9a29-f36eaf1c7f6a}) of ThingClass awning ---------- @@ -216,18 +252,18 @@ The name of the ActionType ({a0460180-e799-4bc6-83ba-11731ef124a3}) of ThingClas - - - - - - - - - - - - + + + + + + + + + + + + Percentage The name of the ParamType (ThingClass: awning, ActionType: percentage, ID: {c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) ---------- @@ -255,10 +291,10 @@ The name of the StateType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass - - - - + + + + Percentage changed The name of the EventType ({c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) of ThingClass awning ---------- @@ -270,22 +306,46 @@ The name of the EventType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClass - + + + + Power + The name of the ParamType (ThingClass: light, ActionType: power, ID: {654ddcdf-b0b7-4c38-a70d-878f0f3857a5}) +---------- +The name of the ParamType (ThingClass: light, EventType: power, ID: {654ddcdf-b0b7-4c38-a70d-878f0f3857a5}) +---------- +The name of the StateType ({654ddcdf-b0b7-4c38-a70d-878f0f3857a5}) of ThingClass light + + + + + Power changed + The name of the EventType ({654ddcdf-b0b7-4c38-a70d-878f0f3857a5}) of ThingClass light + + + + 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 brightness + The name of the ActionType ({1b51ce68-1f7e-4f06-b68d-bfca2d61b353}) of ThingClass light + + + + + + + Set percentage The name of the ActionType ({c409cb9b-82ef-4f59-ae89-eb783d4ebe97}) of ThingClass awning ---------- @@ -297,16 +357,28 @@ The name of the ActionType ({f954ffc7-a6aa-4d30-aee0-0484631c3344}) of ThingClas - - - - - - - - + + Set power + The name of the ActionType ({654ddcdf-b0b7-4c38-a70d-878f0f3857a5}) of ThingClass light + + + + + + + + + + + + + Signal strength - The name of the ParamType (ThingClass: awning, EventType: signalStrength, ID: {b2ad6f4a-c507-45c3-a951-b344603cc3fc}) + The name of the ParamType (ThingClass: light, EventType: signalStrength, ID: {cfaa5533-d26e-4545-9f44-6567c9d7888a}) +---------- +The name of the StateType ({cfaa5533-d26e-4545-9f44-6567c9d7888a}) of ThingClass light +---------- +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 ---------- @@ -324,12 +396,15 @@ The name of the StateType ({67594d96-47a2-4360-a1b8-79e4f22f9ed0}) of ThingClass - - - - + + + + + Signal strength changed - The name of the EventType ({b2ad6f4a-c507-45c3-a951-b344603cc3fc}) of ThingClass awning + The name of the EventType ({cfaa5533-d26e-4545-9f44-6567c9d7888a}) of ThingClass light +---------- +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 ---------- @@ -339,20 +414,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}) ---------- @@ -360,16 +435,16 @@ 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 ({33bec73b-4d15-493a-b553-bcee32c40ee1}) of ThingClass awning ---------- @@ -381,20 +456,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}) ---------- @@ -402,13 +477,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}) From 828598e2dac4d5863ec45d1b4097440fb3fd9d35 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Sun, 4 Apr 2021 23:09:40 +0200 Subject: [PATCH 3/3] somfytahoma: Ignore irrelevant device types Ignore ProtocolGateways (Homekit), ignore Hue lights, ignore internal alarm device. --- somfytahoma/integrationpluginsomfytahoma.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/somfytahoma/integrationpluginsomfytahoma.cpp b/somfytahoma/integrationpluginsomfytahoma.cpp index f220b4ca..d61f90d7 100644 --- a/somfytahoma/integrationpluginsomfytahoma.cpp +++ b/somfytahoma/integrationpluginsomfytahoma.cpp @@ -139,6 +139,10 @@ void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info) descriptor.setParams(ParamList() << Param(lightThingDeviceUrlParamTypeId, deviceUrl)); unknownDevices.append(descriptor); } + } else if (type == QStringLiteral("ProtocolGateway") || + type == QStringLiteral("Alarm") || + (type == QStringLiteral("Light") && deviceUrl.startsWith("hue"))) { + continue; } else { qCInfo(dcSomfyTahoma()) << "Found unsupperted Somfy device:" << label << type << deviceUrl; }