fixed re-authorization

master
bernhard.trinnes 2020-04-06 21:23:32 +02:00
parent a5b74dc4cc
commit 1291311d0c
3 changed files with 100 additions and 41 deletions

View File

@ -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);
}
});
}
}
}

View File

@ -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);

View File

@ -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);