diff --git a/lib/Hoymiles/src/HoymilesRadio.cpp b/lib/Hoymiles/src/HoymilesRadio.cpp index e3b9bc2..7955b6f 100644 --- a/lib/Hoymiles/src/HoymilesRadio.cpp +++ b/lib/Hoymiles/src/HoymilesRadio.cpp @@ -89,7 +89,8 @@ void HoymilesRadio::loop() std::shared_ptr inv = Hoymiles.getInverterBySerial(_commandQueue.front().get()->getTargetAddress()); if (nullptr != inv) { - uint8_t verifyResult = inv->verifyAllFragments(); + CommandAbstract* cmd = _commandQueue.front().get(); + uint8_t verifyResult = inv->verifyAllFragments(cmd); if (verifyResult == FRAGMENT_ALL_MISSING) { if (_commandQueue.front().get()->getSendCount() <= MAX_RESEND_COUNT) { Serial.println(F("Nothing received, resend whole request")); @@ -127,7 +128,6 @@ void HoymilesRadio::loop() CommandAbstract* cmd = _commandQueue.front().get(); auto inv = Hoymiles.getInverterBySerial(cmd->getTargetAddress()); - inv->setLastRequest(cmd->getRequestType()); inv->clearRxFragmentBuffer(); sendEsbPacket(cmd); } diff --git a/lib/Hoymiles/src/commands/AlarmDataCommand.cpp b/lib/Hoymiles/src/commands/AlarmDataCommand.cpp index b602ded..8210d1b 100644 --- a/lib/Hoymiles/src/commands/AlarmDataCommand.cpp +++ b/lib/Hoymiles/src/commands/AlarmDataCommand.cpp @@ -1,4 +1,5 @@ #include "AlarmDataCommand.h" +#include "inverters/InverterAbstract.h" AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_address, time_t time) : MultiDataCommand(target_address, router_address) @@ -6,4 +7,16 @@ AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_addr setTime(time); setDataType(0x11); setTimeout(200); +} + +void AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +{ + // Move all fragments into target buffer + uint8_t offs = 0; + inverter->EventLog()->clearBuffer(); + for (uint8_t i = 0; i < max_fragment_id; i++) { + inverter->EventLog()->appendFragment(offs, fragment[i].fragment, fragment[i].len); + offs += (fragment[i].len); + } + inverter->EventLog()->setLastUpdate(millis()); } \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/AlarmDataCommand.h b/lib/Hoymiles/src/commands/AlarmDataCommand.h index 410d2b7..5492438 100644 --- a/lib/Hoymiles/src/commands/AlarmDataCommand.h +++ b/lib/Hoymiles/src/commands/AlarmDataCommand.h @@ -6,5 +6,5 @@ class AlarmDataCommand : public MultiDataCommand { public: AlarmDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0); - RequestType getRequestType() { return RequestType::AlarmLog; }; + virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); }; \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/CommandAbstract.h b/lib/Hoymiles/src/commands/CommandAbstract.h index 09b8b09..5785cb9 100644 --- a/lib/Hoymiles/src/commands/CommandAbstract.h +++ b/lib/Hoymiles/src/commands/CommandAbstract.h @@ -6,6 +6,8 @@ #define RF_LEN 32 +class InverterAbstract; + class CommandAbstract { public: CommandAbstract(uint64_t target_address = 0, uint64_t router_address = 0); @@ -34,7 +36,7 @@ public: virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no); - virtual RequestType getRequestType() = 0; + virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0; protected: uint8_t _payload[RF_LEN]; diff --git a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp index 6cc364d..391699e 100644 --- a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp +++ b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp @@ -1,4 +1,5 @@ #include "RealTimeRunDataCommand.h" +#include "inverters/InverterAbstract.h" RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t router_address, time_t time) : MultiDataCommand(target_address, router_address) @@ -6,4 +7,16 @@ RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t setTime(time); setDataType(0x0b); setTimeout(200); +} + +void RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +{ + // Move all fragments into target buffer + uint8_t offs = 0; + inverter->Statistics()->clearBuffer(); + for (uint8_t i = 0; i < max_fragment_id; i++) { + inverter->Statistics()->appendFragment(offs, fragment[i].fragment, fragment[i].len); + offs += (fragment[i].len); + } + inverter->Statistics()->setLastUpdate(millis()); } \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.h b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.h index 5dec09d..7414fdb 100644 --- a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.h +++ b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.h @@ -6,5 +6,5 @@ class RealTimeRunDataCommand : public MultiDataCommand { public: RealTimeRunDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0); - RequestType getRequestType() { return RequestType::Stats; }; + virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); }; \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/RequestFrameCommand.cpp b/lib/Hoymiles/src/commands/RequestFrameCommand.cpp index eeaff02..2474ef1 100644 --- a/lib/Hoymiles/src/commands/RequestFrameCommand.cpp +++ b/lib/Hoymiles/src/commands/RequestFrameCommand.cpp @@ -18,4 +18,8 @@ void RequestFrameCommand::setFrameNo(uint8_t frame_no) uint8_t RequestFrameCommand::getFrameNo() { return _payload[9] & (~0x80); +} + +void RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +{ } \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/RequestFrameCommand.h b/lib/Hoymiles/src/commands/RequestFrameCommand.h index 53d49ad..26b467b 100644 --- a/lib/Hoymiles/src/commands/RequestFrameCommand.h +++ b/lib/Hoymiles/src/commands/RequestFrameCommand.h @@ -8,4 +8,6 @@ public: void setFrameNo(uint8_t frame_no); uint8_t getFrameNo(); + + virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); }; \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/SingleDataCommand.h b/lib/Hoymiles/src/commands/SingleDataCommand.h index 811300c..aba0fda 100644 --- a/lib/Hoymiles/src/commands/SingleDataCommand.h +++ b/lib/Hoymiles/src/commands/SingleDataCommand.h @@ -5,6 +5,4 @@ class SingleDataCommand : public CommandAbstract { public: SingleDataCommand(uint64_t target_address = 0, uint64_t router_address = 0); - - RequestType getRequestType() { return RequestType::None; }; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.cpp b/lib/Hoymiles/src/inverters/InverterAbstract.cpp index 7e70891..d50ee86 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.cpp +++ b/lib/Hoymiles/src/inverters/InverterAbstract.cpp @@ -91,7 +91,7 @@ void InverterAbstract::addRxFragment(uint8_t fragment[], uint8_t len) } // Returns Zero on Success or the Fragment ID for retransmit or error code -uint8_t InverterAbstract::verifyAllFragments() +uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd) { // All missing if (_rxFragmentLastPacketId == 0) { @@ -139,45 +139,7 @@ uint8_t InverterAbstract::verifyAllFragments() return FRAGMENT_CRC_ERROR; } - if (getLastRequest() == RequestType::Stats) { - // Move all fragments into target buffer - uint8_t offs = 0; - _statisticsParser.get()->clearBuffer(); - for (uint8_t i = 0; i < _rxFragmentMaxPacketId; i++) { - _statisticsParser.get()->appendFragment(offs, _rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len); - offs += (_rxFragmentBuffer[i].len); - } - _lastStatsUpdate = millis(); + cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId); - } else if (getLastRequest() == RequestType::AlarmLog) { - // Move all fragments into target buffer - uint8_t offs = 0; - _alarmLogParser.get()->clearBuffer(); - for (uint8_t i = 0; i < _rxFragmentMaxPacketId; i++) { - _alarmLogParser.get()->appendFragment(offs, _rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len); - offs += (_rxFragmentBuffer[i].len); - } - _lastAlarmLogUpdate = millis(); - - } else { - Serial.println("Unkown response received"); - } - - setLastRequest(RequestType::None); return FRAGMENT_OK; -} - -uint32_t InverterAbstract::getLastStatsUpdate() -{ - return _lastStatsUpdate; -} - -void InverterAbstract::setLastRequest(RequestType request) -{ - _lastRequest = request; -} - -RequestType InverterAbstract::getLastRequest() -{ - return _lastRequest; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.h b/lib/Hoymiles/src/inverters/InverterAbstract.h index 64f8aef..00679e7 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.h +++ b/lib/Hoymiles/src/inverters/InverterAbstract.h @@ -19,6 +19,8 @@ enum { #define MAX_RF_FRAGMENT_COUNT 5 #define MAX_RETRANSMIT_COUNT 5 +class CommandAbstract; + class InverterAbstract { public: InverterAbstract(uint64_t serial); @@ -32,20 +34,14 @@ public: void clearRxFragmentBuffer(); void addRxFragment(uint8_t fragment[], uint8_t len); - uint8_t verifyAllFragments(); + uint8_t verifyAllFragments(CommandAbstract* cmd); virtual bool sendStatsRequest(HoymilesRadio* radio) = 0; virtual bool sendAlarmLogRequest(HoymilesRadio* radio) = 0; - uint32_t getLastStatsUpdate(); - - void setLastRequest(RequestType request); AlarmLogParser* EventLog(); StatisticsParser* Statistics(); -protected: - RequestType getLastRequest(); - private: serial_u _serial; char _name[MAX_NAME_LENGTH]; @@ -54,11 +50,6 @@ private: uint8_t _rxFragmentLastPacketId = 0; uint8_t _rxFragmentRetransmitCnt = 0; - uint32_t _lastStatsUpdate = 0; - uint32_t _lastAlarmLogUpdate = 0; - - 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/AlarmLogParser.cpp b/lib/Hoymiles/src/parser/AlarmLogParser.cpp index 66953fd..1a64924 100644 --- a/lib/Hoymiles/src/parser/AlarmLogParser.cpp +++ b/lib/Hoymiles/src/parser/AlarmLogParser.cpp @@ -258,6 +258,16 @@ void AlarmLogParser::getLogEntry(uint8_t entryId, AlarmLogEntry_t* entry) } } +uint32_t AlarmLogParser::getLastUpdate() +{ + return _lastUpdate; +} + +void AlarmLogParser::setLastUpdate(uint32_t lastUpdate) +{ + _lastUpdate = lastUpdate; +} + int AlarmLogParser::getTimezoneOffset() { // see: https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c/44063597#44063597 diff --git a/lib/Hoymiles/src/parser/AlarmLogParser.h b/lib/Hoymiles/src/parser/AlarmLogParser.h index c5c7624..3ecb5bb 100644 --- a/lib/Hoymiles/src/parser/AlarmLogParser.h +++ b/lib/Hoymiles/src/parser/AlarmLogParser.h @@ -20,9 +20,14 @@ public: uint8_t getEntryCount(); void getLogEntry(uint8_t entryId, AlarmLogEntry_t* entry); + uint32_t getLastUpdate(); + void setLastUpdate(uint32_t lastUpdate); + private: static int getTimezoneOffset(); uint8_t _payloadAlarmLog[ALARM_LOG_ENTRY_SIZE * ALARM_LOG_ENTRY_COUNT]; uint8_t _alarmLogLength; + + uint32_t _lastUpdate = 0; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/parser/StatisticsParser.cpp b/lib/Hoymiles/src/parser/StatisticsParser.cpp index 2310a42..13ef18d 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.cpp +++ b/lib/Hoymiles/src/parser/StatisticsParser.cpp @@ -112,6 +112,16 @@ void StatisticsParser::setChannelMaxPower(uint8_t channel, uint16_t power) } } +uint32_t StatisticsParser::getLastUpdate() +{ + return _lastUpdate; +} + +void StatisticsParser::setLastUpdate(uint32_t lastUpdate) +{ + _lastUpdate = lastUpdate; +} + static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0) { float yield = 0; diff --git a/lib/Hoymiles/src/parser/StatisticsParser.h b/lib/Hoymiles/src/parser/StatisticsParser.h index 10d7cc2..3a317a1 100644 --- a/lib/Hoymiles/src/parser/StatisticsParser.h +++ b/lib/Hoymiles/src/parser/StatisticsParser.h @@ -110,6 +110,9 @@ public: uint16_t getChannelMaxPower(uint8_t channel); void setChannelMaxPower(uint8_t channel, uint16_t power); + uint32_t getLastUpdate(); + void setLastUpdate(uint32_t lastUpdate); + private: uint8_t _payloadStatistic[STATISTIC_PACKET_SIZE]; uint8_t _statisticLength; @@ -117,4 +120,6 @@ private: const byteAssign_t* _byteAssignment; uint8_t _byteAssignmentCount; + + uint32_t _lastUpdate = 0; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/types.h b/lib/Hoymiles/src/types.h index 1f7c3d3..4cc4c9a 100644 --- a/lib/Hoymiles/src/types.h +++ b/lib/Hoymiles/src/types.h @@ -14,9 +14,3 @@ typedef struct { uint8_t fragment[MAX_RF_PAYLOAD_SIZE]; uint8_t len; } fragment_t; - -enum class RequestType { - None, - Stats, - AlarmLog -}; diff --git a/src/MqttPublishing.cpp b/src/MqttPublishing.cpp index cb724b4..42792c8 100644 --- a/src/MqttPublishing.cpp +++ b/src/MqttPublishing.cpp @@ -36,7 +36,7 @@ void MqttPublishingClass::loop() MqttSettings.publish(subtopic + "/name", inv->name()); - uint32_t lastUpdate = inv->getLastStatsUpdate(); + uint32_t lastUpdate = inv->Statistics()->getLastUpdate(); if (lastUpdate > 0 && lastUpdate != _lastPublishStats[i]) { _lastPublishStats[i] = lastUpdate; diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index 7792ca6..ce03d71 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -44,8 +44,8 @@ void WebApiWsLiveClass::loop() for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { auto inv = Hoymiles.getInverterByPos(i); - if (inv->getLastStatsUpdate() > maxTimeStamp) { - maxTimeStamp = inv->getLastStatsUpdate(); + if (inv->Statistics()->getLastUpdate() > maxTimeStamp) { + maxTimeStamp = inv->Statistics()->getLastUpdate(); } } @@ -80,8 +80,8 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) root[i][F("serial")] = String(buffer); root[i][F("name")] = inv->name(); - root[i][F("data_age")] = (millis() - inv->getLastStatsUpdate()) / 1000; - root[i][F("age_critical")] = ((millis() - inv->getLastStatsUpdate()) / 1000) > Configuration.get().Dtu_PollInterval * 5; + root[i][F("data_age")] = (millis() - inv->Statistics()->getLastUpdate()) / 1000; + root[i][F("age_critical")] = ((millis() - inv->Statistics()->getLastUpdate()) / 1000) > Configuration.get().Dtu_PollInterval * 5; // Loop all channels for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) { @@ -110,8 +110,8 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root) root[i][F("events")] = -1; } - if (inv->getLastStatsUpdate() > _newestInverterTimestamp) { - _newestInverterTimestamp = inv->getLastStatsUpdate(); + if (inv->Statistics()->getLastUpdate() > _newestInverterTimestamp) { + _newestInverterTimestamp = inv->Statistics()->getLastUpdate(); } } }