From 5820b45c2a8b72951dffcfe68c1d020a6a657657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 19 Jan 2022 12:48:15 +0100 Subject: [PATCH 1/3] Handle reconfigure for MQTT and make sure only one reply is pending for a charger --- goecharger/integrationplugingoecharger.cpp | 43 ++++++++++++++-------- goecharger/integrationplugingoecharger.h | 1 + 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/goecharger/integrationplugingoecharger.cpp b/goecharger/integrationplugingoecharger.cpp index 02d8c2b0..06dd199c 100644 --- a/goecharger/integrationplugingoecharger.cpp +++ b/goecharger/integrationplugingoecharger.cpp @@ -105,9 +105,6 @@ void IntegrationPluginGoECharger::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); if (thing->thingClassId() == goeHomeThingClassId) { - - // TODO: handle reconfigure - QNetworkReply *reply = hardwareManager()->networkManager()->get(buildStatusRequest(thing)); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); connect(reply, &QNetworkReply::finished, info, [=](){ @@ -129,6 +126,13 @@ void IntegrationPluginGoECharger::setupThing(ThingSetupInfo *info) qCDebug(dcGoECharger()) << "Received" << qUtf8Printable(jsonDoc.toJson()); QVariantMap statusMap = jsonDoc.toVariant().toMap(); if (thing->paramValue(goeHomeThingUseMqttParamTypeId).toBool()) { + + // Handle reconfigure + if (m_channels.contains(thing)) { + hardwareManager()->mqttProvider()->releaseChannel(m_channels.take(thing)); + // Continue with normal setup + } + // Verify mqtt client and set it up qCDebug(dcGoECharger()) << "Setup using MQTT connection for" << thing; QHostAddress address = QHostAddress(thing->paramValue(goeHomeThingIpAddressParamTypeId).toString()); @@ -151,13 +155,11 @@ void IntegrationPluginGoECharger::postSetupThing(Thing *thing) { if (thing->thingClassId() == goeHomeThingClassId) { // Set up refresh timer if needed and if we are not using mqtt - if (!thing->paramValue(goeHomeThingUseMqttParamTypeId).toBool()) { - if (!m_refreshTimer) { - m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(4); - connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginGoECharger::refreshHttp); - m_refreshTimer->start(); - qCDebug(dcGoECharger()) << "Enable HTTP refresh timer..."; - } + if (!thing->paramValue(goeHomeThingUseMqttParamTypeId).toBool() && !m_refreshTimer) { + qCDebug(dcGoECharger()) << "Enabling HTTP refresh timer..."; + m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(4); + connect(m_refreshTimer, &PluginTimer::timeout, this, &IntegrationPluginGoECharger::refreshHttp); + m_refreshTimer->start(); } } } @@ -169,6 +171,11 @@ void IntegrationPluginGoECharger::thingRemoved(Thing *thing) hardwareManager()->mqttProvider()->releaseChannel(m_channels.take(thing)); } + // Cleanup possible pending replies + if (m_pendingReplies.contains(thing) && m_pendingReplies.value(thing)) { + m_pendingReplies.take(thing)->abort(); + } + // Clean up refresh timer if set up if (m_refreshTimer && myThings().isEmpty()) { hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); @@ -210,36 +217,30 @@ void IntegrationPluginGoECharger::executeAction(ThingActionInfo *info) qCDebug(dcGoECharger()) << "Setting max charging current to" << maxChargingCurrent << "A"; // FIXME: check if we can use amx since it is better for pv charging, not all version seen implement amx // Maybe check if the user sets it or a automatism - // Set the allow value QString configuration = QString("amp=%1").arg(maxChargingCurrent); sendActionRequest(thing, info, configuration); return; } else if (action.actionTypeId() == goeHomeAbsoluteMaxAmpereActionTypeId) { uint maxAmpere = action.paramValue(goeHomeAbsoluteMaxAmpereActionAbsoluteMaxAmpereParamTypeId).toUInt(); qCDebug(dcGoECharger()) << "Setting absolute maximal charging amperes to" << maxAmpere << "A"; - // TODO: use amx if available - // Set the allow value QString configuration = QString("ama=%1").arg(maxAmpere); sendActionRequest(thing, info, configuration); return; } else if (action.actionTypeId() == goeHomeCloudActionTypeId) { bool enabled = action.paramValue(goeHomeCloudActionCloudParamTypeId).toBool(); qCDebug(dcGoECharger()) << "Set cloud" << (enabled ? "enabled" : "disabled"); - // Set the allow value QString configuration = QString("cdi=%1").arg(enabled ? 1: 0); sendActionRequest(thing, info, configuration); return; } else if (action.actionTypeId() == goeHomeLedBrightnessActionTypeId) { quint8 brightness = action.paramValue(goeHomeLedBrightnessActionLedBrightnessParamTypeId).toUInt(); qCDebug(dcGoECharger()) << "Set led brightnss to" << brightness << "/" << 255; - // Set the allow value QString configuration = QString("lbr=%1").arg(brightness); sendActionRequest(thing, info, configuration); return; } else if (action.actionTypeId() == goeHomeLedEnergySaveActionTypeId) { bool enabled = action.paramValue(goeHomeLedEnergySaveActionLedEnergySaveParamTypeId).toBool(); qCDebug(dcGoECharger()) << "Set led energy saving" << (enabled ? "enabled" : "disabled"); - // Set the allow value QString configuration = QString("lse=%1").arg(enabled ? 1: 0); sendActionRequest(thing, info, configuration); return; @@ -682,10 +683,20 @@ void IntegrationPluginGoECharger::refreshHttp() // Poll thing which if not using mqtt if (!thing->paramValue(goeHomeThingUseMqttParamTypeId).toBool()) { + + // Make sure there is not a request pending for this thing, otherwise wait for the next refresh + if (m_pendingReplies.contains(thing) && m_pendingReplies.value(thing)) + continue; + qCDebug(dcGoECharger()) << "Refresh HTTP status from" << thing; QNetworkReply *reply = hardwareManager()->networkManager()->get(buildStatusRequest(thing)); + m_pendingReplies.insert(thing, reply); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); connect(reply, &QNetworkReply::finished, thing, [=](){ + // We are done with this thing reply + m_pendingReplies.remove(thing); + if (reply->error() != QNetworkReply::NoError) { qCWarning(dcGoECharger()) << "HTTP status reply returned error:" << reply->errorString(); thing->setStateValue(goeHomeConnectedStateTypeId, false); diff --git a/goecharger/integrationplugingoecharger.h b/goecharger/integrationplugingoecharger.h index ab9b3a07..dac79095 100644 --- a/goecharger/integrationplugingoecharger.h +++ b/goecharger/integrationplugingoecharger.h @@ -88,6 +88,7 @@ public: private: PluginTimer *m_refreshTimer = nullptr; QHash m_channels; + QHash m_pendingReplies; void update(Thing *thing, const QVariantMap &statusMap); QNetworkRequest buildStatusRequest(Thing *thing); From c16620414dda6be051f0f73d0886091c809667b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 19 Jan 2022 12:54:39 +0100 Subject: [PATCH 2/3] Update readme --- goecharger/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/goecharger/README.md b/goecharger/README.md index dabce807..6b51cf7a 100644 --- a/goecharger/README.md +++ b/goecharger/README.md @@ -2,8 +2,11 @@ nymea plugin for go-eCharger smart wallbox for electic vehicles. -Once you connect to the go-eCharger, nymea will configure the wallbox to use MQTT and send information to nymea. -Please make sure no other service is using the custom MQTT server in the local network, otherwise they will exclude each other, depending who comes first. +If you are using other services like the original goe app to communicate with the wallbox, disable MQTT during the setup in order to make sure +all services are able to communicate with the wallbox. There is no support for multiple MQTT clients on the device and therefore nymea defaults to HTTP +to prevent constant reconfiguration trough the clients. + +The prefered way of communicating would be MQTT, default is HTTP. ## Supported Things From 1b6b334c3573e598bb6c02e67c60153b7d524743 Mon Sep 17 00:00:00 2001 From: simonseres Date: Fri, 25 Mar 2022 18:14:09 +0100 Subject: [PATCH 3/3] updated readme --- goecharger/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/goecharger/README.md b/goecharger/README.md index 6b51cf7a..93eaa813 100644 --- a/goecharger/README.md +++ b/goecharger/README.md @@ -2,11 +2,9 @@ nymea plugin for go-eCharger smart wallbox for electic vehicles. -If you are using other services like the original goe app to communicate with the wallbox, disable MQTT during the setup in order to make sure -all services are able to communicate with the wallbox. There is no support for multiple MQTT clients on the device and therefore nymea defaults to HTTP -to prevent constant reconfiguration trough the clients. +If you are using the original go-e App or other client services to communicate with the wallbox, disable MQTT during the setup in order to make sure all services are able to communicate with the wallbox. There is no support for multiple MQTT clients on go-e devices, thus nymea defaults to HTTP to prevent constant reconfiguration trough the clients. -The prefered way of communicating would be MQTT, default is HTTP. +The preferred way of communicating would be MQTT, default is HTTP. ## Supported Things