diff --git a/lib/Hoymiles/src/commands/PowerControlCommand.cpp b/lib/Hoymiles/src/commands/PowerControlCommand.cpp new file mode 100644 index 0000000..9bd6697 --- /dev/null +++ b/lib/Hoymiles/src/commands/PowerControlCommand.cpp @@ -0,0 +1,56 @@ +#include "PowerControlCommand.h" +#include "inverters/InverterAbstract.h" + +#define CRC_SIZE 2 + +PowerControlCommand::PowerControlCommand(uint64_t target_address, uint64_t router_address) + : DevControlCommand(target_address, router_address) +{ + _payload[10] = 0x00; // TurnOn + _payload[11] = 0x00; + + udpateCRC(CRC_SIZE); // 2 byte crc + + _payload_size = 14; + + setTimeout(2000); +} + +String PowerControlCommand::getCommandName() +{ + return "PowerControl"; +} + +bool PowerControlCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) +{ + if (!DevControlCommand::handleResponse(inverter, fragment, max_fragment_id)) { + return false; + } + + inverter->PowerCommand()->setLastUpdateCommand(millis()); + inverter->PowerCommand()->setLastPowerCommandSuccess(CMD_OK); + return true; +} + +void PowerControlCommand::gotTimeout(InverterAbstract* inverter) +{ + inverter->PowerCommand()->setLastPowerCommandSuccess(CMD_NOK); +} + +void PowerControlCommand::setPowerOn(bool state) +{ + if (state) { + _payload[10] = 0x00; // TurnOn + } else { + _payload[10] = 0x01; // TurnOff + } + + udpateCRC(CRC_SIZE); // 2 byte crc +} + +void PowerControlCommand::setRestart() +{ + _payload[10] = 0x02; // Restart + + udpateCRC(CRC_SIZE); // 2 byte crc +} \ No newline at end of file diff --git a/lib/Hoymiles/src/commands/PowerControlCommand.h b/lib/Hoymiles/src/commands/PowerControlCommand.h new file mode 100644 index 0000000..3b02256 --- /dev/null +++ b/lib/Hoymiles/src/commands/PowerControlCommand.h @@ -0,0 +1,16 @@ +#pragma once + +#include "DevControlCommand.h" + +class PowerControlCommand : public DevControlCommand { +public: + explicit PowerControlCommand(uint64_t target_address = 0, uint64_t router_address = 0); + + virtual String getCommandName(); + + virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); + virtual void gotTimeout(InverterAbstract* inverter); + + void setPowerOn(bool state); + void setRestart(); +}; \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_Abstract.cpp b/lib/Hoymiles/src/inverters/HM_Abstract.cpp index e1c80cf..4fc5dd5 100644 --- a/lib/Hoymiles/src/inverters/HM_Abstract.cpp +++ b/lib/Hoymiles/src/inverters/HM_Abstract.cpp @@ -4,6 +4,7 @@ #include "commands/AlarmDataCommand.h" #include "commands/DevInfoAllCommand.h" #include "commands/DevInfoSimpleCommand.h" +#include "commands/PowerControlCommand.h" #include "commands/RealTimeRunDataCommand.h" #include "commands/SystemConfigParaCommand.h" @@ -110,4 +111,14 @@ bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limi bool HM_Abstract::resendActivePowerControlRequest(HoymilesRadio* radio) { return sendActivePowerControlRequest(radio, _activePowerControlLimit, _activePowerControlType); +} + +bool HM_Abstract::sendPowerControlRequest(HoymilesRadio* radio, bool turnOn) +{ + PowerControlCommand* cmd = radio->enqueCommand(); + cmd->setPowerOn(turnOn); + cmd->setTargetAddress(serial()); + PowerCommand()->setLastPowerCommandSuccess(CMD_PENDING); + + return true; } \ No newline at end of file diff --git a/lib/Hoymiles/src/inverters/HM_Abstract.h b/lib/Hoymiles/src/inverters/HM_Abstract.h index 518af83..3a471fa 100644 --- a/lib/Hoymiles/src/inverters/HM_Abstract.h +++ b/lib/Hoymiles/src/inverters/HM_Abstract.h @@ -11,6 +11,7 @@ public: bool sendSystemConfigParaRequest(HoymilesRadio* radio); bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type); bool resendActivePowerControlRequest(HoymilesRadio* radio); + bool sendPowerControlRequest(HoymilesRadio* radio, bool turnOn); private: uint8_t _lastAlarmLogCnt = 0; diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.cpp b/lib/Hoymiles/src/inverters/InverterAbstract.cpp index d6c1f01..adb3191 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.cpp +++ b/lib/Hoymiles/src/inverters/InverterAbstract.cpp @@ -7,6 +7,7 @@ InverterAbstract::InverterAbstract(uint64_t serial) _serial.u64 = serial; _alarmLogParser.reset(new AlarmLogParser()); _devInfoParser.reset(new DevInfoParser()); + _powerCommandParser.reset(new PowerCommandParser()); _statisticsParser.reset(new StatisticsParser()); _systemConfigParaParser.reset(new SystemConfigParaParser()); } @@ -64,6 +65,11 @@ DevInfoParser* InverterAbstract::DevInfo() return _devInfoParser.get(); } +PowerCommandParser* InverterAbstract::PowerCommand() +{ + return _powerCommandParser.get(); +} + StatisticsParser* InverterAbstract::Statistics() { return _statisticsParser.get(); diff --git a/lib/Hoymiles/src/inverters/InverterAbstract.h b/lib/Hoymiles/src/inverters/InverterAbstract.h index bd53f9e..b8add3f 100644 --- a/lib/Hoymiles/src/inverters/InverterAbstract.h +++ b/lib/Hoymiles/src/inverters/InverterAbstract.h @@ -3,6 +3,7 @@ #include "../commands/ActivePowerControlCommand.h" #include "../parser/AlarmLogParser.h" #include "../parser/DevInfoParser.h" +#include "../parser/PowerCommandParser.h" #include "../parser/StatisticsParser.h" #include "../parser/SystemConfigParaParser.h" #include "HoymilesRadio.h" @@ -51,9 +52,11 @@ public: 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; AlarmLogParser* EventLog(); DevInfoParser* DevInfo(); + PowerCommandParser* PowerCommand(); StatisticsParser* Statistics(); SystemConfigParaParser* SystemConfigPara(); @@ -67,6 +70,7 @@ private: std::unique_ptr _alarmLogParser; std::unique_ptr _devInfoParser; + std::unique_ptr _powerCommandParser; std::unique_ptr _statisticsParser; std::unique_ptr _systemConfigParaParser; }; \ No newline at end of file diff --git a/lib/Hoymiles/src/parser/PowerCommandParser.cpp b/lib/Hoymiles/src/parser/PowerCommandParser.cpp new file mode 100644 index 0000000..1808660 --- /dev/null +++ b/lib/Hoymiles/src/parser/PowerCommandParser.cpp @@ -0,0 +1,22 @@ +#include "PowerCommandParser.h" + +void PowerCommandParser::setLastPowerCommandSuccess(LastCommandSuccess status) +{ + _lastLimitCommandSuccess = status; +} + +LastCommandSuccess PowerCommandParser::getLastPowerCommandSuccess() +{ + return _lastLimitCommandSuccess; +} + +uint32_t PowerCommandParser::getLastUpdateCommand() +{ + return _lastUpdateCommand; +} + +void PowerCommandParser::setLastUpdateCommand(uint32_t lastUpdate) +{ + _lastUpdateCommand = lastUpdate; + setLastUpdate(lastUpdate); +} \ No newline at end of file diff --git a/lib/Hoymiles/src/parser/PowerCommandParser.h b/lib/Hoymiles/src/parser/PowerCommandParser.h new file mode 100644 index 0000000..c0ba6be --- /dev/null +++ b/lib/Hoymiles/src/parser/PowerCommandParser.h @@ -0,0 +1,16 @@ +#pragma once +#include "Parser.h" +#include + +class PowerCommandParser : public Parser { +public: + void setLastPowerCommandSuccess(LastCommandSuccess status); + LastCommandSuccess getLastPowerCommandSuccess(); + uint32_t getLastUpdateCommand(); + void setLastUpdateCommand(uint32_t lastUpdate); + +private: + LastCommandSuccess _lastLimitCommandSuccess = CMD_OK; // Set to OK because we have to assume nothing is done at startup + + uint32_t _lastUpdateCommand = 0; +}; \ No newline at end of file