added dyn. api credentials optaining
This commit is contained in:
parent
df59d45e83
commit
bc2ff5b7be
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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"));
|
||||
|
||||
12
tado/tado.h
12
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);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user