3.1 KiB
3.1 KiB
Plan: Balcony Weather Station Dashboard
1. Project Overview
A real-time, neighborhood-facing weather dashboard that streams sensory data from an MQTT broker (Home Assistant) to a web interface.
Tech Stack
- Backend: Gleam (Target: Erlang/OTP)
- Web Server: Mist (HTTP & WebSockets)
- Database: SQLite (via
sqlight) for persistent uptime tracking - Frontend: SolidJS (Signals-based reactivity) + Tailwind CSS
- Infrastructure: Nomad (Docker-based deployment)
2. Core Architecture & Actors
- MQTT Actor: Subscribes to weather topics (e.g.,
tele/sensor/SENSOR), parses JSON, and broadcasts updates. - Monitor Actor: Tracks sensor "heartbeats." Maintains a state of "Last Seen."
- WebSocket Manager: Handles browser connections; pushes HTML-ready JSON to SolidJS.
- Storage: Single
weather.dbfile using "Schema-on-Boot" (no manual migrations).
3. Implementation Phases
Phase 1: Backend Infrastructure (Gleam)
- Initialize Gleam project with
gleam_otp,mist,wisp, andsqlight. - Implement
database.gleam:- Function
init_dbto runCREATE TABLE IF NOT EXISTS sensor_stats. - Schema:
sensor_id (PK),last_seen (DATETIME),uptime_start (DATETIME).
- Function
- Implement
mqtt_handler.gleam:- Use
gemqtt(wrapper foremqtt) to connect to the broker. - Map incoming payloads to a
WeatherUpdatecustom type.
- Use
Phase 2: Uptime Logic
- Implement the
MonitorActor logic:- On MQTT message: Update
last_seenin SQLite. - If
(CurrentTime - last_seen) > 10 minutes, consider the sensor "disrupted." - On recovery: Reset
uptime_starttonow.
- On MQTT message: Update
- Calculate "Days since disruption" using:
(CurrentTime - UptimeStart) / 86400
Phase 3: Real-time Streaming
- Set up a Mist WebSocket handler.
- Use a simple process registry (or
gleam_otpsubject) to broadcast JSON to all connected clients. - Ensure the JSON payload includes:
temp,humidity,wind, anduptime_days.
Phase 4: Frontend (SolidJS)
- Scaffold SolidJS via Vite.
- Create a
WeatherCardcomponent. - Implement
createEffectfor WebSocket management:- On
ws.onmessage: Update Solid signals. - On
ws.onclose: Implement simple exponential backoff for reconnection.
- On
- Style with Tailwind CSS (Card-based layout, dark mode).
Phase 5: Deployment (Nomad)
- Create a multi-stage
Dockerfile:- Build SolidJS assets.
- Compile Gleam to a production Erlang release.
- Create
weather.nomadjob file:- Mount
host_volumefor the.dbfile. - Configure networking for the WebSocket port (default 8080).
- Mount
4. Claude Code Implementation Instructions
- Start with the Backend: Focus on the
WeatherUpdatetype and the MQTT subscriber first. - Database: Use
sqlight.execto ensure the table exists on every app start. - Frontend: Keep the SolidJS app in a
./frontendsubdirectory. - Mocking: If the MQTT broker isn't reachable during coding, create a "Simulator" actor that sends random weather data every 5 seconds.