diff --git a/lib/Hoymiles/src/HoymilesRadio.cpp b/lib/Hoymiles/src/HoymilesRadio.cpp index 7955b6f..aaa0456 100644 --- a/lib/Hoymiles/src/HoymilesRadio.cpp +++ b/lib/Hoymiles/src/HoymilesRadio.cpp @@ -103,10 +103,12 @@ void HoymilesRadio::loop() } else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) { Serial.println(F("Retransmit timeout")); + _commandQueue.pop(); _busyFlag = false; - } else if (verifyResult == FRAGMENT_CRC_ERROR) { - Serial.println(F("Packet CRC error")); + } else if (verifyResult == FRAGMENT_HANDLE_ERROR) { + Serial.println(F("Packet handling error")); + _commandQueue.pop(); _busyFlag = false; } else if (verifyResult > 0) { diff --git a/lib/Hoymiles/src/commands/AlarmDataCommand.cpp b/lib/Hoymiles/src/commands/AlarmDataCommand.cpp index 8210d1b..af5bae5 100644 --- a/lib/Hoymiles/src/commands/AlarmDataCommand.cpp +++ b/lib/Hoymiles/src/commands/AlarmDataCommand.cpp @@ -9,8 +9,13 @@ AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_addr setTimeout(200); } -void AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +bool AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) { + // Check CRC of whole payload + if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) { + return false; + } + // Move all fragments into target buffer uint8_t offs = 0; inverter->EventLog()->clearBuffer(); @@ -19,4 +24,5 @@ void AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fra offs += (fragment[i].len); } inverter->EventLog()->setLastUpdate(millis()); + return true; } \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/AlarmDataCommand.h b/lib/Hoymiles/src/commands/AlarmDataCommand.h index 5492438..a401558 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); - virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); + virtual bool 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 5785cb9..b09177f 100644 --- a/lib/Hoymiles/src/commands/CommandAbstract.h +++ b/lib/Hoymiles/src/commands/CommandAbstract.h @@ -36,7 +36,7 @@ public: virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no); - virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0; + virtual bool 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/MultiDataCommand.cpp b/lib/Hoymiles/src/commands/MultiDataCommand.cpp index 800c355..e752ea1 100644 --- a/lib/Hoymiles/src/commands/MultiDataCommand.cpp +++ b/lib/Hoymiles/src/commands/MultiDataCommand.cpp @@ -58,6 +58,25 @@ CommandAbstract* MultiDataCommand::getRequestFrameCommand(uint8_t frame_no) return &_cmdRequestFrame; } +bool MultiDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +{ + // All fragments are available --> Check CRC + uint16_t crc = 0xffff, crcRcv; + + for (uint8_t i = 0; i < max_fragment_id; i++) { + if (i == max_fragment_id - 1) { + // Last packet + crc = crc16(fragment[i].fragment, fragment[i].len - 2, crc); + crcRcv = (fragment[i].fragment[fragment[i].len - 2] << 8) + | (fragment[i].fragment[fragment[i].len - 1]); + } else { + crc = crc16(fragment[i].fragment, fragment[i].len, crc); + } + } + + return crc == crcRcv; +} + void MultiDataCommand::udpateCRC() { uint16_t crc = crc16(&_payload[10], 14); // From data_type till password diff --git a/lib/Hoymiles/src/commands/MultiDataCommand.h b/lib/Hoymiles/src/commands/MultiDataCommand.h index 339830f..46129eb 100644 --- a/lib/Hoymiles/src/commands/MultiDataCommand.h +++ b/lib/Hoymiles/src/commands/MultiDataCommand.h @@ -13,6 +13,8 @@ public: CommandAbstract* getRequestFrameCommand(uint8_t frame_no); + virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); + protected: void setDataType(uint8_t data_type); uint8_t getDataType(); diff --git a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp index 391699e..e820375 100644 --- a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp +++ b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp @@ -9,8 +9,13 @@ RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t setTimeout(200); } -void RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +bool RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) { + // Check CRC of whole payload + if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) { + return false; + } + // Move all fragments into target buffer uint8_t offs = 0; inverter->Statistics()->clearBuffer(); @@ -19,4 +24,5 @@ void RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment offs += (fragment[i].len); } inverter->Statistics()->setLastUpdate(millis()); + return true; } \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/RealTimeRunDataCommand.h b/lib/Hoymiles/src/commands/RealTimeRunDataCommand.h index 7414fdb..09a2bc4 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); - virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); + virtual bool 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 2474ef1..d0e1025 100644 --- a/lib/Hoymiles/src/commands/RequestFrameCommand.cpp +++ b/lib/Hoymiles/src/commands/RequestFrameCommand.cpp @@ -20,6 +20,7 @@ uint8_t RequestFrameCommand::getFrameNo() return _payload[9] & (~0x80); } -void RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +bool RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) { + return true; } \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/RequestFrameCommand.h b/lib/Hoymiles/src/commands/RequestFrameCommand.h index 26b467b..4d62767 100644 --- a/lib/Hoymiles/src/commands/RequestFrameCommand.h +++ b/lib/Hoymiles/src/commands/RequestFrameCommand.h @@ -9,5 +9,5 @@ public: void setFrameNo(uint8_t frame_no); uint8_t getFrameNo(); - virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); + virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); }; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.cpp b/lib/Hoymiles/src/inverters/InverterAbstract.cpp index 6ed8212..8cbbb05 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.cpp +++ b/lib/Hoymiles/src/inverters/InverterAbstract.cpp @@ -122,25 +122,9 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd) } } - // All fragments are available --> Check CRC - uint16_t crc = 0xffff, crcRcv; - - for (uint8_t i = 0; i < _rxFragmentMaxPacketId; i++) { - if (i == _rxFragmentMaxPacketId - 1) { - // Last packet - crc = crc16(_rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len - 2, crc); - crcRcv = (_rxFragmentBuffer[i].fragment[_rxFragmentBuffer[i].len - 2] << 8) - | (_rxFragmentBuffer[i].fragment[_rxFragmentBuffer[i].len - 1]); - } else { - crc = crc16(_rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len, crc); - } + if (!cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId)) { + return FRAGMENT_HANDLE_ERROR; } - if (crc != crcRcv) { - return FRAGMENT_CRC_ERROR; - } - - cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId); - return FRAGMENT_OK; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.h b/lib/Hoymiles/src/inverters/InverterAbstract.h index 632f630..74e68c3 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.h +++ b/lib/Hoymiles/src/inverters/InverterAbstract.h @@ -12,7 +12,7 @@ enum { FRAGMENT_ALL_MISSING = 255, FRAGMENT_RETRANSMIT_TIMEOUT = 254, - FRAGMENT_CRC_ERROR = 253, + FRAGMENT_HANDLE_ERROR = 253, FRAGMENT_OK = 0 };