diff --git a/homeconnect/homeconnect.cpp b/homeconnect/homeconnect.cpp index 9b4b93ca..cee8b7b1 100644 --- a/homeconnect/homeconnect.cpp +++ b/homeconnect/homeconnect.cpp @@ -348,6 +348,42 @@ void HomeConnect::getProgramsActiveOption(const QString &haId, const QString &op }); } +void HomeConnect::getStatus(const QString &haid) +{ + QUrl url = QUrl(m_baseControlUrl+"/api/homeappliances/"+haid+"/status"); + + QNetworkRequest request(url); + request.setRawHeader("Authorization", "Bearer "+m_accessToken); + request.setRawHeader("Accept-Language", "en-US"); + request.setRawHeader("accept", "application/vnd.bsh.sdk.v1+json"); + + QNetworkReply *reply = m_networkManager->get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, this, [this, reply]{ + + + // Remote control activation state + // Remote start allowance state + // Local control state + // Operation state + // Door state + + 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()) << "Get home appliances" << data.toJson(); + if (data.toVariant().toMap().contains("data")) { + QVariantMap dataMap = data.toVariant().toMap().value("data").toMap(); + qCDebug(dcHomeConnect()) << "key" << dataMap.value("key").toString() << "value" << dataMap.value("value").toString() << dataMap.value("unit").toString(); + } else if (data.toVariant().toMap().contains("error")) { + qCWarning(dcHomeConnect()) << "Get home appliences" << data.toVariant().toMap().value("error").toMap().value("description").toString(); + } + }); +} + /* Get a list of available setting of the home appliance. * Possible Settings: * Power state @@ -385,3 +421,42 @@ void HomeConnect::getSettings(const QString &haid) } }); } + +QUuid HomeConnect::sendCommand(const QString &haid, const QString &command) +{ + QUuid commandId = QUuid::createUuid(); + QUrl url = QUrl(m_baseControlUrl+"/api/homeappliances/"+haid+"/commands/"+command); + + QNetworkRequest request(url); + request.setRawHeader("Authorization", "Bearer "+m_accessToken); + request.setRawHeader("Accept-Language", "en-US"); + request.setRawHeader("accept", "application/vnd.bsh.sdk.v1+json"); + + QJsonDocument doc; + QJsonObject data; + data.insert("key", command); + data.insert("value", true); + QJsonObject obj; + obj.insert("data", data); + doc.setObject(obj); + QNetworkReply *reply = m_networkManager->put(request, doc.toJson()); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, this, [this, commandId, reply]{ + + QJsonParseError error; + QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) { + qCDebug(dcHomeConnect()) << "Send command: Recieved invalide JSON object"; + return; + } + qCDebug(dcHomeConnect()) << "Send command" << data.toJson(); + if (data.toVariant().toMap().contains("data")) { + QVariantMap dataMap = data.toVariant().toMap().value("data").toMap(); + qCDebug(dcHomeConnect()) << "key" << dataMap.value("key").toString() << "value" << dataMap.value("value").toString() << dataMap.value("unit").toString(); + } else if (data.toVariant().toMap().contains("error")) { + qCWarning(dcHomeConnect()) << "Send command" << data.toVariant().toMap().value("error").toMap().value("description").toString(); + } + emit commandExecuted(commandId, true); + }); + return commandId; +} diff --git a/homeconnect/homeconnect.h b/homeconnect/homeconnect.h index 360b113d..3f92593d 100644 --- a/homeconnect/homeconnect.h +++ b/homeconnect/homeconnect.h @@ -33,6 +33,7 @@ #include #include +#include #include "network/networkaccessmanager.h" @@ -88,8 +89,11 @@ public: void getProgramsAvailable(const QString &haId); void getProgramsActiveOption(const QString &haId, const QString &optionKey); + void getStatus(const QString &haid); void getSettings(const QString &haid); + QUuid sendCommand(const QString &haid, const QString &command); //commands "BSH.Common.Command.ResumeProgram" & "PauseProgram" + private: bool m_simulationMode = false; QByteArray m_baseAuthorizationUrl; @@ -112,7 +116,7 @@ private slots: signals: void connectionChanged(bool connected); void authenticationStatusChanged(bool authenticated); - void actionExecuted(QUuid actionId,bool success); + void commandExecuted(QUuid commandId,bool success); void receivedHomeAppliances(const QList &appliances); }; diff --git a/homeconnect/integrationpluginhomeconnect.cpp b/homeconnect/integrationpluginhomeconnect.cpp index 0a23e115..ba899bea 100644 --- a/homeconnect/integrationpluginhomeconnect.cpp +++ b/homeconnect/integrationpluginhomeconnect.cpp @@ -46,13 +46,15 @@ IntegrationPluginHomeConnect::IntegrationPluginHomeConnect() m_idParamTypeIds.insert(dishwasherThingClassId, dishwasherThingIdParamTypeId); m_idParamTypeIds.insert(washerThingClassId, washerThingIdParamTypeId); m_idParamTypeIds.insert(ovenThingClassId, ovenThingIdParamTypeId); - + m_idParamTypeIds.insert(cookTopThingClassId, cookTopThingIdParamTypeId); + //TODO add new devices 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); + //TODO add new devices } void IntegrationPluginHomeConnect::startPairing(ThingPairingInfo *info) @@ -132,7 +134,7 @@ void IntegrationPluginHomeConnect::setupThing(ThingSetupInfo *info) qCDebug(dcHomeConnect()) << "HomeConnect OAuth setup complete"; homeConnect = m_setupHomeConnectConnections.take(thing->id()); connect(homeConnect, &HomeConnect::connectionChanged, this, &IntegrationPluginHomeConnect::onConnectionChanged); - connect(homeConnect, &HomeConnect::actionExecuted, this, &IntegrationPluginHomeConnect::onRequestExecuted); + connect(homeConnect, &HomeConnect::commandExecuted, this, &IntegrationPluginHomeConnect::onRequestExecuted); connect(homeConnect, &HomeConnect::authenticationStatusChanged, this, &IntegrationPluginHomeConnect::onAuthenticationStatusChanged); connect(homeConnect, &HomeConnect::receivedHomeAppliances, this, &IntegrationPluginHomeConnect::onReceivedHomeAppliances); m_homeConnectConnections.insert(thing, homeConnect); @@ -145,18 +147,18 @@ void IntegrationPluginHomeConnect::setupThing(ThingSetupInfo *info) 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::commandExecuted, this, &IntegrationPluginHomeConnect::onRequestExecuted); connect(homeConnect, &HomeConnect::authenticationStatusChanged, this, &IntegrationPluginHomeConnect::onAuthenticationStatusChanged); connect(homeConnect, &HomeConnect::receivedHomeAppliances, this, &IntegrationPluginHomeConnect::onReceivedHomeAppliances); homeConnect->getAccessTokenFromRefreshToken(refreshToken); m_asyncSetup.insert(homeConnect, info); } } else if ((thing->thingClassId() == dryerThingClassId) || - (thing->thingClassId() == fridgeThingClassId) || - (thing->thingClassId() == washerThingClassId) || - (thing->thingClassId() == dishwasherThingClassId) || - (thing->thingClassId() == coffeMakerThingClassId) || - (thing->thingClassId() == ovenThingClassId)) { + (thing->thingClassId() == fridgeThingClassId) || + (thing->thingClassId() == washerThingClassId) || + (thing->thingClassId() == dishwasherThingClassId) || + (thing->thingClassId() == coffeMakerThingClassId) || + (thing->thingClassId() == ovenThingClassId)) { Thing *parentThing = myThings().findById(thing->parentId()); if (parentThing->setupComplete()) { info->finish(Thing::ThingErrorNoError); @@ -179,12 +181,15 @@ void IntegrationPluginHomeConnect::postSetupThing(Thing *thing) connect(m_pluginTimer5sec, &PluginTimer::timeout, this, [this]() { foreach (Thing *connectionThing, myThings().filterByThingClassId(homeConnectConnectionThingClassId)) { - HomeConnect *HomeConnect = m_homeConnectConnections.value(connectionThing); - if (!HomeConnect) { + HomeConnect *homeConnect = m_homeConnectConnections.value(connectionThing); + if (!homeConnect) { qWarning(dcHomeConnect()) << "No HomeConnect account found for" << connectionThing->name(); continue; } - //TODO upate thing states + foreach (Thing *childThing, myThings().filterByParentId(connectionThing->id())) { + QString haid = childThing->paramValue(m_idParamTypeIds.value(childThing->thingClassId())).toString(); + homeConnect->getStatus(haid); + } } }); } @@ -222,7 +227,8 @@ void IntegrationPluginHomeConnect::postSetupThing(Thing *thing) if (!homeConnect) { qCWarning(dcHomeConnect()) << "Could not find HomeConnect connection for thing" << thing->name(); } else { - homeConnect->getProgramsAvailable(haId); + homeConnect->getStatus(haId); + homeConnect->getSettings(haId); } } else { Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); @@ -234,8 +240,15 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) Thing *thing = info->thing(); Action action = info->action(); if (thing->thingClassId() == homeConnectConnectionThingClassId) { - if (action.actionTypeId() == ActionTypeId("asdf")) { //TODO + Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); + } else if (thing->thingClassId() == ovenThingClassId) { + HomeConnect *homeConnect = m_homeConnectConnections.value(myThings().findById(thing->parentId())); + QString haid = thing->stateValue(m_idParamTypeIds.value(thing->thingClassId())).toString(); + if (action.actionTypeId() == ovenPauseActionTypeId) { + homeConnect->sendCommand(haid, "BSH.Common.Command.PauseProgram"); + } else if (action.actionTypeId() == ovenResumeActionTypeId) { + homeConnect->sendCommand(haid, "BSH.Common.Command.ResumeProgram"); } else { Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); } @@ -263,6 +276,21 @@ void IntegrationPluginHomeConnect::thingRemoved(Thing *thing) } } +void IntegrationPluginHomeConnect::browseThing(BrowseResult *result) +{ + Q_UNUSED(result) +} + +void IntegrationPluginHomeConnect::browserItem(BrowserItemResult *result) +{ + Q_UNUSED(result) +} + +void IntegrationPluginHomeConnect::executeBrowserItem(BrowserActionInfo *info) +{ + Q_UNUSED(info) +} + void IntegrationPluginHomeConnect::onConnectionChanged(bool connected) { HomeConnect *homeConnect = static_cast(sender()); @@ -355,7 +383,7 @@ void IntegrationPluginHomeConnect::onReceivedHomeAppliances(QList