Farm Weather Dashboard Live Tempest conditions, 24h/7d/30d trends, and NWS forecast

A self-hosted live weather dashboard for the Brownsville farm’s WeatherFlow Tempest station. Reads the station straight from farm Home Assistant, styled after the HA “Weather” dashboard, with long-term trends and an NWS forecast. Built 2026-07-20.

Access
URL weather.edmd.me (also http://192.168.8.100:8790/)
Runs on CT100 (192.168.8.100) β€” systemd service tempest-web (native Python, not Docker)
Source /opt/tempest-web/tempest-web.py on CT100 Β· master copy ~/Sync/ED/homelab/tempest-web/
Config /etc/tempest-web.env β€” HA URL + long-lived token (chmod 600)
Port 8790
What it shows

Two tabs, matching Ed’s HA “Weather” dashboard:

Now β€” current conditions with needle gauges (Temperature, Humidity, Wind, UV, each with severity color bands), tiles for every Tempest metric (feels-like, dew point, wet bulb, air density, wind gust/lull/avg/direction, rain rate/type, solar irradiance, illuminance, barometric pressure, lightning + distance, battery), plus the NWS forecast (daily + hourly) at the top.

Trends β€” a 24h / 7d / 30d range selector:

  • 24h β€” raw station readings (HA recorder history)
  • 7d β€” hourly averages Β· 30d β€” daily averages β€” both from HA long-term statistics (permanent retention), with a temperature min/max band
  • Charts: temperature (temp/feels/dew), humidity, barometric pressure, wind + gust, UV + solar, rain accumulation

Auto-refresh: conditions every 20s, forecast every 30 min, trends on demand.

Data sources

All fetched server-side β€” no secrets in the page:

Source How Used for
Farm Home Assistant REST (192.168.0.10:8123) /api/states, /api/history/period Current conditions + 24h trends
Farm HA WebSocket recorder/statistics_during_period 7d / 30d long-term trends (min/mean/max)
NWS api.weather.gov grid ILN/110,86 (Brownsville OH) Daily + hourly forecast β€” no token

CT100 reaches farm HA over the house→farm NetBird route (the same path tempest-logger.py uses). The service authenticates to HA with a long-lived access token (HA → Profile → Security → Long-Lived Access Tokens), stored only in /etc/tempest-web.env.

How it's wired
  • Service β€” dependency-free Python (http.server), stdlib only. Includes a small hand-rolled WebSocket client so it can pull HA long-term statistics directly.

  • systemd β€” /etc/systemd/system/tempest-web.service (Restart=always, EnvironmentFile-style via /etc/tempest-web.env). Manage with systemctl status|restart tempest-web.

  • Caddy β€” CT103 /etc/caddy/Caddyfile, inside the *.edmd.me wildcard block:

    @weather host weather.edmd.me
    handle @weather {
        reverse_proxy 192.168.8.100:8790
    }
    

    TLS is covered by the existing wildcard cert β€” no per-host cert needed. Reload with caddy reload --config /etc/caddy/Caddyfile.

  • DNS β€” weather.edmd.me resolves to 192.168.8.54 (Caddy) locally and to Cloudflare publicly.

Endpoints: / (page) Β· /api/current Β· /api/history?range=24h|7d|30d Β· /api/forecast Β· /healthz.

Maintenance
  • Restart β€” ssh pve pct exec 100 -- systemctl restart tempest-web
  • Update code β€” edit ~/Sync/ED/homelab/tempest-web/tempest-web.py, copy to /opt/tempest-web/ on CT100, restart.
  • Rotate the HA token β€” create a new LLAT in HA, set HA_TOKEN= in /etc/tempest-web.env, restart.
  • Health β€” curl http://192.168.8.100:8790/healthz β†’ ok / degraded.

Gotchas:

  • If /api/current returns 401, the HA token in /etc/tempest-web.env is missing or expired.
  • 7d/30d trends depend on farm HA reachability + the WebSocket path; 24h and current use plain REST and degrade independently.
  • Separate pipeline: the station is also logged every 5 min to farmdb weather_observations by tempest-logger.py (used by the morning briefing). This dashboard is live-from-HA, not from that table.