Fix Shelly unreachable: roll back engine state on failed actions
Without this, a failed Execute() left engine state diverged from hardware. SyncHardwareState would then misread the mismatch as a manual override and apply a 1-hour lockout — causing either a stuck-on or stuck-off loop. Now Execute() returns per-action []error. The control loop calls Engine.RollbackAction() for each failed action, keeping engine state in sync with hardware so the next cycle simply retries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -755,6 +755,34 @@ func (e *Engine) ApplyOverride(consumer Consumer, on bool, duration time.Duratio
|
||||
)
|
||||
}
|
||||
|
||||
// RollbackAction reverts the engine's internal state for an action that the actuator
|
||||
// failed to execute. Without this, the engine believes the switch happened, diverges
|
||||
// from hardware, and SyncHardwareState will misinterpret the next read-back as a
|
||||
// manual override and apply a 1-hour lockout.
|
||||
//
|
||||
// After rollback the engine state matches hardware again, so the next cycle's
|
||||
// SyncHardwareState sees no mismatch and the action is simply retried.
|
||||
func (e *Engine) RollbackAction(action Action) {
|
||||
cs, ok := e.consumers[action.Consumer]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
e.logger.Warn("rolling back engine state after failed action",
|
||||
"consumer", action.Consumer,
|
||||
"turn_on", action.TurnOn,
|
||||
)
|
||||
cs.Active = !action.TurnOn
|
||||
if action.TurnOn {
|
||||
// Turn-on failed: undo activation side-effects
|
||||
cs.ActivatedAt = time.Time{}
|
||||
cs.ProactiveCharging = false
|
||||
cs.ProbeStartGridW = 0
|
||||
cs.LowPowerCycles = 0
|
||||
}
|
||||
// Turn-off failed: just restore Active=true. ActivatedAt is preserved
|
||||
// (shutdown code doesn't reset it), so min-runtime stays correct.
|
||||
}
|
||||
|
||||
// isHeatingPeriod returns true if heating is appropriate given the current month
|
||||
// and outdoor temperature. If HeatingMinAmbientC is configured (> 0), ambient
|
||||
// temperatures above that threshold suppress SG-Ready even within the heating months.
|
||||
|
||||
Reference in New Issue
Block a user