Spaces:
Running
Running
| from __future__ import annotations | |
| import json | |
| import time | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| from modules.display_control import set_brightness | |
| ROOT = Path(__file__).resolve().parents[1] | |
| SCHEDULE_PATH = ROOT / "data" / "brightness_schedule.json" | |
| class ScheduleItem: | |
| at: str # "HH:MM" 24h | |
| value: int | |
| def _load_schedule() -> list[ScheduleItem]: | |
| if not SCHEDULE_PATH.exists(): | |
| SCHEDULE_PATH.parent.mkdir(parents=True, exist_ok=True) | |
| SCHEDULE_PATH.write_text( | |
| json.dumps( | |
| { | |
| "enabled": True, | |
| "items": [ | |
| {"at": "07:00", "value": 80}, | |
| {"at": "22:00", "value": 30}, | |
| ], | |
| }, | |
| indent=2, | |
| ), | |
| encoding="utf-8", | |
| ) | |
| try: | |
| data = json.loads(SCHEDULE_PATH.read_text(encoding="utf-8")) | |
| except Exception: | |
| return [] | |
| if not bool(data.get("enabled", True)): | |
| return [] | |
| items = [] | |
| for it in data.get("items", []): | |
| at = str(it.get("at", "")).strip() | |
| if not at or ":" not in at: | |
| continue | |
| try: | |
| v = int(it.get("value", 50)) | |
| except Exception: | |
| v = 50 | |
| items.append(ScheduleItem(at=at, value=max(0, min(100, v)))) | |
| return sorted(items, key=lambda x: x.at) | |
| def run_loop(poll_seconds: int = 20) -> None: | |
| """Background scheduler. Applies brightness at the matching minute boundary.""" | |
| last_minute = "" | |
| while True: | |
| items = _load_schedule() | |
| if not items: | |
| time.sleep(max(5, int(poll_seconds))) | |
| continue | |
| now = time.localtime() | |
| minute = f"{now.tm_hour:02d}:{now.tm_min:02d}" | |
| if minute != last_minute: | |
| last_minute = minute | |
| for it in items: | |
| if it.at == minute: | |
| set_brightness(it.value) | |
| break | |
| time.sleep(max(5, int(poll_seconds))) | |