From 5bb9acdbc6ebe58e10532286de34021194fa1bac Mon Sep 17 00:00:00 2001 From: Thomas Basler Date: Tue, 12 Jul 2022 18:27:56 +0200 Subject: [PATCH] Refactored Hoymiles Lib: Move statistics parser into separate class --- lib/Hoymiles/src/inverters/HM_Abstract.cpp | 6 +- .../src/inverters/InverterAbstract.cpp | 160 +---------------- lib/Hoymiles/src/inverters/InverterAbstract.h | 103 +---------- lib/Hoymiles/src/parser/StatisticsParser.cpp | 167 ++++++++++++++++++ lib/Hoymiles/src/parser/StatisticsParser.h | 120 +++++++++++++ src/MqttPublishing.cpp | 8 +- src/WebApi_inverter.cpp | 4 +- src/WebApi_ws_live.cpp | 12 +- src/main.cpp | 2 +- 9 files changed, 315 insertions(+), 267 deletions(-) create mode 100644 lib/Hoymiles/src/parser/StatisticsParser.cpp create mode 100644 lib/Hoymiles/src/parser/StatisticsParser.h diff --git a/lib/Hoymiles/src/inverters/HM_Abstract.cpp b/lib/Hoymiles/src/inverters/HM_Abstract.cpp index 2ecfd2e8..9eaa95dd 100644 --- a/lib/Hoymiles/src/inverters/HM_Abstract.cpp +++ b/lib/Hoymiles/src/inverters/HM_Abstract.cpp @@ -48,13 +48,13 @@ bool HM_Abstract::sendAlarmLogRequest(HoymilesRadio* radio) return false; } - if (hasChannelFieldValue(CH0, FLD_EVT_LOG)) { - if ((uint8_t)getChannelFieldValue(CH0, FLD_EVT_LOG) == _lastAlarmLogCnt) { + if (Statistics()->hasChannelFieldValue(CH0, FLD_EVT_LOG)) { + if ((uint8_t)Statistics()->getChannelFieldValue(CH0, FLD_EVT_LOG) == _lastAlarmLogCnt) { return false; } } - _lastAlarmLogCnt = (uint8_t)getChannelFieldValue(CH0, FLD_EVT_LOG); + _lastAlarmLogCnt = (uint8_t)Statistics()->getChannelFieldValue(CH0, FLD_EVT_LOG); time_t now; time(&now); diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.cpp b/lib/Hoymiles/src/inverters/InverterAbstract.cpp index e1505cf2..dfe562ba 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.cpp +++ b/lib/Hoymiles/src/inverters/InverterAbstract.cpp @@ -6,7 +6,7 @@ InverterAbstract::InverterAbstract(uint64_t serial) { _serial.u64 = serial; _alarmLogParser.reset(new AlarmLogParser()); - memset(_payloadStats, 0, MAX_RF_FRAGMENT_COUNT * MAX_RF_PAYLOAD_SIZE); + _statisticsParser.reset(new StatisticsParser()); } uint64_t InverterAbstract::serial() @@ -34,6 +34,11 @@ AlarmLogParser* InverterAbstract::EventLog() return _alarmLogParser.get(); } +StatisticsParser* InverterAbstract::Statistics() +{ + return _statisticsParser.get(); +} + void InverterAbstract::clearRxFragmentBuffer() { memset(_rxFragmentBuffer, 0, MAX_RF_FRAGMENT_COUNT * MAX_RF_PAYLOAD_SIZE); @@ -112,10 +117,11 @@ uint8_t InverterAbstract::verifyAllFragments() if (getLastRequest() == RequestType::Stats) { // Move all fragments into target buffer - memset(_payloadStats, 0, MAX_RF_FRAGMENT_COUNT * MAX_RF_PAYLOAD_SIZE); uint8_t offs = 0; + _statisticsParser.get()->setByteAssignment(getByteAssignment(), getAssignmentCount()); + _statisticsParser.get()->clearBuffer(); for (uint8_t i = 0; i < _rxFragmentMaxPacketId; i++) { - memcpy(&_payloadStats[offs], _rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len); + _statisticsParser.get()->appendFragment(offs, _rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len); offs += (_rxFragmentBuffer[i].len); } _lastStatsUpdate = millis(); @@ -151,152 +157,4 @@ void InverterAbstract::setLastRequest(RequestType request) RequestType InverterAbstract::getLastRequest() { return _lastRequest; -} - -uint8_t InverterAbstract::getChannelCount() -{ - const byteAssign_t* b = getByteAssignment(); - uint8_t cnt = 0; - for (uint8_t pos = 0; pos < getAssignmentCount(); pos++) { - if (b[pos].ch > cnt) { - cnt = b[pos].ch; - } - } - - return cnt; -} - -uint16_t InverterAbstract::getChannelMaxPower(uint8_t channel) -{ - return _chanMaxPower[channel]; -} - -void InverterAbstract::setChannelMaxPower(uint8_t channel, uint16_t power) -{ - if (channel < CH4) { - _chanMaxPower[channel] = power; - } -} - -uint8_t InverterAbstract::getAssignIdxByChannelField(uint8_t channel, uint8_t fieldId) -{ - const byteAssign_t* b = getByteAssignment(); - - uint8_t pos; - for (pos = 0; pos < getAssignmentCount(); pos++) { - if (b[pos].ch == channel && b[pos].fieldId == fieldId) { - return pos; - } - } - return 0xff; -} - -float InverterAbstract::getChannelFieldValue(uint8_t channel, uint8_t fieldId) -{ - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - if (pos == 0xff) { - return 0; - } - - const byteAssign_t* b = getByteAssignment(); - - uint8_t ptr = b[pos].start; - uint8_t end = ptr + b[pos].num; - uint16_t div = b[pos].div; - - if (CMD_CALC != div) { - // Value is a static value - uint32_t val = 0; - do { - val <<= 8; - val |= _payloadStats[ptr]; - } while (++ptr != end); - - return (float)(val) / (float)(div); - } else { - // Value has to be calculated - return calcFunctions[b[pos].start].func(this, b[pos].num); - } - - return 0; -} - -bool InverterAbstract::hasChannelFieldValue(uint8_t channel, uint8_t fieldId) -{ - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - return pos != 0xff; -} - -const char* InverterAbstract::getChannelFieldUnit(uint8_t channel, uint8_t fieldId) -{ - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - const byteAssign_t* b = getByteAssignment(); - - return units[b[pos].unitId]; -} - -const char* InverterAbstract::getChannelFieldName(uint8_t channel, uint8_t fieldId) -{ - uint8_t pos = getAssignIdxByChannelField(channel, fieldId); - const byteAssign_t* b = getByteAssignment(); - - return fields[b[pos].fieldId]; -} - -static float calcYieldTotalCh0(InverterAbstract* iv, uint8_t arg0) -{ - float yield = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - yield += iv->getChannelFieldValue(i, FLD_YT); - } - return yield; -} - -static float calcYieldDayCh0(InverterAbstract* iv, uint8_t arg0) -{ - float yield = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - yield += iv->getChannelFieldValue(i, FLD_YD); - } - return yield; -} - -// arg0 = channel of source -static float calcUdcCh(InverterAbstract* iv, uint8_t arg0) -{ - return iv->getChannelFieldValue(arg0, FLD_UDC); -} - -static float calcPowerDcCh0(InverterAbstract* iv, uint8_t arg0) -{ - float dcPower = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - dcPower += iv->getChannelFieldValue(i, FLD_PDC); - } - return dcPower; -} - -// arg0 = channel -static float calcEffiencyCh0(InverterAbstract* iv, uint8_t arg0) -{ - float acPower = iv->getChannelFieldValue(CH0, FLD_PAC); - float dcPower = 0; - for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { - dcPower += iv->getChannelFieldValue(i, FLD_PDC); - } - if (dcPower > 0) { - return acPower / dcPower * 100.0f; - } - - return 0.0; -} - -// arg0 = channel -static float calcIrradiation(InverterAbstract* iv, uint8_t arg0) -{ - if (NULL != iv) { - if (iv->getChannelMaxPower(arg0 - 1) > 0) - return iv->getChannelFieldValue(arg0, FLD_PDC) / iv->getChannelMaxPower(arg0 - 1) * 100.0f; - } - return 0.0; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.h b/lib/Hoymiles/src/inverters/InverterAbstract.h index e0ded0c7..357ba4d0 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.h +++ b/lib/Hoymiles/src/inverters/InverterAbstract.h @@ -1,6 +1,7 @@ #pragma once #include "../parser/AlarmLogParser.h" +#include "../parser/StatisticsParser.h" #include "HoymilesRadio.h" #include "types.h" #include @@ -8,60 +9,6 @@ #define MAX_NAME_LENGTH 32 -// units -enum { - UNIT_V = 0, - UNIT_A, - UNIT_W, - UNIT_WH, - UNIT_KWH, - UNIT_HZ, - UNIT_C, - UNIT_PCT, - UNIT_CNT -}; -const char* const units[] = { "V", "A", "W", "Wh", "kWh", "Hz", "°C", "%", "" }; - -// field types -enum { - FLD_UDC = 0, - FLD_IDC, - FLD_PDC, - FLD_YD, - FLD_YT, - FLD_UAC, - FLD_IAC, - FLD_PAC, - FLD_F, - FLD_T, - FLD_PCT, - FLD_EFF, - FLD_IRR, - FLD_EVT_LOG -}; -const char* const fields[] = { "Voltage", "Current", "Power", "YieldDay", "YieldTotal", - "Voltage", "Current", "Power", "Frequency", "Temperature", "PowerFactor", "Effiency", "Irradiation", "EventLogCount" }; - -// indices to calculation functions, defined in hmInverter.h -enum { - CALC_YT_CH0 = 0, - CALC_YD_CH0, - CALC_UDC_CH, - CALC_PDC_CH0, - CALC_EFF_CH0, - CALC_IRR_CH -}; -enum { CMD_CALC = 0xffff }; - -// CH0 is default channel (freq, ac, temp) -enum { - CH0 = 0, - CH1, - CH2, - CH3, - CH4 -}; - enum { FRAGMENT_ALL_MISSING = 255, FRAGMENT_RETRANSMIT_TIMEOUT = 254, @@ -69,44 +16,9 @@ enum { FRAGMENT_OK = 0 }; -typedef struct { - uint8_t fieldId; // field id - uint8_t unitId; // uint id - uint8_t ch; // channel 0 - 4 - uint8_t start; // pos of first byte in buffer - uint8_t num; // number of bytes in buffer - uint16_t div; // divisor / calc command -} byteAssign_t; - #define MAX_RF_FRAGMENT_COUNT 5 #define MAX_RETRANSMIT_COUNT 5 -class InverterAbstract; - -// prototypes -static float calcYieldTotalCh0(InverterAbstract* iv, uint8_t arg0); -static float calcYieldDayCh0(InverterAbstract* iv, uint8_t arg0); -static float calcUdcCh(InverterAbstract* iv, uint8_t arg0); -static float calcPowerDcCh0(InverterAbstract* iv, uint8_t arg0); -static float calcEffiencyCh0(InverterAbstract* iv, uint8_t arg0); -static float calcIrradiation(InverterAbstract* iv, uint8_t arg0); - -using func_t = float(InverterAbstract*, uint8_t); - -struct calcFunc_t { - uint8_t funcId; // unique id - func_t* func; // function pointer -}; - -const calcFunc_t calcFunctions[] = { - { CALC_YT_CH0, &calcYieldTotalCh0 }, - { CALC_YD_CH0, &calcYieldDayCh0 }, - { CALC_UDC_CH, &calcUdcCh }, - { CALC_PDC_CH0, &calcPowerDcCh0 }, - { CALC_EFF_CH0, &calcEffiencyCh0 }, - { CALC_IRR_CH, &calcIrradiation } -}; - class InverterAbstract { public: InverterAbstract(uint64_t serial); @@ -116,20 +28,11 @@ public: virtual String typeName() = 0; virtual const byteAssign_t* getByteAssignment() = 0; virtual const uint8_t getAssignmentCount() = 0; - uint8_t getChannelCount(); - uint16_t getChannelMaxPower(uint8_t channel); - void setChannelMaxPower(uint8_t channel, uint16_t power); void clearRxFragmentBuffer(); void addRxFragment(uint8_t fragment[], uint8_t len); uint8_t verifyAllFragments(); - uint8_t getAssignIdxByChannelField(uint8_t channel, uint8_t fieldId); - float getChannelFieldValue(uint8_t channel, uint8_t fieldId); - bool hasChannelFieldValue(uint8_t channel, uint8_t fieldId); - const char* getChannelFieldUnit(uint8_t channel, uint8_t fieldId); - const char* getChannelFieldName(uint8_t channel, uint8_t fieldId); - virtual bool sendStatsRequest(HoymilesRadio* radio) = 0; virtual bool sendAlarmLogRequest(HoymilesRadio* radio) = 0; uint32_t getLastStatsUpdate(); @@ -137,6 +40,7 @@ public: void setLastRequest(RequestType request); AlarmLogParser* EventLog(); + StatisticsParser* Statistics(); protected: RequestType getLastRequest(); @@ -149,12 +53,11 @@ private: uint8_t _rxFragmentLastPacketId = 0; uint8_t _rxFragmentRetransmitCnt = 0; - uint8_t _payloadStats[MAX_RF_FRAGMENT_COUNT * MAX_RF_PAYLOAD_SIZE]; uint32_t _lastStatsUpdate = 0; uint32_t _lastAlarmLogUpdate = 0; - uint16_t _chanMaxPower[CH4]; RequestType _lastRequest = RequestType::None; std::unique_ptr _alarmLogParser; + std::unique_ptr _statisticsParser; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/parser/StatisticsParser.cpp b/lib/Hoymiles/src/parser/StatisticsParser.cpp new file mode 100644 index 00000000..1aaaa6be --- /dev/null +++ b/lib/Hoymiles/src/parser/StatisticsParser.cpp @@ -0,0 +1,167 @@ +#include "StatisticsParser.h" + +void StatisticsParser::setByteAssignment(const byteAssign_t* byteAssignment, const uint8_t count) +{ + _byteAssignment = byteAssignment; + _byteAssignmentCount = count; +} + +void StatisticsParser::clearBuffer() +{ + memset(_payloadStatistic, 0, STATISTIC_PACKET_SIZE); + _statisticLength = 0; +} + +void StatisticsParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len) +{ + memcpy(&_payloadStatistic[offset], payload, len); + _statisticLength += len; +} + +uint8_t StatisticsParser::getAssignIdxByChannelField(uint8_t channel, uint8_t fieldId) +{ + const byteAssign_t* b = _byteAssignment; + + uint8_t pos; + for (pos = 0; pos < _byteAssignmentCount; pos++) { + if (b[pos].ch == channel && b[pos].fieldId == fieldId) { + return pos; + } + } + return 0xff; +} + +float StatisticsParser::getChannelFieldValue(uint8_t channel, uint8_t fieldId) +{ + uint8_t pos = getAssignIdxByChannelField(channel, fieldId); + if (pos == 0xff) { + return 0; + } + + const byteAssign_t* b = _byteAssignment; + + uint8_t ptr = b[pos].start; + uint8_t end = ptr + b[pos].num; + uint16_t div = b[pos].div; + + if (CMD_CALC != div) { + // Value is a static value + uint32_t val = 0; + do { + val <<= 8; + val |= _payloadStatistic[ptr]; + } while (++ptr != end); + + return (float)(val) / (float)(div); + } else { + // Value has to be calculated + return calcFunctions[b[pos].start].func(this, b[pos].num); + } + + return 0; +} + +bool StatisticsParser::hasChannelFieldValue(uint8_t channel, uint8_t fieldId) +{ + uint8_t pos = getAssignIdxByChannelField(channel, fieldId); + return pos != 0xff; +} + +const char* StatisticsParser::getChannelFieldUnit(uint8_t channel, uint8_t fieldId) +{ + uint8_t pos = getAssignIdxByChannelField(channel, fieldId); + const byteAssign_t* b = _byteAssignment; + + return units[b[pos].unitId]; +} + +const char* StatisticsParser::getChannelFieldName(uint8_t channel, uint8_t fieldId) +{ + uint8_t pos = getAssignIdxByChannelField(channel, fieldId); + const byteAssign_t* b = _byteAssignment; + + return fields[b[pos].fieldId]; +} + +uint8_t StatisticsParser::getChannelCount() +{ + const byteAssign_t* b = _byteAssignment; + uint8_t cnt = 0; + for (uint8_t pos = 0; pos < _byteAssignmentCount; pos++) { + if (b[pos].ch > cnt) { + cnt = b[pos].ch; + } + } + + return cnt; +} + +uint16_t StatisticsParser::getChannelMaxPower(uint8_t channel) +{ + return _chanMaxPower[channel]; +} + +void StatisticsParser::setChannelMaxPower(uint8_t channel, uint16_t power) +{ + if (channel < CH4) { + _chanMaxPower[channel] = power; + } +} + +static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0) +{ + float yield = 0; + for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { + yield += iv->getChannelFieldValue(i, FLD_YT); + } + return yield; +} + +static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0) +{ + float yield = 0; + for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { + yield += iv->getChannelFieldValue(i, FLD_YD); + } + return yield; +} + +// arg0 = channel of source +static float calcUdcCh(StatisticsParser* iv, uint8_t arg0) +{ + return iv->getChannelFieldValue(arg0, FLD_UDC); +} + +static float calcPowerDcCh0(StatisticsParser* iv, uint8_t arg0) +{ + float dcPower = 0; + for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { + dcPower += iv->getChannelFieldValue(i, FLD_PDC); + } + return dcPower; +} + +// arg0 = channel +static float calcEffiencyCh0(StatisticsParser* iv, uint8_t arg0) +{ + float acPower = iv->getChannelFieldValue(CH0, FLD_PAC); + float dcPower = 0; + for (uint8_t i = 1; i <= iv->getChannelCount(); i++) { + dcPower += iv->getChannelFieldValue(i, FLD_PDC); + } + if (dcPower > 0) { + return acPower / dcPower * 100.0f; + } + + return 0.0; +} + +// arg0 = channel +static float calcIrradiation(StatisticsParser* iv, uint8_t arg0) +{ + if (NULL != iv) { + if (iv->getChannelMaxPower(arg0 - 1) > 0) + return iv->getChannelFieldValue(arg0, FLD_PDC) / iv->getChannelMaxPower(arg0 - 1) * 100.0f; + } + return 0.0; +} \ No newline at end of file diff --git a/lib/Hoymiles/src/parser/StatisticsParser.h b/lib/Hoymiles/src/parser/StatisticsParser.h new file mode 100644 index 00000000..03ef2598 --- /dev/null +++ b/lib/Hoymiles/src/parser/StatisticsParser.h @@ -0,0 +1,120 @@ +#pragma once +#include +#include + +#define STATISTIC_PACKET_SIZE (4 * 16) + +// units +enum { + UNIT_V = 0, + UNIT_A, + UNIT_W, + UNIT_WH, + UNIT_KWH, + UNIT_HZ, + UNIT_C, + UNIT_PCT, + UNIT_CNT +}; +const char* const units[] = { "V", "A", "W", "Wh", "kWh", "Hz", "°C", "%", "" }; + +// field types +enum { + FLD_UDC = 0, + FLD_IDC, + FLD_PDC, + FLD_YD, + FLD_YT, + FLD_UAC, + FLD_IAC, + FLD_PAC, + FLD_F, + FLD_T, + FLD_PCT, + FLD_EFF, + FLD_IRR, + FLD_EVT_LOG +}; +const char* const fields[] = { "Voltage", "Current", "Power", "YieldDay", "YieldTotal", + "Voltage", "Current", "Power", "Frequency", "Temperature", "PowerFactor", "Effiency", "Irradiation", "EventLogCount" }; + +// indices to calculation functions, defined in hmInverter.h +enum { + CALC_YT_CH0 = 0, + CALC_YD_CH0, + CALC_UDC_CH, + CALC_PDC_CH0, + CALC_EFF_CH0, + CALC_IRR_CH +}; +enum { CMD_CALC = 0xffff }; + +// CH0 is default channel (freq, ac, temp) +enum { + CH0 = 0, + CH1, + CH2, + CH3, + CH4 +}; + +typedef struct { + uint8_t fieldId; // field id + uint8_t unitId; // uint id + uint8_t ch; // channel 0 - 4 + uint8_t start; // pos of first byte in buffer + uint8_t num; // number of bytes in buffer + uint16_t div; // divisor / calc command +} byteAssign_t; + +// prototypes +class StatisticsParser; +static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0); +static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0); +static float calcUdcCh(StatisticsParser* iv, uint8_t arg0); +static float calcPowerDcCh0(StatisticsParser* iv, uint8_t arg0); +static float calcEffiencyCh0(StatisticsParser* iv, uint8_t arg0); +static float calcIrradiation(StatisticsParser* iv, uint8_t arg0); + +using func_t = float(StatisticsParser*, uint8_t); + +struct calcFunc_t { + uint8_t funcId; // unique id + func_t* func; // function pointer +}; + +const calcFunc_t calcFunctions[] = { + { CALC_YT_CH0, &calcYieldTotalCh0 }, + { CALC_YD_CH0, &calcYieldDayCh0 }, + { CALC_UDC_CH, &calcUdcCh }, + { CALC_PDC_CH0, &calcPowerDcCh0 }, + { CALC_EFF_CH0, &calcEffiencyCh0 }, + { CALC_IRR_CH, &calcIrradiation } +}; + +class StatisticsParser { +public: + void clearBuffer(); + void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len); + + void setByteAssignment(const byteAssign_t* byteAssignment, const uint8_t count); + + uint8_t getAssignIdxByChannelField(uint8_t channel, uint8_t fieldId); + float getChannelFieldValue(uint8_t channel, uint8_t fieldId); + bool hasChannelFieldValue(uint8_t channel, uint8_t fieldId); + const char* getChannelFieldUnit(uint8_t channel, uint8_t fieldId); + const char* getChannelFieldName(uint8_t channel, uint8_t fieldId); + + uint8_t getChannelCount(); + + uint16_t getChannelMaxPower(uint8_t channel); + void setChannelMaxPower(uint8_t channel, uint16_t power); + +private: + uint8_t _payloadStatistic[STATISTIC_PACKET_SIZE]; + uint8_t _statisticLength; + uint16_t _chanMaxPower[CH4]; + + const byteAssign_t* _byteAssignment; + uint8_t _byteAssignmentCount; +}; \ No newline at end of file diff --git a/src/MqttPublishing.cpp b/src/MqttPublishing.cpp index 55616605..5b5bd00f 100644 --- a/src/MqttPublishing.cpp +++ b/src/MqttPublishing.cpp @@ -36,7 +36,7 @@ void MqttPublishingClass::loop() _lastPublishStats[i] = lastUpdate; // Loop all channels - for (uint8_t c = 0; c <= inv->getChannelCount(); c++) { + for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { publishField(subtopic, inv, c, FLD_UDC); publishField(subtopic, inv, c, FLD_IDC); if (c == 0) { @@ -66,14 +66,14 @@ void MqttPublishingClass::loop() void MqttPublishingClass::publishField(String subtopic, std::shared_ptr inv, uint8_t channel, uint8_t fieldId, String topic) { - if (inv->hasChannelFieldValue(channel, fieldId)) { + if (inv->Statistics()->hasChannelFieldValue(channel, fieldId)) { String chanName; if (topic == "") { - chanName = inv->getChannelFieldName(channel, fieldId); + chanName = inv->Statistics()->getChannelFieldName(channel, fieldId); } else { chanName = topic; } chanName.toLowerCase(); - MqttSettings.publish(subtopic + "/" + String(channel) + "/" + chanName, String(inv->getChannelFieldValue(channel, fieldId))); + MqttSettings.publish(subtopic + "/" + String(channel) + "/" + chanName, String(inv->Statistics()->getChannelFieldValue(channel, fieldId))); } } \ No newline at end of file diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index c690fa09..922b64c2 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -137,7 +137,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) auto inv = Hoymiles.addInverter(inverter->Name, inverter->Serial); for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - inv->setChannelMaxPower(c, inverter->MaxChannelPower[c]); + inv->Statistics()->setChannelMaxPower(c, inverter->MaxChannelPower[c]); } } @@ -244,7 +244,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) } for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - inv->setChannelMaxPower(c, inverter.MaxChannelPower[c]); + inv->Statistics()->setChannelMaxPower(c, inverter.MaxChannelPower[c]); } } diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index f08883a2..994293aa 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -47,7 +47,7 @@ void WebApiWsLiveClass::loop() root[i][F("age_critical")] = ((millis() - inv->getLastStatsUpdate()) / 1000) > Configuration.get().Dtu_PollInterval * 5; // Loop all channels - for (uint8_t c = 0; c <= inv->getChannelCount(); c++) { + for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { addField(root, i, inv, c, FLD_PAC); addField(root, i, inv, c, FLD_UAC); addField(root, i, inv, c, FLD_IAC); @@ -67,7 +67,7 @@ void WebApiWsLiveClass::loop() addField(root, i, inv, c, FLD_IRR); } - if (inv->hasChannelFieldValue(CH0, FLD_EVT_LOG)) { + if (inv->Statistics()->hasChannelFieldValue(CH0, FLD_EVT_LOG)) { root[i][F("events")] = inv->EventLog()->getEntryCount(); } else { root[i][F("events")] = -1; @@ -91,14 +91,14 @@ void WebApiWsLiveClass::loop() void WebApiWsLiveClass::addField(JsonDocument& root, uint8_t idx, std::shared_ptr inv, uint8_t channel, uint8_t fieldId, String topic) { - if (inv->hasChannelFieldValue(channel, fieldId)) { + if (inv->Statistics()->hasChannelFieldValue(channel, fieldId)) { String chanName; if (topic == "") { - chanName = inv->getChannelFieldName(channel, fieldId); + chanName = inv->Statistics()->getChannelFieldName(channel, fieldId); } else { chanName = topic; } - root[idx][String(channel)][chanName]["v"] = inv->getChannelFieldValue(channel, fieldId); - root[idx][String(channel)][chanName]["u"] = inv->getChannelFieldUnit(channel, fieldId); + root[idx][String(channel)][chanName]["v"] = inv->Statistics()->getChannelFieldValue(channel, fieldId); + root[idx][String(channel)][chanName]["u"] = inv->Statistics()->getChannelFieldUnit(channel, fieldId); } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f7f8647c..61b6c62f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,7 +85,7 @@ void setup() config.Inverter[i].Serial); for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - inv->setChannelMaxPower(c, config.Inverter[i].MaxChannelPower[c]); + inv->Statistics()->setChannelMaxPower(c, config.Inverter[i].MaxChannelPower[c]); } } }