DPL: check more requirements and fix backoff initialization (#290)
* DPL: wait for valid time information we know that the Hoymiles library refuses to send any message to any inverter until the system has valid time information. until then we can do nothing, not even shutdown the inverter. * DPL: wait for device info to be ready a calculated power limit will always be limited to the reported device's max power. that upper limit is only known after the first DevInfoSimpleCommand succeeded. wait for that information to be available. * DPL: fix initial calculcation backoff if the calculation backoff is initialized to zero, the backoff will be doubled to zero until a new, different power limit was calculated for the first time. this lead to the DPL recalculating a power limit hundreds of times without a backoff after startup.
This commit is contained in:
parent
e457ab73f9
commit
107182f948
@ -28,6 +28,7 @@ public:
|
||||
Initializing,
|
||||
DisabledByConfig,
|
||||
DisabledByMqtt,
|
||||
WaitingForValidTimestamp,
|
||||
PowerMeterDisabled,
|
||||
PowerMeterTimeout,
|
||||
PowerMeterPending,
|
||||
@ -37,6 +38,7 @@ public:
|
||||
InverterCommandsDisabled,
|
||||
InverterLimitPending,
|
||||
InverterPowerCmdPending,
|
||||
InverterDevInfoPending,
|
||||
InverterStatsPending,
|
||||
UnconditionalSolarPassthrough,
|
||||
NoVeDirect,
|
||||
@ -59,7 +61,8 @@ private:
|
||||
Status _lastStatus = Status::Initializing;
|
||||
uint32_t _lastStatusPrinted = 0;
|
||||
uint32_t _lastCalculation = 0;
|
||||
uint32_t _calculationBackoffMs = 0;
|
||||
static constexpr uint32_t _calculationBackoffMsDefault = 128;
|
||||
uint32_t _calculationBackoffMs = _calculationBackoffMsDefault;
|
||||
uint8_t _mode = PL_MODE_ENABLE_NORMAL_OP;
|
||||
std::shared_ptr<InverterAbstract> _inverter = nullptr;
|
||||
bool _batteryDischargeEnabled = false;
|
||||
|
||||
@ -30,6 +30,7 @@ std::string const& PowerLimiterClass::getStatusText(PowerLimiterClass::Status st
|
||||
{ Status::Initializing, "initializing (should not see me)" },
|
||||
{ Status::DisabledByConfig, "disabled by configuration" },
|
||||
{ Status::DisabledByMqtt, "disabled by MQTT" },
|
||||
{ Status::WaitingForValidTimestamp, "waiting for valid date and time to be available" },
|
||||
{ Status::PowerMeterDisabled, "no power meter is configured/enabled" },
|
||||
{ Status::PowerMeterTimeout, "power meter readings are outdated" },
|
||||
{ Status::PowerMeterPending, "waiting for sufficiently recent power meter reading" },
|
||||
@ -39,6 +40,7 @@ std::string const& PowerLimiterClass::getStatusText(PowerLimiterClass::Status st
|
||||
{ Status::InverterCommandsDisabled, "inverter configuration prohibits sending commands" },
|
||||
{ Status::InverterLimitPending, "waiting for a power limit command to complete" },
|
||||
{ Status::InverterPowerCmdPending, "waiting for a start/stop/restart command to complete" },
|
||||
{ Status::InverterDevInfoPending, "waiting for inverter device information to be available" },
|
||||
{ Status::InverterStatsPending, "waiting for sufficiently recent inverter data" },
|
||||
{ Status::UnconditionalSolarPassthrough, "unconditionally passing through all solar power (MQTT override)" },
|
||||
{ Status::NoVeDirect, "VE.Direct disabled, connection broken, or data outdated" },
|
||||
@ -97,6 +99,14 @@ void PowerLimiterClass::loop()
|
||||
{
|
||||
CONFIG_T& config = Configuration.get();
|
||||
|
||||
// we know that the Hoymiles library refuses to send any message to any
|
||||
// inverter until the system has valid time information. until then we can
|
||||
// do nothing, not even shutdown the inverter.
|
||||
struct tm timeinfo;
|
||||
if (!getLocalTime(&timeinfo, 5)) {
|
||||
return announceStatus(Status::WaitingForValidTimestamp);
|
||||
}
|
||||
|
||||
if (_shutdownInProgress) {
|
||||
// we transition from SHUTDOWN to OFF when we know the inverter was
|
||||
// shut down. until then, we retry shutting it down. in this case we
|
||||
@ -152,6 +162,13 @@ void PowerLimiterClass::loop()
|
||||
return announceStatus(Status::InverterPowerCmdPending);
|
||||
}
|
||||
|
||||
// a calculated power limit will always be limited to the reported
|
||||
// device's max power. that upper limit is only known after the first
|
||||
// DevInfoSimpleCommand succeeded.
|
||||
if (_inverter->DevInfo()->getMaxPower() <= 0) {
|
||||
return announceStatus(Status::InverterDevInfoPending);
|
||||
}
|
||||
|
||||
if (PL_MODE_SOLAR_PT_ONLY == _mode) {
|
||||
// handle this mode of operation separately
|
||||
return unconditionalSolarPassthrough(_inverter);
|
||||
@ -275,7 +292,7 @@ void PowerLimiterClass::loop()
|
||||
return announceStatus(Status::Stable);
|
||||
}
|
||||
|
||||
_calculationBackoffMs = 128;
|
||||
_calculationBackoffMs = _calculationBackoffMsDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user