POC of fridge thing.

Fixed authentication (refresh token needs to be saved again when
refreshing access token).
This commit is contained in:
Paul Bot 2021-09-08 10:34:28 +03:00
parent ef95857664
commit 7d2de6f268
5 changed files with 252 additions and 21 deletions

View File

@ -30,6 +30,7 @@
#include "integrationpluginmiele.h" #include "integrationpluginmiele.h"
#include "plugininfo.h" #include "plugininfo.h"
#include <cmath>
#include <QJsonDocument> #include <QJsonDocument>
#include <QUrl> #include <QUrl>
@ -56,6 +57,14 @@ IntegrationPluginMiele::IntegrationPluginMiele()
m_connectedStateTypeIds.insert(cookTopThingClassId, cookTopConnectedStateTypeId); m_connectedStateTypeIds.insert(cookTopThingClassId, cookTopConnectedStateTypeId);
m_connectedStateTypeIds.insert(cleaningRobotThingClassId, cleaningRobotConnectedStateTypeId); m_connectedStateTypeIds.insert(cleaningRobotThingClassId, cleaningRobotConnectedStateTypeId);
m_connectedStateTypeIds.insert(hoodThingClassId, hoodConnectedStateTypeId); m_connectedStateTypeIds.insert(hoodThingClassId, hoodConnectedStateTypeId);
m_mieleDeviceTypeLabelToThingClassId.insert("oven", ovenThingClassId);
m_mieleDeviceTypeLabelToThingClassId.insert("washing machine", washerThingClassId);
m_mieleDeviceTypeLabelToThingClassId.insert("dish washer", dishwasherThingClassId);
m_mieleDeviceTypeLabelToThingClassId.insert("coffee system", coffeeMakerThingClassId);
m_mieleDeviceTypeLabelToThingClassId.insert("tumber dryer", dryerThingClassId);
m_mieleDeviceTypeLabelToThingClassId.insert("refrigerator", fridgeThingClassId);
} }
void IntegrationPluginMiele::startPairing(ThingPairingInfo *info) void IntegrationPluginMiele::startPairing(ThingPairingInfo *info)
@ -148,7 +157,15 @@ void IntegrationPluginMiele::setupThing(ThingSetupInfo *info)
m_mieleConnections.insert(info->thing(), miele); m_mieleConnections.insert(info->thing(), miele);
info->finish(Thing::ThingErrorNoError); info->finish(Thing::ThingErrorNoError);
}); });
connect(miele, &Miele::receivedRefreshToken, info, [info, thing, this](const QByteArray &refreshToken){
pluginStorage()->beginGroup(thing->id().toString());
pluginStorage()->setValue("refresh_token", refreshToken);
pluginStorage()->endGroup();
info->finish(Thing::ThingErrorNoError);
});
connect(info, &ThingSetupInfo::aborted, miele, &Miele::deleteLater); connect(info, &ThingSetupInfo::aborted, miele, &Miele::deleteLater);
connect(miele, &Miele::devicesFound, this, &IntegrationPluginMiele::onDevicesFound);
connect(miele, &Miele::deviceStateReceived, this, &IntegrationPluginMiele::onDeviceStateReceived);
} }
} else if (m_idParamTypeIds.contains(thing->thingClassId())) { } else if (m_idParamTypeIds.contains(thing->thingClassId())) {
Thing *parentThing = myThings().findById(thing->parentId()); Thing *parentThing = myThings().findById(thing->parentId());
@ -172,7 +189,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
qCDebug(dcMiele()) << "Post setup thing" << thing->name(); qCDebug(dcMiele()) << "Post setup thing" << thing->name();
if (!m_pluginTimer15min) { if (!m_pluginTimer15min) {
qCDebug(dcMiele()) << "Registering plugin timer"; qCDebug(dcMiele()) << "Registering plugin timer";
m_pluginTimer15min = hardwareManager()->pluginTimerManager()->registerTimer(60*15); m_pluginTimer15min = hardwareManager()->pluginTimerManager()->registerTimer(60 * 1);
connect(m_pluginTimer15min, &PluginTimer::timeout, this, [this]() { connect(m_pluginTimer15min, &PluginTimer::timeout, this, [this]() {
qCDebug(dcMiele()) << "Plugin timer triggered"; qCDebug(dcMiele()) << "Plugin timer triggered";
Q_FOREACH (Thing *thing, myThings().filterByThingClassId(mieleAccountThingClassId)) { Q_FOREACH (Thing *thing, myThings().filterByThingClassId(mieleAccountThingClassId)) {
@ -181,10 +198,10 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
qWarning(dcMiele()) << "No Miele account found for" << thing->name(); qWarning(dcMiele()) << "No Miele account found for" << thing->name();
continue; continue;
} }
miele->getDevices(); miele->getDevicesShort();
Q_FOREACH (Thing *childThing, myThings().filterByParentId(thing->id())) { Q_FOREACH (Thing *childThing, myThings().filterByParentId(thing->id())) {
QString deviceId = childThing->paramValue(m_idParamTypeIds.value(childThing->thingClassId())).toString(); QString deviceId = childThing->paramValue(m_idParamTypeIds.value(childThing->thingClassId())).toString();
miele->getDevice(deviceId); miele->getDeviceState(deviceId);
} }
} }
}); });
@ -192,7 +209,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
if (thing->thingClassId() == mieleAccountThingClassId) { if (thing->thingClassId() == mieleAccountThingClassId) {
Miele *miele = m_mieleConnections.value(thing); Miele *miele = m_mieleConnections.value(thing);
miele->getDevices(); miele->getDevicesShort();
//miele->connectEventStream(); //miele->connectEventStream();
thing->setStateValue(mieleAccountConnectedStateTypeId, true); thing->setStateValue(mieleAccountConnectedStateTypeId, true);
thing->setStateValue(mieleAccountLoggedInStateTypeId, true); thing->setStateValue(mieleAccountLoggedInStateTypeId, true);
@ -206,7 +223,7 @@ void IntegrationPluginMiele::postSetupThing(Thing *thing)
if (!miele) { if (!miele) {
qCWarning(dcMiele()) << "Could not find HomeConnect connection for thing" << thing->name(); qCWarning(dcMiele()) << "Could not find HomeConnect connection for thing" << thing->name();
} else { } else {
miele->getDevice(deviceId); miele->getDeviceState(deviceId);
} }
} else { } else {
Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
@ -221,10 +238,17 @@ void IntegrationPluginMiele::executeAction(ThingActionInfo *info)
if (!miele) { if (!miele) {
return info->finish(Thing::ThingErrorHardwareNotAvailable); return info->finish(Thing::ThingErrorHardwareNotAvailable);
} }
QString haid = thing->paramValue(m_idParamTypeIds.value(thing->thingClassId())).toString(); QString deviceId = thing->paramValue(m_idParamTypeIds.value(thing->thingClassId())).toString();
if (thing->thingClassId() == ovenThingClassId) {
if (thing->thingClassId() == fridgeThingClassId) {
if (action.actionTypeId() == fridgeTargetTemperatureActionTypeId) {
double targetTemp = action.param(fridgeTargetTemperatureActionTargetTemperatureParamTypeId).value().toDouble();
int iTargetTemp = floor(targetTemp);
qCDebug(dcMiele()) << "Setting fridge temp: " << iTargetTemp;
miele->setTargetTemperature(deviceId, 1, iTargetTemp);
info->finish(Thing::ThingErrorNoError);
thing->setStateValue(fridgeTargetTemperatureStateTypeId, iTargetTemp);
}
} else if (thing->thingClassId() == ovenThingClassId) { } else if (thing->thingClassId() == ovenThingClassId) {
} else { } else {
@ -327,4 +351,86 @@ void IntegrationPluginMiele::onRequestExecuted(QUuid requestId, bool success)
} }
} }
void IntegrationPluginMiele::onDevicesFound(QList<Miele::DeviceShort> devices)
{
qCDebug(dcMiele()) << "Found " << devices.size() << " devices";
Miele *miele = static_cast<Miele*>(sender());
if(m_mieleConnections.values().contains(miele)) {
Thing *parentDevice = myThings().findById(m_mieleConnections.key(miele)->id());
qCDebug(dcMiele()) << devices.size() << " devices received for prent: " << parentDevice->id();
ThingDescriptors descriptors;
foreach(Miele::DeviceShort ds, devices) {
qCDebug(dcMiele()) << "Setting up device: " << ds.type << " " << ds.name << " " << ds.state;
if (!m_mieleDeviceTypeLabelToThingClassId.contains(ds.type.toLower())) {
qCDebug(dcMiele()) << "Device type [" << ds.type << "] is not supported!";
continue;
}
ThingClassId deviceClassId = m_mieleDeviceTypeLabelToThingClassId.value(ds.type.toLower());
ThingDescriptor descriptor(deviceClassId, ds.name, "Appliance type: " + ds.type, parentDevice->id());
ParamList params;
params.append(Param(m_idParamTypeIds.value(deviceClassId), ds.fabNumber));
if (myThings().findByParams(params)) {
continue;
}
descriptor.setParams(params);
descriptors.append(descriptor);
}
emit autoThingsAppeared(descriptors);
} else {
// TODO: improve debug message
qCWarning(dcMiele()) << "Miele connection not linked to a thingId";
}
}
void IntegrationPluginMiele::onDeviceStateReceived(const QString &deviceId, const QVariantMap &deviceState)
{
Miele *miele = static_cast<Miele*>(sender());
if (!m_mieleConnections.values().contains(miele)) {
qCWarning(dcMiele()) << "Can't find Miele connection!";
return;
}
Thing *parentDevice = myThings().findById(m_mieleConnections.key(miele)->id());
if (!parentDevice) {
qCWarning(dcMiele()) << "Can't find parent thing!";
return;
}
foreach(Thing *thing, myThings().filterByParentId(parentDevice->id())) {
if (thing->paramValue(m_idParamTypeIds.value(thing->thingClassId())).toString() == deviceId) {
qCDebug(dcMiele()) << "Received state for: " << thing->name();
setThingState(thing, deviceState);
break;
}
}
}
void IntegrationPluginMiele::setThingState(Thing *thing, const QVariantMap &state)
{
qCDebug(dcMiele()) << "Setting device state: " << thing->name();
if (thing->thingClassId() == fridgeThingClassId) {
qCDebug(dcMiele()) << "Setting state for fridge!";
bool connected = state.value("status").toMap().value("value_raw").toInt() == Miele::StatusNotConnected
? false
: true;
thing->setStateValue(m_connectedStateTypeIds.value(thing->thingClassId()), connected);
// Fridges should have only one temperature zone
QVariant fridgeTempZone = state.value("temperature").toList().first();
double fridgeTemp = fridgeTempZone.toMap().value("value_raw").toDouble();
thing->setStateValue(fridgeTemperatureStateTypeId, fridgeTemp / 100);
QVariant fridgeTargetTempZone = state.value("targetTemperature").toList().first();
double fridgeTargetTemp = fridgeTargetTempZone.toMap().value("value_raw").toDouble();
thing->setStateValue(fridgeTargetTemperatureStateTypeId, fridgeTargetTemp / 100);
} else {
qCWarning(dcMiele()) << "Device " << thing->name() << " is not yet supported!";
}
}

View File

@ -67,13 +67,18 @@ private:
QHash<ThingClassId, ParamTypeId> m_idParamTypeIds; QHash<ThingClassId, ParamTypeId> m_idParamTypeIds;
QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds; QHash<ThingClassId, StateTypeId> m_connectedStateTypeIds;
QHash<QString, ThingClassId> m_mieleDeviceTypeLabelToThingClassId;
Miele *createMieleConnection(); Miele *createMieleConnection();
void setThingState(Thing *thing, const QVariantMap &state);
private slots: private slots:
void onConnectionChanged(bool connected); void onConnectionChanged(bool connected);
void onAuthenticationStatusChanged(bool authenticated); void onAuthenticationStatusChanged(bool authenticated);
void onRequestExecuted(QUuid requestId, bool success); void onRequestExecuted(QUuid requestId, bool success);
void onDevicesFound(QList<Miele::DeviceShort> devices);
void onDeviceStateReceived(const QString &deviceId, const QVariantMap &deviceState);
}; };
#endif // INTEGRATIONPLUGINMIELE_H #endif // INTEGRATIONPLUGINMIELE_H

View File

@ -178,7 +178,7 @@
"id": "a03e17fd-8da8-4977-8ac3-c058ada9f547", "id": "a03e17fd-8da8-4977-8ac3-c058ada9f547",
"name": "fridge", "name": "fridge",
"displayName": "Fridge Freezer", "displayName": "Fridge Freezer",
"interfaces": ["connectable"], "interfaces": ["thermostat", "connectable"],
"createMethods": ["auto"], "createMethods": ["auto"],
"paramTypes": [ "paramTypes": [
{ {
@ -198,6 +198,42 @@
"defaultValue": true, "defaultValue": true,
"cached": false, "cached": false,
"type": "bool" "type": "bool"
},
{
"id": "ef656321-e2c8-4339-be18-aa3cdb53dea6",
"name": "temperature",
"displayName": "Temperature",
"displayNameEvent": "Temperature changed",
"defaultValue": 0,
"type": "double",
"minValue": "0",
"maxValue": "10",
"unit": "DegreeCelsius"
},
{
"id": "ebac99f4-cb89-4813-9b21-a9c6bf5209d5",
"name": "targetTemperature",
"displayName": "Temperature Setting",
"displayNameEvent": "Temperature setting changed",
"displayNameAction": "Set target temperature",
"defaultValue": 0,
"type": "double",
"minValue": "0",
"maxValue": "10",
"unit": "DegreeCelsius",
"writable": true,
"ioType": "analogInput"
},
{
"id": "60a46368-febc-4cff-bbfb-99064dbb93a9",
"name": "power",
"displayName": "On/off",
"displayNameEvent": "Turned on/off",
"displayNameAction": "Turn on/off",
"type": "bool",
"defaultValue": false,
"writable": true,
"ioType": "digitalInput"
} }
] ]
}, },

View File

@ -35,6 +35,7 @@
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QUrl> #include <QUrl>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray>
#include <QUrlQuery> #include <QUrlQuery>
#include <QMetaEnum> #include <QMetaEnum>
@ -93,6 +94,10 @@ void Miele::getAccessTokenFromRefreshToken(const QByteArray &refreshToken)
return; return;
} }
//delete me
qCDebug(dcMiele()) << "Refresh token is not empty: " << refreshToken;
qCDebug(dcMiele()) << "Client: " << m_clientId << " secret: " << m_clientSecret;
QUrl url(m_tokenUrl); QUrl url(m_tokenUrl);
QUrlQuery query; QUrlQuery query;
query.clear(); query.clear();
@ -106,7 +111,7 @@ void Miele::getAccessTokenFromRefreshToken(const QByteArray &refreshToken)
QNetworkReply *reply = m_networkManager->post(request, query.toString().toUtf8()); QNetworkReply *reply = m_networkManager->post(request, query.toString().toUtf8());
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
connect(reply, &QNetworkReply::finished, this, [this, reply](){ connect(reply, &QNetworkReply::finished, this, [this, reply, refreshToken](){
QByteArray rawData = reply->readAll(); QByteArray rawData = reply->readAll();
if (!checkStatusCode(reply, rawData)) { if (!checkStatusCode(reply, rawData)) {
@ -114,13 +119,16 @@ void Miele::getAccessTokenFromRefreshToken(const QByteArray &refreshToken)
} }
QJsonDocument data = QJsonDocument::fromJson(rawData); QJsonDocument data = QJsonDocument::fromJson(rawData);
if(!data.toVariant().toMap().contains("access_token")) { if(!data.toVariant().toMap().contains("access_token") || !data.toVariant().toMap().contains("refresh_token")) {
setAuthenticated(false); setAuthenticated(false);
return; return;
} }
m_accessToken = data.toVariant().toMap().value("access_token").toByteArray(); m_accessToken = data.toVariant().toMap().value("access_token").toByteArray();
emit receivedAccessToken(m_accessToken); emit receivedAccessToken(m_accessToken);
m_refreshToken = data.toVariant().toMap().value("refresh_token").toByteArray();
emit receivedRefreshToken(m_refreshToken);
if (data.toVariant().toMap().contains("expires_in")) { if (data.toVariant().toMap().contains("expires_in")) {
int expireTime = data.toVariant().toMap().value("expires_in").toInt(); int expireTime = data.toVariant().toMap().value("expires_in").toInt();
qCDebug(dcMiele) << "Access token expires int" << expireTime << "s, at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); qCDebug(dcMiele) << "Access token expires int" << expireTime << "s, at" << QDateTime::currentDateTime().addSecs(expireTime).toString();
@ -145,7 +153,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
query.clear(); query.clear();
query.addQueryItem("client_id", m_clientId); query.addQueryItem("client_id", m_clientId);
query.addQueryItem("client_secret", m_clientSecret); query.addQueryItem("client_secret", m_clientSecret);
//query.addQueryItem("vg", "de-DE"); query.addQueryItem("vg", "de-DE");
query.addQueryItem("redirect_uri", m_redirectUri); query.addQueryItem("redirect_uri", m_redirectUri);
query.addQueryItem("grant_type", "authorization_code"); query.addQueryItem("grant_type", "authorization_code");
query.addQueryItem("code", authorizationCode); query.addQueryItem("code", authorizationCode);
@ -169,7 +177,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
} }
m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray(); m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray();
receivedAccessToken(m_accessToken); receivedAccessToken(m_accessToken);
m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray(); m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray();
receivedRefreshToken(m_refreshToken); receivedRefreshToken(m_refreshToken);
if (jsonDoc.toVariant().toMap().contains("expires_in")) { if (jsonDoc.toVariant().toMap().contains("expires_in")) {
@ -180,7 +188,7 @@ void Miele::getAccessTokenFromAuthorizationCode(const QByteArray &authorizationC
qCWarning(dcMiele()) << "Expire time too short"; qCWarning(dcMiele()) << "Expire time too short";
return; return;
} }
m_accessTokenExpireTime = QDateTime::currentMSecsSinceEpoch() + (expireTime-(m_refreshInterval*1000)); m_accessTokenExpireTime = QDateTime::currentMSecsSinceEpoch() + (expireTime-(m_refreshInterval*1000));
} }
}); });
} }
@ -207,8 +215,7 @@ void Miele::getDevices()
if (!checkStatusCode(reply, rawData)) { if (!checkStatusCode(reply, rawData)) {
return; return;
} }
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap(); QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
qCDebug(dcMiele()) << "Get devices" << map;
if (map.contains("data")) { if (map.contains("data")) {
QVariantMap dataMap = map.value("data").toMap(); QVariantMap dataMap = map.value("data").toMap();
qCDebug(dcMiele()) << "key" << dataMap.value("key").toString() << "value" << dataMap.value("value").toString() << dataMap.value("unit").toString(); qCDebug(dcMiele()) << "key" << dataMap.value("key").toString() << "value" << dataMap.value("value").toString() << dataMap.value("unit").toString();
@ -218,11 +225,48 @@ void Miele::getDevices()
}); });
} }
void Miele::getDevicesShort()
{
qCDebug(dcMiele()) << "Get devices short";
QUrl url = m_apiUrl;
url.setPath("/v1/short/devices");
url.setQuery("language=en");
QNetworkRequest request(url);
request.setRawHeader("Authorization", "Bearer "+m_accessToken);
request.setRawHeader("accept", "application/json; charset=utf-8");
qCDebug(dcMiele()) << "Sending GET request" << request.url() << request.rawHeader("Authorization");
QNetworkReply *reply = m_networkManager->get(request);
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QByteArray rawData = reply->readAll();
if (!checkStatusCode(reply, rawData)) {
return;
}
QVariantList devices = QJsonDocument::fromJson(rawData).toVariant().toList();
QList<DeviceShort> foundDevices;
foreach (QVariant device, devices) {
QVariantMap deviceObj = device.toMap();
qCDebug(dcMiele()) << "Got device: " << deviceObj;
DeviceShort ds;
ds.fabNumber = deviceObj["fabNumber"].toString();
ds.name = deviceObj["deviceName"].toString();
ds.state = deviceObj["state"].toString();
ds.type = deviceObj["type"].toString();
foundDevices.append(ds);
}
emit devicesFound(foundDevices);
});
}
void Miele::getDevice(const QString &deviceId) void Miele::getDevice(const QString &deviceId)
{ {
qCDebug(dcMiele()) << "Get device" << deviceId; qCDebug(dcMiele()) << "Get device" << deviceId;
QUrl url = m_apiUrl; QUrl url = m_apiUrl;
url.setPath("/v1/devices/"+deviceId); url.setPath("/v1/devices/" + deviceId);
url.setQuery("language=en"); url.setQuery("language=en");
QNetworkRequest request(url); QNetworkRequest request(url);
@ -238,7 +282,31 @@ void Miele::getDevice(const QString &deviceId)
return; return;
} }
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap(); QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
qCDebug(dcMiele()) << "Get device" << map; qCDebug(dcMiele()) << "Got device: " << map;
});
}
void Miele::getDeviceState(const QString &deviceId) {
qCDebug(dcMiele()) << "Get device state for: " << deviceId;
QUrl url = m_apiUrl;
url.setPath("/v1/devices/" + deviceId + "/state");
url.setQuery("language=en");
QNetworkRequest request(url);
request.setRawHeader("Authorization", "Bearer "+m_accessToken);
request.setRawHeader("accept", "application/json; charset=utf-8");
QNetworkReply *reply = m_networkManager->get(request);
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
connect(reply, &QNetworkReply::finished, this, [this, reply, deviceId]{
QByteArray rawData = reply->readAll();
if (!checkStatusCode(reply, rawData)) {
return;
}
QVariantMap map = QJsonDocument::fromJson(rawData).toVariant().toMap();
qCDebug(dcMiele()) << "Got device state for: " << deviceId;
emit deviceStateReceived(deviceId, map);
}); });
} }
@ -298,11 +366,14 @@ QUuid Miele::setTargetTemperature(const QString &deviceId, int zone, int targetT
{ {
QJsonDocument doc; QJsonDocument doc;
QJsonObject object; QJsonObject object;
QJsonObject temperatureObj; QJsonObject temperatureObj;
temperatureObj.insert("zone", zone); temperatureObj.insert("zone", zone);
temperatureObj.insert("value", targetTemperature); temperatureObj.insert("value", targetTemperature);
object.insert("targetTemperature", temperatureObj); QJsonArray tempZones;
doc.setObject(object); tempZones.push_front(temperatureObj);
object.insert("targetTemperature", tempZones);
doc.setObject(object);
return putAction(deviceId, doc); return putAction(deviceId, doc);
} }
@ -491,6 +562,7 @@ bool Miele::checkStatusCode(QNetworkReply *reply, const QByteArray &rawData)
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {
qCWarning(dcMiele()) << "Received invalide JSON object" << rawData; qCWarning(dcMiele()) << "Received invalide JSON object" << rawData;
qCWarning(dcMiele()) << "Status" << status; qCWarning(dcMiele()) << "Status" << status;
qCWarning(dcMiele()) << "Error" << error.errorString();
setAuthenticated(false); setAuthenticated(false);
return false; return false;
} }

View File

@ -90,6 +90,14 @@ public:
StatusNotConnected = 255 StatusNotConnected = 255
}; };
struct DeviceShort {
QString details;
QString name;
QString fabNumber;
QString state;
QString type;
};
Miele(NetworkAccessManager *networkmanager, const QByteArray &clientId, const QByteArray &clientSecret, const QString &language = "en", QObject *parent = nullptr); Miele(NetworkAccessManager *networkmanager, const QByteArray &clientId, const QByteArray &clientSecret, const QString &language = "en", QObject *parent = nullptr);
QByteArray accessToken(); QByteArray accessToken();
QByteArray refreshToken(); QByteArray refreshToken();
@ -101,7 +109,9 @@ public:
// INFORMATION // INFORMATION
void getDevices(); void getDevices();
void getDevicesShort();
void getDevice(const QString &deviceId); void getDevice(const QString &deviceId);
void getDeviceState(const QString &deviceId);
// ACTION // ACTION
void getActions(const QString &deviceId); //The GET action is used to request a device to send the currently supported actions void getActions(const QString &deviceId); //The GET action is used to request a device to send the currently supported actions
@ -150,6 +160,8 @@ signals:
void receivedRefreshToken(const QByteArray &refreshToken); void receivedRefreshToken(const QByteArray &refreshToken);
void receivedAccessToken(const QByteArray &accessToken); void receivedAccessToken(const QByteArray &accessToken);
void commandExecuted(const QUuid &commandId, bool success); void commandExecuted(const QUuid &commandId, bool success);
void devicesFound(QList<DeviceShort> devices);
void deviceStateReceived(const QString &deviceId, const QVariantMap &deviceState);
private slots: private slots:
void onRefreshTimeout(); void onRefreshTimeout();