Skip to content

Commit

Permalink
Added check in statistics data that at least all required bytes are r…
Browse files Browse the repository at this point in the history
…eceived

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

This was mentioned in #1084
  • Loading branch information
tbnobody committed Jun 27, 2023
1 parent 12a18fb commit 69aa247
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 1 deletion.
11 changes: 10 additions & 1 deletion lib/Hoymiles/src/commands/MultiDataCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,13 @@ void MultiDataCommand::udpateCRC()
uint16_t crc = crc16(&_payload[10], 14); // From data_type till password
_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;
}
1 change: 1 addition & 0 deletions lib/Hoymiles/src/commands/MultiDataCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MultiDataCommand : public CommandAbstract {
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;
};
13 changes: 13 additions & 0 deletions lib/Hoymiles/src/commands/RealTimeRunDataCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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();
Expand Down
19 changes: 19 additions & 0 deletions lib/Hoymiles/src/parser/StatisticsParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions lib/Hoymiles/src/parser/StatisticsParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class StatisticsParser : public Parser {

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);

Expand Down

0 comments on commit 69aa247

Please sign in to comment.