Move reference to the radio instance into the inverter instance

This is required to support different radios for different inverters
This commit is contained in:
Thomas Basler 2023-03-06 20:20:16 +01:00
parent c2e4c5d43e
commit a7e9aaa862
22 changed files with 90 additions and 86 deletions

View File

@ -41,36 +41,36 @@ void HoymilesClass::loop()
_messageOutput->print("Fetch inverter: ");
_messageOutput->println(iv->serial(), HEX);
iv->sendStatsRequest(_radio.get());
iv->sendStatsRequest();
// Fetch event log
bool force = iv->EventLog()->getLastAlarmRequestSuccess() == CMD_NOK;
iv->sendAlarmLogRequest(_radio.get(), force);
iv->sendAlarmLogRequest(force);
// Fetch limit
if ((iv->SystemConfigPara()->getLastLimitRequestSuccess() == CMD_NOK)
|| ((millis() - iv->SystemConfigPara()->getLastUpdateRequest() > HOY_SYSTEM_CONFIG_PARA_POLL_INTERVAL)
&& (millis() - iv->SystemConfigPara()->getLastUpdateCommand() > HOY_SYSTEM_CONFIG_PARA_POLL_MIN_DURATION))) {
_messageOutput->println("Request SystemConfigPara");
iv->sendSystemConfigParaRequest(_radio.get());
iv->sendSystemConfigParaRequest();
}
// Set limit if required
if (iv->SystemConfigPara()->getLastLimitCommandSuccess() == CMD_NOK) {
_messageOutput->println("Resend ActivePowerControl");
iv->resendActivePowerControlRequest(_radio.get());
iv->resendActivePowerControlRequest();
}
// Set power status if required
if (iv->PowerCommand()->getLastPowerCommandSuccess() == CMD_NOK) {
_messageOutput->println("Resend PowerCommand");
iv->resendPowerControlRequest(_radio.get());
iv->resendPowerControlRequest();
}
// Fetch dev info (but first fetch stats)
if (iv->Statistics()->getLastUpdate() > 0 && (iv->DevInfo()->getLastUpdateAll() == 0 || iv->DevInfo()->getLastUpdateSimple() == 0)) {
_messageOutput->println("Request device info");
iv->sendDevInfoRequest(_radio.get());
iv->sendDevInfoRequest();
}
}
if (++inverterPos >= getNumInverters()) {
@ -89,17 +89,17 @@ std::shared_ptr<InverterAbstract> HoymilesClass::addInverter(const char* name, u
{
std::shared_ptr<InverterAbstract> i = nullptr;
if (HMS_4CH::isValidSerial(serial)) {
i = std::make_shared<HMS_4CH>(serial);
i = std::make_shared<HMS_4CH>(_radio.get(), serial);
} else if (HMS_2CH::isValidSerial(serial)) {
i = std::make_shared<HMS_2CH>(serial);
i = std::make_shared<HMS_2CH>(_radio.get(), serial);
} else if (HMS_1CH::isValidSerial(serial)) {
i = std::make_shared<HMS_1CH>(serial);
i = std::make_shared<HMS_1CH>(_radio.get(), serial);
} else if (HM_4CH::isValidSerial(serial)) {
i = std::make_shared<HM_4CH>(serial);
i = std::make_shared<HM_4CH>(_radio.get(), serial);
} else if (HM_2CH::isValidSerial(serial)) {
i = std::make_shared<HM_2CH>(serial);
i = std::make_shared<HM_2CH>(_radio.get(), serial);
} else if (HM_1CH::isValidSerial(serial)) {
i = std::make_shared<HM_1CH>(serial);
i = std::make_shared<HM_1CH>(_radio.get(), serial);
}
if (i) {

View File

@ -4,8 +4,8 @@
*/
#include "HMS_1CH.h"
HMS_1CH::HMS_1CH(uint64_t serial)
: HMS_Abstract(serial) {};
HMS_1CH::HMS_1CH(HoymilesRadio* radio, uint64_t serial)
: HMS_Abstract(radio, serial) {};
bool HMS_1CH::isValidSerial(uint64_t serial)
{

View File

@ -6,7 +6,7 @@
class HMS_1CH : public HMS_Abstract {
public:
explicit HMS_1CH(uint64_t serial);
explicit HMS_1CH(HoymilesRadio* radio, uint64_t serial);
static bool isValidSerial(uint64_t serial);
String typeName();
const std::list<byteAssign_t>* getByteAssignment();

View File

@ -4,8 +4,8 @@
*/
#include "HMS_2CH.h"
HMS_2CH::HMS_2CH(uint64_t serial)
: HMS_Abstract(serial) {};
HMS_2CH::HMS_2CH(HoymilesRadio* radio, uint64_t serial)
: HMS_Abstract(radio, serial) {};
bool HMS_2CH::isValidSerial(uint64_t serial)
{

View File

@ -6,7 +6,7 @@
class HMS_2CH : public HMS_Abstract {
public:
explicit HMS_2CH(uint64_t serial);
explicit HMS_2CH(HoymilesRadio* radio, uint64_t serial);
static bool isValidSerial(uint64_t serial);
String typeName();
const std::list<byteAssign_t>* getByteAssignment();

View File

@ -4,8 +4,8 @@
*/
#include "HMS_4CH.h"
HMS_4CH::HMS_4CH(uint64_t serial)
: HMS_Abstract(serial) {};
HMS_4CH::HMS_4CH(HoymilesRadio* radio, uint64_t serial)
: HMS_Abstract(radio, serial) {};
bool HMS_4CH::isValidSerial(uint64_t serial)
{

View File

@ -5,7 +5,7 @@
class HMS_4CH : public HMS_Abstract {
public:
explicit HMS_4CH(uint64_t serial);
explicit HMS_4CH(HoymilesRadio* radio, uint64_t serial);
static bool isValidSerial(uint64_t serial);
String typeName();
const std::list<byteAssign_t>* getByteAssignment();

View File

@ -4,5 +4,5 @@
*/
#include "HMS_Abstract.h"
HMS_Abstract::HMS_Abstract(uint64_t serial)
: HM_Abstract(serial) {};
HMS_Abstract::HMS_Abstract(HoymilesRadio* radio, uint64_t serial)
: HM_Abstract(radio, serial) {};

View File

@ -5,5 +5,5 @@
class HMS_Abstract : public HM_Abstract {
public:
explicit HMS_Abstract(uint64_t serial);
explicit HMS_Abstract(HoymilesRadio* radio, uint64_t serial);
};

View File

@ -4,8 +4,8 @@
*/
#include "HM_1CH.h"
HM_1CH::HM_1CH(uint64_t serial)
: HM_Abstract(serial) {};
HM_1CH::HM_1CH(HoymilesRadio* radio, uint64_t serial)
: HM_Abstract(radio, serial) {};
bool HM_1CH::isValidSerial(uint64_t serial)
{

View File

@ -6,7 +6,7 @@
class HM_1CH : public HM_Abstract {
public:
explicit HM_1CH(uint64_t serial);
explicit HM_1CH(HoymilesRadio* radio, uint64_t serial);
static bool isValidSerial(uint64_t serial);
String typeName();
const std::list<byteAssign_t>* getByteAssignment();

View File

@ -5,8 +5,8 @@
*/
#include "HM_2CH.h"
HM_2CH::HM_2CH(uint64_t serial)
: HM_Abstract(serial) {};
HM_2CH::HM_2CH(HoymilesRadio* radio, uint64_t serial)
: HM_Abstract(radio, serial) {};
bool HM_2CH::isValidSerial(uint64_t serial)
{

View File

@ -5,7 +5,7 @@
class HM_2CH : public HM_Abstract {
public:
explicit HM_2CH(uint64_t serial);
explicit HM_2CH(HoymilesRadio* radio, uint64_t serial);
static bool isValidSerial(uint64_t serial);
String typeName();
const std::list<byteAssign_t>* getByteAssignment();

View File

@ -4,8 +4,8 @@
*/
#include "HM_4CH.h"
HM_4CH::HM_4CH(uint64_t serial)
: HM_Abstract(serial) {};
HM_4CH::HM_4CH(HoymilesRadio* radio, uint64_t serial)
: HM_Abstract(radio, serial) {};
bool HM_4CH::isValidSerial(uint64_t serial)
{

View File

@ -5,7 +5,7 @@
class HM_4CH : public HM_Abstract {
public:
explicit HM_4CH(uint64_t serial);
explicit HM_4CH(HoymilesRadio* radio, uint64_t serial);
static bool isValidSerial(uint64_t serial);
String typeName();
const std::list<byteAssign_t>* getByteAssignment();

View File

@ -12,10 +12,10 @@
#include "commands/RealTimeRunDataCommand.h"
#include "commands/SystemConfigParaCommand.h"
HM_Abstract::HM_Abstract(uint64_t serial)
: InverterAbstract(serial) {};
HM_Abstract::HM_Abstract(HoymilesRadio* radio, uint64_t serial)
: InverterAbstract(radio, serial) {};
bool HM_Abstract::sendStatsRequest(HoymilesRadio* radio)
bool HM_Abstract::sendStatsRequest()
{
if (!getEnablePolling()) {
return false;
@ -29,14 +29,14 @@ bool HM_Abstract::sendStatsRequest(HoymilesRadio* radio)
time_t now;
time(&now);
RealTimeRunDataCommand* cmd = radio->enqueCommand<RealTimeRunDataCommand>();
RealTimeRunDataCommand* cmd = _radio->enqueCommand<RealTimeRunDataCommand>();
cmd->setTime(now);
cmd->setTargetAddress(serial());
return true;
}
bool HM_Abstract::sendAlarmLogRequest(HoymilesRadio* radio, bool force)
bool HM_Abstract::sendAlarmLogRequest(bool force)
{
if (!getEnablePolling()) {
return false;
@ -60,7 +60,7 @@ bool HM_Abstract::sendAlarmLogRequest(HoymilesRadio* radio, bool force)
time_t now;
time(&now);
AlarmDataCommand* cmd = radio->enqueCommand<AlarmDataCommand>();
AlarmDataCommand* cmd = _radio->enqueCommand<AlarmDataCommand>();
cmd->setTime(now);
cmd->setTargetAddress(serial());
EventLog()->setLastAlarmRequestSuccess(CMD_PENDING);
@ -68,7 +68,7 @@ bool HM_Abstract::sendAlarmLogRequest(HoymilesRadio* radio, bool force)
return true;
}
bool HM_Abstract::sendDevInfoRequest(HoymilesRadio* radio)
bool HM_Abstract::sendDevInfoRequest()
{
if (!getEnablePolling()) {
return false;
@ -82,18 +82,18 @@ bool HM_Abstract::sendDevInfoRequest(HoymilesRadio* radio)
time_t now;
time(&now);
DevInfoAllCommand* cmdAll = radio->enqueCommand<DevInfoAllCommand>();
DevInfoAllCommand* cmdAll = _radio->enqueCommand<DevInfoAllCommand>();
cmdAll->setTime(now);
cmdAll->setTargetAddress(serial());
DevInfoSimpleCommand* cmdSimple = radio->enqueCommand<DevInfoSimpleCommand>();
DevInfoSimpleCommand* cmdSimple = _radio->enqueCommand<DevInfoSimpleCommand>();
cmdSimple->setTime(now);
cmdSimple->setTargetAddress(serial());
return true;
}
bool HM_Abstract::sendSystemConfigParaRequest(HoymilesRadio* radio)
bool HM_Abstract::sendSystemConfigParaRequest()
{
if (!getEnablePolling()) {
return false;
@ -107,7 +107,7 @@ bool HM_Abstract::sendSystemConfigParaRequest(HoymilesRadio* radio)
time_t now;
time(&now);
SystemConfigParaCommand* cmd = radio->enqueCommand<SystemConfigParaCommand>();
SystemConfigParaCommand* cmd = _radio->enqueCommand<SystemConfigParaCommand>();
cmd->setTime(now);
cmd->setTargetAddress(serial());
SystemConfigPara()->setLastLimitRequestSuccess(CMD_PENDING);
@ -115,7 +115,7 @@ bool HM_Abstract::sendSystemConfigParaRequest(HoymilesRadio* radio)
return true;
}
bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type)
bool HM_Abstract::sendActivePowerControlRequest(float limit, PowerLimitControlType type)
{
if (!getEnableCommands()) {
return false;
@ -128,7 +128,7 @@ bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limi
_activePowerControlLimit = limit;
_activePowerControlType = type;
ActivePowerControlCommand* cmd = radio->enqueCommand<ActivePowerControlCommand>();
ActivePowerControlCommand* cmd = _radio->enqueCommand<ActivePowerControlCommand>();
cmd->setActivePowerLimit(limit, type);
cmd->setTargetAddress(serial());
SystemConfigPara()->setLastLimitCommandSuccess(CMD_PENDING);
@ -136,12 +136,12 @@ bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limi
return true;
}
bool HM_Abstract::resendActivePowerControlRequest(HoymilesRadio* radio)
bool HM_Abstract::resendActivePowerControlRequest()
{
return sendActivePowerControlRequest(radio, _activePowerControlLimit, _activePowerControlType);
return sendActivePowerControlRequest(_activePowerControlLimit, _activePowerControlType);
}
bool HM_Abstract::sendPowerControlRequest(HoymilesRadio* radio, bool turnOn)
bool HM_Abstract::sendPowerControlRequest(bool turnOn)
{
if (!getEnableCommands()) {
return false;
@ -153,7 +153,7 @@ bool HM_Abstract::sendPowerControlRequest(HoymilesRadio* radio, bool turnOn)
_powerState = 0;
}
PowerControlCommand* cmd = radio->enqueCommand<PowerControlCommand>();
PowerControlCommand* cmd = _radio->enqueCommand<PowerControlCommand>();
cmd->setPowerOn(turnOn);
cmd->setTargetAddress(serial());
PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING);
@ -161,7 +161,7 @@ bool HM_Abstract::sendPowerControlRequest(HoymilesRadio* radio, bool turnOn)
return true;
}
bool HM_Abstract::sendRestartControlRequest(HoymilesRadio* radio)
bool HM_Abstract::sendRestartControlRequest()
{
if (!getEnableCommands()) {
return false;
@ -169,7 +169,7 @@ bool HM_Abstract::sendRestartControlRequest(HoymilesRadio* radio)
_powerState = 2;
PowerControlCommand* cmd = radio->enqueCommand<PowerControlCommand>();
PowerControlCommand* cmd = _radio->enqueCommand<PowerControlCommand>();
cmd->setRestart();
cmd->setTargetAddress(serial());
PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING);
@ -177,17 +177,17 @@ bool HM_Abstract::sendRestartControlRequest(HoymilesRadio* radio)
return true;
}
bool HM_Abstract::resendPowerControlRequest(HoymilesRadio* radio)
bool HM_Abstract::resendPowerControlRequest()
{
switch (_powerState) {
case 0:
return sendPowerControlRequest(radio, false);
return sendPowerControlRequest(false);
break;
case 1:
return sendPowerControlRequest(radio, true);
return sendPowerControlRequest(true);
break;
case 2:
return sendRestartControlRequest(radio);
return sendRestartControlRequest();
break;
default:

View File

@ -5,16 +5,16 @@
class HM_Abstract : public InverterAbstract {
public:
explicit HM_Abstract(uint64_t serial);
bool sendStatsRequest(HoymilesRadio* radio);
bool sendAlarmLogRequest(HoymilesRadio* radio, bool force = false);
bool sendDevInfoRequest(HoymilesRadio* radio);
bool sendSystemConfigParaRequest(HoymilesRadio* radio);
bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type);
bool resendActivePowerControlRequest(HoymilesRadio* radio);
bool sendPowerControlRequest(HoymilesRadio* radio, bool turnOn);
bool sendRestartControlRequest(HoymilesRadio* radio);
bool resendPowerControlRequest(HoymilesRadio* radio);
explicit HM_Abstract(HoymilesRadio* radio, uint64_t serial);
bool sendStatsRequest();
bool sendAlarmLogRequest(bool force = false);
bool sendDevInfoRequest();
bool sendSystemConfigParaRequest();
bool sendActivePowerControlRequest(float limit, PowerLimitControlType type);
bool resendActivePowerControlRequest();
bool sendPowerControlRequest(bool turnOn);
bool sendRestartControlRequest();
bool resendPowerControlRequest();
private:
uint8_t _lastAlarmLogCnt = 0;

View File

@ -7,9 +7,10 @@
#include "crc.h"
#include <cstring>
InverterAbstract::InverterAbstract(uint64_t serial)
InverterAbstract::InverterAbstract(HoymilesRadio *radio, uint64_t serial)
{
_serial.u64 = serial;
_radio = radio;
char serial_buff[sizeof(uint64_t) * 8 + 1];
snprintf(serial_buff, sizeof(serial_buff), "%0x%08x",

View File

@ -32,7 +32,7 @@ class CommandAbstract;
class InverterAbstract {
public:
explicit InverterAbstract(uint64_t serial);
explicit InverterAbstract(HoymilesRadio* radio, uint64_t serial);
void init();
uint64_t serial();
const String& serialString();
@ -54,15 +54,15 @@ public:
void addRxFragment(uint8_t fragment[], uint8_t len);
uint8_t verifyAllFragments(CommandAbstract* cmd);
virtual bool sendStatsRequest(HoymilesRadio* radio) = 0;
virtual bool sendAlarmLogRequest(HoymilesRadio* radio, bool force = false) = 0;
virtual bool sendDevInfoRequest(HoymilesRadio* radio) = 0;
virtual bool sendSystemConfigParaRequest(HoymilesRadio* radio) = 0;
virtual bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type) = 0;
virtual bool resendActivePowerControlRequest(HoymilesRadio* radio) = 0;
virtual bool sendPowerControlRequest(HoymilesRadio* radio, bool turnOn) = 0;
virtual bool sendRestartControlRequest(HoymilesRadio* radio) = 0;
virtual bool resendPowerControlRequest(HoymilesRadio* radio) = 0;
virtual bool sendStatsRequest() = 0;
virtual bool sendAlarmLogRequest(bool force = false) = 0;
virtual bool sendDevInfoRequest() = 0;
virtual bool sendSystemConfigParaRequest() = 0;
virtual bool sendActivePowerControlRequest(float limit, PowerLimitControlType type) = 0;
virtual bool resendActivePowerControlRequest() = 0;
virtual bool sendPowerControlRequest(bool turnOn) = 0;
virtual bool sendRestartControlRequest() = 0;
virtual bool resendPowerControlRequest() = 0;
AlarmLogParser* EventLog();
DevInfoParser* DevInfo();
@ -70,6 +70,9 @@ public:
StatisticsParser* Statistics();
SystemConfigParaParser* SystemConfigPara();
protected:
HoymilesRadio* _radio;
private:
serial_u _serial;
String _serialString;

View File

@ -208,18 +208,18 @@ void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessagePro
if (!strcmp(setting, TOPIC_SUB_LIMIT_PERSISTENT_RELATIVE)) {
// Set inverter limit relative persistent
MessageOutput.printf("Limit Persistent: %d %%\r\n", payload_val);
inv->sendActivePowerControlRequest(Hoymiles.getRadio(), payload_val, PowerLimitControlType::RelativPersistent);
inv->sendActivePowerControlRequest(payload_val, PowerLimitControlType::RelativPersistent);
} else if (!strcmp(setting, TOPIC_SUB_LIMIT_PERSISTENT_ABSOLUTE)) {
// Set inverter limit absolute persistent
MessageOutput.printf("Limit Persistent: %d W\r\n", payload_val);
inv->sendActivePowerControlRequest(Hoymiles.getRadio(), payload_val, PowerLimitControlType::AbsolutPersistent);
inv->sendActivePowerControlRequest(payload_val, PowerLimitControlType::AbsolutPersistent);
} else if (!strcmp(setting, TOPIC_SUB_LIMIT_NONPERSISTENT_RELATIVE)) {
// Set inverter limit relative non persistent
MessageOutput.printf("Limit Non-Persistent: %d %%\r\n", payload_val);
if (!properties.retain) {
inv->sendActivePowerControlRequest(Hoymiles.getRadio(), payload_val, PowerLimitControlType::RelativNonPersistent);
inv->sendActivePowerControlRequest(payload_val, PowerLimitControlType::RelativNonPersistent);
} else {
MessageOutput.println("Ignored because retained");
}
@ -228,7 +228,7 @@ void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessagePro
// Set inverter limit absolute non persistent
MessageOutput.printf("Limit Non-Persistent: %d W\r\n", payload_val);
if (!properties.retain) {
inv->sendActivePowerControlRequest(Hoymiles.getRadio(), payload_val, PowerLimitControlType::AbsolutNonPersistent);
inv->sendActivePowerControlRequest(payload_val, PowerLimitControlType::AbsolutNonPersistent);
} else {
MessageOutput.println("Ignored because retained");
}
@ -236,13 +236,13 @@ void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessagePro
} else if (!strcmp(setting, TOPIC_SUB_POWER)) {
// Turn inverter on or off
MessageOutput.printf("Set inverter power to: %d\r\n", payload_val);
inv->sendPowerControlRequest(Hoymiles.getRadio(), payload_val > 0);
inv->sendPowerControlRequest(payload_val > 0);
} else if (!strcmp(setting, TOPIC_SUB_RESTART)) {
// Restart inverter
MessageOutput.printf("Restart inverter\r\n");
if (!properties.retain && payload_val == 1) {
inv->sendRestartControlRequest(Hoymiles.getRadio());
inv->sendRestartControlRequest();
} else {
MessageOutput.println("Ignored because retained");
}

View File

@ -146,7 +146,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
return;
}
inv->sendActivePowerControlRequest(Hoymiles.getRadio(), limit, type);
inv->sendActivePowerControlRequest(limit, type);
retMsg["type"] = "success";
retMsg["message"] = "Settings saved!";

View File

@ -118,10 +118,10 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request)
if (root.containsKey("power")) {
uint16_t power = root["power"].as<bool>();
inv->sendPowerControlRequest(Hoymiles.getRadio(), power);
inv->sendPowerControlRequest(power);
} else {
if (root["restart"].as<bool>()) {
inv->sendRestartControlRequest(Hoymiles.getRadio());
inv->sendRestartControlRequest();
}
}