# Pi Servers -- Roadmap ## Alarm Configuration Replace the current `randint(30, 60)` test loop in `contents_server.py` with real schedule-driven alarms. ### Config schema File: `pi/alarm_config.json` ```json { "alarm_time": "0700", "alarm_days": ["Mon", "Tue", "Wed", "Thu", "Fri"], "alarm_dates": ["07/20", "10/21"], "alarm_audio": "assets/alarm/alarm_test.wav", "alarm_image": "assets/img/on_alarm.png" } ``` ### Field definitions | Field | Type | Description | |-------|------|-------------| | `alarm_time` | `string` | 4-digit HHMM (24-hour). Triggers on the 0th second of the minute, or as soon as Python detects it. | | `alarm_days` | `string[]` | (Optional) 3-letter day abbreviations: `Mon`, `Tue`, `Wed`, `Thu`, `Fri`, `Sat`, `Sun`. Alarm only fires on listed days. If not supplied, alarms every day. | | `alarm_dates` | `string[]` | (Optional) Strings of `MM/DD` format. If both `alarm_days` and `alarm_dates` are set, only `alarm_days` is effective. | | `alarm_audio` | `string` | Path to WAV file. Relative paths resolve from `pi/`. | | `alarm_image` | `string` | Path to status PNG shown during alarm. Relative paths resolve from `pi/`. If not supplied, default to `assets/img/on_alarm.png` | ### Behavior - On startup, load and validate `alarm_config.json` - Each tick (~5s), check if current local time matches `alarm_time` and today's day name is in `alarm_days`, or if today's date is in `alarm_dates`. - Fire alarm once per matched minute (debounce so it doesn't re-trigger within the same minute) - After alarm completes, return to idle image and resume schedule checking ## Docker Compose Containerize the pi servers for easier deployment. ### Options 1. **Single service** -- `run_all.py` as the entrypoint, both servers in one container 2. **Split services** -- separate containers for `stats_server.py` and `contents_server.py` Single service is simpler. Split services allow independent scaling and restarts. ### Configuration - Volume mount `assets/` and `alarm_config.json` so they're editable without rebuilding - Expose ports 8765 and 8766 - Network mode `host` or a bridge with known IPs for ESP32 discovery - Restart policy: `unless-stopped` ## Repository Extraction The `pi/` directory will become its own git repository. ### Steps 1. Extract `pi/` into a standalone repo with its own `README.md`, `requirements.txt`, and CI 2. Add it back to this project as a git submodule 3. The interface contract between the two repos is the WebSocket protocol -- JSON schemas and binary frame formats documented in `docs/ALARM_PROTOCOL.md` ### Benefits - Independent versioning and release cycle - Pi-side contributors don't need the ESP-IDF toolchain - CI can test the Python servers in isolation - Cleaner separation of concerns between embedded firmware and host services