diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d18f14..c248109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,102 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Phase 3.5 — Dashboard rewrite (multi-plan ranked view) + +Throws away the Amber-vs-current-plan two-comparator dashboard +(2447 LOC) and rebuilds it as a multi-plan ranked-alternatives view +keyed off the Phase 3.2 / 3.3 / 3.4 sensors. Visual seed lifted from +`assets/dashboard-v3-apple.html` — dark default, Outfit + IBM Plex +Mono, ambient radial bg, semantic accent tokens (no per-provider +colours). + +#### Added + +- **Full rewrite of `custom_components/pricehawk/www/dashboard.html`** + (~1250 LOC, down from 2447). New card hierarchy per plan section 5.1: + - NAV bar (brand + connection status pill + clock + theme toggle). + - HERO row: current-cost card + savings-vs-best-alt card (with + projected-annual extrapolation). + - PERIOD TABS: `[Today][Week][Month][3 Month][Year]` — clicking a + tab swaps the entity binding for every rollup card to the matching + `_today` / `_week` / `_month` / `_3month` / `_year` sensor in + one tick. Active tab persists to `localStorage['pricehawk-window']` + so re-opens land on the user's last view. + - RANKED ALTERNATIVES table rendered from + `sensor.pricehawk_ranked_alternatives.attributes.alternatives[]` + (already sorted by cheap-rank score in `summarize_for_sensor`). + Click a row → drill-in card slides up below. + - DRILL-IN CARD: peak rate / daily supply / customer type / plan ID + / cheap-rank score, plus a "Pin as Named Comparator" button that + deep-links to `/config/integrations/integration/pricehawk` (HA + doesn't support per-step deep-linking; locked in plan section 9 + REVISIT 4). + - DATA HEALTH FOOTER: `sensor.pricehawk_backfill_status` state + (state-coloured: green=complete, amber=running, red=failed) + + `days_loaded` + `ranked_alternatives.last_run` as relative + + absolute time + alternatives count. +- **Empty-state UI for first-run users** (plan section 5.3 surprise #3): + when `backfill_status.days_loaded < 7`, hero rollup values are + replaced with an "Accruing… [n/365]" pill instead of showing a + misleading `$0.00`. Surfaces clearly that we don't have enough + history yet. +- **CSP `connect-src` extended** to include `ws://*.local:*` + + `wss://*.local:*` so the dashboard works on Ryan's HA Green at + `homeassistant.local` (plan section 5.3 surprise #1). Existing + `localhost` + `*.ui.nabu.casa` entries preserved. +- **`assets/DESIGN.claude.md` — new PriceHawk Dashboard section** + noting divergence: PriceHawk is a dark data-dashboard inside HA's + sidebar, not a warm-canvas editorial site. Inherits typographic + rationale (humanist sans + mono numerics) and the card-as-surface + model + accent-discipline rule, but uses its own token palette. + The rest of the Claude marketing-site spec stays intact. + +#### Changed + +- **WebSocket auth + URL detection preserved verbatim** from the prior + dashboard: + - `location.protocol === 'https:' ? 'wss://' : 'ws://'` for the WS + URL (AEGIS rule: never hardcode `ws://`). + - Token sourced from URL params first, then `window.parent + .hassConnection`, then `localStorage.hassTokens`, then + `window.parent.localStorage.hassTokens` (AEGIS rule: never + hardcode the token). +- **Per-provider colour tokens deleted** (`--amber-primary`, + `--globird-primary`). Replaced with `--accent-positive` / + `--accent-negative` / `--accent-neutral` / `--accent-warn` — matches + the Phase 3.0 pivot away from provider-specific branding. +- **`dashboard_config.setup_panel_iframe` cache-busting unchanged** — + the existing `?v=.` query param survives the + rewrite (it's appended to the URL, doesn't touch dashboard.html + itself). Verified by smoke test; no code change. + +#### Removed + +- CSV import card, backfill-trigger button, Amber-API winner card, + GloBird TOU strip, Amber forecast strip, sparkline chart, grid-power + gauge, two-provider rate chart, ZeroHero status card — all replaced + by the ranked-alternatives + rollup-sensor model. + +#### Notes + +- **No new JS framework, no build step.** Vanilla JS only, same + constraint as the prior dashboard. All CSS + JS inlined; no CDN + fetches beyond the Google Fonts stylesheet that the prior dashboard + already used. +- **30s setInterval re-render** for the ranked + footer cards so + relative timestamps ("ran 27s ago / 3h ago") tick forward without + waiting on a state_changed event. Cheap (<1ms per tick on HA Green). +- **XSS hardening**: all CDR-sourced strings (plan_id, display_name, + brand, customer_type) pass through `escapeHtml()` before innerHTML + insertion. Defensive — current registry payloads don't contain + HTML-ish characters, but future ones might. +- **Manual UAT only** for this commit (per plan section 6.3 table — + `3.5 | none | manual on Ryan's HA + JS console`). Local smoke test: + HTML parses cleanly via `html.parser`; JS extracted + run under + Node `--check` + mock-DOM render harness exercising all 5 period + windows + accruing branch + empty-ranked branch + drill render + without throwing. + ### Phase 3.4 — Named comparator drill-in Lets the user pin ONE CDR plan from the ranked alternatives list as a diff --git a/assets/DESIGN.claude.md b/assets/DESIGN.claude.md index 0d8c89d..5aa7afd 100644 --- a/assets/DESIGN.claude.md +++ b/assets/DESIGN.claude.md @@ -587,3 +587,88 @@ When photography is used (rare — mostly testimonials), avatars crop to perfect - Form validation states beyond `{component.text-input-focused}` are not extracted — error / success states would need a sign-up or feedback flow to confirm. - The actual Claude product surface (claude.ai chat interface) shares some tokens with the marketing site but adds many product-specific components (chat bubbles, message tools, file upload chips, conversation history sidebar) that are out of scope for this marketing-surface document. - The "agent" / "computer use" demo cards on certain pages display animated Claude controlling a browser — the static screenshot doesn't fully capture the animation chrome. + +--- + +## PriceHawk Dashboard (divergence from this spec) + +The PriceHawk HA integration dashboard at +`custom_components/pricehawk/www/dashboard.html` deliberately does NOT +follow the Claude marketing-site spec above. PriceHawk is a dark +**data-dashboard** surfaced inside the Home Assistant sidebar iframe, +not a warm-canvas editorial site, and its visual language is +incompatible with the cream/coral/dark-navy trinity documented in this +file. + +### Why divergence + +- **Surface context**: PriceHawk renders inside HA's chrome alongside + other dark dashboards (Lovelace, Energy, Logbook). A warm-cream canvas + would look broken next to those panels. Most HA users run dark mode + by default; cream-on-cream would be uncomfortable late at night + during high-tariff windows when the dashboard is actually consulted. +- **Information density**: a data-dashboard with 16+ live entity reads + + a ranked alternatives table needs tabular numerals, mono digits, + and high-contrast accent colours. The editorial typography stack + (serif display + humanist sans) doesn't suit dense tabular layouts. +- **Brand independence**: PriceHawk is an open-source HACS integration, + not an Anthropic product. The Anthropic coral / radial-spike mark + doesn't apply here. PriceHawk has its own logo (orange hawk-head + glyph at `custom_components/pricehawk/icon.png`). + +### What PriceHawk DOES inherit from this spec + +- **Typographic rationale**: humanist sans (Outfit, here, vs StyreneB) + for UI text; mono with tabular numerics (IBM Plex Mono, here, vs no + mono in the Claude spec) for all money + rate values. The "use mono + for numbers users compare against each other" rule is unbreakable. +- **Card-as-surface model**: rounded `border-radius` (12-16px), + subtle border, optional 1px gradient top-stroke on hover for + affordance. PriceHawk uses `--card-radius: 16px` matching the Claude + spec's `r-lg: 18px` ballpark. +- **Accent-colour discipline**: ONE positive, ONE negative, ONE + neutral. Don't introduce a fourth accent. Claude uses + primary-coral as its single accent; PriceHawk uses + `--accent-positive` (savings green) + `--accent-negative` (loss red) + + `--accent-neutral` (info blue) + `--accent-warn` (accruing amber) + — four because the dashboard surfaces four distinct semantic states, + not as decoration. + +### PriceHawk token map (for reference) + +```css +--bg-base: #070B14 // OLED-friendly true black +--bg-surface: #0C1220 +--bg-card: rgba(15,23,42,0.6) +--text-primary: #F1F5F9 +--text-secondary: #94A3B8 +--text-muted: #64748B +--accent-positive: #10B981 // savings, "you save" +--accent-negative: #EF4444 // loss, "you lose" +--accent-neutral: #38BDF8 // info, current plan / pinned baseline +--accent-warn: #F59E0B // accruing, < 7 days of backfill history +--card-radius: 16px +--card-blur: 20px +``` + +Light theme inverts via `[data-theme="light"]` selector overriding the +same tokens (canvas: `#F5F6FA`, card: `rgba(255,255,255,0.78)`, accents +shift one stop darker for contrast). Theme persists to +`localStorage['pricehawk-theme']`; first-visit defaults to OS +`prefers-color-scheme`. + +### Where to look for PriceHawk's full visual treatment + +- `assets/dashboard-v3-apple.html` — the v3 visual seed (1478 LOC + dark-theme mockup; ambient radial bg, noise overlay, Outfit + IBM + Plex Mono). Not the deployed dashboard, but the design-language + source-of-truth. +- `custom_components/pricehawk/www/dashboard.html` — the actual + deployed dashboard at `/local/pricehawk/dashboard.html`. Hierarchy: + nav / hero row (current cost + savings) / period tabs + (today|week|month|3month|year) / ranked alternatives table / + drill-in card / data-health footer. + +Don't try to reconcile PriceHawk back into the Claude spec. +They are different products and the visual languages are +deliberately separate. diff --git a/custom_components/pricehawk/www/dashboard.html b/custom_components/pricehawk/www/dashboard.html index d316d06..9080ad1 100644 --- a/custom_components/pricehawk/www/dashboard.html +++ b/custom_components/pricehawk/www/dashboard.html @@ -3,8 +3,16 @@ - -PriceHawk Dashboard + + +PriceHawk @@ -12,95 +20,81 @@ @@ -636,469 +485,190 @@
- + -
- - -
- - -
-
-
-
BEST RATE RIGHT NOW
-
---
-
-
Cheapest right now
-
-
--.-c/kWh
-
-
+
+ + +
+ +
+
This month · Current plan
+
$--
+
+ on +
-
- Cheap - Average - Expensive -
-
-
-
TODAY'S SAVING
-
$0.00
-
-
-
MONTH SAVING
-
$0.00
-
-
-
WIN %
-
--%
-
-
-
LAST UPDATED
-
--:--
-
+
+ + +
+
Savings this month · vs best alternative
+
$--
+
+ Best alt: +
-
- - -
-
-
- - Current Rates -
-
- -
-
-
-
Amber Electric
- Wholesale -
-
- Import - 0.00 c/kWh -
-
- Feed-in - 0.00 c/kWh -
-
- -
-
-
-
GloBird Energy
- Shoulder -
-
- Import - 0.00 c/kWh -
-
- Feed-in - 0.00 c/kWh -
-
-
+
Projected annual: $—
+
- -
- - -
-
-
- - Rate Comparison -
-
TODAY
-
-
- -
-
--:--
-
Amber--
-
GloBird--
-
-
-
-
Amber Import
-
GloBird Import
-
Amber Feed-in
-
GloBird Feed-in
-
Forecast (dashed)
-
-
-
-
AMBER TOTAL
-
$0.00
-
-
-
GLOBIRD TOTAL
-
$0.00
-
-
-
DIFFERENCE
-
$0.00
-
-
-
CHEAPEST TODAY
-
---
-
-
-
- - -
-
-
- - Cost Breakdown -
-
-
- - -
-
- -
+ +
+
+ + + + +
- -
- - -
-
-
- - GloBird Incentives -
-
- -
-
- ZEROHERO Credit - Pending -
-
$1/day credit if grid imports stay low 6-8pm
-
- -
-
- Super Export - Tracking -
-
15c/kWh bonus for exports during 6-8pm window
-
-
-
-
- 0.0 kWh - / 15.0 kWh -
-
- -
-
- Free Power Window - Inactive -
-
Free electricity during promotional windows
-
- -
-
- Critical Peak - No event -
-
Demand response events with bonus credits
-
-
- - -
-
-
- - Savings History + +
+
+
+
+ Ranked alternatives + Top cheaper plans for your usage profile
-
--
-
-
- - - - -
-
-
Amber won
-
GloBird won
-
-
-
- History will appear after the first full day +
--
+ +
+ + + + + + + + + + + + + + +
+ Waiting for the daily ranking job… +
Alternatives appear once the first ranking run completes.
-
- BEST DAY - -- -
-
+
- -