Remove RequestType and place handling of response in the command class

This commit is contained in:
Thomas Basler 2022-08-03 18:50:34 +02:00
parent a73707380f
commit 857e4a3671
18 changed files with 81 additions and 72 deletions

View File

@ -89,7 +89,8 @@ void HoymilesRadio::loop()
std::shared_ptr<InverterAbstract> 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);
}

View File

@ -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)
@ -7,3 +8,15 @@ AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_addr
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());
}

View File

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

View File

@ -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];

View File

@ -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)
@ -7,3 +8,15 @@ RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t
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());
}

View File

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

View File

@ -19,3 +19,7 @@ uint8_t RequestFrameCommand::getFrameNo()
{
return _payload[9] & (~0x80);
}
void RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{
}

View File

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

View File

@ -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; };
};

View File

@ -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;
}

View File

@ -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> _alarmLogParser;
std::unique_ptr<StatisticsParser> _statisticsParser;
};

View File

@ -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

View File

@ -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;
};

View File

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

View File

@ -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;
};

View File

@ -14,9 +14,3 @@ typedef struct {
uint8_t fragment[MAX_RF_PAYLOAD_SIZE];
uint8_t len;
} fragment_t;
enum class RequestType {
None,
Stats,
AlarmLog
};

View File

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

View File

@ -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();
}
}
}