Remove RequestType and place handling of response in the command class
This commit is contained in:
parent
a73707380f
commit
857e4a3671
@ -89,7 +89,8 @@ void HoymilesRadio::loop()
|
|||||||
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(_commandQueue.front().get()->getTargetAddress());
|
std::shared_ptr<InverterAbstract> inv = Hoymiles.getInverterBySerial(_commandQueue.front().get()->getTargetAddress());
|
||||||
|
|
||||||
if (nullptr != inv) {
|
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 (verifyResult == FRAGMENT_ALL_MISSING) {
|
||||||
if (_commandQueue.front().get()->getSendCount() <= MAX_RESEND_COUNT) {
|
if (_commandQueue.front().get()->getSendCount() <= MAX_RESEND_COUNT) {
|
||||||
Serial.println(F("Nothing received, resend whole request"));
|
Serial.println(F("Nothing received, resend whole request"));
|
||||||
@ -127,7 +128,6 @@ void HoymilesRadio::loop()
|
|||||||
CommandAbstract* cmd = _commandQueue.front().get();
|
CommandAbstract* cmd = _commandQueue.front().get();
|
||||||
|
|
||||||
auto inv = Hoymiles.getInverterBySerial(cmd->getTargetAddress());
|
auto inv = Hoymiles.getInverterBySerial(cmd->getTargetAddress());
|
||||||
inv->setLastRequest(cmd->getRequestType());
|
|
||||||
inv->clearRxFragmentBuffer();
|
inv->clearRxFragmentBuffer();
|
||||||
sendEsbPacket(cmd);
|
sendEsbPacket(cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "AlarmDataCommand.h"
|
#include "AlarmDataCommand.h"
|
||||||
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_address, time_t time)
|
AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_address, time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(target_address, router_address)
|
||||||
@ -6,4 +7,16 @@ AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_addr
|
|||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x11);
|
setDataType(0x11);
|
||||||
setTimeout(200);
|
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());
|
||||||
}
|
}
|
||||||
@ -6,5 +6,5 @@ class AlarmDataCommand : public MultiDataCommand {
|
|||||||
public:
|
public:
|
||||||
AlarmDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0);
|
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);
|
||||||
};
|
};
|
||||||
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#define RF_LEN 32
|
#define RF_LEN 32
|
||||||
|
|
||||||
|
class InverterAbstract;
|
||||||
|
|
||||||
class CommandAbstract {
|
class CommandAbstract {
|
||||||
public:
|
public:
|
||||||
CommandAbstract(uint64_t target_address = 0, uint64_t router_address = 0);
|
CommandAbstract(uint64_t target_address = 0, uint64_t router_address = 0);
|
||||||
@ -34,7 +36,7 @@ public:
|
|||||||
|
|
||||||
virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no);
|
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:
|
protected:
|
||||||
uint8_t _payload[RF_LEN];
|
uint8_t _payload[RF_LEN];
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "RealTimeRunDataCommand.h"
|
#include "RealTimeRunDataCommand.h"
|
||||||
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t router_address, time_t time)
|
RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t router_address, time_t time)
|
||||||
: MultiDataCommand(target_address, router_address)
|
: MultiDataCommand(target_address, router_address)
|
||||||
@ -6,4 +7,16 @@ RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t
|
|||||||
setTime(time);
|
setTime(time);
|
||||||
setDataType(0x0b);
|
setDataType(0x0b);
|
||||||
setTimeout(200);
|
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());
|
||||||
}
|
}
|
||||||
@ -6,5 +6,5 @@ class RealTimeRunDataCommand : public MultiDataCommand {
|
|||||||
public:
|
public:
|
||||||
RealTimeRunDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0);
|
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);
|
||||||
};
|
};
|
||||||
@ -18,4 +18,8 @@ void RequestFrameCommand::setFrameNo(uint8_t frame_no)
|
|||||||
uint8_t RequestFrameCommand::getFrameNo()
|
uint8_t RequestFrameCommand::getFrameNo()
|
||||||
{
|
{
|
||||||
return _payload[9] & (~0x80);
|
return _payload[9] & (~0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
@ -8,4 +8,6 @@ public:
|
|||||||
|
|
||||||
void setFrameNo(uint8_t frame_no);
|
void setFrameNo(uint8_t frame_no);
|
||||||
uint8_t getFrameNo();
|
uint8_t getFrameNo();
|
||||||
|
|
||||||
|
virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
|
||||||
};
|
};
|
||||||
@ -5,6 +5,4 @@
|
|||||||
class SingleDataCommand : public CommandAbstract {
|
class SingleDataCommand : public CommandAbstract {
|
||||||
public:
|
public:
|
||||||
SingleDataCommand(uint64_t target_address = 0, uint64_t router_address = 0);
|
SingleDataCommand(uint64_t target_address = 0, uint64_t router_address = 0);
|
||||||
|
|
||||||
RequestType getRequestType() { return RequestType::None; };
|
|
||||||
};
|
};
|
||||||
@ -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
|
// 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
|
// All missing
|
||||||
if (_rxFragmentLastPacketId == 0) {
|
if (_rxFragmentLastPacketId == 0) {
|
||||||
@ -139,45 +139,7 @@ uint8_t InverterAbstract::verifyAllFragments()
|
|||||||
return FRAGMENT_CRC_ERROR;
|
return FRAGMENT_CRC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getLastRequest() == RequestType::Stats) {
|
cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId);
|
||||||
// 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();
|
|
||||||
|
|
||||||
} 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;
|
return FRAGMENT_OK;
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t InverterAbstract::getLastStatsUpdate()
|
|
||||||
{
|
|
||||||
return _lastStatsUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InverterAbstract::setLastRequest(RequestType request)
|
|
||||||
{
|
|
||||||
_lastRequest = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestType InverterAbstract::getLastRequest()
|
|
||||||
{
|
|
||||||
return _lastRequest;
|
|
||||||
}
|
}
|
||||||
@ -19,6 +19,8 @@ enum {
|
|||||||
#define MAX_RF_FRAGMENT_COUNT 5
|
#define MAX_RF_FRAGMENT_COUNT 5
|
||||||
#define MAX_RETRANSMIT_COUNT 5
|
#define MAX_RETRANSMIT_COUNT 5
|
||||||
|
|
||||||
|
class CommandAbstract;
|
||||||
|
|
||||||
class InverterAbstract {
|
class InverterAbstract {
|
||||||
public:
|
public:
|
||||||
InverterAbstract(uint64_t serial);
|
InverterAbstract(uint64_t serial);
|
||||||
@ -32,20 +34,14 @@ public:
|
|||||||
|
|
||||||
void clearRxFragmentBuffer();
|
void clearRxFragmentBuffer();
|
||||||
void addRxFragment(uint8_t fragment[], uint8_t len);
|
void addRxFragment(uint8_t fragment[], uint8_t len);
|
||||||
uint8_t verifyAllFragments();
|
uint8_t verifyAllFragments(CommandAbstract* cmd);
|
||||||
|
|
||||||
virtual bool sendStatsRequest(HoymilesRadio* radio) = 0;
|
virtual bool sendStatsRequest(HoymilesRadio* radio) = 0;
|
||||||
virtual bool sendAlarmLogRequest(HoymilesRadio* radio) = 0;
|
virtual bool sendAlarmLogRequest(HoymilesRadio* radio) = 0;
|
||||||
uint32_t getLastStatsUpdate();
|
|
||||||
|
|
||||||
void setLastRequest(RequestType request);
|
|
||||||
|
|
||||||
AlarmLogParser* EventLog();
|
AlarmLogParser* EventLog();
|
||||||
StatisticsParser* Statistics();
|
StatisticsParser* Statistics();
|
||||||
|
|
||||||
protected:
|
|
||||||
RequestType getLastRequest();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
serial_u _serial;
|
serial_u _serial;
|
||||||
char _name[MAX_NAME_LENGTH];
|
char _name[MAX_NAME_LENGTH];
|
||||||
@ -54,11 +50,6 @@ private:
|
|||||||
uint8_t _rxFragmentLastPacketId = 0;
|
uint8_t _rxFragmentLastPacketId = 0;
|
||||||
uint8_t _rxFragmentRetransmitCnt = 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<AlarmLogParser> _alarmLogParser;
|
||||||
std::unique_ptr<StatisticsParser> _statisticsParser;
|
std::unique_ptr<StatisticsParser> _statisticsParser;
|
||||||
};
|
};
|
||||||
@ -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()
|
int AlarmLogParser::getTimezoneOffset()
|
||||||
{
|
{
|
||||||
// see: https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c/44063597#44063597
|
// see: https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c/44063597#44063597
|
||||||
|
|||||||
@ -20,9 +20,14 @@ public:
|
|||||||
uint8_t getEntryCount();
|
uint8_t getEntryCount();
|
||||||
void getLogEntry(uint8_t entryId, AlarmLogEntry_t* entry);
|
void getLogEntry(uint8_t entryId, AlarmLogEntry_t* entry);
|
||||||
|
|
||||||
|
uint32_t getLastUpdate();
|
||||||
|
void setLastUpdate(uint32_t lastUpdate);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int getTimezoneOffset();
|
static int getTimezoneOffset();
|
||||||
|
|
||||||
uint8_t _payloadAlarmLog[ALARM_LOG_ENTRY_SIZE * ALARM_LOG_ENTRY_COUNT];
|
uint8_t _payloadAlarmLog[ALARM_LOG_ENTRY_SIZE * ALARM_LOG_ENTRY_COUNT];
|
||||||
uint8_t _alarmLogLength;
|
uint8_t _alarmLogLength;
|
||||||
|
|
||||||
|
uint32_t _lastUpdate = 0;
|
||||||
};
|
};
|
||||||
@ -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)
|
static float calcYieldTotalCh0(StatisticsParser* iv, uint8_t arg0)
|
||||||
{
|
{
|
||||||
float yield = 0;
|
float yield = 0;
|
||||||
|
|||||||
@ -110,6 +110,9 @@ public:
|
|||||||
uint16_t getChannelMaxPower(uint8_t channel);
|
uint16_t getChannelMaxPower(uint8_t channel);
|
||||||
void setChannelMaxPower(uint8_t channel, uint16_t power);
|
void setChannelMaxPower(uint8_t channel, uint16_t power);
|
||||||
|
|
||||||
|
uint32_t getLastUpdate();
|
||||||
|
void setLastUpdate(uint32_t lastUpdate);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _payloadStatistic[STATISTIC_PACKET_SIZE];
|
uint8_t _payloadStatistic[STATISTIC_PACKET_SIZE];
|
||||||
uint8_t _statisticLength;
|
uint8_t _statisticLength;
|
||||||
@ -117,4 +120,6 @@ private:
|
|||||||
|
|
||||||
const byteAssign_t* _byteAssignment;
|
const byteAssign_t* _byteAssignment;
|
||||||
uint8_t _byteAssignmentCount;
|
uint8_t _byteAssignmentCount;
|
||||||
|
|
||||||
|
uint32_t _lastUpdate = 0;
|
||||||
};
|
};
|
||||||
@ -14,9 +14,3 @@ typedef struct {
|
|||||||
uint8_t fragment[MAX_RF_PAYLOAD_SIZE];
|
uint8_t fragment[MAX_RF_PAYLOAD_SIZE];
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
} fragment_t;
|
} fragment_t;
|
||||||
|
|
||||||
enum class RequestType {
|
|
||||||
None,
|
|
||||||
Stats,
|
|
||||||
AlarmLog
|
|
||||||
};
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ void MqttPublishingClass::loop()
|
|||||||
|
|
||||||
MqttSettings.publish(subtopic + "/name", inv->name());
|
MqttSettings.publish(subtopic + "/name", inv->name());
|
||||||
|
|
||||||
uint32_t lastUpdate = inv->getLastStatsUpdate();
|
uint32_t lastUpdate = inv->Statistics()->getLastUpdate();
|
||||||
if (lastUpdate > 0 && lastUpdate != _lastPublishStats[i]) {
|
if (lastUpdate > 0 && lastUpdate != _lastPublishStats[i]) {
|
||||||
_lastPublishStats[i] = lastUpdate;
|
_lastPublishStats[i] = lastUpdate;
|
||||||
|
|
||||||
|
|||||||
@ -44,8 +44,8 @@ void WebApiWsLiveClass::loop()
|
|||||||
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
|
||||||
auto inv = Hoymiles.getInverterByPos(i);
|
auto inv = Hoymiles.getInverterByPos(i);
|
||||||
|
|
||||||
if (inv->getLastStatsUpdate() > maxTimeStamp) {
|
if (inv->Statistics()->getLastUpdate() > maxTimeStamp) {
|
||||||
maxTimeStamp = inv->getLastStatsUpdate();
|
maxTimeStamp = inv->Statistics()->getLastUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,8 +80,8 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
|||||||
|
|
||||||
root[i][F("serial")] = String(buffer);
|
root[i][F("serial")] = String(buffer);
|
||||||
root[i][F("name")] = inv->name();
|
root[i][F("name")] = inv->name();
|
||||||
root[i][F("data_age")] = (millis() - inv->getLastStatsUpdate()) / 1000;
|
root[i][F("data_age")] = (millis() - inv->Statistics()->getLastUpdate()) / 1000;
|
||||||
root[i][F("age_critical")] = ((millis() - inv->getLastStatsUpdate()) / 1000) > Configuration.get().Dtu_PollInterval * 5;
|
root[i][F("age_critical")] = ((millis() - inv->Statistics()->getLastUpdate()) / 1000) > Configuration.get().Dtu_PollInterval * 5;
|
||||||
|
|
||||||
// Loop all channels
|
// Loop all channels
|
||||||
for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) {
|
for (uint8_t c = 0; c <= inv->Statistics()->getChannelCount(); c++) {
|
||||||
@ -110,8 +110,8 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
|
|||||||
root[i][F("events")] = -1;
|
root[i][F("events")] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inv->getLastStatsUpdate() > _newestInverterTimestamp) {
|
if (inv->Statistics()->getLastUpdate() > _newestInverterTimestamp) {
|
||||||
_newestInverterTimestamp = inv->getLastStatsUpdate();
|
_newestInverterTimestamp = inv->Statistics()->getLastUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user