Implemented method to check whether the last command was successfull
This also allows to retransmit the command after specific time if not successfull
This commit is contained in:
parent
a8ee8afb17
commit
a707ab501d
@ -32,11 +32,17 @@ void HoymilesClass::loop()
|
||||
iv->sendAlarmLogRequest(_radio.get());
|
||||
|
||||
// Fetch limit
|
||||
if ((iv->SystemConfigPara()->getLastUpdate() == 0) || (millis() - iv->SystemConfigPara()->getLastUpdate() > HOY_SYSTEM_CONFIG_PARA_POLL_INTERVAL)) {
|
||||
if ((iv->SystemConfigPara()->getLastLimitRequestSuccess() == CMD_NOK) || (millis() - iv->SystemConfigPara()->getLastUpdate() > HOY_SYSTEM_CONFIG_PARA_POLL_INTERVAL)) {
|
||||
Serial.println("Request SystemConfigPara");
|
||||
iv->sendSystemConfigParaRequest(_radio.get());
|
||||
}
|
||||
|
||||
// Set limit if required
|
||||
if (iv->SystemConfigPara()->getLastLimitCommandSuccess() == CMD_NOK) {
|
||||
Serial.println(F("Resend ActivePowerControl"));
|
||||
iv->resendActivePowerControlRequest(_radio.get());
|
||||
}
|
||||
|
||||
// Fetch dev info (but first fetch stats)
|
||||
if (iv->Statistics()->getLastUpdate() > 0 && (iv->DevInfo()->getLastUpdateAll() == 0 || iv->DevInfo()->getLastUpdateSample() == 0)) {
|
||||
Serial.println(F("Request device info"));
|
||||
|
||||
@ -91,15 +91,14 @@ void HoymilesRadio::loop()
|
||||
if (nullptr != inv) {
|
||||
CommandAbstract* cmd = _commandQueue.front().get();
|
||||
uint8_t verifyResult = inv->verifyAllFragments(cmd);
|
||||
if (verifyResult == FRAGMENT_ALL_MISSING) {
|
||||
if (_commandQueue.front().get()->getSendCount() <= MAX_RESEND_COUNT) {
|
||||
if (verifyResult == FRAGMENT_ALL_MISSING_RESEND) {
|
||||
Serial.println(F("Nothing received, resend whole request"));
|
||||
sendLastPacketAgain();
|
||||
} else {
|
||||
|
||||
} else if (verifyResult == FRAGMENT_ALL_MISSING_TIMEOUT) {
|
||||
Serial.println(F("Nothing received, resend count exeeded"));
|
||||
_commandQueue.pop();
|
||||
_busyFlag = false;
|
||||
}
|
||||
|
||||
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
|
||||
Serial.println(F("Retransmit timeout"));
|
||||
|
||||
@ -12,8 +12,6 @@
|
||||
// number of fragments hold in buffer
|
||||
#define FRAGMENT_BUFFER_SIZE 30
|
||||
|
||||
#define MAX_RESEND_COUNT 4
|
||||
|
||||
#ifndef HOYMILES_PIN_MISO
|
||||
#define HOYMILES_PIN_MISO 19
|
||||
#endif
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "ActivePowerControlCommand.h"
|
||||
#include "inverters/InverterAbstract.h"
|
||||
|
||||
#define CRC_SIZE 6
|
||||
|
||||
@ -34,6 +35,16 @@ void ActivePowerControlCommand::setActivePowerLimit(float limit, PowerLimitContr
|
||||
udpateCRC(CRC_SIZE);
|
||||
}
|
||||
|
||||
bool ActivePowerControlCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
|
||||
{
|
||||
if (!DevControlCommand::handleResponse(inverter, fragment, max_fragment_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inverter->SystemConfigPara()->setLastLimitCommandSuccess(CMD_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
float ActivePowerControlCommand::getLimit()
|
||||
{
|
||||
uint16_t l = (((uint16_t)_payload[12] << 8) | _payload[13]);
|
||||
@ -44,3 +55,8 @@ PowerLimitControlType ActivePowerControlCommand::getType()
|
||||
{
|
||||
return (PowerLimitControlType)(((uint16_t)_payload[14] << 8) | _payload[15]);
|
||||
}
|
||||
|
||||
void ActivePowerControlCommand::gotTimeout(InverterAbstract* inverter)
|
||||
{
|
||||
inverter->SystemConfigPara()->setLastLimitCommandSuccess(CMD_NOK);
|
||||
}
|
||||
@ -12,6 +12,8 @@ typedef enum { // ToDo: to be verified by field tests
|
||||
class ActivePowerControlCommand : public DevControlCommand {
|
||||
public:
|
||||
ActivePowerControlCommand(uint64_t target_address = 0, uint64_t router_address = 0);
|
||||
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
|
||||
virtual void gotTimeout(InverterAbstract* inverter);
|
||||
|
||||
void setActivePowerLimit(float limit, PowerLimitControlType type = RelativNonPersistent);
|
||||
float getLimit();
|
||||
|
||||
@ -100,3 +100,7 @@ void CommandAbstract::convertSerialToPacketId(uint8_t buffer[], uint64_t serial)
|
||||
buffer[1] = s.b[2];
|
||||
buffer[0] = s.b[3];
|
||||
}
|
||||
|
||||
void CommandAbstract::gotTimeout(InverterAbstract* inverter)
|
||||
{
|
||||
}
|
||||
@ -37,6 +37,7 @@ public:
|
||||
virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no);
|
||||
|
||||
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0;
|
||||
virtual void gotTimeout(InverterAbstract* inverter);
|
||||
|
||||
protected:
|
||||
uint8_t _payload[RF_LEN];
|
||||
|
||||
@ -24,5 +24,11 @@ bool SystemConfigParaCommand::handleResponse(InverterAbstract* inverter, fragmen
|
||||
offs += (fragment[i].len);
|
||||
}
|
||||
inverter->SystemConfigPara()->setLastUpdate(millis());
|
||||
inverter->SystemConfigPara()->setLastLimitRequestSuccess(CMD_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SystemConfigParaCommand::gotTimeout(InverterAbstract* inverter)
|
||||
{
|
||||
inverter->SystemConfigPara()->setLastLimitRequestSuccess(CMD_NOK);
|
||||
}
|
||||
@ -7,4 +7,5 @@ public:
|
||||
explicit SystemConfigParaCommand(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);
|
||||
virtual void gotTimeout(InverterAbstract* inverter);
|
||||
};
|
||||
@ -86,18 +86,28 @@ bool HM_Abstract::sendSystemConfigParaRequest(HoymilesRadio* radio)
|
||||
SystemConfigParaCommand* cmd = radio->enqueCommand<SystemConfigParaCommand>();
|
||||
cmd->setTime(now);
|
||||
cmd->setTargetAddress(serial());
|
||||
SystemConfigPara()->setLastLimitRequestSuccess(CMD_PENDING);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type)
|
||||
{
|
||||
_activePowerControlLimit = limit;
|
||||
_activePowerControlType = type;
|
||||
|
||||
ActivePowerControlCommand* cmd = radio->enqueCommand<ActivePowerControlCommand>();
|
||||
cmd->setActivePowerLimit(limit, type);
|
||||
cmd->setTargetAddress(serial());
|
||||
SystemConfigPara()->setLastLimitCommandSuccess(CMD_PENDING);
|
||||
|
||||
// request updated limits
|
||||
sendSystemConfigParaRequest(radio);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HM_Abstract::resendActivePowerControlRequest(HoymilesRadio* radio)
|
||||
{
|
||||
return sendActivePowerControlRequest(radio, _activePowerControlLimit, _activePowerControlType);
|
||||
}
|
||||
@ -10,7 +10,10 @@ public:
|
||||
bool sendDevInfoRequest(HoymilesRadio* radio);
|
||||
bool sendSystemConfigParaRequest(HoymilesRadio* radio);
|
||||
bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type);
|
||||
bool resendActivePowerControlRequest(HoymilesRadio* radio);
|
||||
|
||||
private:
|
||||
uint8_t _lastAlarmLogCnt = 0;
|
||||
float _activePowerControlLimit = 0;
|
||||
PowerLimitControlType _activePowerControlType = PowerLimitControlType::AbsolutNonPersistent;
|
||||
};
|
||||
@ -110,7 +110,13 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
|
||||
// All missing
|
||||
if (_rxFragmentLastPacketId == 0) {
|
||||
Serial.println(F("All missing"));
|
||||
return FRAGMENT_ALL_MISSING;
|
||||
if (cmd->getSendCount() <= MAX_RESEND_COUNT) {
|
||||
return FRAGMENT_ALL_MISSING_RESEND;
|
||||
}
|
||||
else {
|
||||
cmd->gotTimeout(this);
|
||||
return FRAGMENT_ALL_MISSING_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
// Last fragment is missing (thte one with 0x80)
|
||||
@ -119,6 +125,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
|
||||
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
|
||||
return _rxFragmentLastPacketId + 1;
|
||||
} else {
|
||||
cmd->gotTimeout(this);
|
||||
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
@ -130,12 +137,14 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
|
||||
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
|
||||
return i + 1;
|
||||
} else {
|
||||
cmd->gotTimeout(this);
|
||||
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId)) {
|
||||
cmd->gotTimeout(this);
|
||||
return FRAGMENT_HANDLE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -13,14 +13,16 @@
|
||||
#define MAX_NAME_LENGTH 32
|
||||
|
||||
enum {
|
||||
FRAGMENT_ALL_MISSING = 255,
|
||||
FRAGMENT_RETRANSMIT_TIMEOUT = 254,
|
||||
FRAGMENT_HANDLE_ERROR = 253,
|
||||
FRAGMENT_ALL_MISSING_RESEND = 255,
|
||||
FRAGMENT_ALL_MISSING_TIMEOUT = 254,
|
||||
FRAGMENT_RETRANSMIT_TIMEOUT = 253,
|
||||
FRAGMENT_HANDLE_ERROR = 252,
|
||||
FRAGMENT_OK = 0
|
||||
};
|
||||
|
||||
#define MAX_RF_FRAGMENT_COUNT 13
|
||||
#define MAX_RETRANSMIT_COUNT 5
|
||||
#define MAX_RETRANSMIT_COUNT 5 // Used to send the retransmit package
|
||||
#define MAX_RESEND_COUNT 4 // Used if all packages are missing
|
||||
|
||||
class CommandAbstract;
|
||||
|
||||
@ -44,6 +46,7 @@ public:
|
||||
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;
|
||||
|
||||
AlarmLogParser* EventLog();
|
||||
DevInfoParser* DevInfo();
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
typedef enum {
|
||||
CMD_OK,
|
||||
CMD_NOK,
|
||||
CMD_PENDING
|
||||
} LastCommandSuccess;
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
uint32_t getLastUpdate();
|
||||
|
||||
@ -21,3 +21,23 @@ float SystemConfigParaParser::getLimitPercent()
|
||||
{
|
||||
return ((((uint16_t)_payload[2]) << 8) | _payload[3]) / 10;
|
||||
}
|
||||
|
||||
void SystemConfigParaParser::setLastLimitCommandSuccess(LastCommandSuccess status)
|
||||
{
|
||||
_lastLimitCommandSuccess = status;
|
||||
}
|
||||
|
||||
LastCommandSuccess SystemConfigParaParser::getLastLimitCommandSuccess()
|
||||
{
|
||||
return _lastLimitCommandSuccess;
|
||||
}
|
||||
|
||||
void SystemConfigParaParser::setLastLimitRequestSuccess(LastCommandSuccess status)
|
||||
{
|
||||
_lastLimitRequestSuccess = status;
|
||||
}
|
||||
|
||||
LastCommandSuccess SystemConfigParaParser::getLastLimitRequestSuccess()
|
||||
{
|
||||
return _lastLimitRequestSuccess;
|
||||
}
|
||||
@ -11,7 +11,16 @@ public:
|
||||
|
||||
float getLimitPercent();
|
||||
|
||||
void setLastLimitCommandSuccess(LastCommandSuccess status);
|
||||
LastCommandSuccess getLastLimitCommandSuccess();
|
||||
|
||||
void setLastLimitRequestSuccess(LastCommandSuccess status);
|
||||
LastCommandSuccess getLastLimitRequestSuccess();
|
||||
|
||||
private:
|
||||
uint8_t _payload[SYSTEM_CONFIG_PARA_SIZE];
|
||||
uint8_t _payloadLength;
|
||||
|
||||
LastCommandSuccess _lastLimitCommandSuccess = CMD_OK; // Set to OK because we have to assume nothing is done at startup
|
||||
LastCommandSuccess _lastLimitRequestSuccess = CMD_NOK; // Set to NOK to fetch at startup
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user