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());
|
iv->sendAlarmLogRequest(_radio.get());
|
||||||
|
|
||||||
// Fetch limit
|
// 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");
|
Serial.println("Request SystemConfigPara");
|
||||||
iv->sendSystemConfigParaRequest(_radio.get());
|
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)
|
// Fetch dev info (but first fetch stats)
|
||||||
if (iv->Statistics()->getLastUpdate() > 0 && (iv->DevInfo()->getLastUpdateAll() == 0 || iv->DevInfo()->getLastUpdateSample() == 0)) {
|
if (iv->Statistics()->getLastUpdate() > 0 && (iv->DevInfo()->getLastUpdateAll() == 0 || iv->DevInfo()->getLastUpdateSample() == 0)) {
|
||||||
Serial.println(F("Request device info"));
|
Serial.println(F("Request device info"));
|
||||||
|
|||||||
@ -91,15 +91,14 @@ void HoymilesRadio::loop()
|
|||||||
if (nullptr != inv) {
|
if (nullptr != inv) {
|
||||||
CommandAbstract* cmd = _commandQueue.front().get();
|
CommandAbstract* cmd = _commandQueue.front().get();
|
||||||
uint8_t verifyResult = inv->verifyAllFragments(cmd);
|
uint8_t verifyResult = inv->verifyAllFragments(cmd);
|
||||||
if (verifyResult == FRAGMENT_ALL_MISSING) {
|
if (verifyResult == FRAGMENT_ALL_MISSING_RESEND) {
|
||||||
if (_commandQueue.front().get()->getSendCount() <= MAX_RESEND_COUNT) {
|
Serial.println(F("Nothing received, resend whole request"));
|
||||||
Serial.println(F("Nothing received, resend whole request"));
|
sendLastPacketAgain();
|
||||||
sendLastPacketAgain();
|
|
||||||
} else {
|
} else if (verifyResult == FRAGMENT_ALL_MISSING_TIMEOUT) {
|
||||||
Serial.println(F("Nothing received, resend count exeeded"));
|
Serial.println(F("Nothing received, resend count exeeded"));
|
||||||
_commandQueue.pop();
|
_commandQueue.pop();
|
||||||
_busyFlag = false;
|
_busyFlag = false;
|
||||||
}
|
|
||||||
|
|
||||||
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
|
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
|
||||||
Serial.println(F("Retransmit timeout"));
|
Serial.println(F("Retransmit timeout"));
|
||||||
|
|||||||
@ -12,8 +12,6 @@
|
|||||||
// number of fragments hold in buffer
|
// number of fragments hold in buffer
|
||||||
#define FRAGMENT_BUFFER_SIZE 30
|
#define FRAGMENT_BUFFER_SIZE 30
|
||||||
|
|
||||||
#define MAX_RESEND_COUNT 4
|
|
||||||
|
|
||||||
#ifndef HOYMILES_PIN_MISO
|
#ifndef HOYMILES_PIN_MISO
|
||||||
#define HOYMILES_PIN_MISO 19
|
#define HOYMILES_PIN_MISO 19
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "ActivePowerControlCommand.h"
|
#include "ActivePowerControlCommand.h"
|
||||||
|
#include "inverters/InverterAbstract.h"
|
||||||
|
|
||||||
#define CRC_SIZE 6
|
#define CRC_SIZE 6
|
||||||
|
|
||||||
@ -34,6 +35,16 @@ void ActivePowerControlCommand::setActivePowerLimit(float limit, PowerLimitContr
|
|||||||
udpateCRC(CRC_SIZE);
|
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()
|
float ActivePowerControlCommand::getLimit()
|
||||||
{
|
{
|
||||||
uint16_t l = (((uint16_t)_payload[12] << 8) | _payload[13]);
|
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]);
|
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 {
|
class ActivePowerControlCommand : public DevControlCommand {
|
||||||
public:
|
public:
|
||||||
ActivePowerControlCommand(uint64_t target_address = 0, uint64_t router_address = 0);
|
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);
|
void setActivePowerLimit(float limit, PowerLimitControlType type = RelativNonPersistent);
|
||||||
float getLimit();
|
float getLimit();
|
||||||
|
|||||||
@ -99,4 +99,8 @@ void CommandAbstract::convertSerialToPacketId(uint8_t buffer[], uint64_t serial)
|
|||||||
buffer[2] = s.b[1];
|
buffer[2] = s.b[1];
|
||||||
buffer[1] = s.b[2];
|
buffer[1] = s.b[2];
|
||||||
buffer[0] = s.b[3];
|
buffer[0] = s.b[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandAbstract::gotTimeout(InverterAbstract* inverter)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
@ -37,6 +37,7 @@ public:
|
|||||||
virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no);
|
virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no);
|
||||||
|
|
||||||
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0;
|
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0;
|
||||||
|
virtual void gotTimeout(InverterAbstract* inverter);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t _payload[RF_LEN];
|
uint8_t _payload[RF_LEN];
|
||||||
|
|||||||
@ -24,5 +24,11 @@ bool SystemConfigParaCommand::handleResponse(InverterAbstract* inverter, fragmen
|
|||||||
offs += (fragment[i].len);
|
offs += (fragment[i].len);
|
||||||
}
|
}
|
||||||
inverter->SystemConfigPara()->setLastUpdate(millis());
|
inverter->SystemConfigPara()->setLastUpdate(millis());
|
||||||
|
inverter->SystemConfigPara()->setLastLimitRequestSuccess(CMD_OK);
|
||||||
return true;
|
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);
|
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 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>();
|
SystemConfigParaCommand* cmd = radio->enqueCommand<SystemConfigParaCommand>();
|
||||||
cmd->setTime(now);
|
cmd->setTime(now);
|
||||||
cmd->setTargetAddress(serial());
|
cmd->setTargetAddress(serial());
|
||||||
|
SystemConfigPara()->setLastLimitRequestSuccess(CMD_PENDING);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type)
|
bool HM_Abstract::sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type)
|
||||||
{
|
{
|
||||||
|
_activePowerControlLimit = limit;
|
||||||
|
_activePowerControlType = type;
|
||||||
|
|
||||||
ActivePowerControlCommand* cmd = radio->enqueCommand<ActivePowerControlCommand>();
|
ActivePowerControlCommand* cmd = radio->enqueCommand<ActivePowerControlCommand>();
|
||||||
cmd->setActivePowerLimit(limit, type);
|
cmd->setActivePowerLimit(limit, type);
|
||||||
cmd->setTargetAddress(serial());
|
cmd->setTargetAddress(serial());
|
||||||
|
SystemConfigPara()->setLastLimitCommandSuccess(CMD_PENDING);
|
||||||
|
|
||||||
// request updated limits
|
// request updated limits
|
||||||
sendSystemConfigParaRequest(radio);
|
sendSystemConfigParaRequest(radio);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HM_Abstract::resendActivePowerControlRequest(HoymilesRadio* radio)
|
||||||
|
{
|
||||||
|
return sendActivePowerControlRequest(radio, _activePowerControlLimit, _activePowerControlType);
|
||||||
}
|
}
|
||||||
@ -10,7 +10,10 @@ public:
|
|||||||
bool sendDevInfoRequest(HoymilesRadio* radio);
|
bool sendDevInfoRequest(HoymilesRadio* radio);
|
||||||
bool sendSystemConfigParaRequest(HoymilesRadio* radio);
|
bool sendSystemConfigParaRequest(HoymilesRadio* radio);
|
||||||
bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type);
|
bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type);
|
||||||
|
bool resendActivePowerControlRequest(HoymilesRadio* radio);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _lastAlarmLogCnt = 0;
|
uint8_t _lastAlarmLogCnt = 0;
|
||||||
|
float _activePowerControlLimit = 0;
|
||||||
|
PowerLimitControlType _activePowerControlType = PowerLimitControlType::AbsolutNonPersistent;
|
||||||
};
|
};
|
||||||
@ -110,7 +110,13 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
|
|||||||
// All missing
|
// All missing
|
||||||
if (_rxFragmentLastPacketId == 0) {
|
if (_rxFragmentLastPacketId == 0) {
|
||||||
Serial.println(F("All missing"));
|
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)
|
// Last fragment is missing (thte one with 0x80)
|
||||||
@ -119,6 +125,7 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
|
|||||||
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
|
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
|
||||||
return _rxFragmentLastPacketId + 1;
|
return _rxFragmentLastPacketId + 1;
|
||||||
} else {
|
} else {
|
||||||
|
cmd->gotTimeout(this);
|
||||||
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,12 +137,14 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
|
|||||||
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
|
if (_rxFragmentRetransmitCnt++ < MAX_RETRANSMIT_COUNT) {
|
||||||
return i + 1;
|
return i + 1;
|
||||||
} else {
|
} else {
|
||||||
|
cmd->gotTimeout(this);
|
||||||
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
return FRAGMENT_RETRANSMIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId)) {
|
if (!cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId)) {
|
||||||
|
cmd->gotTimeout(this);
|
||||||
return FRAGMENT_HANDLE_ERROR;
|
return FRAGMENT_HANDLE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,14 +13,16 @@
|
|||||||
#define MAX_NAME_LENGTH 32
|
#define MAX_NAME_LENGTH 32
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FRAGMENT_ALL_MISSING = 255,
|
FRAGMENT_ALL_MISSING_RESEND = 255,
|
||||||
FRAGMENT_RETRANSMIT_TIMEOUT = 254,
|
FRAGMENT_ALL_MISSING_TIMEOUT = 254,
|
||||||
FRAGMENT_HANDLE_ERROR = 253,
|
FRAGMENT_RETRANSMIT_TIMEOUT = 253,
|
||||||
|
FRAGMENT_HANDLE_ERROR = 252,
|
||||||
FRAGMENT_OK = 0
|
FRAGMENT_OK = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_RF_FRAGMENT_COUNT 13
|
#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;
|
class CommandAbstract;
|
||||||
|
|
||||||
@ -44,6 +46,7 @@ public:
|
|||||||
virtual bool sendDevInfoRequest(HoymilesRadio* radio) = 0;
|
virtual bool sendDevInfoRequest(HoymilesRadio* radio) = 0;
|
||||||
virtual bool sendSystemConfigParaRequest(HoymilesRadio* radio) = 0;
|
virtual bool sendSystemConfigParaRequest(HoymilesRadio* radio) = 0;
|
||||||
virtual bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type) = 0;
|
virtual bool sendActivePowerControlRequest(HoymilesRadio* radio, float limit, PowerLimitControlType type) = 0;
|
||||||
|
virtual bool resendActivePowerControlRequest(HoymilesRadio* radio) = 0;
|
||||||
|
|
||||||
AlarmLogParser* EventLog();
|
AlarmLogParser* EventLog();
|
||||||
DevInfoParser* DevInfo();
|
DevInfoParser* DevInfo();
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CMD_OK,
|
||||||
|
CMD_NOK,
|
||||||
|
CMD_PENDING
|
||||||
|
} LastCommandSuccess;
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
uint32_t getLastUpdate();
|
uint32_t getLastUpdate();
|
||||||
|
|||||||
@ -20,4 +20,24 @@ void SystemConfigParaParser::appendFragment(uint8_t offset, uint8_t* payload, ui
|
|||||||
float SystemConfigParaParser::getLimitPercent()
|
float SystemConfigParaParser::getLimitPercent()
|
||||||
{
|
{
|
||||||
return ((((uint16_t)_payload[2]) << 8) | _payload[3]) / 10;
|
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();
|
float getLimitPercent();
|
||||||
|
|
||||||
|
void setLastLimitCommandSuccess(LastCommandSuccess status);
|
||||||
|
LastCommandSuccess getLastLimitCommandSuccess();
|
||||||
|
|
||||||
|
void setLastLimitRequestSuccess(LastCommandSuccess status);
|
||||||
|
LastCommandSuccess getLastLimitRequestSuccess();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _payload[SYSTEM_CONFIG_PARA_SIZE];
|
uint8_t _payload[SYSTEM_CONFIG_PARA_SIZE];
|
||||||
uint8_t _payloadLength;
|
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