Fix: Prevent wrong values of statistics data because of non-atomic transaction
This commit is contained in:
parent
9821c1905b
commit
14305a9f12
@ -40,11 +40,13 @@ bool RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment
|
|||||||
|
|
||||||
// Move all fragments into target buffer
|
// Move all fragments into target buffer
|
||||||
uint8_t offs = 0;
|
uint8_t offs = 0;
|
||||||
|
inverter->Statistics()->beginAppendFragment();
|
||||||
inverter->Statistics()->clearBuffer();
|
inverter->Statistics()->clearBuffer();
|
||||||
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
for (uint8_t i = 0; i < max_fragment_id; i++) {
|
||||||
inverter->Statistics()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
inverter->Statistics()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
|
||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
|
inverter->Statistics()->endAppendFragment();
|
||||||
inverter->Statistics()->resetRxFailureCount();
|
inverter->Statistics()->resetRxFailureCount();
|
||||||
inverter->Statistics()->setLastUpdate(millis());
|
inverter->Statistics()->setLastUpdate(millis());
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -5,6 +5,11 @@
|
|||||||
#include "StatisticsParser.h"
|
#include "StatisticsParser.h"
|
||||||
#include "../Hoymiles.h"
|
#include "../Hoymiles.h"
|
||||||
|
|
||||||
|
#define HOY_SEMAPHORE_TAKE() \
|
||||||
|
do { \
|
||||||
|
} while (xSemaphoreTake(_xSemaphore, portMAX_DELAY) != pdPASS)
|
||||||
|
#define HOY_SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore)
|
||||||
|
|
||||||
static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0);
|
static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0);
|
||||||
static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0);
|
static float calcYieldDayCh0(StatisticsParser* iv, uint8_t arg0);
|
||||||
static float calcUdcCh(StatisticsParser* iv, uint8_t arg0);
|
static float calcUdcCh(StatisticsParser* iv, uint8_t arg0);
|
||||||
@ -28,6 +33,13 @@ const calcFunc_t calcFunctions[] = {
|
|||||||
{ CALC_IRR_CH, &calcIrradiation }
|
{ CALC_IRR_CH, &calcIrradiation }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
StatisticsParser::StatisticsParser()
|
||||||
|
: Parser()
|
||||||
|
{
|
||||||
|
_xSemaphore = xSemaphoreCreateMutex();
|
||||||
|
HOY_SEMAPHORE_GIVE(); // release before first use
|
||||||
|
}
|
||||||
|
|
||||||
void StatisticsParser::setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size)
|
void StatisticsParser::setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size)
|
||||||
{
|
{
|
||||||
_byteAssignment = byteAssignment;
|
_byteAssignment = byteAssignment;
|
||||||
@ -62,6 +74,16 @@ void StatisticsParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t
|
|||||||
_statisticLength += len;
|
_statisticLength += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatisticsParser::beginAppendFragment()
|
||||||
|
{
|
||||||
|
HOY_SEMAPHORE_TAKE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsParser::endAppendFragment()
|
||||||
|
{
|
||||||
|
HOY_SEMAPHORE_GIVE();
|
||||||
|
}
|
||||||
|
|
||||||
const byteAssign_t* StatisticsParser::getAssignmentByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId)
|
const byteAssign_t* StatisticsParser::getAssignmentByChannelField(ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < _byteAssignmentSize; i++) {
|
for (uint8_t i = 0; i < _byteAssignmentSize; i++) {
|
||||||
@ -98,10 +120,12 @@ float StatisticsParser::getChannelFieldValue(ChannelType_t type, ChannelNum_t ch
|
|||||||
if (CMD_CALC != div) {
|
if (CMD_CALC != div) {
|
||||||
// Value is a static value
|
// Value is a static value
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
|
HOY_SEMAPHORE_TAKE();
|
||||||
do {
|
do {
|
||||||
val <<= 8;
|
val <<= 8;
|
||||||
val |= _payloadStatistic[ptr];
|
val |= _payloadStatistic[ptr];
|
||||||
} while (++ptr != end);
|
} while (++ptr != end);
|
||||||
|
HOY_SEMAPHORE_GIVE();
|
||||||
|
|
||||||
float result;
|
float result;
|
||||||
if (pos->isSigned && pos->num == 2) {
|
if (pos->isSigned && pos->num == 2) {
|
||||||
|
|||||||
@ -104,8 +104,11 @@ typedef struct {
|
|||||||
|
|
||||||
class StatisticsParser : public Parser {
|
class StatisticsParser : public Parser {
|
||||||
public:
|
public:
|
||||||
|
StatisticsParser();
|
||||||
void clearBuffer();
|
void clearBuffer();
|
||||||
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len);
|
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len);
|
||||||
|
void beginAppendFragment();
|
||||||
|
void endAppendFragment();
|
||||||
|
|
||||||
void setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size);
|
void setByteAssignment(const byteAssign_t* byteAssignment, uint8_t size);
|
||||||
|
|
||||||
@ -146,4 +149,6 @@ private:
|
|||||||
std::list<fieldSettings_t> _fieldSettings;
|
std::list<fieldSettings_t> _fieldSettings;
|
||||||
|
|
||||||
uint32_t _rxFailureCount = 0;
|
uint32_t _rxFailureCount = 0;
|
||||||
|
|
||||||
|
SemaphoreHandle_t _xSemaphore;
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue
Block a user