Add time-based screen scheduling (e.g. Journey every morning 6-8)
New "Time-based schedule" section on the Rotation settings page: up to
4 rules, each a screen + a daily HH:MM-HH:MM window (crossing midnight
is fine, e.g. 22:00-02:00). While a rule's window is active, that
screen overrides rotation and any manual pin -- without touching
either's underlying state, so things go back to exactly how they were
once the window ends. Navidrome-playing still wins on top of a
schedule rule, same as it already does over everything else.
config.py: new schedules list (get_schedules/set_schedules), each rule
just {screen_id, start, end} -- being in the list *is* being enabled,
no separate flag (a settings row is "disabled" by leaving its screen
dropdown on "-- none --").
scheduler.py: _time_in_window() handles same-day and midnight-wrapping
windows, treats a zero-width window as never-matching (more likely a
blank settings row than an intentional all-day rule).
_active_scheduled_screen() slots into _select_screen() between
Navidrome-priority and the pin/rotation fallback.
Verified: unit tests for _time_in_window's edge cases (wraparound,
zero-width, malformed input) and the priority override, plus an
end-to-end run against the real app -- pinned a screen, added a rule
active right now, confirmed the status page switched to the scheduled
screen within one tick.
This commit is contained in:
1 parent
33b964f1f6
commit
9aacd4936a
5 files changed
+103
-3
No files matched your search
@@ -43,6 +43,7 @@ class Config:
|
||||
data["rotation"].setdefault("enabled", DEFAULT_ROTATION["enabled"])
|
||||
data.setdefault("navidrome_priority", True)
|
||||
data.setdefault("pinned_screen", None)
|
||||
data.setdefault("schedules", [])
|
||||
data.setdefault("settings", {})
|
||||
for screen_id, screen in screens.items():
|
||||
data["settings"].setdefault(screen_id, {})
|
||||
@@ -108,6 +109,22 @@ class Config:
|
||||
self._data["pinned_screen"] = None
|
||||
self.save()
|
||||
|
||||
# ----------------------------------------------------------- schedules
|
||||
|
||||
def get_schedules(self) -> list[dict]:
|
||||
"""Each rule: {"screen_id", "start", "end"} with start/end as
|
||||
"HH:MM" local time. A rule being in this list *is* it being
|
||||
enabled -- there's no separate flag, disabling one is just removing
|
||||
it (the settings form does this by leaving its screen dropdown on
|
||||
"-- none --")."""
|
||||
with self._lock:
|
||||
return list(self._data["schedules"])
|
||||
|
||||
def set_schedules(self, schedules: list[dict]) -> None:
|
||||
with self._lock:
|
||||
self._data["schedules"] = schedules
|
||||
self.save()
|
||||
|
||||
def get_navidrome_priority(self) -> bool:
|
||||
with self._lock:
|
||||
return bool(self._data["navidrome_priority"])
|
||||
|
||||
Reference in new issue
Block a user