Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2093284
build(frontend): sync dist bundle with Favorites visibility-recover fix
cayossarian Apr 19, 2026
57e159b
build(frontend): sync dist bundle with list-row gap fix
cayossarian Apr 19, 2026
2c7c0b8
build(frontend): sync dist bundle with list-power min-width removal
cayossarian Apr 19, 2026
63964fb
build(frontend): sync dist bundle with narrow-width fold layout
cayossarian Apr 19, 2026
1ded3f6
update changelog for row foldering for name preservation
cayossarian Apr 19, 2026
0b37b75
bump release version to 2.0.7
cayossarian Apr 19, 2026
4f76055
build(frontend): sync dist bundle with HA-component-free refactor
cayossarian Apr 19, 2026
65064dd
Merge refactor/drop-ha-frontend-deps into release/v2.0.7
cayossarian Apr 20, 2026
4c56e92
build(frontend): sync dist bundle with code-review followups
cayossarian Apr 20, 2026
a6a3ddb
fix(favorites): treat sub-device-attached entities as device favorites
cayossarian Apr 20, 2026
17e3c48
build(frontend): sync dist bundle with copilot review fixes
cayossarian Apr 20, 2026
8c8c2fd
docs(changelog): concise 2.0.7 notes for HA frontend-deps removal and…
cayossarian Apr 20, 2026
2c8e4ca
build(frontend): sync dist bundle with panel-grid gutter shrink
cayossarian Apr 20, 2026
46ab779
build(frontend): sync dist bundle with folded col-span row-height fix
cayossarian Apr 20, 2026
04f4c89
build(frontend): sync dist bundle with breaker-badge tightening
cayossarian Apr 20, 2026
d1d5714
build(frontend): sync dist bundle with copilot round-2 fixes
cayossarian Apr 20, 2026
0588bde
build(frontend): sync dist bundle removing custom-monitoring indicator
cayossarian Apr 20, 2026
58b787f
bump span-panel-api to 2.6.3 and update changelog
cayossarian Apr 20, 2026
ca1d3e0
Merge remote-tracking branch 'origin/main' into release/v2.0.7
cayossarian Apr 20, 2026
6b4804e
revert span-panel-api pin to 2.6.2 and remove Kirchhoff changelog entry
cayossarian Apr 22, 2026
efd1fb0
build(frontend): sync dist bundle with span-error-banner guard fix
cayossarian Apr 22, 2026
b43fbc6
build(frontend): sync dist bundle with blank-view band-aid removal
cayossarian Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to this project will be documented in this file.

## [2.0.7] - 4/2026

### Fixed

- **Favorites view no longer goes blank** after returning to Home Assistant from a backgrounded browser tab.
- **Circuit names display fully on narrow displays** — the row folds to a second line when the name would otherwise truncate.
- **Favoriting an EVSE now shows it as a device card** instead of a circuit row, matching the By Panel view.

### Changed

- **Dashboard now ships its own frontend components** so it no longer breaks when Home Assistant migrates its internal UI library (per
[Frontend Component Updates 2026.4](https://developers.home-assistant.io/blog/2026/03/25/frontend-component-updates-2026.4)). No visual change; bundle grows
~500 KB.

## [2.0.6] - 4/2026

**Important** 2.0.x cautions still apply — read those carefully if not already on 2.0.x BEFORE proceeding:
Expand Down
152 changes: 123 additions & 29 deletions custom_components/span_panel/frontend/dist/span-panel-card.js

Large diffs are not rendered by default.

181 changes: 156 additions & 25 deletions custom_components/span_panel/frontend/dist/span-panel.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion custom_components/span_panel/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"requirements": [
"span-panel-api==2.6.2"
],
"version": "2.0.6",
"version": "2.0.7",
"zeroconf": [
{
"type": "_span._tcp.local."
Expand Down
29 changes: 16 additions & 13 deletions custom_components/span_panel/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,25 +566,28 @@ def _resolve_entity_to_favorite_target(entity_id: str) -> tuple[str, FavoriteKin
else:
panel_device_id = device_entry.id

# Circuit-favorite branch takes precedence over the sub-device branch.
# EVSE feed-circuit sensors are re-assigned to the EVSE sub-device via
# the device override in sensor.py, but their unique_id still encodes
# the underlying circuit. When the unique_id embeds a 32-char circuit
# UUID (``span_{serial}_{circuit_uuid}_{suffix}``), favorite the
# circuit keyed by the parent panel — not the sub-device it happens
# to be attached to.
# Sub-device-attached entities favorite the sub-device itself.
# Rationale: the device card on the dashboard already represents
# both the sub-device's status sensors AND its feed-circuit
# power. Routing a feed-circuit sensor (current/power, whose
# unique_id encodes a circuit UUID) to a circuit favorite would
# make a Favorites view show the same physical thing twice — a
# device card and a circuit row — and prevent the user from
# ever favoriting "the device" via a click on a feed-circuit
# entity. Treat any entity attached to a sub-device as the
# device-favorite for that sub-device.
if device_entry.via_device_id is not None:
return panel_device_id, "sub_devices", device_entry.id

# Main-panel entity (regular breaker circuit) — favorite the
# circuit. Requires a unique_id that embeds the 32-char circuit
# UUID (``span_{serial}_{circuit_uuid}_{suffix}``).
circuit_uuid = (
extract_circuit_uuid_from_unique_id(entry.unique_id) if entry.unique_id else None
)
if circuit_uuid is not None:
return panel_device_id, "circuits", circuit_uuid

# No circuit UUID — sub-device metadata sensor (BESS %, EVSE status,
# etc.). Favorite the sub-device itself.
if device_entry.via_device_id is not None:
return panel_device_id, "sub_devices", device_entry.id

# Main-panel entity without a circuit UUID — not favoritable.
if not entry.unique_id:
raise ServiceValidationError(
f"Entity {entity_id} has no unique id to resolve.",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "span"
version = "2.0.6"
version = "2.0.7"
description = "Span Panel Custom Integration for Home Assistant"
authors = [{name = "SpanPanel"}]
license = {text = "MIT"}
Expand Down
15 changes: 9 additions & 6 deletions tests/test_favorites_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,13 +412,16 @@ async def test_add_favorite_accepts_sub_device_entity(
assert result == {"favorites": {"d_main": _panel_entry([], ["d_bess"])}}

@pytest.mark.asyncio
async def test_add_favorite_on_evse_feed_circuit_sensor_favorites_circuit(
async def test_add_favorite_on_evse_feed_circuit_sensor_favorites_sub_device(
self, _patched_store: Any
) -> None:
"""EVSE feed-circuit sensors are re-assigned to the EVSE sub-device via
a device override, but their unique_id still carries the circuit UUID.
Favoriting such an entity must store a *circuit* favorite keyed by the
parent panel, not a sub-device favorite keyed by the EVSE."""
"""EVSE feed-circuit sensors are device-info-attached to the EVSE
sub-device. Even though their unique_id still encodes the underlying
circuit UUID, favoriting one must produce a *sub-device* favorite —
the device card on the dashboard already represents both the EVSE's
status sensors and its feed-circuit power, so a circuit favorite would
duplicate the same physical thing as both a card and a row in the
Favorites view."""
hass = MagicMock()
registered = _capture_registered_handlers(hass)
handler = registered["handlers"]["add_favorite"]
Expand All @@ -444,7 +447,7 @@ async def test_add_favorite_on_evse_feed_circuit_sensor_favorites_circuit(
_make_service_call({"entity_id": "sensor.evse_feed_power"})
)

assert result == {"favorites": {"d_main": _panel_entry([circuit_uuid])}}
assert result == {"favorites": {"d_main": _panel_entry([], ["d_evse"])}}

@pytest.mark.asyncio
async def test_add_favorite_rejects_entity_without_uuid_in_unique_id(
Expand Down
Loading