- Favorites view blanks after
visibilitychangerestore — Restored a_recoverIfNeededhelper on the panel's visibilitychange handler. It wraps_scheduleTabRenderin try/catch and verifies#tab-contentreceived content; on thrown error or zero child nodes, it makes the initial render and then retries up to three times with 2s / 4s / 6s backoff (four total renders in the worst case). The Favorites render path clears its container before awaiting several async build steps (FavoritesController.build,fetchAndBuildHorizonMaps,fetchMergedMonitoringStatus), and when HA's WebSocket drops mid-render one of those resolved empty or null without throwing, leaving the container blank with no console error. The retry catches the silent bailout. Dashboard (By Panel) avoided the symptom because its simpler render produces an error message on failure instead of bailing quietly. The helper matches the pre-LitElement behaviour removed during thec4154d2refactor. - List row
.list-power-valuemin-width shrank the name column for no benefit — Dropped the 70pxmin-widthandtext-align: righton.list-power-value. Short readings (1.3A) were right-aligned inside a 70px cell, leaving a ~40px empty column between the relay control and the reading that robbed width from theflex:1 .list-circuit-name. The value now sizes to content and hugs the preceding relay pill; the freed column flows back into the name.
- Narrow-viewport list rows fold to a two-row grid — New
@media (max-width: 520px)rule switches.list-rowfrom flex to grid withgrid-template-areasso the circuit name occupies the whole first row (paired with the expand chevron) andbreaker-badge,utilization, shedding icon, status control, power value, and gear drop to a second row. A1frgap column between the status and power slots keeps the relay pill snug against the reading. - By Panel breaker cells fold based on grid width, not viewport — Made
.panel-grida size-query container (container-type: inline-size) and added an@container (max-width: 760px)rule on.circuit-slot. Each cell is half the grid's width, so truncation kicks in well before any viewport media query would trigger. The fold usesdisplay: contentson.circuit-header,.circuit-info,.circuit-controls, and.circuit-statusso the leaf elements can be placed directly viagrid-areaon the outer grid — name spans the full first row, the second row mirrors the list-row layout (badge, util, shed, status, power, gear), and.chart-containerstays as a full-width third row.
- Compact expanded list rows — Expanding a row in By Activity / By Area now shows only the chart. The gear icon and a real toggle-pill (arm-protected by the slide-to-confirm) moved onto the always-visible list row so expanding no longer duplicates information above the chart.
- Configurable list view columns — 1 / 2 / 3 column grid for By Activity and By Area, set in Graph Settings → List View Columns. Persisted in localStorage as a browser-wide preference (single key, not scoped per device). Narrow viewports (< 600px) force single-column regardless. Expanded charts stay in their own column so row-to-chart association stays clear.
- Favorites per-panel status grid — The Favorites view now renders a responsive grid of per-contributing-panel status cards (Site / Grid / Upstream / Downstream / Solar / Battery) below the slider + W/A row. One card per panel that contributes to the Favorites set; live values update on each tick.
- Slide-to-arm in Favorites — Favorites view header now hosts the slide-confirm control so tappable ON/OFF toggles in list rows can actually fire. The non-Favorites list views (By Activity / By Area on real panels) also gain a working slide-to-arm (previously the slider rendered but drag handlers were never bound).
- Panel tabs inline with dropdown — The panel tab bar (By Panel / By Activity / By Area / Monitoring) now sits on the same row as the panel-selector dropdown in the toolbar.
- Favorites utilization % now renders — The list view was passing
nullmonitoring status for Favorites, leaving utilization badges blank. Added per-entry fetch + merge (mergeMonitoringStatuses) with a keyed 30s cache so cross-panel favorites show the same utilization data the single-panel views show. - List / panel view flashing on tab, W/A, and panel switches — Event handlers were both mutating
@stateand explicitly scheduling renders, so every interaction fired two concurrent re-renders. Fixed by moving to the reactive-only path and adding a render coalescer plus a supersession-token guard so superseded renders bail out at each async boundary. - Amps chart didn't redraw on unit switch —
powerHistorymerged new-metric points into the existing Watts map under the same UUID key. Now cleared before every full re-render. [data-uuid]selector shadowing —dom-updaterscoped to.circuit-slot[data-uuid]so the expanded chart-only slot is targeted instead of the list row (which now also carriesdata-uuid).- ON/OFF badge no longer silently non-functional — The tappable badge now routes through the real toggle pipeline with the slide-confirm gate; list views
previously dropped clicks because no
.slide-confirmelement existed in their header. - Favorites view now shows offline banner per contributing panel — Previously the Favorites view silently hid the red "SPAN Panel unreachable" banner even when a contributing panel was offline. The view now renders one banner row per offline panel, labeled with the panel's name (e.g. "Span Panel 2 unreachable"), so users mixing favorites from multiple panels can see which one is down.
- Graph Settings → List View Columns selector now shows the current setting — the 1/2/3 segmented control rendered without any styling in the side-panel's
shadow DOM, so the active option was invisible. The side-panel now ships its own
.unit-togglestyles and highlights the current column count.
- Utilization % moved next to breaker badge — In both the list rows and the By Panel breaker-grid slots, the utilization percent now sits immediately after the breaker badge rather than alongside the battery shedding icon, where it competed visually with battery SoC.
- Favorites header simplified — Removed the redundant "Favorites · N favorites" text (the dropdown already says "Favorites"). The header row now holds just the slide-to-arm and W/A unit toggle.
buildListRowHTMLreplaced the static ON/OFF badge with a real toggle-pill for controllable circuits. Non-controllable circuits (PV, no switch entity) keep a static text badge so they can't be accidentally toggled.
- Extracted
buildPanelStatsHTML/updatePanelStatsBlockso stats-block render + update are shared between the persistent panel header and the Favorites per-panel grid. - Extracted
mergeMonitoringStatusespure helper plus a newMonitoringStatusMultiCacheper-entry keyed cache;DashboardController.fetchMergedMonitoringStatusnow reuses cached results within the 30s TTL instead of fanning out WS calls on every render. - Extracted
FavoritesViewStatepersistence (src/panel/favorites-view-state.ts) and the render coalescing / token helpers (src/panel/coalesce.ts) out of the ~1000-line panel element. Both are pure and now tested. CARD_STYLESemitted once via Litstatic stylesrather thaninsertAdjacentHTML'd per tab render.CSS.escapewrapper applied to every identifier-interpolatedquerySelector.- Each circuit in a list view now wraps its row + optional expansion in a
.list-cellcontainer so the expansion stays in the same CSS-grid column as its row in multi-column mode. - Debounced Favorites view-state localStorage persistence (250ms) so long search queries don't thrash storage.
- Tests grew from 109 → 132 (new coverage:
getCircuitStateClasses,mergeMonitoringStatuses,FavoritesController.buildcomposite-id construction, and render-coalescing / supersession-token contracts).
- Cross-panel Favorites view — A synthetic "Favorites" entry appears in the dashboard panel dropdown (only when at least one favorite is configured) and
aggregates favorited circuits and sub-devices (BESS, EVSE) from every configured SPAN panel into a single workspace.
- Heart toggles in the Graph Settings side panel and per-circuit / per-sub-device side panels (dashboard mode only — never in the standalone Lovelace card).
- Favorites view shows By Activity / By Area / Monitoring tabs (no By Panel). When more than one panel contributes, circuit and sub-device names are prefixed with their panel name. Sub-device tiles render above the circuit list. Monitoring stacks per-panel blocks.
- Stateful: active tab, expanded rows, and search query persist via localStorage and restore on return.
- Persistent panel-stats header — Site / Grid / Upstream / Downstream / Solar / Battery stats now stay visible across all tabs (By Panel, By Activity, By Area, Monitoring) on real panels. Lifted out of the By-Panel grid into the wrapper. Favorites pseudo-panel shows a count summary instead.
- Sub-device per-target horizon override — Setting an individual BESS or EVSE horizon from the sub-device side panel had no effect when more than one SPAN
panel was configured: the service call omitted
config_entry_id, so the backend wrote the override to the first loaded entry's manager (wrong panel). The per-circuit side panel and the panel-mode (Graph Settings) list already threaded it; the sub-device side panel now does too. <ha-menu-button>first-render crash — The dashboard panel no longer createsha-menu-buttonuntil Home Assistant has assignedhass; HA's component readsthis.hass.kioskModeinwillUpdateand would throw before the property was set.
- Side-panel domain service calls thread
config_entry_id— Circuit horizon, sub-device horizon, and circuit threshold service calls now route to the originating panel's config entry. Required for cross-panel Favorites edits to target the right panel and fixes the same-panel bug above. - W/A unit toggle moved to the persistent header — The duplicate toggle below the search bar was removed since the persistent panel-stats header now owns it. The Favorites pseudo-panel's summary strip carries its own toggle.
- By Activity view — Circuits sorted by power consumption (or current) with collapsible rows that expand to full circuit graphs. Includes search filtering and W/A unit toggle.
- By Area view — Circuits grouped by Home Assistant area with the same expandable row format. Areas resolve from entity assignments first, then fall back to the device area. Live registry subscriptions update grouping when areas change.
- Shared tab bar — Both the integration panel and Lovelace card now show By Panel, By Activity, and By Area tabs. The card supports a configurable tab style (text or icon) via the card editor.
- Search with clear button — Incremental search filtering by circuit name with an X button to reset.
- Settings tab removed from the integration panel; graph settings remain accessible via the gear icon in the panel header.
- Shedding icons hidden for circuits with unknown priority (e.g. PV systems).
ha-chart-basereceiveshassbefore DOM insertion, preventingperformUpdateerrors.
- Blank dashboard after backgrounding — Migrated panel and card from vanilla
HTMLElementto LitElement. HA's frontend removes vanilla custom panels during WebSocket reconnection without re-creating them; LitElement survives this lifecycle.
- Build output switched from IIFE to ESM
- Added
lit^3.3.2 dependency
- Add integration panel with tab router and multi-panel selector
- Add monitoring tab with overrides table, summary bar, and notification settings
- Add settings tab with integration link and global monitoring configuration
- Add side panel for circuit and panel configuration
- Add A/W toggle switching all values and chart axes
- Add shedding icons, monitoring indicators, and gear icons to circuit cells
- Add i18n support with translations for en, es, fr, ja, pt
- Use topology panel_entities instead of pattern matching
- Show amps instead of watts above circuit graphs when chart metric is set to
current - Fix Y-axis scale to 0–125% of breaker rating in current mode
- Add red horizontal line at 100% of breaker rating (NEC trip point)
- Add yellow dashed line at 80% of breaker rating (NEC continuous load limit)
- Add total current (amps) stat to panel header
- Chart Y-axis formatting uses absolute values for power metric
- Use dynamic
panel_sizefrom topology instead of hardcoded 32
- Fix editor storing default 5 minutes when user only changes days/hours
- Use statistics API for long-duration charts
- Fix 0-minute config bug
- Add project tooling, CI, and HACS support
- Initial SPAN Panel custom Lovelace card