From 214b1052a2df20564cd0c2809a7a25566c250e71 Mon Sep 17 00:00:00 2001 From: "bernhard.trinnes" Date: Sat, 11 Jul 2020 15:38:17 +0200 Subject: [PATCH] addded get home appliances --- homeconnect/homeconnect.cpp | 107 +++++++----- homeconnect/homeconnect.h | 28 ++- homeconnect/integrationpluginhomeconnect.cpp | 162 ++++++++++++++---- homeconnect/integrationpluginhomeconnect.h | 8 +- homeconnect/integrationpluginhomeconnect.json | 55 +++++- 5 files changed, 276 insertions(+), 84 deletions(-) diff --git a/homeconnect/homeconnect.cpp b/homeconnect/homeconnect.cpp index 5822f62f..0dbb9cc0 100644 --- a/homeconnect/homeconnect.cpp +++ b/homeconnect/homeconnect.cpp @@ -36,17 +36,19 @@ #include #include -HomeConnect::HomeConnect(NetworkAccessManager *networkmanager, const QByteArray &clientKey, const QByteArray &clientSecret, QObject *parent) : +HomeConnect::HomeConnect(NetworkAccessManager *networkmanager, const QByteArray &clientKey, const QByteArray &clientSecret, bool simulationMode, QObject *parent) : QObject(parent), m_clientKey(clientKey), m_clientSecret(clientSecret), m_networkManager(networkmanager) + { if(!m_tokenRefreshTimer) { m_tokenRefreshTimer = new QTimer(this); m_tokenRefreshTimer->setSingleShot(true); connect(m_tokenRefreshTimer, &QTimer::timeout, this, &HomeConnect::onRefreshTimeout); } + setSimulationMode(simulationMode); } QByteArray HomeConnect::accessToken() @@ -59,6 +61,20 @@ QByteArray HomeConnect::refreshToken() return m_refreshToken; } +void HomeConnect::setSimulationMode(bool simulation) +{ + m_simulationMode = simulation; + if (simulation) { + m_baseAuthorizationUrl = "https://simulator.home-connect.com/security/oauth/authorize"; + m_baseTokenUrl = "https://simulator.home-connect.com/security/oauth/token"; + m_baseControlUrl = "https://simulator.home-connect.com"; + } else { + m_baseAuthorizationUrl = "https://api.home-connect.com/security/oauth/authorize"; + m_baseTokenUrl = "https://api.home-connect.com/security/oauth/token"; + m_baseControlUrl = "https://api.home-connect.com"; + } +} + QUrl HomeConnect::getLoginUrl(const QUrl &redirectUrl, const QString &scope) { if (m_clientKey.isEmpty()) { @@ -130,40 +146,44 @@ void HomeConnect::getAccessTokenFromRefreshToken(const QByteArray &refreshToken) return; } - QUrl url(m_baseAuthorizationUrl); + QUrl url(m_baseTokenUrl); QUrlQuery query; query.clear(); query.addQueryItem("grant_type", "refresh_token"); query.addQueryItem("refresh_token", refreshToken); - url.setQuery(query); + query.addQueryItem("client_secret", m_clientSecret); QNetworkRequest request(url); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded; charset=UTF-8"); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - QByteArray auth = QByteArray(m_clientKey + ':' + m_clientSecret).toBase64(QByteArray::Base64Encoding | QByteArray::KeepTrailingEquals); - request.setRawHeader("Authorization", QString("Basic %1").arg(QString(auth)).toUtf8()); - - QNetworkReply *reply = m_networkManager->post(request, QByteArray()); + QNetworkReply *reply = m_networkManager->post(request, query.toString().toUtf8()); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); connect(reply, &QNetworkReply::finished, this, [this, reply](){ - QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (status != 200 || reply->error() != QNetworkReply::NoError) { - if(jsonDoc.toVariant().toMap().contains("error_description")) { - qWarning(dcHomeConnect()) << "Access token error:" << jsonDoc.toVariant().toMap().value("error_description").toString(); - } + qWarning(dcHomeConnect()) << "Access token error:" << reply->errorString() << reply->readAll(); emit authenticationStatusChanged(false); return; } - if(!jsonDoc.toVariant().toMap().contains("access_token")) { + QJsonParseError error; + QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) { emit authenticationStatusChanged(false); + qCDebug(dcHomeConnect()) << "Received invalide JSON object" << data.toJson(); return; } - m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray(); + qCDebug(dcHomeConnect()) << "get access token from refresh token" << data.toJson(); - if (jsonDoc.toVariant().toMap().contains("expires_in")) { - int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt(); + if(!data.toVariant().toMap().contains("access_token")) { + emit authenticationStatusChanged(false); + return; + } + m_accessToken = data.toVariant().toMap().value("access_token").toByteArray(); + + if (data.toVariant().toMap().contains("expires_in")) { + int expireTime = data.toVariant().toMap().value("expires_in").toInt(); qCDebug(dcHomeConnect) << "Access token expires at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); if (!m_tokenRefreshTimer) { qWarning(dcHomeConnect()) << "Access token refresh timer not initialized"; @@ -195,10 +215,9 @@ void HomeConnect::getAccessTokenFromAuthorizationCode(const QByteArray &authoriz query.addQueryItem("grant_type", "authorization_code"); query.addQueryItem("code", authorizationCode); query.addQueryItem("code_verifier", m_codeChallenge); - /* Code verifier which was used during code challenge creation on client side. Please note that it is required if the code_challenge parameter was included in the authorization request. */ + QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - qCDebug(dcHomeConnect()) << "Get access token" << url.toString(); QNetworkReply *reply = m_networkManager->post(request, query.toString().toUtf8()); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); @@ -210,8 +229,6 @@ void HomeConnect::getAccessTokenFromAuthorizationCode(const QByteArray &authoriz return; } QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); - - qCDebug(dcHomeConnect()) << "HomeConnect accessToken reply:" << this << reply->error() << reply->errorString() << jsonDoc.toJson(); if(!jsonDoc.toVariant().toMap().contains("access_token") || !jsonDoc.toVariant().toMap().contains("refresh_token") ) { emit authenticationStatusChanged(false); return; @@ -224,7 +241,7 @@ void HomeConnect::getAccessTokenFromAuthorizationCode(const QByteArray &authoriz if (jsonDoc.toVariant().toMap().contains("expires_in")) { int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt(); - qCDebug(dcHomeConnect()) << "expires at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); + qCDebug(dcHomeConnect()) << "Token expires at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); if (!m_tokenRefreshTimer) { qWarning(dcHomeConnect()) << "Token refresh timer not initialized"; emit authenticationStatusChanged(false); @@ -238,40 +255,42 @@ void HomeConnect::getAccessTokenFromAuthorizationCode(const QByteArray &authoriz void HomeConnect::getHomeAppliances() { - QUrl url = QUrl(m_baseAuthorizationUrl); + QUrl url = QUrl(m_baseControlUrl+"/api/homeappliances"); QNetworkRequest request(url); - - QByteArray auth = QByteArray(m_clientKey + ':' + m_clientSecret).toBase64(QByteArray::Base64Encoding | QByteArray::KeepTrailingEquals); - request.setRawHeader("Authorization", QString("Basic %1").arg(QString(auth)).toUtf8()); + request.setRawHeader("Authorization", "Bearer "+m_accessToken); request.setRawHeader("accept", "application/vnd.bsh.sdk.v1+json"); QNetworkReply *reply = m_networkManager->get(request); connect(reply, &QNetworkReply::finished, this, [this, reply](){ reply->deleteLater(); - QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll()); - qCDebug(dcHomeConnect()) << "HomeConnect accessToken reply:" << this << reply->error() << reply->errorString() << jsonDoc.toJson(); - if(!jsonDoc.toVariant().toMap().contains("access_token") || !jsonDoc.toVariant().toMap().contains("refresh_token") ) { - emit authenticationStatusChanged(false); + QJsonParseError error; + QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) { + qCDebug(dcHomeConnect()) << "Get home appliances: Recieved invalide JSON object"; return; } - qCDebug(dcHomeConnect()) << "Access token:" << jsonDoc.toVariant().toMap().value("access_token").toString(); - m_accessToken = jsonDoc.toVariant().toMap().value("access_token").toByteArray(); - - qCDebug(dcHomeConnect()) << "Refresh token:" << jsonDoc.toVariant().toMap().value("refresh_token").toString(); - m_refreshToken = jsonDoc.toVariant().toMap().value("refresh_token").toByteArray(); - - if (jsonDoc.toVariant().toMap().contains("expires_in")) { - int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt(); - qCDebug(dcHomeConnect()) << "expires at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); - if (!m_tokenRefreshTimer) { - qWarning(dcHomeConnect()) << "Token refresh timer not initialized"; - emit authenticationStatusChanged(false); - return; + qCDebug(dcHomeConnect()) << "Get home appliances" << data.toJson(); + if (data.toVariant().toMap().contains("data")) { + QVariantMap dataMap = data.toVariant().toMap().value("data").toMap(); + QList appliances; + foreach (const QVariant &variant, dataMap.value("homeappliances").toList()) { + QVariantMap obj = variant.toMap(); + HomeAppliance appliance; + appliance.name = obj["name"].toString(); + appliance.brand = obj["brand"].toString(); + appliance.vib = obj["vib"].toString(); + appliance.type = obj["type"].toString(); + appliance.homeApplianceId = obj["haId"].toString(); + appliance.enumber = obj["enumber"].toString(); + appliance.connected = obj["connected"].toBool(); + appliances.append(appliance); } - m_tokenRefreshTimer->start((expireTime - 20) * 1000); + if (!appliances.isEmpty()) + emit receivedHomeAppliances(appliances); + } else if (data.toVariant().toMap().contains("error")) { + qCWarning(dcHomeConnect()) << "Get home appliences" << data.toVariant().toMap().value("error").toMap().value("description").toString(); } - emit authenticationStatusChanged(true); }); } diff --git a/homeconnect/homeconnect.h b/homeconnect/homeconnect.h index fd3e3922..9325a7cb 100644 --- a/homeconnect/homeconnect.h +++ b/homeconnect/homeconnect.h @@ -41,19 +41,34 @@ class HomeConnect : public QObject Q_OBJECT public: enum Type { - + Oven, + Dishwasher, + Washer, + Dryer, + WasherDryer, + FridgeFreezer, + Refrigerator, + Freezer, + WineCooler, + CoffeeMaker, + Hood, + CleaningRobot, + CookProcessor }; struct HomeAppliance { QString name; QString brand; - QString typeCode; + QString enumber; + QString vib; bool connected; QString type; + QString homeApplianceId; }; - HomeConnect(NetworkAccessManager *networkmanager, const QByteArray &clientKey, const QByteArray &clientSecret, QObject *parent = nullptr); + HomeConnect(NetworkAccessManager *networkmanager, const QByteArray &clientKey, const QByteArray &clientSecret, bool simulationMode = false, QObject *parent = nullptr); QByteArray accessToken(); QByteArray refreshToken(); + void setSimulationMode(bool simulation); QUrl getLoginUrl(const QUrl &redirectUrl, const QString &scope); void checkStatusCode(int status, const QByteArray &payload); @@ -64,9 +79,10 @@ public: void getHomeAppliance(const QString &haid); private: - QByteArray m_baseAuthorizationUrl = "https://api.home-connect.com/security/oauth/authorize"; - QByteArray m_baseTokenUrl = "https://api.home-connect.com/security/oauth/token"; - QByteArray m_baseControlUrl = "https://api.home-connect.com"; + bool m_simulationMode = false; + QByteArray m_baseAuthorizationUrl; + QByteArray m_baseTokenUrl; + QByteArray m_baseControlUrl; QByteArray m_clientKey; QByteArray m_clientSecret; diff --git a/homeconnect/integrationpluginhomeconnect.cpp b/homeconnect/integrationpluginhomeconnect.cpp index 2e7b0bbb..7dca3352 100644 --- a/homeconnect/integrationpluginhomeconnect.cpp +++ b/homeconnect/integrationpluginhomeconnect.cpp @@ -40,28 +40,28 @@ IntegrationPluginHomeConnect::IntegrationPluginHomeConnect() { -} + m_idParamTypeIds.insert(fridgeThingClassId, fridgeThingIdParamTypeId); + m_idParamTypeIds.insert(dryerThingClassId, dryerThingIdParamTypeId); + m_idParamTypeIds.insert(coffeMakerThingClassId, coffeMakerThingIdParamTypeId); + m_idParamTypeIds.insert(dishwasherThingClassId, dishwasherThingIdParamTypeId); + m_idParamTypeIds.insert(washerThingClassId, washerThingIdParamTypeId); + m_idParamTypeIds.insert(ovenThingClassId, ovenThingIdParamTypeId); - -IntegrationPluginHomeConnect::~IntegrationPluginHomeConnect() -{ - if (m_pluginTimer5sec) - hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer5sec); - if (m_pluginTimer60sec) - hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer60sec); -} - -void IntegrationPluginHomeConnect::discoverThings(ThingDiscoveryInfo *info) -{ - Q_UNUSED(info) + m_connectedStateTypeIds.insert(fridgeThingClassId, fridgeConnectedStateTypeId); + m_connectedStateTypeIds.insert(dryerThingClassId, dryerConnectedStateTypeId); + m_connectedStateTypeIds.insert(coffeMakerThingClassId, coffeMakerConnectedStateTypeId); + m_connectedStateTypeIds.insert(dishwasherThingClassId, dishwasherConnectedStateTypeId); + m_connectedStateTypeIds.insert(washerThingClassId, washerConnectedStateTypeId); + m_connectedStateTypeIds.insert(ovenThingClassId, ovenConnectedStateTypeId); } void IntegrationPluginHomeConnect::startPairing(ThingPairingInfo *info) { if (info->thingClassId() == homeConnectConnectionThingClassId) { - HomeConnect *homeConnect = new HomeConnect(hardwareManager()->networkManager(), "423713AB3EDA5B44BCE6E7B3546C43DADCB27A156C681E30455250637B2213DB", "AE182EA9F1CB99416DFD62CE61BF6DCDB3BB7D4697B58D4499D3792EC9F7412D", this); - QUrl url = homeConnect->getLoginUrl(QUrl("https://127.0.0.1:8888"), "Monitor"); + bool simulationMode = configValue(homeConnectPluginSimulationModeParamTypeId).toBool(); + HomeConnect *homeConnect = new HomeConnect(hardwareManager()->networkManager(), "423713AB3EDA5B44BCE6E7B3546C43DADCB27A156C681E30455250637B2213DB", "AE182EA9F1CB99416DFD62CE61BF6DCDB3BB7D4697B58D4499D3792EC9F7412D", simulationMode, this); + QUrl url = homeConnect->getLoginUrl(QUrl("https://127.0.0.1:8888"), "IdentifyAppliance Monitor Settings"); qCDebug(dcHomeConnect()) << "HomeConnect url:" << url; info->setOAuthUrl(url); info->finish(Thing::ThingErrorNoError); @@ -115,8 +115,7 @@ void IntegrationPluginHomeConnect::confirmPairing(ThingPairingInfo *info, const info->finish(Thing::ThingErrorNoError); }); } else { - qCWarning(dcHomeConnect()) << "Invalid thingClassId -> no pairing possible with this device"; - info->finish(Thing::ThingErrorThingClassNotFound); + Q_ASSERT_X(false, "confirmPairing", QString("Unhandled thingClassId: %1").arg(info->thingClassId().toString()).toUtf8()); } } @@ -125,7 +124,8 @@ void IntegrationPluginHomeConnect::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - if (info->thing()->thingClassId() == homeConnectConnectionThingClassId) { + if (thing->thingClassId() == homeConnectConnectionThingClassId) { + bool simulationMode = configValue(homeConnectPluginSimulationModeParamTypeId).toBool(); HomeConnect *homeConnect; if (m_setupHomeConnectConnections.keys().contains(thing->id())) { //Fresh device setup, has already a fresh access token @@ -134,24 +134,38 @@ void IntegrationPluginHomeConnect::setupThing(ThingSetupInfo *info) connect(homeConnect, &HomeConnect::connectionChanged, this, &IntegrationPluginHomeConnect::onConnectionChanged); connect(homeConnect, &HomeConnect::actionExecuted, this, &IntegrationPluginHomeConnect::onRequestExecuted); connect(homeConnect, &HomeConnect::authenticationStatusChanged, this, &IntegrationPluginHomeConnect::onAuthenticationStatusChanged); + connect(homeConnect, &HomeConnect::receivedHomeAppliances, this, &IntegrationPluginHomeConnect::onReceivedHomeAppliances); m_homeConnectConnections.insert(thing, homeConnect); - return; + m_homeConnectConnections.insert(thing, homeConnect); + info->finish(Thing::ThingErrorNoError); } else { //device loaded from the device database, needs a new access token; pluginStorage()->beginGroup(thing->id().toString()); QByteArray refreshToken = pluginStorage()->value("refresh_token").toByteArray(); pluginStorage()->endGroup(); - homeConnect = new HomeConnect(hardwareManager()->networkManager(), "423713AB3EDA5B44BCE6E7B3546C43DADCB27A156C681E30455250637B2213DB", "AE182EA9F1CB99416DFD62CE61BF6DCDB3BB7D4697B58D4499D3792EC9F7412D", this); + homeConnect = new HomeConnect(hardwareManager()->networkManager(), "423713AB3EDA5B44BCE6E7B3546C43DADCB27A156C681E30455250637B2213DB", "AE182EA9F1CB99416DFD62CE61BF6DCDB3BB7D4697B58D4499D3792EC9F7412D", simulationMode, this); connect(homeConnect, &HomeConnect::connectionChanged, this, &IntegrationPluginHomeConnect::onConnectionChanged); connect(homeConnect, &HomeConnect::actionExecuted, this, &IntegrationPluginHomeConnect::onRequestExecuted); connect(homeConnect, &HomeConnect::authenticationStatusChanged, this, &IntegrationPluginHomeConnect::onAuthenticationStatusChanged); + connect(homeConnect, &HomeConnect::receivedHomeAppliances, this, &IntegrationPluginHomeConnect::onReceivedHomeAppliances); homeConnect->getAccessTokenFromRefreshToken(refreshToken); - m_homeConnectConnections.insert(thing, homeConnect); - info->finish(Thing::ThingErrorNoError); + m_asyncSetup.insert(homeConnect, info); } + } else if (thing->thingClassId() == dryerThingClassId) { + info->finish(Thing::ThingErrorNoError); + } else if (thing->thingClassId() == fridgeThingClassId) { + info->finish(Thing::ThingErrorNoError); + } else if (thing->thingClassId() == washerThingClassId) { + info->finish(Thing::ThingErrorNoError); + } else if (thing->thingClassId() == dishwasherThingClassId) { + info->finish(Thing::ThingErrorNoError); + } else if (thing->thingClassId() == coffeMakerThingClassId) { + info->finish(Thing::ThingErrorNoError); + } else if (thing->thingClassId() == ovenThingClassId) { + info->finish(Thing::ThingErrorNoError); } else { - info->finish(Thing::ThingErrorThingClassNotFound); + Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); } } @@ -167,6 +181,7 @@ void IntegrationPluginHomeConnect::postSetupThing(Thing *thing) qWarning(dcHomeConnect()) << "No HomeConnect account found for" << connectionThing->name(); continue; } + //TODO upate thing states } }); } @@ -180,14 +195,28 @@ void IntegrationPluginHomeConnect::postSetupThing(Thing *thing) qWarning(dcHomeConnect()) << "No HomeConnect account found for" << thing->name(); continue; } - + homeConnect->getHomeAppliances(); } }); } if (thing->thingClassId() == homeConnectConnectionThingClassId) { HomeConnect *homeConnect = m_homeConnectConnections.value(thing); - Q_UNUSED(homeConnect) + homeConnect->getHomeAppliances(); + thing->setStateValue(homeConnectConnectionConnectedStateTypeId, true); + thing->setStateValue(homeConnectConnectionLoggedInStateTypeId, true); + } else if ((thing->thingClassId() == dryerThingClassId) || + (thing->thingClassId() == fridgeThingClassId) || + (thing->thingClassId() == washerThingClassId) || + (thing->thingClassId() == dishwasherThingClassId) || + (thing->thingClassId() == coffeMakerThingClassId) || + (thing->thingClassId() == ovenThingClassId)) { + Thing *parentThing = myThings().findById(thing->parentId()); + HomeConnect *homeConnect = m_homeConnectConnections.value(parentThing); + if (homeConnect) + homeConnect->getHomeAppliances(); + } else { + Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); } } @@ -214,10 +243,14 @@ void IntegrationPluginHomeConnect::thingRemoved(Thing *thing) } if (myThings().empty()) { - hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer5sec); - hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer60sec); - m_pluginTimer5sec = nullptr; - m_pluginTimer60sec = nullptr; + if (m_pluginTimer5sec) { + m_pluginTimer5sec = nullptr; + hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer5sec); + } + if (m_pluginTimer60sec) { + hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer60sec); + m_pluginTimer60sec = nullptr; + } } } @@ -228,6 +261,11 @@ void IntegrationPluginHomeConnect::onConnectionChanged(bool connected) if (!thing) return; thing->setStateValue(homeConnectConnectionConnectedStateTypeId, connected); + if (!connected) { + Q_FOREACH(Thing *child, myThings().filterByParentId(thing->id())) { + child->setStateValue(m_connectedStateTypeIds.value(child->thingClassId()), connected); + } + } } void IntegrationPluginHomeConnect::onAuthenticationStatusChanged(bool authenticated) @@ -236,8 +274,10 @@ void IntegrationPluginHomeConnect::onAuthenticationStatusChanged(bool authentica if (m_asyncSetup.contains(homeConnectConnection)) { ThingSetupInfo *info = m_asyncSetup.take(homeConnectConnection); if (authenticated) { + m_homeConnectConnections.insert(info->thing(), homeConnectConnection); info->finish(Thing::ThingErrorNoError); } else { + homeConnectConnection->deleteLater(); info->finish(Thing::ThingErrorHardwareFailure); } } else { @@ -267,3 +307,67 @@ void IntegrationPluginHomeConnect::onRequestExecuted(QUuid requestId, bool succe } } } + +void IntegrationPluginHomeConnect::onReceivedHomeAppliances(QList appliances) +{ + HomeConnect *homeConnectConnection = static_cast(sender()); + Thing *parentThing = m_homeConnectConnections.key(homeConnectConnection); + if (!parentThing) + return; + + ThingDescriptors desciptors; + Q_FOREACH(HomeConnect::HomeAppliance appliance, appliances) { + ThingClassId thingClassId; + /*Oven, + Dishwasher, + Washer, + Dryer, + WasherDryer, + FridgeFreezer, + Refrigerator, + Freezer, + WineCooler, + CoffeeMaker, + Hood, + CleaningRobot, + CookProcessor*/ + + if (appliance.type.contains("Oven", Qt::CaseInsensitive)) { + thingClassId = ovenThingClassId; + } else if (appliance.type.contains("Dishwasher", Qt::CaseInsensitive)) { + thingClassId = dishwasherThingClassId; + } else if (appliance.type.contains("Washer", Qt::CaseInsensitive)) { + thingClassId = washerThingClassId; + } else if (appliance.type.contains("FidgeFreezer", Qt::CaseInsensitive)) { + thingClassId = fridgeThingClassId; + } else if (appliance.type.contains("Refrigerator", Qt::CaseInsensitive)) { + thingClassId = fridgeThingClassId; + } else if (appliance.type.contains("Freezer", Qt::CaseInsensitive)) { + thingClassId = fridgeThingClassId; + } else if (appliance.type.contains("WineCooler", Qt::CaseInsensitive)) { + thingClassId = fridgeThingClassId; + } else if (appliance.type.contains("CoffeMaker", Qt::CaseInsensitive)) { + thingClassId = coffeMakerThingClassId; + } else if (appliance.type.contains("Dryer", Qt::CaseInsensitive)) { + thingClassId = dryerThingClassId; + } else { + qCWarning(dcHomeConnect()) << "Unknown thing type" << appliance.type; + continue; + } + + if (!myThings().filterByParam(m_idParamTypeIds.value(thingClassId), appliance.homeApplianceId).isEmpty()) { + Thing * existingThing = myThings().filterByParam(m_idParamTypeIds.value(thingClassId), appliance.homeApplianceId).first(); + existingThing->setStateValue(m_connectedStateTypeIds.value(thingClassId), appliance.connected); + continue; + } + + ThingDescriptor descriptor(thingClassId, appliance.name, appliance.brand+" "+appliance.vib, parentThing->id()); + + ParamList params; + params << Param(m_idParamTypeIds.value(thingClassId), appliance.homeApplianceId); + descriptor.setParams(params); + desciptors.append(descriptor); + } + if (!desciptors.isEmpty()) + emit autoThingsAppeared(desciptors); +} diff --git a/homeconnect/integrationpluginhomeconnect.h b/homeconnect/integrationpluginhomeconnect.h index e7cbbe2a..d3208d8b 100644 --- a/homeconnect/integrationpluginhomeconnect.h +++ b/homeconnect/integrationpluginhomeconnect.h @@ -46,9 +46,6 @@ class IntegrationPluginHomeConnect : public IntegrationPlugin public: explicit IntegrationPluginHomeConnect(); - ~IntegrationPluginHomeConnect() override; - - void discoverThings(ThingDiscoveryInfo *info) override; void startPairing(ThingPairingInfo *info) override; void confirmPairing(ThingPairingInfo *info, const QString &username, const QString &secret) override; @@ -69,10 +66,15 @@ private: QHash m_pendingActions; + QHash m_idParamTypeIds; + QHash m_connectedStateTypeIds; + + HomeConnect *createHomeConnection(); private slots: void onConnectionChanged(bool connected); void onAuthenticationStatusChanged(bool authenticated); void onRequestExecuted(QUuid requestId, bool success); + void onReceivedHomeAppliances(QList appliances); }; #endif // INTEGRATIONPLUGINHOMECONNECT_H diff --git a/homeconnect/integrationpluginhomeconnect.json b/homeconnect/integrationpluginhomeconnect.json index ba26e672..04855731 100644 --- a/homeconnect/integrationpluginhomeconnect.json +++ b/homeconnect/integrationpluginhomeconnect.json @@ -2,6 +2,15 @@ "id": "109abdc7-5d53-4f63-a4b2-851e97cea8ea", "name": "homeConnect", "displayName": "Home Connect", + "paramTypes": [ + { + "id": "82a1d671-4774-49df-97dc-ed89398c0dc9", + "name": "simulationMode", + "displayName": "Simulation mode", + "defaultValue": false, + "type": "bool" + } + ], "vendors": [ { "id": "43cfb7a4-402f-4315-86b5-ce095697fd13", @@ -52,6 +61,13 @@ "interfaces": ["connectable"], "createMethods": ["auto"], "paramTypes": [ + { + "id": "661c1603-356e-4a78-baf4-7ea0bc9da316", + "name": "id", + "displayName": "ID", + "defaultValue": "-", + "type": "QString" + } ], "stateTypes": [ { @@ -72,6 +88,13 @@ "interfaces": ["connectable"], "createMethods": ["auto"], "paramTypes": [ + { + "id": "f6b86d1b-481a-4496-975e-055f5ecc2bdb", + "name": "id", + "displayName": "ID", + "defaultValue": "-", + "type": "QString" + } ], "stateTypes": [ { @@ -87,11 +110,18 @@ }, { "id": "f6b39ce2-8276-4db7-b2a3-4a04cafacbb9", - "name": "coffeMachine", - "displayName": "Coffe Machine", + "name": "coffeMaker", + "displayName": "Coffe Maker", "interfaces": ["connectable"], "createMethods": ["auto"], "paramTypes": [ + { + "id": "85d48203-e97b-45cc-a899-494c375389a5", + "name": "id", + "displayName": "ID", + "defaultValue": "-", + "type": "QString" + } ], "stateTypes": [ { @@ -112,6 +142,13 @@ "interfaces": ["connectable"], "createMethods": ["auto"], "paramTypes": [ + { + "id": "cad8a1f9-6313-48dd-bb1d-b285006c760b", + "name": "id", + "displayName": "ID", + "defaultValue": "-", + "type": "QString" + } ], "stateTypes": [ { @@ -132,6 +169,13 @@ "interfaces": ["connectable"], "createMethods": ["auto"], "paramTypes": [ + { + "id": "ba36e6a0-cb88-42d2-bdb9-9d7d106dec83", + "name": "id", + "displayName": "ID", + "defaultValue": "-", + "type": "QString" + } ], "stateTypes": [ { @@ -152,6 +196,13 @@ "interfaces": ["connectable"], "createMethods": ["auto"], "paramTypes": [ + { + "id": "be4a1dcf-a0ce-44bb-a374-65f875e53c94", + "name": "id", + "displayName": "ID", + "defaultValue": "-", + "type": "QString" + } ], "stateTypes": [ {