Skip to content

Rebuild UI as Vite + Preact SPA with settings editor, forecast-vs-actuals, and selling landing page #417

@albinati

Description

@albinati

The existing ui/ is a 6-page vanilla-JS multi-page app: solid plumbing, no charting library, no shared component model, no "selling" framing. Every page reads as an operator's console.

This issue tracks rebuilding it so HEM can:

  1. Adjust runtime settings end-to-end — the API already exposes 33 runtime-tunable keys via GET/PUT /api/v1/settings + batch simulate/apply with the X-Simulation-Id header. Today's settings.html surfaces only a subset. Especially: DHW night/morning targets (DHW_TEMP_NORMAL_C, DHW_TEMP_PV_ABUNDANCE_TARGET_C, DHW_TANK_OVERNIGHT_TARGET_C) need to be one click in.
  2. See forecast vs actuals — overlay PV forecast (Quartz/Open-Meteo via /weather) on Fox realised (/execution/today); same for outdoor temperature; plus the Agile rate timeline. No such view exists.
  3. Look like a "selling" dashboard — landing page with a savings narrative ("£X saved vs fixed last month"), tariff comparison, attribution donut. Pulled from /energy/report, /energy/monthly, /attribution/day.
  4. Token-economical polling — never hit /daikin/status?refresh=true from the cockpit; poll cached /cockpit/now only.

Stack decisions

Framework Preact 10 (~5 KB) + wouter-preact (~3 KB)
Charts ECharts 5, lazy-loaded chunk
Build Vite 5 + TypeScript 5 strict
Replacement Full ui/* rewrite in one PR; /history, /insights, /workbench ride along as legacy HTML until a follow-up

Plan file: /home/stkoverflow/.claude/plans/let-s-rebuild-the-ui-hazy-snowflake.md (not committed; lives in local Claude session state).

Scope ✅ in this PR

  • / landing — hero savings number, KPI strip, monthly-savings bar chart, attribution donut, "how it works" cards
  • /cockpit — animated power flow SVG, SoC ring, dispatch reason chips, next-transition strip, polling
  • /forecast — three stacked ECharts (PV / outdoor temp / Agile prices) with synchronised hover
  • /settings — Mode switcher (OPTIMIZATION_PRESET) prominent at top, 8 grouped sections covering all 33 keys, simulate → apply flow
  • Multi-stage Dockerfile (node:20-alpine build → nginx:1.27-alpine runtime)
  • nginx coexistence so /history, /insights, /workbench still serve from the same container

Out of scope (follow-ups)

  • Rebuilding /history, /insights, /workbench — they stay on vanilla HTML
  • Endpoint changes (this PR consumes the API as-is)
  • Auth model changes (bearer-via-entrypoint stays)
  • PWA / offline / mobile-app shell

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions