Implemented DevInfo command

This commit is contained in:
Thomas Basler 2022-08-08 19:59:11 +02:00
parent 35a72acf34
commit 8715320282
11 changed files with 133 additions and 4 deletions

View File

@ -3,6 +3,7 @@
#include "inverters/HM_2CH.h" #include "inverters/HM_2CH.h"
#include "inverters/HM_4CH.h" #include "inverters/HM_4CH.h"
#include <Arduino.h> #include <Arduino.h>
#include <Every.h>
HoymilesClass Hoymiles; HoymilesClass Hoymiles;
@ -30,6 +31,15 @@ void HoymilesClass::loop()
// Fetch event log // Fetch event log
iv->sendAlarmLogRequest(_radio.get()); iv->sendAlarmLogRequest(_radio.get());
// Fetch dev info
if (iv->DevInfo()->getLastUpdate() == 0) {
EVERY_N_MINUTES(10)
{
Serial.println(F("Request device info"));
iv->sendDevInfoRequest(_radio.get());
}
}
} }
if (++inverterPos >= getNumInverters()) { if (++inverterPos >= getNumInverters()) {
@ -46,11 +56,9 @@ std::shared_ptr<InverterAbstract> HoymilesClass::addInverter(const char* name, u
std::shared_ptr<InverterAbstract> i; std::shared_ptr<InverterAbstract> i;
if (HM_4CH::isValidSerial(serial)) { if (HM_4CH::isValidSerial(serial)) {
i = std::make_shared<HM_4CH>(serial); i = std::make_shared<HM_4CH>(serial);
} } else if (HM_2CH::isValidSerial(serial)) {
else if (HM_2CH::isValidSerial(serial)) {
i = std::make_shared<HM_2CH>(serial); i = std::make_shared<HM_2CH>(serial);
} } else if (HM_1CH::isValidSerial(serial)) {
else if (HM_1CH::isValidSerial(serial)) {
i = std::make_shared<HM_1CH>(serial); i = std::make_shared<HM_1CH>(serial);
} }

View File

@ -0,0 +1,28 @@
#include "DevInfoAllCommand.h"
#include "inverters/InverterAbstract.h"
DevInfoAllCommand::DevInfoAllCommand(uint64_t target_address, uint64_t router_address, time_t time)
: MultiDataCommand(target_address, router_address)
{
setTime(time);
setDataType(0x01);
setTimeout(200);
}
bool DevInfoAllCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{
// Check CRC of whole payload
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
return false;
}
// Move all fragments into target buffer
uint8_t offs = 0;
inverter->DevInfo()->clearBuffer();
for (uint8_t i = 0; i < max_fragment_id; i++) {
inverter->DevInfo()->appendFragment(offs, fragment[i].fragment, fragment[i].len);
offs += (fragment[i].len);
}
inverter->DevInfo()->setLastUpdate(millis());
return true;
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "MultiDataCommand.h"
class DevInfoAllCommand : public MultiDataCommand {
public:
DevInfoAllCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0);
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
};

View File

@ -1,6 +1,7 @@
#include "HM_Abstract.h" #include "HM_Abstract.h"
#include "HoymilesRadio.h" #include "HoymilesRadio.h"
#include "commands/AlarmDataCommand.h" #include "commands/AlarmDataCommand.h"
#include "commands/DevInfoAllCommand.h"
#include "commands/RealTimeRunDataCommand.h" #include "commands/RealTimeRunDataCommand.h"
HM_Abstract::HM_Abstract(uint64_t serial) HM_Abstract::HM_Abstract(uint64_t serial)
@ -45,5 +46,22 @@ bool HM_Abstract::sendAlarmLogRequest(HoymilesRadio* radio)
cmd->setTime(now); cmd->setTime(now);
cmd->setTargetAddress(serial()); cmd->setTargetAddress(serial());
return true;
}
bool HM_Abstract::sendDevInfoRequest(HoymilesRadio* radio)
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return false;
}
time_t now;
time(&now);
DevInfoAllCommand* cmd = radio->enqueCommand<DevInfoAllCommand>();
cmd->setTime(now);
cmd->setTargetAddress(serial());
return true; return true;
} }

View File

@ -7,6 +7,7 @@ public:
HM_Abstract(uint64_t serial); HM_Abstract(uint64_t serial);
bool sendStatsRequest(HoymilesRadio* radio); bool sendStatsRequest(HoymilesRadio* radio);
bool sendAlarmLogRequest(HoymilesRadio* radio); bool sendAlarmLogRequest(HoymilesRadio* radio);
bool sendDevInfoRequest(HoymilesRadio* radio);
private: private:
uint8_t _lastAlarmLogCnt = 0; uint8_t _lastAlarmLogCnt = 0;

View File

@ -6,6 +6,7 @@ InverterAbstract::InverterAbstract(uint64_t serial)
{ {
_serial.u64 = serial; _serial.u64 = serial;
_alarmLogParser.reset(new AlarmLogParser()); _alarmLogParser.reset(new AlarmLogParser());
_devInfoParser.reset(new DevInfoParser());
_statisticsParser.reset(new StatisticsParser()); _statisticsParser.reset(new StatisticsParser());
} }
@ -43,6 +44,11 @@ AlarmLogParser* InverterAbstract::EventLog()
return _alarmLogParser.get(); return _alarmLogParser.get();
} }
DevInfoParser* InverterAbstract::DevInfo()
{
return _devInfoParser.get();
}
StatisticsParser* InverterAbstract::Statistics() StatisticsParser* InverterAbstract::Statistics()
{ {
return _statisticsParser.get(); return _statisticsParser.get();

View File

@ -2,6 +2,7 @@
#include "../parser/AlarmLogParser.h" #include "../parser/AlarmLogParser.h"
#include "../parser/StatisticsParser.h" #include "../parser/StatisticsParser.h"
#include "../parser/DevInfoParser.h"
#include "HoymilesRadio.h" #include "HoymilesRadio.h"
#include "types.h" #include "types.h"
#include <Arduino.h> #include <Arduino.h>
@ -38,8 +39,10 @@ public:
virtual bool sendStatsRequest(HoymilesRadio* radio) = 0; virtual bool sendStatsRequest(HoymilesRadio* radio) = 0;
virtual bool sendAlarmLogRequest(HoymilesRadio* radio) = 0; virtual bool sendAlarmLogRequest(HoymilesRadio* radio) = 0;
virtual bool sendDevInfoRequest(HoymilesRadio* radio) = 0;
AlarmLogParser* EventLog(); AlarmLogParser* EventLog();
DevInfoParser* DevInfo();
StatisticsParser* Statistics(); StatisticsParser* Statistics();
private: private:
@ -51,5 +54,6 @@ private:
uint8_t _rxFragmentRetransmitCnt = 0; uint8_t _rxFragmentRetransmitCnt = 0;
std::unique_ptr<AlarmLogParser> _alarmLogParser; std::unique_ptr<AlarmLogParser> _alarmLogParser;
std::unique_ptr<DevInfoParser> _devInfoParser;
std::unique_ptr<StatisticsParser> _statisticsParser; std::unique_ptr<StatisticsParser> _statisticsParser;
}; };

View File

@ -0,0 +1,18 @@
#include "DevInfoParser.h"
#include <cstring>
void DevInfoParser::clearBuffer()
{
memset(_payloadDevInfo, 0, DEV_INFO_SIZE);
_devInfoLength = 0;
}
void DevInfoParser::appendFragment(uint8_t offset, uint8_t* payload, uint8_t len)
{
if (offset + len > DEV_INFO_SIZE) {
Serial.printf("FATAL: (%s, %d) stats packet too large for buffer\n", __FILE__, __LINE__);
return;
}
memcpy(&_payloadDevInfo[offset], payload, len);
_devInfoLength += len;
}

View File

@ -0,0 +1,14 @@
#include "Parser.h"
#include <Arduino.h>
#define DEV_INFO_SIZE 30
class DevInfoParser : public Parser {
public:
void clearBuffer();
void appendFragment(uint8_t offset, uint8_t* payload, uint8_t len);
private:
uint8_t _payloadDevInfo[DEV_INFO_SIZE];
uint8_t _devInfoLength;
};

View File

@ -0,0 +1,11 @@
#include "Parser.h"
uint32_t Parser::getLastUpdate()
{
return _lastUpdate;
}
void Parser::setLastUpdate(uint32_t lastUpdate)
{
_lastUpdate = lastUpdate;
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <cstdint>
class Parser {
public:
uint32_t getLastUpdate();
void setLastUpdate(uint32_t lastUpdate);
private:
uint32_t _lastUpdate = 0;
};