From ea791afbfaff76b388c533062c20e6093731efa4 Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Tue, 17 Mar 2020 14:49:03 +0100 Subject: [PATCH] added heatign interface, made actions async and fixed device setup --- tado/integrationplugintado.cpp | 86 ++++++++++++++++++++++++++++----- tado/integrationplugintado.h | 1 + tado/integrationplugintado.json | 4 +- 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 92761e94..5485a9d6 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -36,6 +36,7 @@ #include #include #include +#include IntegrationPluginTado::IntegrationPluginTado() { @@ -52,6 +53,7 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString Tado *tado = new Tado(hardwareManager()->networkManager(), username, this); connect(tado, &Tado::tokenReceived, this, &IntegrationPluginTado::onTokenReceived); connect(tado, &Tado::authenticationStatusChanged, this, &IntegrationPluginTado::onAuthenticationStatusChanged); + connect(tado, &Tado::requestExecuted, this, &IntegrationPluginTado::onRequestExecuted); connect(tado, &Tado::connectionChanged, this, &IntegrationPluginTado::onConnectionChanged); connect(tado, &Tado::homesReceived, this, &IntegrationPluginTado::onHomesReceived); connect(tado, &Tado::zonesReceived, this, &IntegrationPluginTado::onZonesReceived); @@ -88,6 +90,7 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) tado = new Tado(hardwareManager()->networkManager(), username, this); connect(tado, &Tado::tokenReceived, this, &IntegrationPluginTado::onTokenReceived); connect(tado, &Tado::authenticationStatusChanged, this, &IntegrationPluginTado::onAuthenticationStatusChanged); + connect(tado, &Tado::requestExecuted, this, &IntegrationPluginTado::onRequestExecuted); connect(tado, &Tado::connectionChanged, this, &IntegrationPluginTado::onConnectionChanged); connect(tado, &Tado::homesReceived, this, &IntegrationPluginTado::onHomesReceived); connect(tado, &Tado::zonesReceived, this, &IntegrationPluginTado::onZonesReceived); @@ -96,14 +99,20 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) tado->getToken(password); m_tadoAccounts.insert(thing->id(), tado); m_asyncDeviceSetup.insert(tado, info); - return; + connect(info, &ThingSetupInfo::aborted, [info, this] { + Tado *tado = m_tadoAccounts.take(info->thing()->id()); + m_asyncDeviceSetup.remove(tado); + tado->deleteLater(); + }); } } else if (thing->thingClassId() == zoneThingClassId) { qCDebug(dcTado) << "Setup tado thermostat" << thing->params(); return info->finish(Thing::ThingErrorNoError); + } else { + return info->finish(Thing::ThingErrorThingClassNotFound); + qCWarning(dcTado()) << "Unhandled thing class in setupDevice"; } - qCWarning(dcTado()) << "Unhandled thing class in setupDevice"; } void IntegrationPluginTado::thingRemoved(Thing *thing) @@ -148,35 +157,56 @@ void IntegrationPluginTado::executeAction(ThingActionInfo *info) if (thing->thingClassId() == zoneThingClassId) { Tado *tado = m_tadoAccounts.value(thing->parentId()); - if (!tado) + if (!tado) { + info->finish(Thing::ThingErrorThingNotFound); return; + } QString homeId = thing->paramValue(zoneThingHomeIdParamTypeId).toString(); QString zoneId = thing->paramValue(zoneThingZoneIdParamTypeId).toString(); if (action.actionTypeId() == zoneModeActionTypeId) { - + QUuid requestId; if (action.param(zoneModeActionModeParamTypeId).value().toString() == "Tado") { - tado->deleteOverlay(homeId, zoneId); + requestId = tado->deleteOverlay(homeId, zoneId); } else if (action.param(zoneModeActionModeParamTypeId).value().toString() == "Off") { - tado->setOverlay(homeId, zoneId, false, thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble()); + requestId = tado->setOverlay(homeId, zoneId, false, thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble()); } else { if(thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble() <= 5.0) { - tado->setOverlay(homeId, zoneId, true, 5); + requestId = tado->setOverlay(homeId, zoneId, true, 5); } else { - tado->setOverlay(homeId, zoneId, true, thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble()); + requestId = tado->setOverlay(homeId, zoneId, true, thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble()); } } - info->finish(Thing::ThingErrorNoError); + m_asyncActions.insert(requestId, info); + connect(info, &ThingActionInfo::aborted, [requestId, this] {m_asyncActions.remove(requestId);}); } else if (action.actionTypeId() == zoneTargetTemperatureActionTypeId) { double temperature = action.param(zoneTargetTemperatureActionTargetTemperatureParamTypeId).value().toDouble(); + QUuid requestId; if (temperature <= 0) { - QUuid requestId = tado->setOverlay(homeId, zoneId, false, 0); - m_asyncActions.insert(requestId, info); + requestId = tado->setOverlay(homeId, zoneId, false, 0); } else { - tado->setOverlay(homeId, zoneId, true, temperature); + requestId = tado->setOverlay(homeId, zoneId, true, temperature); } - info->finish(Thing::ThingErrorNoError); + m_asyncActions.insert(requestId, info); + connect(info, &ThingActionInfo::aborted, [requestId, this] {m_asyncActions.remove(requestId);}); + } else if (action.actionTypeId() == zonePowerActionTypeId) { + bool power = action.param(zonePowerActionPowerParamTypeId).value().toBool(); + QUuid requestId; + double temperature = thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble(); + if (!power) { + requestId = tado->setOverlay(homeId, zoneId, false, 0); + } else { + requestId = tado->setOverlay(homeId, zoneId, true, temperature); + } + m_asyncActions.insert(requestId, info); + connect(info, &ThingActionInfo::aborted, [requestId, this] {m_asyncActions.remove(requestId);}); + } else { + qCWarning(dcTado()) << "Execute action, unhandled actionTypeId" << action.actionTypeId(); + info->finish(Thing::ThingErrorActionTypeNotFound); } + } else { + qCWarning(dcTado()) << "Execute action, unhandled thingClassId" << thing->thingClassId(); + info->finish(Thing::ThingErrorThingClassNotFound); } } @@ -197,8 +227,24 @@ void IntegrationPluginTado::onConnectionChanged(bool connected) { Tado *tado = static_cast(sender()); + if (m_asyncDeviceSetup.contains(tado)) { + // thing setup failed, try as lon as ThingSetupInfo is valid. + if (!connected) { + QTimer::singleShot(2000, [tado, this]{ + if(m_asyncDeviceSetup.contains(tado)){ + //Check once more if the ThingSetupInfo is still valid + pluginStorage()->beginGroup(m_asyncDeviceSetup.value(tado)->thing()->id().toString()); + QString password = pluginStorage()->value("password").toString(); + pluginStorage()->endGroup(); + tado->getToken(password); + } + }); + } + } if (m_tadoAccounts.values().contains(tado)){ Thing *thing = myThings().findById(m_tadoAccounts.key(tado)); + if (!thing) + return; thing->setStateValue(tadoConnectionConnectedStateTypeId, connected); foreach(Thing *zoneThing, myThings().filterByParentId(thing->id())) { @@ -220,10 +266,24 @@ void IntegrationPluginTado::onAuthenticationStatusChanged(bool authenticated) if (m_tadoAccounts.values().contains(tado)){ Thing *thing = myThings().findById(m_tadoAccounts.key(tado)); + if (!thing) + return; thing->setStateValue(tadoConnectionLoggedInStateTypeId, authenticated); } } +void IntegrationPluginTado::onRequestExecuted(QUuid requestId, bool success) +{ + if (m_asyncActions.contains(requestId)) { + ThingActionInfo *info = m_asyncActions.take(requestId); + if (success) { + info->finish(Thing::ThingErrorNoError); + } else { + info->finish(Thing::ThingErrorHardwareNotAvailable); + } + } +} + void IntegrationPluginTado::onTokenReceived(Tado::Token token) { Q_UNUSED(token); diff --git a/tado/integrationplugintado.h b/tado/integrationplugintado.h index 5f4485ed..23c46063 100644 --- a/tado/integrationplugintado.h +++ b/tado/integrationplugintado.h @@ -68,6 +68,7 @@ private slots: void onConnectionChanged(bool connected); void onAuthenticationStatusChanged(bool authenticated); + void onRequestExecuted(QUuid requestId, bool success); void onTokenReceived(Tado::Token token); void onHomesReceived(QList homes); void onZonesReceived(const QString &homeId, QList zones); diff --git a/tado/integrationplugintado.json b/tado/integrationplugintado.json index 161dacbd..b2d722f5 100644 --- a/tado/integrationplugintado.json +++ b/tado/integrationplugintado.json @@ -46,7 +46,7 @@ "id": "1a7bb944-fb9c-490a-8a4c-794b27282292", "name": "zone", "displayName": "Zone", - "interfaces": ["thermostat", "temperaturesensor", "connectable"], + "interfaces": ["heating", "thermostat", "temperaturesensor", "connectable"], "createMethods": ["auto"], "paramTypes": [ { @@ -110,7 +110,9 @@ "name": "power", "displayName": "Power", "displayNameEvent": "Power changed", + "displayNameAction": "Set power", "type": "bool", + "writable": true, "defaultValue": false }, {