From a157095bc0dda8194a9acffaad7419036800dd1b Mon Sep 17 00:00:00 2001 From: Giovanni Condello Date: Wed, 24 Jun 2026 22:11:15 +0200 Subject: [PATCH] feat(ha): dynamic SoC icon reflects charging state Adds icon_template to the SoC MQTT discovery payload so HA renders mdi:battery-charging-{N} when the vehicle is charging and the standard mdi:battery-{N} icons otherwise. Thresholds match HA's native battery device_class icon mapping. Requires HA 2024.x for icon_template support in MQTT sensor discovery. --- src/integrations/home_assistant/base.py | 3 ++ src/integrations/home_assistant/discovery.py | 30 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/integrations/home_assistant/base.py b/src/integrations/home_assistant/base.py index a7603dd..322fa60 100644 --- a/src/integrations/home_assistant/base.py +++ b/src/integrations/home_assistant/base.py @@ -270,6 +270,7 @@ def _publish_sensor( state_class: str | None = None, unit_of_measurement: str | None = None, icon: str | None = None, + icon_template: str | None = None, value_template: str = "{{ value }}", custom_availability: HaCustomAvailabilityConfig | None = None, ) -> str: @@ -288,6 +289,8 @@ def _publish_sensor( payload["unit_of_measurement"] = unit_of_measurement if icon is not None: payload["icon"] = icon + if icon_template is not None: + payload["icon_template"] = icon_template return self._publish_ha_discovery_message( "sensor", name, payload, custom_availability diff --git a/src/integrations/home_assistant/discovery.py b/src/integrations/home_assistant/discovery.py index 1a8cafe..91a94bf 100644 --- a/src/integrations/home_assistant/discovery.py +++ b/src/integrations/home_assistant/discovery.py @@ -132,12 +132,42 @@ def __publish_ha_discovery_messages_real(self) -> None: ) # Standard sensors + charging_entity_id = f"binary_sensor.{self.vin}_battery_charging" + soc_icon_template = ( + "{% set soc = value | int %}" + f"{{% if is_state('{charging_entity_id}', 'on') %}}" + "{%- if soc >= 95 %}mdi:battery-charging-100" + "{%- elif soc >= 85 %}mdi:battery-charging-90" + "{%- elif soc >= 75 %}mdi:battery-charging-80" + "{%- elif soc >= 65 %}mdi:battery-charging-70" + "{%- elif soc >= 55 %}mdi:battery-charging-60" + "{%- elif soc >= 45 %}mdi:battery-charging-50" + "{%- elif soc >= 35 %}mdi:battery-charging-40" + "{%- elif soc >= 25 %}mdi:battery-charging-30" + "{%- elif soc >= 15 %}mdi:battery-charging-20" + "{%- elif soc >= 5 %}mdi:battery-charging-10" + "{%- else %}mdi:battery-charging-outline{%- endif %}" + "{% else %}" + "{%- if soc >= 95 %}mdi:battery" + "{%- elif soc >= 85 %}mdi:battery-90" + "{%- elif soc >= 75 %}mdi:battery-80" + "{%- elif soc >= 65 %}mdi:battery-70" + "{%- elif soc >= 55 %}mdi:battery-60" + "{%- elif soc >= 45 %}mdi:battery-50" + "{%- elif soc >= 35 %}mdi:battery-40" + "{%- elif soc >= 25 %}mdi:battery-30" + "{%- elif soc >= 15 %}mdi:battery-20" + "{%- elif soc >= 5 %}mdi:battery-10" + "{%- else %}mdi:battery-outline{%- endif %}" + "{% endif %}" + ) self._publish_sensor( mqtt_topics.DRIVETRAIN_SOC, "SoC", device_class="battery", state_class="measurement", unit_of_measurement="%", + icon_template=soc_icon_template, ) self._publish_sensor( mqtt_topics.DRIVETRAIN_SOC_KWH,