Skip to content

Refresh cstate.endTime when active schedule window advances (closes #1192)#1193

Open
pawmmm wants to merge 1 commit into
tagyoureit:masterfrom
pawmmm:fix/master/schedule-rollover-stale-endtime
Open

Refresh cstate.endTime when active schedule window advances (closes #1192)#1193
pawmmm wants to merge 1 commit into
tagyoureit:masterfrom
pawmmm:fix/master/schedule-rollover-stale-endtime

Conversation

@pawmmm
Copy link
Copy Markdown

@pawmmm pawmmm commented May 22, 2026

Summary

  • SystemBoard.syncScheduleStates: also refresh cstate.endTime when an active schedule's scheduleTime.endTime has advanced past the cached cstate.endTime (previously only happened on schedIsOn transitions, which never occur for continuous 24-hour schedules).
  • IntelliCenterBoard.syncScheduleStates: fix circs.push; (method-reference, no-op) → circs.push(c); so the existing refresh loop actually runs.

Both edits are about the same class of bug — a stale cstate.endTime after the schedule's window rolls forward — observed in production on Nixie and dead-coded on IntelliCenter.

Reference issue

Closes #1192 — full trace and a real-world journal excerpt are in the issue.

Short version: a 12:00 AM → 12:00 AM continuous schedule on a Nixie filter pump caused checkCircuitEggTimerExpirationAsync to fire the morning after midnight (~00:01:02), with the pump then staying off ~6.5 hours until the user manually re-armed it. The schedule's own shouldBeOn was correctly true throughout; the off-event came from comparing the live time against the previous day's stale cstate.endTime.

Test plan

  • tsc --noEmit passes (baseline clean before, still clean after).
  • Manual / Nixie: configure a single 12:00 AM → 12:00 AM schedule on a filter pump circuit (all 7 days), confirm the circuit stays on across multiple midnight rollovers and no NCP: Setting Circuit ... to false lines appear in the journal at 00:0X.
  • Manual / IntelliCenter: verify cstate.endTime updates within ~10s of a schedule edit that changes the endTime (previously this path was a no-op due to the circs.push; typo).

Risk

The new branch in SystemBoard only fires when:

  • the schedule is currently on (schedIsOn === true), AND
  • the circuit is currently on (scirc.isOn === true), AND
  • both scirc.endTime and ssched.scheduleTime.endTime are defined, AND
  • the schedule's endTime is strictly greater than scirc.endTime (i.e. the cached value is genuinely stale).

It calls the same setEndTime path that the existing transition branch uses, just under a different precondition. The IntelliCenter change is a one-character fix to a loop that was previously dead — so its behavior change is just "the loop runs as originally intended."

Out of scope (documented in #1192)

Once this lands, the secondary "stuck ssched.triggered" behavior in controller/nixie/schedules/Schedule.ts:120-188 becomes moot for the continuous-schedule case — the egg-timer expiration no longer fires, so the schedule never needs to re-arm itself after a spurious off. Whether the trigger loop should also re-arm after an external off-event is tangled with Manual OP semantics; happy to file as a follow-up if maintainers want it addressed separately.

Two related fixes to the cstate.endTime refresh path so that
checkCircuitEggTimerExpirationAsync does not force-turn-off a circuit
whose schedule is still active.

SystemBoard.syncScheduleStates previously called setEndTime only when
schedIsOn != ssched.isOn.  For a continuously-active schedule (e.g.
a 12:00 AM -> 12:00 AM window) that transition never happens at the
local midnight rollover, so cstate.endTime froze at the previous day's
value while ssched.scheduleTime.endTime advanced.  Within ~1 minute
after midnight the circuit was being turned off in error.  Now we also
refresh when the schedule is still on, the circuit is still on, and
the schedule's endTime has advanced past the cached cstate.endTime.

IntelliCenterBoard.syncScheduleStates had `circs.push;` (a reference to
the method, not a call) at line 4817, so the array stayed empty and
the subsequent refresh loop never ran.  Same intent, same bug class.

Fixes tagyoureit#1192
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nixie continuous schedule: circuit force-turned-off ~1 minute after local midnight due to stale cstate.endTime

1 participant