From 233b89d65e602df2ec2b9ecbd16ece1992696232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 8 Aug 2025 13:48:23 +0200 Subject: [PATCH] homeconnect: Add Qt6 support --- homeconnect/homeconnect.cpp | 39 ++++++------- homeconnect/homeconnect.h | 8 +-- homeconnect/integrationpluginhomeconnect.cpp | 60 ++++++++++---------- homeconnect/integrationpluginhomeconnect.h | 9 +-- 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/homeconnect/homeconnect.cpp b/homeconnect/homeconnect.cpp index 23b5fdc2..b0307b84 100644 --- a/homeconnect/homeconnect.cpp +++ b/homeconnect/homeconnect.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -35,6 +35,7 @@ #include #include #include +#include HomeConnect::HomeConnect(NetworkAccessManager *networkmanager, const QByteArray &clientKey, const QByteArray &clientSecret, bool simulationMode, QObject *parent) : QObject(parent), @@ -76,12 +77,12 @@ void HomeConnect::setSimulationMode(bool simulation) QUrl HomeConnect::getLoginUrl(const QUrl &redirectUrl, const QString &scope) { if (m_clientKey.isEmpty()) { - qWarning(dcHomeConnect) << "Client key not defined!"; + qCWarning(dcHomeConnect()) << "Client key not defined!"; return QUrl(""); } if (redirectUrl.isEmpty()){ - qWarning(dcHomeConnect) << "No redirect uri defined!"; + qCWarning(dcHomeConnect()) << "No redirect uri defined!"; } m_redirectUri = QUrl::toPercentEncoding(redirectUrl.toString()); @@ -93,7 +94,7 @@ QUrl HomeConnect::getLoginUrl(const QUrl &redirectUrl, const QString &scope) queryParams.addQueryItem("scope", scope); queryParams.addQueryItem("state", QUuid::createUuid().toString()); queryParams.addQueryItem("nonce", QUuid::createUuid().toString()); - m_codeChallenge = QUuid::createUuid().toString().remove(QRegExp("[{}-]")); + m_codeChallenge = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]")); queryParams.addQueryItem("code_challenge", m_codeChallenge); queryParams.addQueryItem("code_challenge_method", "plain"); url.setQuery(queryParams); @@ -103,7 +104,7 @@ QUrl HomeConnect::getLoginUrl(const QUrl &redirectUrl, const QString &scope) void HomeConnect::onRefreshTimeout() { - qCDebug(dcHomeConnect) << "Refresh authentication token"; + qCDebug(dcHomeConnect()) << "Refresh authentication token"; getAccessTokenFromRefreshToken(m_refreshToken); } @@ -131,19 +132,19 @@ bool HomeConnect::checkStatusCode(QNetworkReply *reply, const QByteArray &rawDat case 400: //Error occurred (e.g. validation error - value is out of range) if(!jsonDoc.toVariant().toMap().contains("error")) { if(jsonDoc.toVariant().toMap().value("error").toString() == "invalid_client") { - qWarning(dcHomeConnect()) << "Client token provided doesn’t correspond to client that generated auth code."; + qCWarning(dcHomeConnect()) << "Client token provided doesn’t correspond to client that generated auth code."; } if(jsonDoc.toVariant().toMap().value("error").toString() == "invalid_redirect_uri") { - qWarning(dcHomeConnect()) << "Missing redirect_uri parameter."; + qCWarning(dcHomeConnect()) << "Missing redirect_uri parameter."; } if(jsonDoc.toVariant().toMap().value("error").toString() == "invalid_code") { - qWarning(dcHomeConnect()) << "Expired authorization code."; + qCWarning(dcHomeConnect()) << "Expired authorization code."; } } setAuthenticated(false); return false; case 401: - qWarning(dcHomeConnect()) << "Client does not have permission to use this API."; + qCWarning(dcHomeConnect()) << "Client does not have permission to use this API."; setAuthenticated(false); return false; case 403: @@ -154,7 +155,7 @@ bool HomeConnect::checkStatusCode(QNetworkReply *reply, const QByteArray &rawDat qCWarning(dcHomeConnect()) << "Not Found. This resource is not available (e.g. no images on washing machine)"; return false; case 405: - qWarning(dcHomeConnect()) << "Wrong HTTP method used."; + qCWarning(dcHomeConnect()) << "Wrong HTTP method used."; setAuthenticated(false); return false; case 408: @@ -194,7 +195,7 @@ bool HomeConnect::checkStatusCode(QNetworkReply *reply, const QByteArray &rawDat void HomeConnect::getAccessTokenFromRefreshToken(const QByteArray &refreshToken) { if (refreshToken.isEmpty()) { - qWarning(dcHomeConnect) << "No refresh token given!"; + qCWarning(dcHomeConnect()) << "No refresh token given!"; setAuthenticated(false); return; } @@ -228,9 +229,9 @@ void HomeConnect::getAccessTokenFromRefreshToken(const QByteArray &refreshToken) if (data.toVariant().toMap().contains("expires_in")) { int expireTime = data.toVariant().toMap().value("expires_in").toInt(); - qCDebug(dcHomeConnect) << "Access token expires int" << expireTime << "s, at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); + qCDebug(dcHomeConnect()) << "Access token expires int" << expireTime << "s, at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); if (!m_tokenRefreshTimer) { - qWarning(dcHomeConnect()) << "Access token refresh timer not initialized"; + qCWarning(dcHomeConnect()) << "Access token refresh timer not initialized"; return; } if (expireTime < 20) { @@ -246,11 +247,11 @@ void HomeConnect::getAccessTokenFromAuthorizationCode(const QByteArray &authoriz { // Obtaining access token if(authorizationCode.isEmpty()) - qWarning(dcHomeConnect) << "No authorization code given!"; + qCWarning(dcHomeConnect()) << "No authorization code given!"; if(m_clientKey.isEmpty()) - qWarning(dcHomeConnect) << "Client key not set!"; + qCWarning(dcHomeConnect()) << "Client key not set!"; if(m_clientSecret.isEmpty()) - qWarning(dcHomeConnect) << "Client secret not set!"; + qCWarning(dcHomeConnect()) << "Client secret not set!"; QUrl url = QUrl(m_baseTokenUrl); QUrlQuery query; url.setQuery(query); @@ -288,7 +289,7 @@ void HomeConnect::getAccessTokenFromAuthorizationCode(const QByteArray &authoriz int expireTime = jsonDoc.toVariant().toMap().value("expires_in").toInt(); qCDebug(dcHomeConnect()) << "Token expires in" << expireTime << "s, at" << QDateTime::currentDateTime().addSecs(expireTime).toString(); if (!m_tokenRefreshTimer) { - qWarning(dcHomeConnect()) << "Token refresh timer not initialized"; + qCWarning(dcHomeConnect()) << "Token refresh timer not initialized"; setAuthenticated(false); return; } @@ -546,7 +547,7 @@ QUuid HomeConnect::selectProgram(const QString &haId, const QString &programKey, QUuid HomeConnect::setSelectedProgramOptions(const QString &haId, QList options) { if (options.isEmpty()) - return ""; + return QUuid(); QUuid commandId = QUuid::createUuid(); QUrl url = QUrl(m_baseControlUrl+"/api/homeappliances/"+haId+"/programs/selected/options"); @@ -754,7 +755,7 @@ void HomeConnect::connectEventStream() QNetworkReply *reply = m_networkManager->get(request); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - connect(reply, &QNetworkReply::finished, [reply, this] { + connect(reply, &QNetworkReply::finished, this, [reply, this] { int reconnectTime = 5000; // Usual reconnect in 5 s if (reply->error() != QNetworkReply::NetworkError::NoError) { qCDebug(dcHomeConnect()) << "Event stream error" << reply->errorString() << reply->readAll(); diff --git a/homeconnect/homeconnect.h b/homeconnect/homeconnect.h index 486bb651..e69c867d 100644 --- a/homeconnect/homeconnect.h +++ b/homeconnect/homeconnect.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -35,7 +35,7 @@ #include #include -#include "network/networkaccessmanager.h" +#include class HomeConnect : public QObject { @@ -177,13 +177,13 @@ signals: void receivedAccessToken(const QByteArray &accessToken); void commandExecuted(const QUuid &commandId, bool success); - void receivedHomeAppliances(const QList &appliances); + void receivedHomeAppliances(const QList &appliances); void receivedStatusList(const QString &haId, const QHash &statusList); void receivedPrograms(const QString &haId, const QStringList &programs); void receivedAvailablePrograms(const QString &haId, const QStringList &programs); void receivedSettings(const QString &haId, const QHash &settings); void receivedActiveProgram(const QString &haId, const QString &key, const QHash &options); void receivedSelectedProgram(const QString &haId, const QString &key, const QHash &options); - void receivedEvents(EventType eventType, const QString &haId, const QList &events); + void receivedEvents(HomeConnect::EventType eventType, const QString &haId, const QList &events); }; #endif // HOMECONNECT_H diff --git a/homeconnect/integrationpluginhomeconnect.cpp b/homeconnect/integrationpluginhomeconnect.cpp index f687d95a..9e94a049 100644 --- a/homeconnect/integrationpluginhomeconnect.cpp +++ b/homeconnect/integrationpluginhomeconnect.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -29,10 +29,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "integrationpluginhomeconnect.h" -#include "integrations/integrationplugin.h" -#include "network/networkaccessmanager.h" #include "plugininfo.h" +#include + #include #include #include @@ -218,7 +218,7 @@ void IntegrationPluginHomeConnect::confirmPairing(ThingPairingInfo *info, const HomeConnect *homeConnect = m_setupHomeConnectConnections.value(info->thingId()); if (!homeConnect) { - qWarning(dcHomeConnect()) << "No HomeConnect connection found for device:" << info->thingName(); + qCWarning(dcHomeConnect()) << "No HomeConnect connection found for device:" << info->thingName(); m_setupHomeConnectConnections.remove(info->thingId()); return info->finish(Thing::ThingErrorHardwareFailure); } @@ -326,7 +326,7 @@ void IntegrationPluginHomeConnect::postSetupThing(Thing *thing) Q_FOREACH (Thing *thing, myThings().filterByThingClassId(homeConnectAccountThingClassId)) { HomeConnect *homeConnect = m_homeConnectConnections.value(thing); if (!homeConnect) { - qWarning(dcHomeConnect()) << "No HomeConnect account found for" << thing->name(); + qCWarning(dcHomeConnect()) << "No HomeConnect account found for" << thing->name(); continue; } homeConnect->getHomeAppliances(); @@ -411,7 +411,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) options.append(coffeeTemperature); requestId = homeConnect->setSelectedProgramOptions(haid, options); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); @@ -429,7 +429,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) options.append(beanAmount); requestId = homeConnect->setSelectedProgramOptions(haid, options); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); @@ -443,7 +443,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) options.append(fillQuantity); requestId = homeConnect->setSelectedProgramOptions(haid, options); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); } else if (action.actionTypeId() == coffeeMakerStartActionTypeId) { @@ -454,7 +454,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) QUuid requestId; requestId = homeConnect->startProgram(haid, m_selectedProgram.value(thing), QList()); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); } @@ -473,7 +473,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) startTime.value = action.param(dishwasherStartActionStartTimeParamTypeId).value().toInt() * 60; requestId = homeConnect->startProgram(haid, m_selectedProgram.value(thing), QList() << startTime); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); } else { @@ -489,7 +489,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) QUuid requestId; requestId = homeConnect->startProgram(haid, m_selectedProgram.value(thing), QList()); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); } @@ -502,7 +502,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) QUuid requestId; requestId = homeConnect->startProgram(haid, m_selectedProgram.value(thing), QList()); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); } else if (action.actionTypeId() == dryerDryingTargetActionTypeId) { @@ -521,7 +521,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) options.append(dryingTarget); requestId = homeConnect->setSelectedProgramOptions(haid, options); m_pendingActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, [requestId, this] { + connect(info, &ThingActionInfo::aborted, this, [requestId, this] { m_pendingActions.remove(requestId); }); } @@ -538,7 +538,7 @@ void IntegrationPluginHomeConnect::executeAction(ThingActionInfo *info) void IntegrationPluginHomeConnect::thingRemoved(Thing *thing) { - qCDebug(dcHomeConnect) << "Delete " << thing->name(); + qCDebug(dcHomeConnect()) << "Delete " << thing->name(); if (thing->thingClassId() == homeConnectAccountThingClassId) { HomeConnect *homeConnect = m_homeConnectConnections.take(thing); if (homeConnect) @@ -567,7 +567,7 @@ void IntegrationPluginHomeConnect::browseThing(BrowseResult *result) homeConnect->getProgramsAvailable(haid); connect(homeConnect, &HomeConnect::receivedAvailablePrograms, result, [result, this] (const QString &haId, const QStringList programs) { if(result->thing()->paramValue(m_idParamTypeIds.value(result->thing()->thingClassId())).toString() == haId) { - Q_FOREACH(QString program, programs) { + Q_FOREACH(const QString &program, programs) { BrowserItem item; item.setExecutable(true); item.setDisplayName(program.split('.').last()); @@ -723,7 +723,7 @@ void IntegrationPluginHomeConnect::parseKey(Thing *thing, const QString &key, co if (value.toString().split('.').last().contains("Finished")) { //apparently the finished event is not emitted by HomeConnect so this will hopefully do the trick if (m_programFinishedEventTypeIds.contains(thing->thingClassId())) { - emitEvent(Event(m_programFinishedEventTypeIds.value(thing->thingClassId()), thing->id())); + emit emitEvent(Event(m_programFinishedEventTypeIds.value(thing->thingClassId()), thing->id())); } if (m_progressStateTypeIds.contains(thing->thingClassId())) { thing->setStateValue(m_progressStateTypeIds.value(thing->thingClassId()), 0); @@ -732,21 +732,21 @@ void IntegrationPluginHomeConnect::parseKey(Thing *thing, const QString &key, co // Program Progress Events } else if (key == "BSH.Common.Event.ProgramAborted") { if (m_programFinishedEventTypeIds.contains(thing->thingClassId())) { - emitEvent(Event(m_programFinishedEventTypeIds.value(thing->thingClassId()), thing->id())); + emit emitEvent(Event(m_programFinishedEventTypeIds.value(thing->thingClassId()), thing->id())); } if (m_progressStateTypeIds.contains(thing->thingClassId())) { thing->setStateValue(m_progressStateTypeIds.value(thing->thingClassId()), 0); } } else if (key == "BSH.Common.Event.ProgramFinished") { if (m_programFinishedEventTypeIds.contains(thing->thingClassId())) { - emitEvent(Event(m_programFinishedEventTypeIds.value(thing->thingClassId()), thing->id())); + emit emitEvent(Event(m_programFinishedEventTypeIds.value(thing->thingClassId()), thing->id())); } if (m_progressStateTypeIds.contains(thing->thingClassId())) { thing->setStateValue(m_progressStateTypeIds.value(thing->thingClassId()), 0); } //} else if (key == "BSH.Common.Event.AlarmClockElapsed") { } else if (key == "Cooking.Oven.Event.PreheatFinished") { - emitEvent(Event(ovenPreheatFinishedEventTypeId, thing->id())); + emit emitEvent(Event(ovenPreheatFinishedEventTypeId, thing->id())); // Home Appliance State Changes //} else if (key == "BSH.Common.Setting.PowerState") { } else if (key == "BSH.Common.Status.RemoteControlActive") { @@ -768,23 +768,23 @@ void IntegrationPluginHomeConnect::parseKey(Thing *thing, const QString &key, co // Home Appliance Events } else if (key == "ConsumerProducts.CoffeeMaker.Event.BeanContainerEmpty") { - emitEvent(Event(coffeeMakerBeanContainerEmptyEventTypeId, thing->id())); + emit emitEvent(Event(coffeeMakerBeanContainerEmptyEventTypeId, thing->id())); } else if (key == "ConsumerProducts.CoffeeMaker.Event.WaterTankEmpty") { - emitEvent(Event(coffeeMakerWaterTankEmptyEventTypeId, thing->id())); + emit emitEvent(Event(coffeeMakerWaterTankEmptyEventTypeId, thing->id())); } else if (key == "ConsumerProducts.CoffeeMaker.Event.DripTrayFull") { - emitEvent(Event(coffeeMakerDripTrayFullEventTypeId, thing->id())); + emit emitEvent(Event(coffeeMakerDripTrayFullEventTypeId, thing->id())); } else if (key == "Refrigeration.FridgeFreezer.Event.DoorAlarmFreezer") {; - emitEvent(Event(fridgeDoorAlarmFreezerEventTypeId, thing->id())); + emit emitEvent(Event(fridgeDoorAlarmFreezerEventTypeId, thing->id())); } else if (key == "Refrigeration.FridgeFreezer.Event.DoorAlarmRefrigerator") { - emitEvent(Event(fridgeDoorAlarmRefrigeratorEventTypeId, thing->id())); + emit emitEvent(Event(fridgeDoorAlarmRefrigeratorEventTypeId, thing->id())); } else if (key == "Refrigeration.FridgeFreezer.Event.TemperatureAlarmFreezer") { - emitEvent(Event(fridgeTemperatureAlarmFreezerEventTypeId, thing->id())); + emit emitEvent(Event(fridgeTemperatureAlarmFreezerEventTypeId, thing->id())); } else if (key == "ConsumerProducts.CleaningRobot.Event.EmptyDustBoxAndCleanFilter") { - emitEvent(Event(cleaningRobotEmptyDustBoxAndCleanFilterEventTypeId, thing->id())); + emit emitEvent(Event(cleaningRobotEmptyDustBoxAndCleanFilterEventTypeId, thing->id())); } else if (key == "ConsumerProducts.CleaningRobot.Event.RobotIsStuck") { - emitEvent(Event(cleaningRobotRobotIsStuckEventTypeId, thing->id())); + emit emitEvent(Event(cleaningRobotRobotIsStuckEventTypeId, thing->id())); } else if (key == "ConsumerProducts.CleaningRobot.Event.DockingStationNotFound") { - emitEvent(Event(cleaningRobotDockingStationNotFoundEventTypeId, thing->id())); + emit emitEvent(Event(cleaningRobotDockingStationNotFoundEventTypeId, thing->id())); // UNDOCUMENTED } else if (key == "Cooking.Oven.Status.CurrentCavityTemperature") { @@ -999,7 +999,7 @@ void IntegrationPluginHomeConnect::onReceivedStatusList(const QString &haId, con Q_FOREACH(Thing *thing, myThings().filterByParentId(parentThing->id())) { if (thing->paramValue(m_idParamTypeIds.value(thing->thingClassId())).toString() == haId) { qCDebug(dcHomeConnect()) << "Received status list device" << thing->name(); - Q_FOREACH(QString key, statusList.keys()) { + Q_FOREACH(const QString &key, statusList.keys()) { parseKey(thing, key, statusList.value(key)); } break; @@ -1076,7 +1076,7 @@ void IntegrationPluginHomeConnect::onReceivedSettings(const QString &haId, const Q_FOREACH(Thing *thing, myThings().filterByParentId(parentThing->id())) { if (thing->paramValue(m_idParamTypeIds.value(thing->thingClassId())).toString() == haId) { qCDebug(dcHomeConnect()) << "Received setting" << thing->name() << settings; - Q_FOREACH(QString setting, settings.keys()) { + Q_FOREACH(const QString &setting, settings.keys()) { parseSettingKey(thing, setting, settings.value(setting)); } break; diff --git a/homeconnect/integrationpluginhomeconnect.h b/homeconnect/integrationpluginhomeconnect.h index 28f9b00e..0f20ed78 100644 --- a/homeconnect/integrationpluginhomeconnect.h +++ b/homeconnect/integrationpluginhomeconnect.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2025, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -31,13 +31,14 @@ #ifndef INTEGRATIONPLUGINHOMECONNECT_H #define INTEGRATIONPLUGINHOMECONNECT_H -#include "integrations/integrationplugin.h" -#include "plugintimer.h" -#include "homeconnect.h" +#include +#include #include #include +#include "homeconnect.h" + class IntegrationPluginHomeConnect : public IntegrationPlugin { Q_OBJECT