# ROADMAP Goal: a small, phone-first webpage that tells whether the laundry is done, based on the washing machine's power consumption. ## Priority 1 Objective: show the laundry status from the last 3 one-minute power samples of the Tasmota plug. ### Decided - Data source: MQTT topic `tele/tasmota_washingmashine_C21183/SENSOR` (Tasmota JSON, field `ENERGY.Power` in watts). - Broker: `192.168.1.11:1883`, no credentials assumed. Address, port, topic and credentials (optional) are configurable via env vars. - Tasmota `TelePeriod` is 10 s, so the plug publishes about 6 messages per minute. - Architecture: small Go backend, packaged in Docker (Dockerfile plus docker-compose example), deployed by the user on their own server. - Subscribes to the broker over TCP and runs continuously, whether or not any page is open. - Sampling: it keeps the most recent `ENERGY.Power` message and records one sample per minute. A minute with no message received is recorded as a missing sample. - Keeps the last 3 samples in memory. - Serves the webpage and a JSON status endpoint (e.g. `/api/status`). Status is computed on the backend, so a page load shows the correct state at once. - HTTP port is configurable, default 8080. - The page re-fetches the status every 60 s. - Status rule (threshold 3 W, strictly below means idle): | Condition | Message | Color | |---|---|---| | fewer than 3 samples since backend start | "Waiting for data..." | grey | | any of the last 3 samples is missing | "Incomplete data" | grey | | all 3 samples under 3.00 W | "Laundry done" | default text color | | otherwise (any sample 3.00 W or more) | "Laundry not yet done" | red | - Page design: - White background, status text very large (the main element), readable on phones (responsive, viewport meta, no horizontal scroll). - Below the status, the last 3 power values in normal-size black text with a `W` suffix and 2 decimals (e.g. `47.70W`). A missing sample is shown as `--`. - Access: home Wi-Fi only. No TLS or authentication in scope. - Language: English for UI text, code comments, logs, README. ### Notes - State is in memory only. After a backend restart the page shows "Waiting for data..." until 3 samples are collected (about 3 minutes). ## Priority 2 Objective: the page refreshes itself whenever a new MQTT power message arrives, instead of waiting for the 60 s poll. ### Decided - Mechanism: Server-Sent Events. New endpoint `GET /api/events` (name adjustable during planning) streams an event each time the backend receives a valid `ENERGY.Power` message (about every 10 s). - The event is only a notification. The page reacts by re-fetching `/api/status`, so the status rule, JSON contract and 1-minute sampling stay unchanged. - Readings still show the last 3 one-minute samples; they visibly change once per minute. No live-reading line is added. - Page uses `EventSource` (auto-reconnect). The 60 s poll stays as a fallback if the stream is down; on reconnect the page refreshes once. - Backend: the sampler (or MQTT handler) broadcasts to all connected SSE clients without blocking on slow clients. The HTTP `WriteTimeout` of 10 s must not kill the stream (per-route override or periodic keep-alive). - Invalid payloads do not trigger an event. - Docs: README documents the new endpoint and behavior. ### Open - None.