Added check in statistics data that at least all required bytes are received

It can occour for some inverters that incomplete fragments with valid crc but less bytes are received

This was mentioned in #1084
This commit is contained in:
Thomas Basler 2023-06-27 18:59:54 +02:00
parent 12a18fb34b
commit 69aa247470
5 changed files with 46 additions and 1 deletions

View File

@ -92,3 +92,12 @@ void MultiDataCommand::udpateCRC()
_payload[24] = (uint8_t)(crc >> 8);
_payload[25] = (uint8_t)(crc);
}
uint8_t MultiDataCommand::getTotalFragmentSize(fragment_t fragment[], uint8_t max_fragment_id)
{
uint8_t fragmentSize = 0;
for (uint8_t i = 0; i < max_fragment_id; i++) {
fragmentSize += fragment[i].len;
}
return fragmentSize;
}

View File

@ -20,6 +20,7 @@ protected:
void setDataType(uint8_t data_type);
uint8_t getDataType();
void udpateCRC();
static uint8_t getTotalFragmentSize(fragment_t fragment[], uint8_t max_fragment_id);
RequestFrameCommand _cmdRequestFrame;
};

View File

@ -3,6 +3,7 @@
* Copyright (C) 2022 Thomas Basler and others
*/
#include "RealTimeRunDataCommand.h"
#include "Hoymiles.h"
#include "inverters/InverterAbstract.h"
RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t router_address, time_t time)
@ -25,6 +26,18 @@ bool RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment
return false;
}
// Check if at least all required bytes are received
// In case of low power in the inverter it occours that some incomplete fragments
// with a valid CRC are received.
if (getTotalFragmentSize(fragment, max_fragment_id) < inverter->Statistics()->getMaxByteCount()) {
Hoymiles.getMessageOutput()->printf("ERROR in %s: Received fragment size: %d min. expected size: %d\r\n",
getCommandName().c_str(),
getTotalFragmentSize(fragment, max_fragment_id),
inverter->Statistics()->getMaxByteCount());
return false;
}
// Move all fragments into target buffer
uint8_t offs = 0;
inverter->Statistics()->clearBuffer();

View File

@ -34,6 +34,25 @@ void StatisticsParser::setByteAssignment(const byteAssign_t* byteAssignment, uin
_byteAssignmentSize = size;
}
uint8_t StatisticsParser::getMaxByteCount()
{
static uint8_t maxByteCount = 0;
// Use already calculated value
if (maxByteCount > 0) {
return maxByteCount;
}
for (uint8_t i = 0; i < _byteAssignmentSize; i++) {
if (_byteAssignment[i].div == CMD_CALC) {
continue;
}
maxByteCount = max<uint8_t>(maxByteCount, _byteAssignment[i].start + _byteAssignment[i].num);
}
return maxByteCount;
}
void StatisticsParser::clearBuffer()
{
memset(_payloadStatistic, 0, STATISTIC_PACKET_SIZE);

View File

@ -109,6 +109,9 @@ public:
void setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size);
// Returns 1 based amount of expected bytes of statistic data
uint8_t getMaxByteCount();
const byteAssign_t* getAssignmentByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId);
fieldSettings_t* getSettingByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId);