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:
14
main.go
14
main.go
@@ -361,8 +361,10 @@ func runCycle(
|
||||
return
|
||||
}
|
||||
|
||||
if err := act.Execute(ctx, actions); err != nil {
|
||||
logger.Error("execution failed", "error", err)
|
||||
for i, err := range act.Execute(ctx, actions) {
|
||||
if err != nil {
|
||||
eng.RollbackAction(actions[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,8 +522,8 @@ func wwResetHandler(act *actuator.Actuator, eng *engine.Engine, cfg *config.Conf
|
||||
TargetTempC: cfg.Strategic.WWBaseC,
|
||||
Reason: "manual WW reset via web UI",
|
||||
}
|
||||
if err := act.Execute(ctx, []engine.Action{action}); err != nil {
|
||||
logger.Error("WW reset: actuator failed", "error", err)
|
||||
if errs := act.Execute(ctx, []engine.Action{action}); errs[0] != nil {
|
||||
logger.Error("WW reset: actuator failed", "error", errs[0])
|
||||
} else {
|
||||
logger.Info("WW boost reset", "base_c", cfg.Strategic.WWBaseC, "locked_until", midnight.Format("15:04"))
|
||||
}
|
||||
@@ -611,8 +613,8 @@ func overrideHandler(act *actuator.Actuator, eng *engine.Engine, logger *slog.Lo
|
||||
TurnOn: turnOn,
|
||||
Reason: fmt.Sprintf("manual override via web UI (%s)", duration),
|
||||
}
|
||||
if err := act.Execute(ctx, []engine.Action{action}); err != nil {
|
||||
logger.Error("web UI override failed", "consumer", consumerKey, "state", stateVal, "error", err)
|
||||
if errs := act.Execute(ctx, []engine.Action{action}); errs[0] != nil {
|
||||
logger.Error("web UI override failed", "consumer", consumerKey, "state", stateVal, "error", errs[0])
|
||||
http.Error(w, "switch failed — check logs", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user