From bc2ff5b7be10d4e0eaff4b5417125ecaf050e14d Mon Sep 17 00:00:00 2001 From: Boernsman Date: Tue, 27 Oct 2020 13:08:25 +0100 Subject: [PATCH 1/7] added dyn. api credentials optaining --- tado/integrationplugintado.cpp | 59 +++++++++------------ tado/tado.cpp | 93 +++++++++++++++++++++++++++++++++- tado/tado.h | 12 +++-- 3 files changed, 125 insertions(+), 39 deletions(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 380dc406..178e15a5 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -63,13 +63,6 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString { qCDebug(dcTado()) << "Confirm pairing" << username << "Network manager available" << hardwareManager()->networkManager()->available(); Tado *tado = new Tado(hardwareManager()->networkManager(), username, this); - 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); - connect(tado, &Tado::zoneStateReceived, this, &IntegrationPluginTado::onZoneStateReceived); - connect(tado, &Tado::overlayReceived, this, &IntegrationPluginTado::onOverlayReceived); m_unfinishedTadoAccounts.insert(info->thingId(), tado); connect(info, &ThingPairingInfo::aborted, this, [info, tado, this]() { @@ -78,13 +71,18 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString tado->deleteLater(); }); - connect(tado, &Tado::connectionError, info, [this, info] (QNetworkReply::NetworkError error){ + connect(tado, &Tado::connectionError, info, [info] (QNetworkReply::NetworkError error){ if (error != QNetworkReply::NetworkError::NoError){ - info->finish(Thing::ThingErrorSetupFailed); + qCWarning(dcTado()) << "Confirm pairing failed" << error; + info->finish(Thing::ThingErrorSetupFailed, tr("Connection error")); } // info->finish(success) will be called after the token has been received }); + connect(tado, &Tado::apiCredentialsReceived, info, [password, tado] { + tado->getToken(password); + }); + connect(tado, &Tado::tokenReceived, info, [this, info, username, password](Tado::Token token) { Q_UNUSED(token) @@ -95,7 +93,7 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString info->finish(Thing::ThingErrorNoError); }); - tado->getToken(password); + tado->getApiCredentials(); } void IntegrationPluginTado::setupThing(ThingSetupInfo *info) @@ -109,7 +107,7 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) if (m_unfinishedTadoAccounts.contains(thing->id())) { tado = m_unfinishedTadoAccounts.take(thing->id()); m_tadoAccounts.insert(thing->id(), tado); - return info->finish(Thing::ThingErrorNoError); + info->finish(Thing::ThingErrorNoError); } else { pluginStorage()->beginGroup(thing->id().toString()); QString username = pluginStorage()->value("username").toString(); @@ -117,14 +115,6 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) pluginStorage()->endGroup(); tado = new Tado(hardwareManager()->networkManager(), username, this); - 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); - connect(tado, &Tado::zoneStateReceived, this, &IntegrationPluginTado::onZoneStateReceived); - connect(tado, &Tado::overlayReceived, this, &IntegrationPluginTado::onOverlayReceived); - m_tadoAccounts.insert(thing->id(), tado); connect(info, &ThingSetupInfo::aborted, [info, this] { if (m_tadoAccounts.contains(info->thing()->id())) { @@ -133,7 +123,11 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) } }); - connect(tado, &Tado::tokenReceived, info, [this, info, tado](Tado::Token token) { + connect(tado, &Tado::apiCredentialsReceived, info, [password, tado] { + tado->getToken(password); + }); + + connect(tado, &Tado::tokenReceived, info, [ info](Tado::Token token) { Q_UNUSED(token) qCDebug(dcTado()) << "Token received, account setup successfull"; @@ -141,18 +135,7 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) }); connect(tado, &Tado::connectionError, info, [this, info] (QNetworkReply::NetworkError error){ - if (error == QNetworkReply::NetworkError::HostNotFoundError) { - QTimer::singleShot(2000, info, [info, this] { - - pluginStorage()->beginGroup(info->thing()->id().toString()); - QString password = pluginStorage()->value("password").toString(); - pluginStorage()->endGroup(); - if (m_tadoAccounts.contains(info->thing()->id())) { - Tado *tado = m_tadoAccounts.take(info->thing()->id()); - tado->getToken(password); - } - }); - } else if (error != QNetworkReply::NetworkError::NoError){ + if (error != QNetworkReply::NetworkError::NoError){ if (m_tadoAccounts.contains(info->thing()->id())) { Tado *tado = m_tadoAccounts.take(info->thing()->id()); tado->deleteLater(); @@ -160,15 +143,23 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) info->finish(Thing::ThingErrorSetupFailed); } }); - tado->getToken(password); + tado->getApiCredentials(); } + 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); + connect(tado, &Tado::zoneStateReceived, this, &IntegrationPluginTado::onZoneStateReceived); + connect(tado, &Tado::overlayReceived, this, &IntegrationPluginTado::onOverlayReceived); + return; } 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"; + return info->finish(Thing::ThingErrorThingClassNotFound); } } diff --git a/tado/tado.cpp b/tado/tado.cpp index 71338c39..c52a7bee 100644 --- a/tado/tado.cpp +++ b/tado/tado.cpp @@ -56,6 +56,11 @@ QString Tado::username() return m_username; } +bool Tado::apiAvailable() +{ + return m_apiAvailable; +} + bool Tado::authenticated() { return m_authenticationStatus; @@ -66,8 +71,61 @@ bool Tado::connected() return m_connectionStatus; } +void Tado::getApiCredentials(const QString &url) +{ + QNetworkRequest request; + request.setUrl(url); + QNetworkReply *reply = m_networkManager->get(request); + qCDebug(dcTado()) << "Sending request" << request.url(); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, this, [reply, this] { + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + // Check HTTP status code + if (status != 200 || reply->error() != QNetworkReply::NoError) { + qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); + return; + } + QRegExp filter; + filter.setPatternSyntax(QRegExp::Wildcard); + filter.setPattern("*tgaRestApiV2Endpoint:*"); + + QStringList list = QString(reply->readAll()).split('\n'); + int index = list.indexOf(filter); + if (index == -1) + return; + m_baseControlUrl = list.value(index).split(": ").last().remove(QRegExp("[,']"));; + qCDebug(dcTado()) << "Received control url" << m_baseControlUrl; + filter.setPattern("*apiEndpoint*"); + index = list.indexOf(filter); + if (index == -1) + return; + m_baseAuthorizationUrl = list.value(index).split(": ").last().remove(QRegExp("[,']"))+"/token"; + qCDebug(dcTado()) << "Received auth url" << m_baseAuthorizationUrl; + filter.setPattern("*clientId*"); + index = list.indexOf(filter); + if (index == -1) + return; + m_clientId = list.value(index).split(": ").last().remove(QRegExp("[,']")); + qCDebug(dcTado()) << "Received client id" << m_clientId; + filter.setPattern("*clientSecret*"); + index = list.indexOf(filter); + if (index == -1) + return; + m_clientSecret = list.value(index).split(": ").last().remove(QRegExp("[,']")); + qCDebug(dcTado()) << "Received client secret" << m_clientSecret; + m_apiAvailable = true; + emit apiCredentialsReceived(); + }); +} + void Tado::getToken(const QString &password) { + if (!m_apiAvailable) { + qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + return; + } + QNetworkRequest request; request.setUrl(QUrl(m_baseAuthorizationUrl)); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/x-www-form-urlencoded"); @@ -102,7 +160,7 @@ void Tado::getToken(const QString &password) QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Received invalide JSON object"; + qDebug(dcTado()) << "Get Token: Received invalide JSON object:" << data; return; } if (data.isObject()) { @@ -137,6 +195,11 @@ void Tado::getToken(const QString &password) void Tado::getHomes() { + if (!m_apiAvailable) { + qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + return; + } + if(m_accessToken.isEmpty()) { qCWarning(dcTado()) << "Not sending request, get the access token first"; return; @@ -188,6 +251,16 @@ void Tado::getHomes() void Tado::getZones(const QString &homeId) { + if (!m_apiAvailable) { + qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + return; + } + + if(m_accessToken.isEmpty()) { + qCWarning(dcTado()) << "Not sending request, get the access token first"; + return; + } + QNetworkRequest request; request.setUrl(QUrl(m_baseControlUrl+"/homes/"+homeId+"/zones")); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/x-www-form-urlencoded"); @@ -235,10 +308,16 @@ void Tado::getZones(const QString &homeId) void Tado::getZoneState(const QString &homeId, const QString &zoneId) { + if (!m_apiAvailable) { + qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + return; + } + if(m_accessToken.isEmpty()) { qCWarning(dcTado()) << "Not sending request, get the access token first"; return; } + QNetworkRequest request; request.setUrl(QUrl(m_baseControlUrl+"/homes/"+homeId+"/zones/"+zoneId+"/state")); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/x-www-form-urlencoded"); @@ -307,10 +386,16 @@ void Tado::getZoneState(const QString &homeId, const QString &zoneId) QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, double targetTemperature) { + if (!m_apiAvailable) { + qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + return ""; + } + if(m_accessToken.isEmpty()) { qCWarning(dcTado()) << "Not sending request, get the access token first"; return ""; } + QUuid requestId = QUuid::createUuid(); QNetworkRequest request; request.setUrl(QUrl(m_baseControlUrl+"/homes/"+homeId+"/zones/"+zoneId+"/overlay")); @@ -376,10 +461,16 @@ QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, QUuid Tado::deleteOverlay(const QString &homeId, const QString &zoneId) { + if (!m_apiAvailable) { + qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + return ""; + } + if(m_accessToken.isEmpty()) { qCWarning(dcTado()) << "Not sending request, get the access token first"; return ""; } + QUuid requestId = QUuid::createUuid(); QNetworkRequest request; request.setUrl(QUrl(m_baseControlUrl+"/homes/"+homeId+"/zones/"+zoneId+"/overlay")); diff --git a/tado/tado.h b/tado/tado.h index 1e813130..3fe7fb78 100644 --- a/tado/tado.h +++ b/tado/tado.h @@ -93,9 +93,11 @@ public: void setUsername(const QString &username); QString username(); + bool apiAvailable(); bool authenticated(); bool connected(); + void getApiCredentials(const QString &url = "https://my.tado.com/webapp/env.js"); void getToken(const QString &password); void getHomes(); void getZones(const QString &homeId); @@ -105,10 +107,11 @@ public: QUuid deleteOverlay(const QString &homeId, const QString &zoneId); private: - QByteArray m_baseAuthorizationUrl = "https://auth.tado.com/oauth/token"; - QByteArray m_baseControlUrl = "https://my.tado.com/api/v2"; - QByteArray m_clientSecret = "4HJGRffVR8xb3XdEUQpjgZ1VplJi6Xgw"; - QByteArray m_clientId = "public-api-preview"; + bool m_apiAvailable = false; + QString m_baseAuthorizationUrl; + QString m_baseControlUrl; + QString m_clientSecret; + QString m_clientId; NetworkAccessManager *m_networkManager = nullptr; QString m_username; @@ -123,6 +126,7 @@ private: signals: void connectionChanged(bool connected); + void apiCredentialsReceived(); void authenticationStatusChanged(bool authenticated); void requestExecuted(QUuid requestId, bool success); From b9cd18a45e81e39fe152b72aebb53ae3a9053e13 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Tue, 27 Oct 2020 14:01:41 +0100 Subject: [PATCH 2/7] start zone setup after parent setup has been completed --- tado/integrationplugintado.cpp | 74 ++++++++++++++++++++------------- tado/integrationplugintado.json | 12 +++--- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 178e15a5..57232b66 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -100,7 +100,7 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - if (thing->thingClassId() == tadoConnectionThingClassId) { + if (thing->thingClassId() == tadoAccountThingClassId) { qCDebug(dcTado) << "Setup tado connection" << thing->name() << thing->params(); Tado *tado; @@ -155,8 +155,18 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) return; } else if (thing->thingClassId() == zoneThingClassId) { - qCDebug(dcTado) << "Setup tado thermostat" << thing->params(); - return info->finish(Thing::ThingErrorNoError); + qCDebug(dcTado) << "Setup Tado zone" << thing->params(); + Thing *parentThing = myThings().findById(thing->parentId()); + if(parentThing->setupComplete()) { + return info->finish(Thing::ThingErrorNoError); + } else { + connect(parentThing, &Thing::setupStatusChanged, info, [parentThing, info]{ + if (parentThing->setupComplete()) { + info->finish(Thing::ThingErrorNoError); + } + }); + } + } else { qCWarning(dcTado()) << "Unhandled thing class in setupDevice"; return info->finish(Thing::ThingErrorThingClassNotFound); @@ -165,7 +175,7 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) void IntegrationPluginTado::thingRemoved(Thing *thing) { - if (thing->thingClassId() == tadoConnectionThingClassId) { + if (thing->thingClassId() == tadoAccountThingClassId) { Tado *tado = m_tadoAccounts.take(thing->id()); tado->deleteLater(); } @@ -183,11 +193,11 @@ void IntegrationPluginTado::postSetupThing(Thing *thing) connect(m_pluginTimer, &PluginTimer::timeout, this, &IntegrationPluginTado::onPluginTimer); } - if (thing->thingClassId() == tadoConnectionThingClassId) { + if (thing->thingClassId() == tadoAccountThingClassId) { Tado *tado = m_tadoAccounts.value(thing->id()); - thing->setStateValue(tadoConnectionUserDisplayNameStateTypeId, tado->username()); - thing->setStateValue(tadoConnectionLoggedInStateTypeId, true); - thing->setStateValue(tadoConnectionConnectedStateTypeId, true); + thing->setStateValue(tadoAccountUserDisplayNameStateTypeId, tado->username()); + thing->setStateValue(tadoAccountLoggedInStateTypeId, true); + thing->setStateValue(tadoAccountConnectedStateTypeId, true); tado->getHomes(); } else if (thing->thingClassId() == zoneThingClassId) { @@ -261,16 +271,22 @@ void IntegrationPluginTado::executeAction(ThingActionInfo *info) void IntegrationPluginTado::onPluginTimer() { - foreach (Thing *thing, myThings().filterByThingClassId(zoneThingClassId)) { - Tado *tado = m_tadoAccounts.value(thing->parentId()); - if (!tado){ - qCWarning(dcTado()) << "Could not find any Tado connection to Zone" << thing->name(); - continue; + Q_FOREACH(Tado *tado, m_tadoAccounts){ + ThingId accountThingId = m_tadoAccounts.key(tado); + if (!tado->authenticated()) { + pluginStorage()->beginGroup(accountThingId.toString()); + QString password = pluginStorage()->value("password").toString(); + pluginStorage()->endGroup(); + tado->getToken(password); + } else { + Q_FOREACH(Thing *thing, myThings().filterByParentId(accountThingId)) { + if (thing->thingClassId() == zoneThingClassId) { + QString homeId = thing->paramValue(zoneThingHomeIdParamTypeId).toString(); + QString zoneId = thing->paramValue(zoneThingZoneIdParamTypeId).toString(); + tado->getZoneState(homeId, zoneId); + } + } } - - QString homeId = thing->paramValue(zoneThingHomeIdParamTypeId).toString(); - QString zoneId = thing->paramValue(zoneThingZoneIdParamTypeId).toString(); - tado->getZoneState(homeId, zoneId); } } @@ -282,10 +298,14 @@ void IntegrationPluginTado::onConnectionChanged(bool connected) Thing *thing = myThings().findById(m_tadoAccounts.key(tado)); if (!thing) return; - thing->setStateValue(tadoConnectionConnectedStateTypeId, connected); + thing->setStateValue(tadoAccountConnectedStateTypeId, connected); - foreach(Thing *zoneThing, myThings().filterByParentId(thing->id())) { - zoneThing->setStateValue(zoneConnectedStateTypeId, connected); + if (!connected) { + Q_FOREACH(Thing *child, myThings().filterByParentId(thing->id())) { + if (child->thingClassId() == zoneThingClassId) { + child->setStateValue(zoneConnectedStateTypeId, connected); + } + } } } } @@ -300,17 +320,13 @@ void IntegrationPluginTado::onAuthenticationStatusChanged(bool authenticated) qCWarning(dcTado()) << "OnAuthenticationChanged no thing found by ID" << m_tadoAccounts.key(tado); return; } - thing->setStateValue(tadoConnectionLoggedInStateTypeId, authenticated); - + thing->setStateValue(tadoAccountLoggedInStateTypeId, authenticated); if (!authenticated) { - QTimer::singleShot(5000, tado, [this, tado, thing] { - if (!tado->connected()) { - pluginStorage()->beginGroup(thing->id().toString()); - QString password = pluginStorage()->value("password").toString(); - pluginStorage()->endGroup(); - tado->getToken(password); + Q_FOREACH(Thing *child, myThings().filterByParentId(thing->id())) { + if (child->thingClassId() == zoneThingClassId) { + child->setStateValue(zoneConnectedStateTypeId, authenticated); } - }); + } } } } diff --git a/tado/integrationplugintado.json b/tado/integrationplugintado.json index 29a95edd..d50901e6 100644 --- a/tado/integrationplugintado.json +++ b/tado/integrationplugintado.json @@ -10,8 +10,8 @@ "thingClasses": [ { "id": "69be7d15-5658-4442-872e-42abbd8bff81", - "name": "tadoConnection", - "displayName": "Tado Connection", + "name": "tadoAccount", + "displayName": "Tado account", "interfaces": ["account"], "createMethods": ["user"], "setupMethod": "userandpassword", @@ -19,8 +19,8 @@ { "id": "2f79bc1d-27ed-480a-b583-728363c83ea6", "name": "connected", - "displayName": "Available", - "displayNameEvent": "Available changed", + "displayName": "Connected", + "displayNameEvent": "Connected changed", "type": "bool", "defaultValue": false }, @@ -77,8 +77,8 @@ { "id": "9f45a703-6a15-447c-a77a-0df731cda48e", "name": "connected", - "displayName": "Available", - "displayNameEvent": "Available changed", + "displayName": "Connected", + "displayNameEvent": "Connected changed", "type": "bool", "defaultValue": false }, From 99194bded3cc718b7ae1516554251931b4eac7f3 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Mon, 7 Dec 2020 09:19:36 +0100 Subject: [PATCH 3/7] added setup failure on missing client credentials --- tado/integrationplugintado.cpp | 8 ++++++-- tado/tado.cpp | 27 ++++++++++++++++++++------- tado/tado.h | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 57232b66..024b0b86 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -79,8 +79,12 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString // info->finish(success) will be called after the token has been received }); - connect(tado, &Tado::apiCredentialsReceived, info, [password, tado] { - tado->getToken(password); + connect(tado, &Tado::apiCredentialsReceived, info, [info, password, tado] (bool success) { + if (success) { + tado->getToken(password); + } else { + info->finish(Thing::ThingErrorAuthenticationFailure, "Client credentials not found, the plug-in version might be outdated."); + } }); connect(tado, &Tado::tokenReceived, info, [this, info, username, password](Tado::Token token) { diff --git a/tado/tado.cpp b/tado/tado.cpp index c52a7bee..16667a88 100644 --- a/tado/tado.cpp +++ b/tado/tado.cpp @@ -84,6 +84,7 @@ void Tado::getApiCredentials(const QString &url) // Check HTTP status code if (status != 200 || reply->error() != QNetworkReply::NoError) { qCWarning(dcTado()) << "Request error:" << status << reply->errorString(); + emit apiCredentialsReceived(false); return; } QRegExp filter; @@ -92,30 +93,42 @@ void Tado::getApiCredentials(const QString &url) QStringList list = QString(reply->readAll()).split('\n'); int index = list.indexOf(filter); - if (index == -1) + if (index == -1) { + qCWarning(dcTado()) << "GetApiCredenitals: Could not find the API url"; + emit apiCredentialsReceived(false); return; + } m_baseControlUrl = list.value(index).split(": ").last().remove(QRegExp("[,']"));; qCDebug(dcTado()) << "Received control url" << m_baseControlUrl; filter.setPattern("*apiEndpoint*"); index = list.indexOf(filter); - if (index == -1) + if (index == -1) { + qCWarning(dcTado()) << "GetApiCredenitals: Could not find the authorization url"; + emit apiCredentialsReceived(false); return; + } m_baseAuthorizationUrl = list.value(index).split(": ").last().remove(QRegExp("[,']"))+"/token"; qCDebug(dcTado()) << "Received auth url" << m_baseAuthorizationUrl; filter.setPattern("*clientId*"); index = list.indexOf(filter); - if (index == -1) + if (index == -1) { + emit apiCredentialsReceived(false); + qCWarning(dcTado()) << "GetApiCredenitals: Could not find the client Id"; return; + } m_clientId = list.value(index).split(": ").last().remove(QRegExp("[,']")); - qCDebug(dcTado()) << "Received client id" << m_clientId; + qCDebug(dcTado()) << "Received client id" << m_clientId.mid(0, 4)+"*****"; filter.setPattern("*clientSecret*"); index = list.indexOf(filter); - if (index == -1) + if (index == -1) { + qCWarning(dcTado()) << "GetApiCredenitals: Could not find the client secret"; + emit apiCredentialsReceived(false); return; + } m_clientSecret = list.value(index).split(": ").last().remove(QRegExp("[,']")); - qCDebug(dcTado()) << "Received client secret" << m_clientSecret; + qCDebug(dcTado()) << "Received client secret" << m_clientSecret.mid(0, 4)+"*****"; m_apiAvailable = true; - emit apiCredentialsReceived(); + emit apiCredentialsReceived(true); }); } diff --git a/tado/tado.h b/tado/tado.h index 3fe7fb78..5ba134c9 100644 --- a/tado/tado.h +++ b/tado/tado.h @@ -126,7 +126,7 @@ private: signals: void connectionChanged(bool connected); - void apiCredentialsReceived(); + void apiCredentialsReceived(bool success); void authenticationStatusChanged(bool authenticated); void requestExecuted(QUuid requestId, bool success); From 4e69b26888c7de860149998eb235d7ecf705af55 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Mon, 7 Dec 2020 09:22:21 +0100 Subject: [PATCH 4/7] updated translation --- ...b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts | 127 +++++++++--------- ...2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts | 121 +++++++++-------- 2 files changed, 129 insertions(+), 119 deletions(-) diff --git a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts index 3740f582..2cf433d8 100644 --- a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts @@ -13,42 +13,47 @@ Please enter the login credentials for your Tado account. Bitte geben Sie die Anmeldeinformationen für Ihr Tado-Konto ein. + + + Connection error + Verbindungsfehler + Tado - - - - - Available + + + + + Connected 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 ParamType (ThingClass: tadoAccount, EventType: connected, ID: {2f79bc1d-27ed-480a-b583-728363c83ea6}) ---------- -The name of the StateType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoConnection - Verfügbar +The name of the StateType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoAccount + Verbunden - - - Available changed + + + Connected 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 +The name of the EventType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoAccount + Verbunden 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}) ---------- @@ -56,30 +61,30 @@ The name of the StateType ({0faaaff1-2a33-44ec-b68d-d8855f584b02}) of ThingClass 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 ParamType (ThingClass: tadoAccount, EventType: loggedIn, ID: {2aed240b-8c5c-418b-a9d1-0d75412c1c27}) ---------- -The name of the StateType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection +The name of the StateType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoAccount Eingelogged - + Logged in changed - The name of the EventType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection + The name of the EventType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoAccount Eingelogged geändert - - - + + + Mode The name of the ParamType (ThingClass: zone, ActionType: mode, ID: {4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) ---------- @@ -89,15 +94,15 @@ The name of the StateType ({4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) of ThingClass 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}) ---------- @@ -107,32 +112,32 @@ The name of the StateType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass 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}) ---------- @@ -140,14 +145,14 @@ The name of the plugin Tado ({b4f2d2ee-50bb-4786-b7f5-261fed204fa5})Tado - - Tado Connection + + Tado account The name of the ThingClass ({69be7d15-5658-4442-872e-42abbd8bff81}) - Tado Verbindung + Tado-Benutzerkonto - - + + Tado mode The name of the ParamType (ThingClass: zone, EventType: tadoMode, ID: {8b800998-5c2d-4940-9d0e-036979cf49ca}) ---------- @@ -155,15 +160,15 @@ The name of the StateType ({8b800998-5c2d-4940-9d0e-036979cf49ca}) of ThingClass 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}) ---------- @@ -173,14 +178,14 @@ The name of the StateType ({684fcc62-f12b-4669-988e-4b79f153b0f2}) of ThingClass 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}) ---------- @@ -188,35 +193,35 @@ The name of the StateType ({80098178-7d92-43dd-a216-23704cc0eaa2}) of ThingClass 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 ParamType (ThingClass: tadoAccount, EventType: userDisplayName, ID: {33f55afc-a673-47a4-9fb0-75fdac6a66f4}) ---------- -The name of the StateType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection +The name of the StateType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoAccount Benutzername - + Username changed - The name of the EventType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection + The name of the EventType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoAccount Passwort - - + + Window open The name of the ParamType (ThingClass: zone, EventType: windowOpen, ID: {c7a04e26-bb22-406e-b117-262bdb8b9c0e}) ---------- @@ -224,19 +229,19 @@ The name of the StateType ({c7a04e26-bb22-406e-b117-262bdb8b9c0e}) of ThingClass 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 a142ff51..6d1a2698 100644 --- a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts @@ -13,42 +13,47 @@ Please enter the login credentials for your Tado account. + + + Connection error + + Tado - - - - - Available + + + + + Connected 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 ParamType (ThingClass: tadoAccount, EventType: connected, ID: {2f79bc1d-27ed-480a-b583-728363c83ea6}) ---------- -The name of the StateType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoConnection +The name of the StateType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoAccount - - - Available changed + + + Connected 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 +The name of the EventType ({2f79bc1d-27ed-480a-b583-728363c83ea6}) of ThingClass tadoAccount - + 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}) ---------- @@ -56,30 +61,30 @@ 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}) + The name of the ParamType (ThingClass: tadoAccount, EventType: loggedIn, ID: {2aed240b-8c5c-418b-a9d1-0d75412c1c27}) ---------- -The name of the StateType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection +The name of the StateType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoAccount - + Logged in changed - The name of the EventType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoConnection + The name of the EventType ({2aed240b-8c5c-418b-a9d1-0d75412c1c27}) of ThingClass tadoAccount - - - + + + Mode The name of the ParamType (ThingClass: zone, ActionType: mode, ID: {4cecf87c-8a5d-4bc4-a4ba-d2ee6103714b}) ---------- @@ -89,15 +94,15 @@ 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, ActionType: power, ID: {e886377d-34b7-4908-ad0d-ed463fc6181d}) ---------- @@ -107,32 +112,32 @@ The name of the StateType ({e886377d-34b7-4908-ad0d-ed463fc6181d}) of ThingClass - + 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}) ---------- @@ -140,14 +145,14 @@ The name of the plugin Tado ({b4f2d2ee-50bb-4786-b7f5-261fed204fa5}) - - Tado Connection + + Tado account 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}) ---------- @@ -155,15 +160,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}) ---------- @@ -173,14 +178,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}) ---------- @@ -188,35 +193,35 @@ 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}) + The name of the ParamType (ThingClass: tadoAccount, EventType: userDisplayName, ID: {33f55afc-a673-47a4-9fb0-75fdac6a66f4}) ---------- -The name of the StateType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection +The name of the StateType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoAccount - + Username changed - The name of the EventType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoConnection + The name of the EventType ({33f55afc-a673-47a4-9fb0-75fdac6a66f4}) of ThingClass tadoAccount - - + + Window open The name of the ParamType (ThingClass: zone, EventType: windowOpen, ID: {c7a04e26-bb22-406e-b117-262bdb8b9c0e}) ---------- @@ -224,19 +229,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 58e65a042037ca094eb0b01b21ee45951363088b Mon Sep 17 00:00:00 2001 From: Boernsman Date: Mon, 7 Dec 2020 09:51:36 +0100 Subject: [PATCH 5/7] added more debug information --- tado/integrationplugintado.cpp | 26 ++++++++++++++----- ...b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts | 18 ++++++++++--- ...2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts | 18 ++++++++++--- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 024b0b86..936ff3b3 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -45,15 +45,17 @@ IntegrationPluginTado::IntegrationPluginTado() void IntegrationPluginTado::startPairing(ThingPairingInfo *info) { - // Checking the internet connection + qCDebug(dcTado()) << "Start pairing process, checking the internet connection ..."; NetworkAccessManager *network = hardwareManager()->networkManager(); QNetworkReply *reply = network->get(QNetworkRequest(QUrl("https://my.tado.com/api/v2"))); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); connect(reply, &QNetworkReply::finished, info, [reply, info] { if (reply->error() == QNetworkReply::NetworkError::HostNotFoundError) { + qCWarning(dcTado()) << "Tado server is not reachable, likely because of a missing internet connection."; info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Tado server is not reachable.")); } else { + qCDebug(dcTado()) << "Internet connection available"; info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Please enter the login credentials for your Tado account.")); } }); @@ -72,9 +74,13 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString }); connect(tado, &Tado::connectionError, info, [info] (QNetworkReply::NetworkError error){ - if (error != QNetworkReply::NetworkError::NoError){ + + if (error == QNetworkReply::NetworkError::ProtocolInvalidOperationError) { + qCWarning(dcTado()) << "Confirm pairing failed, wrong username or password"; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Wrong username or password.")); + } else if (error != QNetworkReply::NetworkError::NoError){ qCWarning(dcTado()) << "Confirm pairing failed" << error; - info->finish(Thing::ThingErrorSetupFailed, tr("Connection error")); + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Connection error")); } // info->finish(success) will be called after the token has been received }); @@ -83,7 +89,7 @@ void IntegrationPluginTado::confirmPairing(ThingPairingInfo *info, const QString if (success) { tado->getToken(password); } else { - info->finish(Thing::ThingErrorAuthenticationFailure, "Client credentials not found, the plug-in version might be outdated."); + info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Client credentials not found, the plug-in version might be outdated.")); } }); @@ -138,13 +144,21 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) info->finish(Thing::ThingErrorNoError); }); - connect(tado, &Tado::connectionError, info, [this, info] (QNetworkReply::NetworkError error){ + connect(tado, &Tado::connectionError, info, [this, info] (QNetworkReply::NetworkError error) { + if (error != QNetworkReply::NetworkError::NoError){ + if (m_tadoAccounts.contains(info->thing()->id())) { Tado *tado = m_tadoAccounts.take(info->thing()->id()); tado->deleteLater(); } - info->finish(Thing::ThingErrorSetupFailed); + if (error == QNetworkReply::NetworkError::ProtocolInvalidOperationError) { + qCWarning(dcTado()) << "Confirm pairing failed, wrong username or password"; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Wrong username or password.")); + } else { + qCWarning(dcTado()) << "Confirm pairing failed" << error; + info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Connection error")); + } } }); tado->getApiCredentials(); diff --git a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts index 2cf433d8..7127d557 100644 --- a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-de.ts @@ -4,20 +4,32 @@ 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. - + + + Wrong username or password. + Fascher Benutzername oder Passwort. + + + + Connection error Verbindungsfehler + + + Client credentials not found, the plug-in version might be outdated. + Client-Anmeldeinformationen nicht gefunden, die Plug-In-Version ist möglicherweise veraltet. + Tado 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 6d1a2698..eae07dfd 100644 --- a/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts +++ b/tado/translations/b4f2d2ee-50bb-4786-b7f5-261fed204fa5-en_US.ts @@ -4,20 +4,32 @@ IntegrationPluginTado - + Tado server is not reachable. - + Please enter the login credentials for your Tado account. - + + + Wrong username or password. + + + + + Connection error + + + Client credentials not found, the plug-in version might be outdated. + + Tado From 465dcf9b290f02389c2df0c5e7b52afc48dbc543 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Mon, 7 Dec 2020 09:53:44 +0100 Subject: [PATCH 6/7] fixed typos --- tado/tado.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tado/tado.cpp b/tado/tado.cpp index 16667a88..f333033e 100644 --- a/tado/tado.cpp +++ b/tado/tado.cpp @@ -135,7 +135,7 @@ void Tado::getApiCredentials(const QString &url) void Tado::getToken(const QString &password) { if (!m_apiAvailable) { - qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + qCWarning(dcTado()) << "Not sending request, get API credentials first"; return; } @@ -173,7 +173,7 @@ void Tado::getToken(const QString &password) QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Received invalide JSON object:" << data; + qDebug(dcTado()) << "Get Token: Received invalid JSON object:" << data; return; } if (data.isObject()) { @@ -209,7 +209,7 @@ void Tado::getToken(const QString &password) void Tado::getHomes() { if (!m_apiAvailable) { - qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + qCWarning(dcTado()) << "Not sending request, get API credentials first"; return; } @@ -246,7 +246,7 @@ void Tado::getHomes() QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Recieved invalide JSON object"; + qDebug(dcTado()) << "Get Token: Recieved invalid JSON object"; return; } QList homes; @@ -265,7 +265,7 @@ void Tado::getHomes() void Tado::getZones(const QString &homeId) { if (!m_apiAvailable) { - qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + qCWarning(dcTado()) << "Not sending request, get API credentials first"; return; } @@ -302,7 +302,7 @@ void Tado::getZones(const QString &homeId) QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Recieved invalide JSON object"; + qDebug(dcTado()) << "Get Token: Recieved invalid JSON object"; return; } QList zones; @@ -322,7 +322,7 @@ void Tado::getZones(const QString &homeId) void Tado::getZoneState(const QString &homeId, const QString &zoneId) { if (!m_apiAvailable) { - qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + qCWarning(dcTado()) << "Not sending request, get API credentials first"; return; } @@ -362,7 +362,7 @@ void Tado::getZoneState(const QString &homeId, const QString &zoneId) QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Recieved invalide JSON object"; + qDebug(dcTado()) << "Get Token: Recieved invalid JSON object"; return; } ZoneState state; @@ -400,7 +400,7 @@ void Tado::getZoneState(const QString &homeId, const QString &zoneId) QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, double targetTemperature) { if (!m_apiAvailable) { - qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + qCWarning(dcTado()) << "Not sending request, get API credentials first"; return ""; } @@ -453,7 +453,7 @@ QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Recieved invalide JSON object"; + qDebug(dcTado()) << "Get Token: Recieved invalid JSON object"; return; } QVariantMap map = data.toVariant().toMap(); @@ -475,7 +475,7 @@ QUuid Tado::setOverlay(const QString &homeId, const QString &zoneId, bool power, QUuid Tado::deleteOverlay(const QString &homeId, const QString &zoneId) { if (!m_apiAvailable) { - qCWarning(dcTado()) << "Not sending request, get API credentials firs"; + qCWarning(dcTado()) << "Not sending request, get API credentials first"; return ""; } @@ -518,7 +518,7 @@ QUuid Tado::deleteOverlay(const QString &homeId, const QString &zoneId) QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Recieved invalide JSON object"; + qDebug(dcTado()) << "Get Token: Recieved invalid JSON object"; return; } QVariantMap map = data.toVariant().toMap(); @@ -598,7 +598,7 @@ void Tado::onRefreshTimer() QJsonParseError error; QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); if (error.error != QJsonParseError::NoError) { - qDebug(dcTado()) << "Get Token: Recieved invalide JSON object"; + qDebug(dcTado()) << "Get Token: Recieved invalid JSON object"; return; } Token token; From 3d8c9bdd56b991e5837f2b6a0a5e8bc2ff0d1102 Mon Sep 17 00:00:00 2001 From: Boernsman Date: Wed, 9 Dec 2020 13:27:51 +0100 Subject: [PATCH 7/7] fixed memory leak on reconfigure --- tado/integrationplugintado.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tado/integrationplugintado.cpp b/tado/integrationplugintado.cpp index 936ff3b3..758fe904 100644 --- a/tado/integrationplugintado.cpp +++ b/tado/integrationplugintado.cpp @@ -112,9 +112,16 @@ void IntegrationPluginTado::setupThing(ThingSetupInfo *info) if (thing->thingClassId() == tadoAccountThingClassId) { - qCDebug(dcTado) << "Setup tado connection" << thing->name() << thing->params(); + qCDebug(dcTado) << "Setup Tado account" << thing->name() << thing->params(); Tado *tado; + + if (m_tadoAccounts.contains(thing->id())) { + qCDebug(dcTado()) << "Setup after reconfigure, cleaning up"; + m_tadoAccounts.take(thing->id())->deleteLater(); + } + if (m_unfinishedTadoAccounts.contains(thing->id())) { + qCDebug(dcTado()) << "Using Tado connection from pairing process"; tado = m_unfinishedTadoAccounts.take(thing->id()); m_tadoAccounts.insert(thing->id(), tado); info->finish(Thing::ThingErrorNoError);