From ea791afbfaff76b388c533062c20e6093731efa4 Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Tue, 17 Mar 2020 14:49:03 +0100 Subject: [PATCH 1/5] 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 }, { From a5b74dc4cce2f3c9e9fddf96d29f4972fad1f37d Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Wed, 18 Mar 2020 20:42:10 +0100 Subject: [PATCH 2/5] removed thermostat interface --- tado/integrationplugintado.cpp | 1 + tado/integrationplugintado.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 5485a9d6..5262909c 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -191,6 +191,7 @@ void IntegrationPluginTado::executeAction(ThingActionInfo *info) connect(info, &ThingActionInfo::aborted, [requestId, this] {m_asyncActions.remove(requestId);}); } else if (action.actionTypeId() == zonePowerActionTypeId) { bool power = action.param(zonePowerActionPowerParamTypeId).value().toBool(); + thing->setStateValue(zonePowerStateTypeId, power); // the actual power set response might be slow QUuid requestId; double temperature = thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble(); if (!power) { diff --git a/tado/integrationplugintado.json b/tado/integrationplugintado.json index b2d722f5..29a95edd 100644 --- a/tado/integrationplugintado.json +++ b/tado/integrationplugintado.json @@ -46,7 +46,7 @@ "id": "1a7bb944-fb9c-490a-8a4c-794b27282292", "name": "zone", "displayName": "Zone", - "interfaces": ["heating", "thermostat", "temperaturesensor", "connectable"], + "interfaces": ["heating", "temperaturesensor", "humiditysensor", "connectable"], "createMethods": ["auto"], "paramTypes": [ { From 1291311d0c32ce8387124b5b1e337386ddbcbcec Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Mon, 6 Apr 2020 21:23:32 +0200 Subject: [PATCH 3/5] fixed re-authorization --- tado/integrationplugintado.cpp | 28 ++++++++- tado/tado.cpp | 106 +++++++++++++++++++++------------ tado/tado.h | 7 +++ 3 files changed, 100 insertions(+), 41 deletions(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 5262909c..6f5a16d9 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -45,7 +45,18 @@ IntegrationPluginTado::IntegrationPluginTado() void IntegrationPluginTado::startPairing(ThingPairingInfo *info) { - info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please enter the login credentials.")); + // Checking the internet connection + NetworkAccessManager *network = hardwareManager()->networkManager(); + QNetworkReply *reply = network->get(QNetworkRequest(QUrl("https://my.tado.com/api/v2"))); + connect(reply, &QNetworkReply::finished, this, [reply, info] { + reply->deleteLater(); + + if (reply->error() == QNetworkReply::NetworkError::HostNotFoundError) { + info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Tado server is not reachable.")); + } else { + info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please enter the login credentials for your Tado account.")); + } + }); } void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &password) @@ -164,14 +175,14 @@ void IntegrationPluginTado::executeAction(ThingActionInfo *info) QString homeId = thing->paramValue(zoneThingHomeIdParamTypeId).toString(); QString zoneId = thing->paramValue(zoneThingZoneIdParamTypeId).toString(); if (action.actionTypeId() == zoneModeActionTypeId) { - QUuid requestId; + QUuid requestId; if (action.param(zoneModeActionModeParamTypeId).value().toString() == "Tado") { requestId = tado->deleteOverlay(homeId, zoneId); } else if (action.param(zoneModeActionModeParamTypeId).value().toString() == "Off") { requestId = tado->setOverlay(homeId, zoneId, false, thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble()); } else { if(thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble() <= 5.0) { - requestId = tado->setOverlay(homeId, zoneId, true, 5); + requestId = tado->setOverlay(homeId, zoneId, true, 5); } else { requestId = tado->setOverlay(homeId, zoneId, true, thing->stateValue(zoneTargetTemperatureStateTypeId).toDouble()); } @@ -270,6 +281,17 @@ void IntegrationPluginTado::onAuthenticationStatusChanged(bool authenticated) if (!thing) return; thing->setStateValue(tadoConnectionLoggedInStateTypeId, authenticated); + + if (!authenticated) { + QTimer::singleShot(5000, [this, tado, thing] { + if (!tado->connected()) { + pluginStorage()->beginGroup(thing->id().toString()); + QString password = pluginStorage()->value("password").toString(); + pluginStorage()->endGroup(); + tado->getToken(password); + } + }); + } } } diff --git a/tado/tado.cpp b/tado/tado.cpp index 21f4b329..462a6d70 100644 --- a/tado/tado.cpp +++ b/tado/tado.cpp @@ -56,6 +56,16 @@ QString Tado::username() return m_username; } +bool Tado::authenticated() +{ + return m_authenticationStatus; +} + +bool Tado::connected() +{ + return m_connectionStatus; +} + void Tado::getToken(const QString &password) { QNetworkRequest request; @@ -78,15 +88,15 @@ void Tado::getToken(const QString &password) // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } - if (status == 401) { - emit authenticationStatusChanged(false); + if (status == 401 || status == 400) { + setAuthenticationStatus(false); } qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); return; } - emit connectionChanged(true); + setConnectionStatus(true); QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); @@ -111,15 +121,15 @@ void Tado::getToken(const QString &password) token.expires = obj["expires_in"].toInt(); m_refreshTimer->start((token.expires - 10)*1000); } else { - qCWarning(dcTado()) << "Received response doesn't contain an expire time"; + qCWarning(dcTado()) << "Received response doesn't contain an expire time"; } token.scope = obj["scope"].toString(); token.jti = obj["jti"].toString(); - emit authenticationStatusChanged(true); + setAuthenticationStatus(true); emit tokenReceived(token); } else { qCWarning(dcTado()) << "Received response isn't an object" << data.toJson(); - emit authenticationStatusChanged(false); + setAuthenticationStatus(false); } }); } @@ -139,16 +149,16 @@ void Tado::getHomes() // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } - if (status == 401) { - emit authenticationStatusChanged(false); + if (status == 401 || status == 400) { + setAuthenticationStatus(false); } qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); return; } - emit connectionChanged(true); - emit authenticationStatusChanged(true); + setConnectionStatus(true); + setAuthenticationStatus(true); QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); @@ -184,16 +194,16 @@ void Tado::getZones(const QString &homeId) // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } - if (status == 401) { - emit authenticationStatusChanged(false); + if (status == 401 || status == 400) { + setAuthenticationStatus(false); } qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); return; } - emit connectionChanged(true); - emit authenticationStatusChanged(true); + setConnectionStatus(true); + setAuthenticationStatus(true); QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); @@ -230,17 +240,17 @@ void Tado::getZoneState(const QString &homeId, const QString &zoneId) // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } - if (status == 401) { - emit authenticationStatusChanged(false); + if (status == 401 || status == 400) { + setAuthenticationStatus(false); } qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); return; } - emit connectionChanged(true); - emit authenticationStatusChanged(true); + setConnectionStatus(true); + setAuthenticationStatus(true); QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); @@ -291,9 +301,9 @@ QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, QByteArray body; QByteArray powerString; if (power) - powerString = "ON"; + powerString = "ON"; else - powerString = "OFF"; + powerString = "OFF"; body.append("{\"setting\":{\"type\":\"HEATING\",\"power\":\""+ powerString + "\",\"temperature\":{\"celsius\":" + QVariant(targetTemperature).toByteArray() + "}},\"termination\":{\"type\":\"MANUAL\"}}"); //qCDebug(dcTado()) << "Sending request" << body; @@ -306,10 +316,10 @@ QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, if (status != 200 || reply->error() != QNetworkReply::NoError) { emit requestExecuted(requestId, false); if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } - if (status == 401) { //Unauthorized - emit authenticationStatusChanged(false); + if (status == 401 || status == 400) { //Unauthorized + setAuthenticationStatus(false); } else if (status == 422) { //Unprocessable Entity qCWarning(dcTado()) << "Unprocessable Entity, probably a value out of range"; } else { @@ -317,8 +327,8 @@ QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, } return; } - emit authenticationStatusChanged(true); - emit connectionChanged(true); + setAuthenticationStatus(true); + setConnectionStatus(true); emit requestExecuted(requestId, true); QJsonParseError error; @@ -358,10 +368,10 @@ QUuid Tado::deleteOverlay(const QString &homeId, const QString &zoneId) if (status < 200 || status > 210 || reply->error() != QNetworkReply::NoError) { emit requestExecuted(requestId ,false); if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } - if (status == 401) { //Unauthorized - emit authenticationStatusChanged(false); + if (status == 401 || status == 400) { //Unauthorized + setAuthenticationStatus(false); } else if (status == 422) { //Unprocessable Entity qCWarning(dcTado()) << "Unprocessable Entity, probably a value out of range"; } else { @@ -370,8 +380,8 @@ QUuid Tado::deleteOverlay(const QString &homeId, const QString &zoneId) qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); return; } - emit authenticationStatusChanged(true); - emit connectionChanged(true); + setAuthenticationStatus(true); + setConnectionStatus(true); emit requestExecuted(requestId, true); QJsonParseError error; @@ -396,6 +406,26 @@ QUuid Tado::deleteOverlay(const QString &homeId, const QString &zoneId) return requestId; } +void Tado::setAuthenticationStatus(bool status) +{ + if (m_authenticationStatus != status) { + m_authenticationStatus = status; + emit authenticationStatusChanged(status); + } + + if (!status) { + m_refreshTimer->stop(); + } +} + +void Tado::setConnectionStatus(bool status) +{ + if (m_connectionStatus != status) { + m_connectionStatus = status; + emit connectionChanged(status); + } +} + void Tado::onRefreshTimer() { QNetworkRequest request; @@ -416,16 +446,16 @@ void Tado::onRefreshTimer() // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { if (reply->error() == QNetworkReply::HostNotFoundError) { - emit connectionChanged(false); + setConnectionStatus(false); } if (status == 400 || status == 401) { - emit authenticationStatusChanged(false); + setAuthenticationStatus(false); } qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); return; } - emit connectionChanged(true); - emit authenticationStatusChanged(true); + setConnectionStatus(true); + setAuthenticationStatus(true); QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); diff --git a/tado/tado.h b/tado/tado.h index 856b9565..1efa7a76 100644 --- a/tado/tado.h +++ b/tado/tado.h @@ -93,6 +93,8 @@ public: void setUsername(const QString &username); QString username(); + bool authenticated(); + bool connected(); void getToken(const QString &password); void getHomes(); @@ -114,6 +116,11 @@ private: QString m_refreshToken; QTimer *m_refreshTimer = nullptr; + bool m_authenticationStatus = false; + bool m_connectionStatus = false; + void setAuthenticationStatus(bool status); + void setConnectionStatus(bool status); + signals: void connectionChanged(bool connected); void authenticationStatusChanged(bool authenticated); From f6bdaa9da966a6a710a7dc3d955fb0de4becf0ef Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Mon, 6 Apr 2020 21:55:13 +0200 Subject: [PATCH 4/5] added german translation --- ...2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts | 245 ++++++++++++++++++ ...2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts | 110 ++++---- 2 files changed, 307 insertions(+), 48 deletions(-) create mode 100644 tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts diff --git a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts new file mode 100644 index 00000000..511057f9 --- /dev/null +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts @@ -0,0 +1,245 @@ + + + + + IntegrationPluginTado + + + Tado server is not reachable. + Tado-Server ist nicht erreichbar. + + + + Please enter the login credentials for your Tado account. + Bitte geben Sie die Anmeldeinformationen für Ihr Tado-Konto ein. + + + + Tado + + + + + + Available + The name of the ParamType (ThingClass: zone, EventType: connected, ID: {9f45a703-6a15-447c-a77a-0df731cda48e}) +---------- +The name of the StateType ({9f45a703-6a15-447c-a77a-0df731cda48e}) of ThingClass zone +---------- +The name of the ParamType (ThingClass: tadoConnection, EventType: connected, ID: {2f79bc1d-27ed-480a-b583-728363c83ea6}) +---------- +The name of the StateType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoConnection + Verfügbar + + + + + Available changed + The name of the EventType ({9f45a703-6a15-447c-a77a-0df731cda48e}) of ThingClass zone +---------- +The name of the EventType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoConnection + Verfügbar geändert + + + + Home id + The name of the ParamType (ThingClass: zone, Type: thing, ID: {330cad74-6f07-42ad-b226-299927c3c4f0}) + Home id + + + + + Humidity + The name of the ParamType (ThingClass: zone, EventType: humidity, ID: {0faaaff1-2a33-44ec-b68d-d8855f584b02}) +---------- +The name of the StateType ({0faaaff1-2a33-44ec-b68d-d8855f584b02}) of ThingClass zone + Luftfeuchte + + + + Humidity changed + The name of the EventType ({0faaaff1-2a33-44ec-b68d-d8855f584b02}) of ThingClass zone + Luftfeuchte geändert + + + + + Logged in + The name of the ParamType (ThingClass: tadoConnection, EventType: loggedIn, ID: {2aed240b-8c5c-418b-a9d1-0d75412c1c27}) +---------- +The name of the StateType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection + Eingelogged + + + + Logged in changed + The name of the EventType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection + Eingelogged geändert + + + + + + Mode + The name of the ParamType (ThingClass: zone, ActionType: mode, ID: {4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) +---------- +The name of the ParamType (ThingClass: zone, EventType: mode, ID: {4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) +---------- +The name of the StateType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass zone + Modus + + + + Mode changed + The name of the EventType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass zone + Modus geändert + + + + + + Power + The name of the ParamType (ThingClass: zone, ActionType: power, ID: {e886377d-34b7-4908-ad0d-ed463fc6181d}) +---------- +The name of the ParamType (ThingClass: zone, EventType: power, ID: {e886377d-34b7-4908-ad0d-ed463fc6181d}) +---------- +The name of the StateType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass zone + Eingeschalten + + + + Power changed + The name of the EventType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass zone + Eingeschalten geändert + + + + Set mode + The name of the ActionType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass zone + Setze Modus + + + + Set power + The name of the ActionType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass zone + Setze Eingeschalten + + + + Set target temperature + The name of the ActionType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass zone + Setze Zieltemperatur + + + + + Tado + The name of the vendor ({23c8a19f-bd6a-4c90-bcc9-2f0c0d9292c5}) +---------- +The name of the plugin Tado ({b4f2d2ee-50bb-4786-b7f5-261fed204fa5}) + Tado + + + + Tado Connection + The name of the ThingClass ({69be7d15-5658-4442-872e-42abbd8bff81}) + Tado Verbindung + + + + + Tado mode + The name of the ParamType (ThingClass: zone, EventType: tadoMode, ID: {8b800998-5c2d-4940-9d0e-036979cf49ca}) +---------- +The name of the StateType ({8b800998-5c2d-4940-9d0e-036979cf49ca}) of ThingClass zone + Tado Modus + + + + Tado mode changed + The name of the EventType ({8b800998-5c2d-4940-9d0e-036979cf49ca}) of ThingClass zone + Tado Modus geändert + + + + + + Target temperature + The name of the ParamType (ThingClass: zone, ActionType: targetTemperature, ID: {684fcc62-f12b-4669-988e-4b79f153b0f2}) +---------- +The name of the ParamType (ThingClass: zone, EventType: targetTemperature, ID: {684fcc62-f12b-4669-988e-4b79f153b0f2}) +---------- +The name of the StateType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass zone + Zieltemperatur + + + + Target temperature changed + The name of the EventType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass zone + Zieltemperatur geändert + + + + + Temperature + The name of the ParamType (ThingClass: zone, EventType: temperature, ID: {80098178-7d92-43dd-a216-23704cc0eaa2}) +---------- +The name of the StateType ({80098178-7d92-43dd-a216-23704cc0eaa2}) of ThingClass zone + Temperatur + + + + Temperature changed + The name of the EventType ({80098178-7d92-43dd-a216-23704cc0eaa2}) of ThingClass zone + Temperatur geändert + + + + Type + The name of the ParamType (ThingClass: zone, Type: thing, ID: {8e86797e-5333-4428-9dba-9ed5ac243b44}) + Typ + + + + + Username + The name of the ParamType (ThingClass: tadoConnection, EventType: userDisplayName, ID: {33f55afc-a673-47a4-9fb0-75fdac6a66f4}) +---------- +The name of the StateType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection + Benutzername + + + + Username changed + The name of the EventType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection + Passwort + + + + + Window open + The name of the ParamType (ThingClass: zone, EventType: windowOpen, ID: {c7a04e26-bb22-406e-b117-262bdb8b9c0e}) +---------- +The name of the StateType ({c7a04e26-bb22-406e-b117-262bdb8b9c0e}) of ThingClass zone + Fenster offen + + + + Window open changed + The name of the EventType ({c7a04e26-bb22-406e-b117-262bdb8b9c0e}) of ThingClass zone + Fenster offen geändert + + + + Zone + The name of the ThingClass ({1a7bb944-fb9c-490a-8a4c-794b27282292}) + Zone + + + + Zone id + The name of the ParamType (ThingClass: zone, Type: thing, ID: {cd67476b-978d-4a22-a40e-50cbc941e09e}) + Zonen-ID + + + diff --git a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts index 32cc7ded..a142ff51 100644 --- a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts @@ -2,20 +2,25 @@ - DevicePluginTado + IntegrationPluginTado - - Please enter the login credentials. + + Tado server is not reachable. + + + + + Please enter the login credentials for your Tado account. Tado - - - - + + + + Available The name of the ParamType (ThingClass: zone, EventType: connected, ID: {9f45a703-6a15-447c-a77a-0df731cda48e}) ---------- @@ -27,8 +32,8 @@ The name of the StateType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass - - + + Available changed The name of the EventType ({9f45a703-6a15-447c-a77a-0df731cda48e}) of ThingClass zone ---------- @@ -36,14 +41,14 @@ The name of the EventType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass - + Home id The name of the ParamType (ThingClass: zone, Type: thing, ID: {330cad74-6f07-42ad-b226-299927c3c4f0}) - - + + Humidity The name of the ParamType (ThingClass: zone, EventType: humidity, ID: {0faaaff1-2a33-44ec-b68d-d8855f584b02}) ---------- @@ -51,14 +56,14 @@ The name of the StateType ({0faaaff1-2a33-44ec-b68d-d8855f584b02}) of ThingClass - + Humidity changed The name of the EventType ({0faaaff1-2a33-44ec-b68d-d8855f584b02}) of ThingClass zone - - + + Logged in The name of the ParamType (ThingClass: tadoConnection, EventType: loggedIn, ID: {2aed240b-8c5c-418b-a9d1-0d75412c1c27}) ---------- @@ -66,15 +71,15 @@ The name of the StateType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass - + Logged in changed The name of the EventType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection - - - + + + Mode The name of the ParamType (ThingClass: zone, ActionType: mode, ID: {4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) ---------- @@ -84,41 +89,50 @@ The name of the StateType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass - + Mode changed The name of the EventType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass zone - - + + + Power - The name of the ParamType (ThingClass: zone, EventType: power, ID: {e886377d-34b7-4908-ad0d-ed463fc6181d}) + The name of the ParamType (ThingClass: zone, ActionType: power, ID: {e886377d-34b7-4908-ad0d-ed463fc6181d}) +---------- +The name of the ParamType (ThingClass: zone, EventType: power, ID: {e886377d-34b7-4908-ad0d-ed463fc6181d}) ---------- The name of the StateType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass zone - + Power changed The name of the EventType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass zone - + Set mode The name of the ActionType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass zone - + + Set power + The name of the ActionType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass zone + + + + Set target temperature The name of the ActionType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass zone - - + + Tado The name of the vendor ({23c8a19f-bd6a-4c90-bcc9-2f0c0d9292c5}) ---------- @@ -126,14 +140,14 @@ The name of the plugin Tado ({b4f2d2ee-50bb-4786-b7f5-261fed204fa5}) - + Tado Connection The name of the ThingClass ({69be7d15-5658-4442-872e-42abbd8bff81}) - - + + Tado mode The name of the ParamType (ThingClass: zone, EventType: tadoMode, ID: {8b800998-5c2d-4940-9d0e-036979cf49ca}) ---------- @@ -141,15 +155,15 @@ The name of the StateType ({8b800998-5c2d-4940-9d0e-036979cf49ca}) of ThingClass - + Tado mode changed The name of the EventType ({8b800998-5c2d-4940-9d0e-036979cf49ca}) of ThingClass zone - - - + + + Target temperature The name of the ParamType (ThingClass: zone, ActionType: targetTemperature, ID: {684fcc62-f12b-4669-988e-4b79f153b0f2}) ---------- @@ -159,14 +173,14 @@ The name of the StateType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass - + Target temperature changed The name of the EventType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass zone - - + + Temperature The name of the ParamType (ThingClass: zone, EventType: temperature, ID: {80098178-7d92-43dd-a216-23704cc0eaa2}) ---------- @@ -174,20 +188,20 @@ The name of the StateType ({80098178-7d92-43dd-a216-23704cc0eaa2}) of ThingClass - + Temperature changed The name of the EventType ({80098178-7d92-43dd-a216-23704cc0eaa2}) of ThingClass zone - + Type The name of the ParamType (ThingClass: zone, Type: thing, ID: {8e86797e-5333-4428-9dba-9ed5ac243b44}) - - + + Username The name of the ParamType (ThingClass: tadoConnection, EventType: userDisplayName, ID: {33f55afc-a673-47a4-9fb0-75fdac6a66f4}) ---------- @@ -195,14 +209,14 @@ The name of the StateType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass - + Username changed The name of the EventType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection - - + + Window open The name of the ParamType (ThingClass: zone, EventType: windowOpen, ID: {c7a04e26-bb22-406e-b117-262bdb8b9c0e}) ---------- @@ -210,19 +224,19 @@ The name of the StateType ({c7a04e26-bb22-406e-b117-262bdb8b9c0e}) of ThingClass - + Window open changed The name of the EventType ({c7a04e26-bb22-406e-b117-262bdb8b9c0e}) of ThingClass zone - + Zone The name of the ThingClass ({1a7bb944-fb9c-490a-8a4c-794b27282292}) - + Zone id The name of the ParamType (ThingClass: zone, Type: thing, ID: {cd67476b-978d-4a22-a40e-50cbc941e09e}) From 39b52a4f7e9a5416eeb75499370f072b2ac920fc Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Thu, 28 May 2020 14:10:23 +0200 Subject: [PATCH 5/5] changes requested by reviewer --- tado/integrationplugintado.cpp | 12 ++++++------ ...ts => b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts} | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) rename tado/translations/{b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts => b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts} (99%) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 6f5a16d9..bb236ff3 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -48,8 +48,7 @@ void IntegrationPluginTado::startPairing(ThingPairingInfo *info) // Checking the internet connection NetworkAccessManager *network = hardwareManager()->networkManager(); QNetworkReply *reply = network->get(QNetworkRequest(QUrl("https://my.tado.com/api/v2"))); - connect(reply, &QNetworkReply::finished, this, [reply, info] { - reply->deleteLater(); + connect(reply, &QNetworkReply::finished, info, [reply, info] { if (reply->error() == QNetworkReply::NetworkError::HostNotFoundError) { info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Tado server is not reachable.")); @@ -57,6 +56,7 @@ void IntegrationPluginTado::startPairing(ThingPairingInfo *info) info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please enter the login credentials for your Tado account.")); } }); + connect(reply, &QNetworkReply::finished, this, &QNetworkReply::deleteLater); } void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &password) @@ -240,9 +240,9 @@ 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. + //Thing setup failed, try as long as ThingSetupInfo is valid. if (!connected) { - QTimer::singleShot(2000, [tado, this]{ + QTimer::singleShot(2000, tado, [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()); @@ -283,7 +283,7 @@ void IntegrationPluginTado::onAuthenticationStatusChanged(bool authenticated) thing->setStateValue(tadoConnectionLoggedInStateTypeId, authenticated); if (!authenticated) { - QTimer::singleShot(5000, [this, tado, thing] { + QTimer::singleShot(5000, tado, [this, tado, thing] { if (!tado->connected()) { pluginStorage()->beginGroup(thing->id().toString()); QString password = pluginStorage()->value("password").toString(); @@ -309,7 +309,7 @@ void IntegrationPluginTado::onRequestExecuted(QUuid requestId, bool success) void IntegrationPluginTado::onTokenReceived(Tado::Token token) { - Q_UNUSED(token); + Q_UNUSED(token) qCDebug(dcTado()) << "Token received"; Tado *tado = static_cast(sender()); diff --git a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts similarity index 99% rename from tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts rename to tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts index 511057f9..3740f582 100644 --- a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de_DE.ts +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts @@ -1,6 +1,6 @@ - + IntegrationPluginTado