No reviewers
Labels
No labels
area/ai
area/backend
area/frontend
area/infra
area/scheduler
area/wled
good-first-issue
priority/high
priority/low
priority/medium
type/bug
type/chore
type/ci-cd
type/docs
type/feature
type/qa
v1.0.0
v1.1.0
v1.2.0
v2.0.0
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Iris-WLED!68
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/43-push-paths"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Wave-2 backend correctness cluster. These four issues all touch
schedule_service.py/wled_push.py/routers/wled.py, so per the #43 note they're done sequentially on one branch (4 commits, one per issue) to avoid conflicts.#43 — Wire push paths to
priority_resolver.get_events_for_dateBoth
push_today(API) and the scheduler daily push used naivemax(priority)queries, so date pins and Promote-Secondary had no runtime effect. Both now callget_events_for_date(honors date-level pins + user-event shadowing). The scheduler now resolves against the DB (pins/shadow rows don't exist in the in-memory cache), capturingprimary.idbefore the session closes.#44 — Honor the no-event
default_scheme(§5.4)New shared
resolve_no_event_statehelper used by both push paths:off→ lights-off;dim_white→ warm-white (~2700K) at the configured late-night brightness; scheme reference → validate exists+approved, else off + logged WARNING. 5 tests across all modes. (Frontend Settings control is #48; the no-event responseactionfield now carries the mode instead of the literal"lights_off".)#47 — Revert active quick push at the
onevent (§6.1)trigger_scheduler_revertwas called on dim/off but noton, so a quick push spanning theonboundary survived it. Now reverted in the shared_push_today_scheme(before pushing) — also covers the manual push-today/push-now endpoints and avoids a stale-saved-state clobber.#45 — Finish fallback policies (§5.3)
retryno longer blocks in an immediate loop — it makes one attempt then schedules 3 spaced retries (5-minDateTriggerjobs) on the existing APScheduler + persistent jobstore (picklable args → survive restart;wled_push_retryid for dedup).last_known_goodgains a 1-min reconnect watcher that pushes the expected state once on reconnect then removes its own job.push_failedwebhook is now owned bywled_pushand fires only after the final retry; callers updated (_raise_on_failed_pushis raise-only).PushResultgainsretry_scheduled.Verification
Backend
ruff check/ruff format --check/mypy app/clean;pytest217 passed locally (the only 2 errors are pre-existing Windows-onlytest_backup.pyfile-lockingPermissionErrors — they pass on the Linux CI runner). New tests:test_push_resolution.py,test_no_event_default.py,test_scheduler.py(on-revert),test_wled_fallback.py.Closes #43, closes #44, closes #47, closes #45.
🤖 Generated with Claude Code
The API push (routers/wled.py::push_today) and scheduler daily push (services/schedule_service.py::_push_today_scheme) resolved today's event with naive max(priority) queries, so date-level pins ("Promote Secondary") and user-event shadowing had no runtime effect on the controller. Both paths now call priority_resolver.get_events_for_date, which honors date_overrides pins and parent-event shadowing. Behavior around scheme selection, phase resolution, logging, audit, and webhooks is preserved. The scheduler now resolves against the DB (inside its existing session) instead of the in-memory event cache, since pins/shadowing live in the DB. Adds tests proving the wiring: a pin via PUT /event-date-overrides/{date} changes what POST /wled/push sends, and a user-event override shadows its parent in the scheduler push path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Both push paths previously pushed unconditional lights-off on days with no matching event, ignoring the configured default_scheme runtime setting. Adds a shared helper, no_event_resolver.resolve_no_event_state(db, runtime) -> (wled_state, reason), that maps default_scheme to a WLED state: - None / "off" -> lights_off_state() (reason "no_event") - "dim_white" -> warm-white ambient at (reason "default_dim_white") late-night brightness - "<scheme id>" -> that saved scheme, if it (reason "default_scheme") exists and is approved A missing/unapproved scheme reference logs a WARNING and falls back to lights-off, mirroring how the normal push path guards scheme availability. The no-event branch of routers/wled.py::push_today and services/schedule_service.py::_push_today_scheme now use this helper; the resolved reason flows into the return dict / audit / webhook context. Adds scheme_translator.dim_white_state + WARM_WHITE_RGB for the ambient state. Tests cover all three modes plus the invalid- and unapproved-reference fallbacks end-to-end through POST /wled/push. Frontend Settings control for default_scheme is tracked separately in #48 and is intentionally untouched here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>