Redesign panels, add 11 card fixes, new icons and app surfaces
CI / Identify a merged version PR (push) Canceled after 0s
CI / Rust checks, rendering, and native package (push) Canceled after 0s
CI / Publish release and Homebrew feed (push) Canceled after 0s
Release PR / Maintain Version Packages PR (push) Canceled after 0s

Panel fixes: tall card row_span, room tab styling, vacuum card
image+value, AC airflow labels, AC fan speed sections (auto 3-btn
+ manual 5-step slider), light subtitle fallback, curtain pane
dividers, dimmable light presets, LED panel brightness + reorder.

New assets: 34 ui-icons (climate modes, cover, effects, battery,
led-strip, switch states), 3 logos, 90 app surface PNGs, design
system specs (components, ux-mechanics, tokens).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kaloyan DanchevandClaude Opus 4.6 committed 2026-10-27 23:29:32 +02:00
1 parent 89ff17a3bc
commit 86191ba5f3
221 files changed
+6017 -1123

No files matched your search

@@ -31,6 +31,9 @@ LUMA_CARD_TYPE_MAP = {
"custom:luma-action-card": "action",
"custom:luma-vacuum-card": "vacuum",
"custom:luma-weather-card": "weather",
"custom:luma-led-strip-card": "led_strip",
"custom:luma-govee-tv-card": "govee_tv",
"custom:luma-ac-control-card": "ac_control",
}
HA_CARD_TYPE_MAP = {
@@ -87,7 +90,7 @@ def _flatten_cards(cards: list[dict[str, Any]]) -> list[dict[str, Any]]:
return result
def _map_card(card: dict[str, Any]) -> dict[str, Any] | None:
def _map_card(card: dict[str, Any], hass: HomeAssistant | None = None) -> dict[str, Any] | None:
"""Map a Lovelace card config to a Luma v2 card config.
Returns None if the card type is not recognized.
@@ -114,6 +117,18 @@ def _map_card(card: dict[str, Any]) -> dict[str, Any] | None:
if card_type in HA_CARD_TYPE_MAP:
luma_type = HA_CARD_TYPE_MAP[card_type]
entity = card.get("entity", "")
# Override: detect LED strip lights for the "light" HA card type
if card_type == "light" and hass is not None:
state = hass.states.get(entity)
if state is not None:
attrs = state.attributes
has_effects = bool(attrs.get("effect_list"))
color_modes = attrs.get("supported_color_modes", [])
has_rgb = "rgb" in color_modes or "rgbw" in color_modes or "rgbww" in color_modes
if has_effects and has_rgb:
luma_type = "led_strip"
return {
"type": luma_type,
"entity_id": entity,
@@ -131,6 +146,29 @@ def _map_card(card: dict[str, Any]) -> dict[str, Any] | None:
entity = card.get("entity", "")
if entity:
domain = entity.split(".")[0] if "." in entity else ""
# Detect LED strip lights: lights with effect_list and rgb_color support
if domain == "light" and hass is not None:
state = hass.states.get(entity)
if state is not None:
attrs = state.attributes
has_effects = bool(attrs.get("effect_list"))
color_modes = attrs.get("supported_color_modes", [])
has_rgb = "rgb" in color_modes or "rgbw" in color_modes or "rgbww" in color_modes
if has_effects and has_rgb:
return {
"type": "led_strip",
"entity_id": entity,
"name": card.get("name", ""),
"size": "1x1",
"accent_color": "",
"glow_color": "",
"icon": card.get("icon", ""),
"tap_action": card.get("tap_action"),
"hold_action": card.get("hold_action"),
"confirmation": False,
}
domain_map = {
"light": "range",
"switch": "toggle",
@@ -160,11 +198,11 @@ def _map_card(card: dict[str, Any]) -> dict[str, Any] | None:
return None
def _map_view(view: dict[str, Any]) -> dict[str, Any]:
def _map_view(view: dict[str, Any], hass: HomeAssistant | None = None) -> dict[str, Any]:
"""Map a Lovelace view to a Luma v2 room."""
raw_cards = view.get("cards", [])
flat_cards = _flatten_cards(raw_cards)
mapped = [c for c in (_map_card(card) for card in flat_cards) if c is not None]
mapped = [c for c in (_map_card(card, hass) for card in flat_cards) if c is not None]
return {
"id": view.get("path", view.get("title", "").lower().replace(" ", "_")),
@@ -199,7 +237,7 @@ async def handle_get_config(
return
views = config.get("views", [])
rooms = [_map_view(v) for v in views]
rooms = [_map_view(v, hass) for v in views]
result = {
"version": CONFIG_SCHEMA_VERSION,