added token refresh and overlay deletion
This commit is contained in:
parent
8d87047bf2
commit
0a8e8ef280
@ -39,11 +39,6 @@ DevicePluginTado::~DevicePluginTado()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginTado::init()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DevicePluginTado::startPairing(DevicePairingInfo *info)
|
void DevicePluginTado::startPairing(DevicePairingInfo *info)
|
||||||
{
|
{
|
||||||
info->finish(Device::DeviceErrorNoError, QT_TR_NOOP("Please enter the login credentials."));
|
info->finish(Device::DeviceErrorNoError, QT_TR_NOOP("Please enter the login credentials."));
|
||||||
@ -125,7 +120,7 @@ void DevicePluginTado::deviceRemoved(Device *device)
|
|||||||
void DevicePluginTado::postSetupDevice(Device *device)
|
void DevicePluginTado::postSetupDevice(Device *device)
|
||||||
{
|
{
|
||||||
if (!m_pluginTimer) {
|
if (!m_pluginTimer) {
|
||||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(600);
|
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
|
||||||
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginTado::onPluginTimer);
|
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginTado::onPluginTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,16 +143,42 @@ void DevicePluginTado::postSetupDevice(Device *device)
|
|||||||
void DevicePluginTado::executeAction(DeviceActionInfo *info)
|
void DevicePluginTado::executeAction(DeviceActionInfo *info)
|
||||||
{
|
{
|
||||||
Device *device = info->device();
|
Device *device = info->device();
|
||||||
|
Action action = info->action();
|
||||||
|
|
||||||
if (device->deviceClassId() == zoneDeviceClassId) {
|
if (device->deviceClassId() == zoneDeviceClassId) {
|
||||||
|
Tado *tado = m_tadoAccounts.value(device->parentId());
|
||||||
|
if (!tado)
|
||||||
|
return;
|
||||||
|
QString homeId = device->paramValue(zoneDeviceHomeIdParamTypeId).toString();
|
||||||
|
QString zoneId = device->paramValue(zoneDeviceZoneIdParamTypeId).toString();
|
||||||
|
if (action.actionTypeId() == zoneModeActionTypeId) {
|
||||||
|
|
||||||
|
if (action.param(zoneModeActionModeParamTypeId).value().toString() == "Home") {
|
||||||
|
tado->deleteOverlay(homeId, zoneId);
|
||||||
|
} else {
|
||||||
|
|
||||||
info->finish(Device::DeviceErrorNoError);
|
}
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
} else if (action.actionTypeId() == zoneTargetTemperatureActionTypeId) {
|
||||||
|
|
||||||
|
double temperature = action.param(zoneTargetTemperatureActionTargetTemperatureParamTypeId).value().toDouble();
|
||||||
|
tado->setOverlay(homeId, zoneId, "MANUAL", temperature);
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginTado::onPluginTimer()
|
void DevicePluginTado::onPluginTimer()
|
||||||
{
|
{
|
||||||
|
foreach (Device *device, myDevices().filterByDeviceClassId(zoneDeviceClassId)) {
|
||||||
|
Tado *tado = m_tadoAccounts.value(device->parentId());
|
||||||
|
if (!tado)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QString homeId = device->paramValue(zoneDeviceHomeIdParamTypeId).toString();
|
||||||
|
QString zoneId = device->paramValue(zoneDeviceZoneIdParamTypeId).toString();
|
||||||
|
tado->getZoneState(homeId, zoneId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginTado::onConnectionChanged(bool connected)
|
void DevicePluginTado::onConnectionChanged(bool connected)
|
||||||
@ -168,7 +189,9 @@ void DevicePluginTado::onConnectionChanged(bool connected)
|
|||||||
Device *device = myDevices().findById(m_tadoAccounts.key(tado));
|
Device *device = myDevices().findById(m_tadoAccounts.key(tado));
|
||||||
device->setStateValue(tadoConnectionConnectedStateTypeId, connected);
|
device->setStateValue(tadoConnectionConnectedStateTypeId, connected);
|
||||||
|
|
||||||
//TODO set connected state in child devices
|
foreach(Device *zoneDevice, myDevices().filterByParentDeviceId(device->id())) {
|
||||||
|
zoneDevice->setStateValue(zoneConnectedStateTypeId, connected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,10 +254,15 @@ void DevicePluginTado::onZonesReceived(const QString &homeId, QList<Tado::Zone>
|
|||||||
|
|
||||||
DeviceDescriptors descriptors;
|
DeviceDescriptors descriptors;
|
||||||
foreach (Tado::Zone zone, zones) {
|
foreach (Tado::Zone zone, zones) {
|
||||||
|
|
||||||
DeviceDescriptor descriptor(zoneDeviceClassId, zone.name, "Type:" + zone.type, parentDevice->id());
|
DeviceDescriptor descriptor(zoneDeviceClassId, zone.name, "Type:" + zone.type, parentDevice->id());
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params.append(Param(zoneDeviceHomeIdParamTypeId, homeId));
|
params.append(Param(zoneDeviceHomeIdParamTypeId, homeId));
|
||||||
params.append(Param(zoneDeviceZoneIdParamTypeId, zone.id));
|
params.append(Param(zoneDeviceZoneIdParamTypeId, zone.id));
|
||||||
|
if (myDevices().findByParams(params))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
params.append(Param(zoneDeviceTypeParamTypeId, zone.type));
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
descriptors.append(descriptor);
|
descriptors.append(descriptor);
|
||||||
}
|
}
|
||||||
@ -246,18 +274,29 @@ void DevicePluginTado::onZonesReceived(const QString &homeId, QList<Tado::Zone>
|
|||||||
|
|
||||||
void DevicePluginTado::onZoneStateReceived(const QString &homeId, const QString &zoneId, Tado::ZoneState state)
|
void DevicePluginTado::onZoneStateReceived(const QString &homeId, const QString &zoneId, Tado::ZoneState state)
|
||||||
{
|
{
|
||||||
qCDebug(dcTado()) << "Zone state received:";
|
|
||||||
Tado *tado = static_cast<Tado*>(sender());
|
Tado *tado = static_cast<Tado*>(sender());
|
||||||
DeviceId parentId = m_tadoAccounts.key(tado);
|
DeviceId parentId = m_tadoAccounts.key(tado);
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params.append(Param(zoneDeviceHomeIdParamTypeId, homeId));
|
params.append(Param(zoneDeviceHomeIdParamTypeId, homeId));
|
||||||
params.append(Param(zoneDeviceZoneIdParamTypeId, zoneId));
|
params.append(Param(zoneDeviceZoneIdParamTypeId, zoneId));
|
||||||
Device *device = myDevices().filterByParentDeviceId(parentId).findByParams(params);
|
Device *device = myDevices().filterByParentDeviceId(parentId).findByParams(params);
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state.overlayIsSet) {
|
||||||
|
if (state.overlaySettingPower) {
|
||||||
|
device->setStateValue(zoneModeStateTypeId, "Manual");
|
||||||
|
} else {
|
||||||
|
device->setStateValue(zoneModeStateTypeId, "Off");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device->setStateValue(zoneModeStateTypeId, "Home");
|
||||||
|
}
|
||||||
|
|
||||||
device->setStateValue(zoneModeStateTypeId, state.tadoMode);
|
|
||||||
device->setStateValue(zonePowerStateTypeId, state.power);
|
device->setStateValue(zonePowerStateTypeId, state.power);
|
||||||
device->setStateValue(zoneConnectedStateTypeId, state.connected);
|
device->setStateValue(zoneConnectedStateTypeId, state.connected);
|
||||||
device->setStateValue(zoneTargetTemperatureStateTypeId, state.targetTemperature);
|
device->setStateValue(zoneTargetTemperatureStateTypeId, state.settingTemperature);
|
||||||
device->setStateValue(zoneTemperatureStateTypeId, state.temperature);
|
device->setStateValue(zoneTemperatureStateTypeId, state.temperature);
|
||||||
device->setStateValue(zoneHumidityStateTypeId, state.humidity);
|
device->setStateValue(zoneHumidityStateTypeId, state.humidity);
|
||||||
|
device->setStateValue(zoneWindowOpenStateTypeId, state.windowOpen);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,6 @@ public:
|
|||||||
explicit DevicePluginTado();
|
explicit DevicePluginTado();
|
||||||
~DevicePluginTado();
|
~DevicePluginTado();
|
||||||
|
|
||||||
void init() override;
|
|
||||||
void startPairing(DevicePairingInfo *info) override;
|
void startPairing(DevicePairingInfo *info) override;
|
||||||
void confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret) override;
|
void confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret) override;
|
||||||
void setupDevice(DeviceSetupInfo *info) override;
|
void setupDevice(DeviceSetupInfo *info) override;
|
||||||
|
|||||||
@ -19,8 +19,8 @@
|
|||||||
{
|
{
|
||||||
"id": "2f79bc1d-27ed-480a-b583-728363c83ea6",
|
"id": "2f79bc1d-27ed-480a-b583-728363c83ea6",
|
||||||
"name": "connected",
|
"name": "connected",
|
||||||
"displayName": "available",
|
"displayName": "Available",
|
||||||
"displayNameEvent": "available changed",
|
"displayNameEvent": "Available changed",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false
|
"defaultValue": false
|
||||||
},
|
},
|
||||||
@ -64,14 +64,21 @@
|
|||||||
"type": "QString",
|
"type": "QString",
|
||||||
"inputType": "TextLine",
|
"inputType": "TextLine",
|
||||||
"readOnly": true
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8e86797e-5333-4428-9dba-9ed5ac243b44",
|
||||||
|
"name": "type",
|
||||||
|
"displayName": "Type",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"stateTypes": [
|
"stateTypes": [
|
||||||
{
|
{
|
||||||
"id": "9f45a703-6a15-447c-a77a-0df731cda48e",
|
"id": "9f45a703-6a15-447c-a77a-0df731cda48e",
|
||||||
"name": "connected",
|
"name": "connected",
|
||||||
"displayName": "available",
|
"displayName": "Available",
|
||||||
"displayNameEvent": "available changed",
|
"displayNameEvent": "Available changed",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false
|
"defaultValue": false
|
||||||
},
|
},
|
||||||
@ -82,10 +89,10 @@
|
|||||||
"displayNameEvent": "Mode changed",
|
"displayNameEvent": "Mode changed",
|
||||||
"displayNameAction": "Set mode",
|
"displayNameAction": "Set mode",
|
||||||
"type": "QString",
|
"type": "QString",
|
||||||
"defaultValue": "Auto",
|
"defaultValue": "Home",
|
||||||
"possibleValues": [
|
"possibleValues": [
|
||||||
"Manual",
|
"Manual",
|
||||||
"Auto",
|
"Home",
|
||||||
"Off"
|
"Off"
|
||||||
],
|
],
|
||||||
"writable": true
|
"writable": true
|
||||||
@ -98,11 +105,19 @@
|
|||||||
"type": "bool",
|
"type": "bool",
|
||||||
"defaultValue": false
|
"defaultValue": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "c7a04e26-bb22-406e-b117-262bdb8b9c0e",
|
||||||
|
"name": "windowOpen",
|
||||||
|
"displayName": "Window open",
|
||||||
|
"displayNameEvent": "Window open changed",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "80098178-7d92-43dd-a216-23704cc0eaa2",
|
"id": "80098178-7d92-43dd-a216-23704cc0eaa2",
|
||||||
"name": "temperature",
|
"name": "temperature",
|
||||||
"displayName": "temperature",
|
"displayName": "Temperature",
|
||||||
"displayNameEvent": "temperature changed",
|
"displayNameEvent": "Temperature changed",
|
||||||
"unit": "DegreeCelsius",
|
"unit": "DegreeCelsius",
|
||||||
"type": "double",
|
"type": "double",
|
||||||
"defaultValue": 0
|
"defaultValue": 0
|
||||||
@ -121,8 +136,8 @@
|
|||||||
{
|
{
|
||||||
"id": "0faaaff1-2a33-44ec-b68d-d8855f584b02",
|
"id": "0faaaff1-2a33-44ec-b68d-d8855f584b02",
|
||||||
"name": "humidity",
|
"name": "humidity",
|
||||||
"displayName": "humidity",
|
"displayName": "Humidity",
|
||||||
"displayNameEvent": "humidity changed",
|
"displayNameEvent": "Humidity changed",
|
||||||
"unit": "Percentage",
|
"unit": "Percentage",
|
||||||
"type": "double",
|
"type": "double",
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
|
|||||||
155
tado/tado.cpp
155
tado/tado.cpp
@ -33,7 +33,9 @@ Tado::Tado(NetworkAccessManager *networkManager, const QString &username, QObjec
|
|||||||
m_networkManager(networkManager),
|
m_networkManager(networkManager),
|
||||||
m_username(username)
|
m_username(username)
|
||||||
{
|
{
|
||||||
|
m_refreshTimer = new QTimer(this);
|
||||||
|
m_refreshTimer->setSingleShot(true);
|
||||||
|
connect(m_refreshTimer, &QTimer::timeout, this, &Tado::onRefreshTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tado::setUsername(const QString &username)
|
void Tado::setUsername(const QString &username)
|
||||||
@ -91,7 +93,9 @@ void Tado::getToken(const QString &password)
|
|||||||
m_accessToken = token.accesToken;
|
m_accessToken = token.accesToken;
|
||||||
token.tokenType = obj["token_type"].toString();
|
token.tokenType = obj["token_type"].toString();
|
||||||
token.refreshToken = obj["refresh_token"].toString();
|
token.refreshToken = obj["refresh_token"].toString();
|
||||||
|
m_refreshToken = token.refreshToken;
|
||||||
token.expires = obj["expires_in"].toInt();
|
token.expires = obj["expires_in"].toInt();
|
||||||
|
m_refreshTimer->start((token.expires - 10)*1000);
|
||||||
token.scope = obj["scope"].toString();
|
token.scope = obj["scope"].toString();
|
||||||
token.jti = obj["jti"].toString();
|
token.jti = obj["jti"].toString();
|
||||||
emit tokenReceived(token);
|
emit tokenReceived(token);
|
||||||
@ -216,30 +220,165 @@ void Tado::getZoneState(const QString &homeId, const QString &zoneId)
|
|||||||
qDebug(dcTado()) << "Get Token: Recieved invalide JSON object";
|
qDebug(dcTado()) << "Get Token: Recieved invalide JSON object";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneState state;
|
ZoneState state;
|
||||||
QVariantMap map = data.toVariant().toMap();
|
QVariantMap map = data.toVariant().toMap();
|
||||||
state.tadoMode = map["tado_mode"].toString();
|
state.tadoMode = map["tadoMode"].toString();
|
||||||
|
state.windowOpen = map["openWindow"].toBool();
|
||||||
|
|
||||||
QVariantMap settingsMap = map["setting"].toMap();
|
QVariantMap settingsMap = map["setting"].toMap();
|
||||||
state.type = settingsMap["type"].toString();
|
state.settingType = settingsMap["type"].toString();
|
||||||
state.power = (settingsMap["power"].toString() == "ON");
|
state.settingPower = (settingsMap["power"].toString() == "ON");
|
||||||
state.targetTemperature = settingsMap["temperature"].toMap().value("celsius").toDouble();
|
state.settingTemperature = settingsMap["temperature"].toMap().value("celsius").toDouble();
|
||||||
|
|
||||||
state.connected = (map["link"].toMap().value("state").toString() == "ONLINE");
|
state.connected = (map["link"].toMap().value("state").toString() == "ONLINE");
|
||||||
|
|
||||||
|
QVariantMap activityDataMap = map["activityDataPoints"].toMap();
|
||||||
|
state.heatingPowerPercentage = activityDataMap["heatingPower"].toMap().value("percentage").toDouble();
|
||||||
|
state.heatingPowerType = activityDataMap["heatingPower"].toMap().value("type").toString();
|
||||||
|
|
||||||
QVariantMap dataMap = map["sensorDataPoints"].toMap();
|
QVariantMap dataMap = map["sensorDataPoints"].toMap();
|
||||||
state.temperature = dataMap["insideTemperature"].toMap().value("celsius").toDouble();
|
state.temperature = dataMap["insideTemperature"].toMap().value("celsius").toDouble();
|
||||||
state.humidity = dataMap["humidity"].toMap().value("percentage").toDouble();
|
state.humidity = dataMap["humidity"].toMap().value("percentage").toDouble();
|
||||||
|
|
||||||
|
if (!map["overlay"].toMap().isEmpty()){
|
||||||
|
state.overlayIsSet = true;
|
||||||
|
QVariantMap overlayMap = map["overlay"].toMap();
|
||||||
|
state.overlayType = map["overlayType"].toString();
|
||||||
|
state.overlaySettingPower = (overlayMap["settings"].toMap().value("power").toString() == "ON");
|
||||||
|
state.overlaySettingTemperature = overlayMap["settings"].toMap().value("temperature").toDouble();
|
||||||
|
} else {
|
||||||
|
state.overlayIsSet = false;
|
||||||
|
}
|
||||||
emit zoneStateReceived(homeId, zoneId, state);
|
emit zoneStateReceived(homeId, zoneId, state);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tado::setOverlay(const QString &homeId, const QString &zoneId, const QString &mode, double targetTemperature)
|
void Tado::setOverlay(const QString &homeId, const QString &zoneId, const QString &mode, double targetTemperature)
|
||||||
{
|
{
|
||||||
Q_UNUSED(zoneId);
|
|
||||||
Q_UNUSED(homeId);
|
|
||||||
Q_UNUSED(mode);
|
Q_UNUSED(mode);
|
||||||
Q_UNUSED(targetTemperature);
|
Q_UNUSED(targetTemperature);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(QUrl(m_baseControlUrl+"/homes/"+homeId+"/zones/"+zoneId+"/overlay"));
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8");
|
||||||
|
request.setRawHeader("Authorization", "Bearer " + m_accessToken.toLocal8Bit());
|
||||||
|
QJsonDocument doc;
|
||||||
|
QJsonObject obj;
|
||||||
|
QJsonObject setting;
|
||||||
|
setting.insert("type", "HEATING");
|
||||||
|
setting.insert("power", "ON");
|
||||||
|
QJsonObject temperature;
|
||||||
|
temperature.insert("celsius", targetTemperature);
|
||||||
|
temperature.insert("fahrenheit", (targetTemperature * (9.0/5.0)) + 32.0);
|
||||||
|
setting.insert("temperature", temperature);
|
||||||
|
obj.insert("setting", setting);
|
||||||
|
QJsonObject termination;
|
||||||
|
termination.insert("type", "MANUAL");
|
||||||
|
obj.insert("termination", termination);
|
||||||
|
doc.setObject(obj);
|
||||||
|
|
||||||
|
QNetworkReply *reply = m_networkManager->put(request, doc.toJson());
|
||||||
|
qCDebug(dcTado()) << "Sending request" << request.url() << doc.toJson();
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
// Check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
if (reply->error() == QNetworkReply::HostNotFoundError) {
|
||||||
|
emit connectionChanged(false);
|
||||||
|
}
|
||||||
|
if (status == 400 || status == 401) {
|
||||||
|
emit authenticationStatusChanged(false);
|
||||||
|
}
|
||||||
|
qCWarning(dcTado()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcTado()) << "Get Token: Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QVariantMap map = data.toVariant().toMap();
|
||||||
|
qCDebug(dcTado()) << map["type"].toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tado::deleteOverlay(const QString &homeId, const QString &zoneId)
|
||||||
|
{
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(QUrl(m_baseControlUrl+"/homes/"+homeId+"/zones/"+zoneId+"/overlay"));
|
||||||
|
request.setRawHeader("Authorization", "Bearer " + m_accessToken.toLocal8Bit());
|
||||||
|
QNetworkReply *reply = m_networkManager->deleteResource(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
// Check HTTP status code
|
||||||
|
if (status < 200 || status > 210 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
if (reply->error() == QNetworkReply::HostNotFoundError) {
|
||||||
|
emit connectionChanged(false);
|
||||||
|
}
|
||||||
|
if (status == 400 || status == 401) {
|
||||||
|
emit authenticationStatusChanged(false);
|
||||||
|
}
|
||||||
|
qCWarning(dcTado()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tado::onRefreshTimer()
|
||||||
|
{
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(QUrl(m_baseAuthorizationUrl));
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
|
QByteArray body;
|
||||||
|
body.append("client_id=" + m_clientId);
|
||||||
|
body.append("&client_secret=" + m_clientSecret);
|
||||||
|
body.append("&grant_type=refresh_token");
|
||||||
|
body.append("&refresh_token=" + m_refreshToken);
|
||||||
|
body.append("&scope=home.user");
|
||||||
|
|
||||||
|
QNetworkReply *reply = m_networkManager->post(request, body);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
// Check HTTP status code
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
if (reply->error() == QNetworkReply::HostNotFoundError) {
|
||||||
|
emit connectionChanged(false);
|
||||||
|
}
|
||||||
|
if (status == 400 || status == 401) {
|
||||||
|
emit authenticationStatusChanged(false);
|
||||||
|
}
|
||||||
|
qCWarning(dcTado()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit authenticationStatusChanged(true);
|
||||||
|
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcTado()) << "Get Token: Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Token token;
|
||||||
|
QVariantMap obj = data.toVariant().toMap();
|
||||||
|
token.accesToken = obj["access_token"].toString();
|
||||||
|
m_accessToken = token.accesToken;
|
||||||
|
token.tokenType = obj["token_type"].toString();
|
||||||
|
token.refreshToken = obj["refresh_token"].toString();
|
||||||
|
m_refreshToken = token.refreshToken;
|
||||||
|
token.expires = obj["expires_in"].toInt();
|
||||||
|
m_refreshTimer->start((token.expires - 10)*1000);
|
||||||
|
token.scope = obj["scope"].toString();
|
||||||
|
token.jti = obj["jti"].toString();
|
||||||
|
emit tokenReceived(token);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
18
tado/tado.h
18
tado/tado.h
@ -27,6 +27,7 @@
|
|||||||
#include "devices/device.h"
|
#include "devices/device.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class Tado : public QObject
|
class Tado : public QObject
|
||||||
{
|
{
|
||||||
@ -50,11 +51,19 @@ public:
|
|||||||
struct ZoneState {
|
struct ZoneState {
|
||||||
bool connected;
|
bool connected;
|
||||||
bool power;
|
bool power;
|
||||||
double targetTemperature;
|
|
||||||
QString tadoMode;
|
QString tadoMode;
|
||||||
QString type;
|
QString settingType;
|
||||||
|
double settingTemperature;
|
||||||
|
bool settingPower;
|
||||||
double temperature;
|
double temperature;
|
||||||
double humidity;
|
double humidity;
|
||||||
|
bool windowOpen;
|
||||||
|
double heatingPowerPercentage;
|
||||||
|
QString heatingPowerType;
|
||||||
|
bool overlayIsSet;
|
||||||
|
bool overlaySettingPower;
|
||||||
|
double overlaySettingTemperature;
|
||||||
|
QString overlayType;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Home {
|
struct Home {
|
||||||
@ -73,6 +82,7 @@ public:
|
|||||||
void getZoneState(const QString &homeId, const QString &zoneId);
|
void getZoneState(const QString &homeId, const QString &zoneId);
|
||||||
|
|
||||||
void setOverlay(const QString &homeId, const QString &zoneId, const QString &mode, double targetTemperature);
|
void setOverlay(const QString &homeId, const QString &zoneId, const QString &mode, double targetTemperature);
|
||||||
|
void deleteOverlay(const QString &homeId, const QString &zoneId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray m_baseAuthorizationUrl = "https://auth.tado.com/oauth/token";
|
QByteArray m_baseAuthorizationUrl = "https://auth.tado.com/oauth/token";
|
||||||
@ -83,6 +93,8 @@ private:
|
|||||||
NetworkAccessManager *m_networkManager = nullptr;
|
NetworkAccessManager *m_networkManager = nullptr;
|
||||||
QString m_username;
|
QString m_username;
|
||||||
QString m_accessToken;
|
QString m_accessToken;
|
||||||
|
QString m_refreshToken;
|
||||||
|
QTimer *m_refreshTimer = nullptr;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectionChanged(bool connected);
|
void connectionChanged(bool connected);
|
||||||
@ -93,6 +105,8 @@ signals:
|
|||||||
void homesReceived(QList<Home> homes);
|
void homesReceived(QList<Home> homes);
|
||||||
void zonesReceived(const QString &homeId, QList<Zone> zones);
|
void zonesReceived(const QString &homeId, QList<Zone> zones);
|
||||||
void zoneStateReceived(const QString &homeId,const QString &zoneId, ZoneState sate);
|
void zoneStateReceived(const QString &homeId,const QString &zoneId, ZoneState sate);
|
||||||
|
private slots:
|
||||||
|
void onRefreshTimer();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user