Skip to content

feat(web): the charts take the iOS app's palette - #1859

Open
frahlg wants to merge 2 commits into
masterfrom
web-ios-charts
Open

frahlg wants to merge 2 commits into
masterfrom
web-ios-charts

Conversation

@frahlg

@frahlg frahlg commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #1857, which gave the box page the iOS palette in CSS. The canvases and a few CSS rules still drew with fixed hex values. This moves them onto the same roles.

What moves

  • theme-runtime.js palette() and app.js chartColors() gain the roles: solar, stores, gives, grid, car, live, alarm. The old line key grid becomes line, so grid means energy everywhere.
  • Plan (plan.js, index.html legend):
    • Prices are ink at three strengths by tercile; tariff and VAT are faint ink.
    • PV is solar, the load line is ink and the car is violet.
    • The battery charges cyan and discharges orange, and its SoC line is cyan.
    • Plan marks draw at 75 %, as on the phone.
  • Energy (app.js): the live chart, the 24 h battery chart (which now redraws on a theme change) and their tooltips. BATTERY_PALETTE/EV_PALETTE are gone: every battery is cyan and every car violet, one step fainter each in name order.
  • History (energy-history.js): home use is ink and solar yellow. Import and export are both the grid pink, so export now hangs below the zero line. Its legend reads "Grid export, below the line".
  • Diagnose and heating: prices in ink levels. Temperatures and heat-pump power are ink told apart by dash.
  • style.css/app.css: pills, banners, fuse bars, status bar ok/warn/err (live/ink/alarm), driver cards (failed is alarm), and the car plan timeline (violet).

Calls to look at

  1. Export below the zero line in History. One pink both ways cannot tell side-by-side bars apart.
  2. Heating lines in ink and dashes. A temperature is not an energy kind.
  3. Several batteries or cars told apart by strength, not hue.
  4. Setup banner, "plan stale", HA "not connected" and .ha-warn became alarm. .ha-warn also covers "unsaved change", which may be too strong.

Evidence

  • Before and after shots, dark and light, from the home box through a GET-only proxy: plan, energy, history, and heating with sample data. Fredrik has the sheet. /api/config was never called on the box.
  • Box npm test: 891/891. New web/chart-palette.test.mjs checks that no old fixed chart hue remains, and checks the plan price and battery roles, the history bar roles and export going down, and the battery and car colours. theme-runtime.test.mjs resolves each role from theme.css in both themes.
  • make verify passes. check-token-drift.mjs against this branch reports no drift: 35 names, both themes.

The box page needs a human look before merge (AGENTS.md). The stats page in the web app is a separate PR: srcfl/ftw-webapp, branch web-ios-charts.

After review (928c2d1)

An agent review found no crash and no theme-switching bug. Fixed:

  • Live Energy: import and export were both filled pink and could not be told apart. Export now draws dashed with no fill, in the same pink, with a dashed legend swatch and tooltip mark.

  • Alarm only for refused, failed or blocked:

    • HA "unsaved change" now has its own ink class (ha-pending).
    • The first-run setup banner and the optimiser-fallback box are now ink.
    • "Not connected", "endpoint unreachable", "plan stale" and the failed driver card stay alarm.
  • History below zero: one step serves both sides, so the lowest gridline and label always reach the largest export. A small "sold" caption sits under the zero line, and no label has a sign.

  • Plan: tariff 35 %, VAT 20 %. Before, they were nearly invisible.

  • 24 h battery chart: redraws from the items it last drew on a theme change, without a network read.

  • Heating: the return line is dashed, so it separates from supply.

  • Tests:

    • app.js chartColors() is held to the same tokens as theme-runtime.js;
    • export larger than every bar above zero;
    • live export dashed in the series, tooltip and legend.

    npm test: 894/894. make verify passes. The branch merges cleanly with current master.

Not shown with real data: a dashed export line, since the box was buying at the time. The tests cover it.

Left alone, as it predates this PR: the raw minus in formatW and in the plan and diagnose axis labels.

🤖 Generated with Claude Code

The canvases and chart palettes that kept raw hex after #1857 now read
colour roles. window.ftwThemeColors gains the energy and state roles
(solar, stores, gives, grid, car, live, alarm), and app.js's chart
colours gain the same, so every canvas draws in the theme it shows.

- Plan: prices are ink by tercile (32/50/80 %), tariff and VAT fainter
  ink3. The battery stores in cyan and gives in orange, the car is
  violet, the home is ink, the now line is ink. Plan marks draw at 75 %,
  as on the phone.
- History: home use is ink, solar amber, and the grid one pink both
  ways, so export hangs below the zero line.
- Live chart and 24 h battery chart: grid, solar, home, every battery in
  the storing hue and every car in violet, each a step fainter when a
  site has several. BATTERY_PALETTE and EV_PALETTE are gone. The 24 h
  chart redraws when the theme changes.
- Diagnose chart, heating charts (ink levels told apart by dash), the
  car plan timeline and the legends follow.
- style.css: diagnostics reasons, driver warning card, status bar,
  setup banner, fuse bars, plan tooltip and the remaining white
  overlays move to roles. Scrims and shadows stay black.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T18:27:18.369209Z 0ab7091 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ab7091e96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/app.js Outdated
Comment on lines +1116 to +1117
{ data: toKwh(chartHistory.e_import), color: C.grid, width: 2, dash: [], name: "Import", fill: true },
{ data: toKwh(chartHistory.e_export), color: C.grid, width: 2, dash: [], name: "Export", fill: true },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep cumulative import and export visually distinguishable

In the Energy view of the live chart, import and export now have identical colors, solid strokes, widths and fills, while toKwh() still keeps both cumulative counters positive. For a household that both imports and exports during the day, neither the traces nor their identical legend swatches identify which curve represents buying versus selling without hovering. The daily History chart handles the shared grid hue by putting export below zero, but this chart does not. Give these two series a distinguishing dash pattern or a corresponding directional treatment.

Useful? React with 👍 / 👎.

Review fixes on the chart palette.

- Live Energy view: export draws dashed and unfilled in the one grid
  pink, with a dashed legend swatch and tooltip mark.
- Alarm only for refused, failed or blocked: an unsaved Home Assistant
  change gets its own ink class (ha-pending), and the first-run setup
  banner and the optimiser fallback box go to ink. "Plan stale", the
  failed driver card and HA "not connected" stay alarm.
- History: one step serves both sides of zero and both sides take whole
  steps, so a day that sells more than any bar above zero still has a
  gridline and a label under it. A "sold" caption under the zero line
  says what the unsigned lower labels count.
- Plan: tariff and VAT slices rise to 35 % and 20 % ink3, and the
  legend swatches match.
- The 24 h battery chart redraws from the items it last drew when the
  theme changes, rather than fetching again.
- Heating: the return line takes a dash, so it parts from supply.
- Tests: the live chart maps each role to the same token as the shared
  resolver; export larger than every bar above zero reaches the lowest
  gridline with no minus sign; live export is dashed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant