diff --git a/include/MqttHandleInverterTotal.h b/include/MqttHandleInverterTotal.h new file mode 100644 index 0000000..fa4ce4b --- /dev/null +++ b/include/MqttHandleInverterTotal.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include + +class MqttHandleInverterTotalClass { +public: + void init(); + void loop(); + +private: + TimeoutHelper _lastPublish; +}; + +extern MqttHandleInverterTotalClass MqttHandleInverterTotal; \ No newline at end of file diff --git a/src/MqttHandleInverterTotal.cpp b/src/MqttHandleInverterTotal.cpp new file mode 100644 index 0000000..6d14576 --- /dev/null +++ b/src/MqttHandleInverterTotal.cpp @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2023 Thomas Basler and others + */ +#include "MqttHandleInverterTotal.h" +#include "Configuration.h" +#include "MqttSettings.h" +#include + +MqttHandleInverterTotalClass MqttHandleInverterTotal; + +void MqttHandleInverterTotalClass::init() +{ + _lastPublish.set(Configuration.get().Mqtt_PublishInterval * 1000); +} + +void MqttHandleInverterTotalClass::loop() +{ + if (!MqttSettings.getConnected() || !Hoymiles.isAllRadioIdle()) { + return; + } + + if (_lastPublish.occured()) { + float totalAcPower = 0; + float totalDcPower = 0; + float totalDcPowerIrr = 0; + float totalDcPowerIrrInst = 0; + float totalAcYieldDay = 0; + float totalAcYieldTotal = 0; + uint8_t totalAcPowerDigits = 0; + uint8_t totalDcPowerDigits = 0; + uint8_t totalAcYieldDayDigits = 0; + uint8_t totalAcYieldTotalDigits = 0; + bool totalReachable = true; + + for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { + auto inv = Hoymiles.getInverterByPos(i); + if (inv == nullptr || !inv->getEnablePolling()) { + continue; + } + + if (!inv->isReachable()) { + totalReachable = false; + } + + for (auto& c : inv->Statistics()->getChannelsByType(TYPE_AC)) { + totalAcPower += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_PAC); + totalAcPowerDigits = max(totalAcPowerDigits, inv->Statistics()->getChannelFieldDigits(TYPE_AC, c, FLD_PAC)); + + totalAcYieldDay += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_YD); + totalAcYieldDayDigits = max(totalAcYieldDayDigits, inv->Statistics()->getChannelFieldDigits(TYPE_AC, c, FLD_YD)); + + totalAcYieldTotal += inv->Statistics()->getChannelFieldValue(TYPE_AC, c, FLD_YT); + totalAcYieldTotalDigits = max(totalAcYieldTotalDigits, inv->Statistics()->getChannelFieldDigits(TYPE_AC, c, FLD_YT)); + } + for (auto& c : inv->Statistics()->getChannelsByType(TYPE_DC)) { + totalDcPower += inv->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC); + totalDcPowerDigits = max(totalDcPowerDigits, inv->Statistics()->getChannelFieldDigits(TYPE_DC, c, FLD_PDC)); + + if (inv->Statistics()->getStringMaxPower(c) > 0) { + totalDcPowerIrr += inv->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC); + totalDcPowerIrrInst += inv->Statistics()->getStringMaxPower(c); + } + } + } + + MqttSettings.publish("ac/power", String(totalAcPower, static_cast(totalAcPowerDigits))); + MqttSettings.publish("ac/yieldtotal", String(totalAcYieldDay, static_cast(totalAcYieldDayDigits))); + MqttSettings.publish("ac/yieldday", String(totalAcYieldTotal, static_cast(totalAcYieldTotalDigits))); + MqttSettings.publish("ac/is_valid", String(totalReachable)); + MqttSettings.publish("dc/power", String(totalDcPower, static_cast(totalAcPowerDigits))); + MqttSettings.publish("dc/irradiation", String(totalDcPowerIrrInst > 0 ? totalDcPowerIrr / totalDcPowerIrrInst * 100.0f : 0, 3)); + MqttSettings.publish("dc/is_valid", String(totalReachable)); + + _lastPublish.set(Configuration.get().Mqtt_PublishInterval * 1000); + } +} diff --git a/src/main.cpp b/src/main.cpp index 76cb1f3..172b3a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "MqttHandleDtu.h" #include "MqttHandleHass.h" #include "MqttHandleInverter.h" +#include "MqttHandleInverterTotal.h" #include "MqttSettings.h" #include "NetworkSettings.h" #include "NtpSettings.h" @@ -92,6 +93,7 @@ void setup() MqttSettings.init(); MqttHandleDtu.init(); MqttHandleInverter.init(); + MqttHandleInverterTotal.init(); MqttHandleHass.init(); MessageOutput.println("done"); @@ -146,6 +148,7 @@ void loop() yield(); MqttHandleInverter.loop(); yield(); + MqttHandleInverterTotal.loop(); MqttHandleHass.loop(); yield(); WebApi.loop();