From 69c387a360c91d2bfbe397bf57e4e82555ed5793 Mon Sep 17 00:00:00 2001 From: tmenguy Date: Wed, 30 Apr 2025 01:03:01 -0700 Subject: [PATCH] Improve Renault plug status binary sensor (#143931) improve binary plug sensor --- .../components/renault/binary_sensor.py | 40 +++++++++++++++++-- .../renault/snapshots/test_binary_sensor.ambr | 2 +- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/renault/binary_sensor.py b/homeassistant/components/renault/binary_sensor.py index 5930462fe9d..5e4f08e9d5c 100644 --- a/homeassistant/components/renault/binary_sensor.py +++ b/homeassistant/components/renault/binary_sensor.py @@ -2,6 +2,7 @@ from __future__ import annotations +from collections.abc import Callable from dataclasses import dataclass from renault_api.kamereon.enums import ChargeState, PlugState @@ -22,6 +23,16 @@ from .entity import RenaultDataEntity, RenaultDataEntityDescription # Coordinator is used to centralize the data updates PARALLEL_UPDATES = 0 +_PLUG_FROM_CHARGE_STATUS: set[ChargeState] = { + ChargeState.CHARGE_IN_PROGRESS, + ChargeState.WAITING_FOR_CURRENT_CHARGE, + ChargeState.CHARGE_ENDED, + ChargeState.V2G_CHARGING_NORMAL, + ChargeState.V2G_CHARGING_WAITING, + ChargeState.V2G_DISCHARGING, + ChargeState.WAITING_FOR_A_PLANNED_CHARGE, +} + @dataclass(frozen=True, kw_only=True) class RenaultBinarySensorEntityDescription( @@ -30,8 +41,9 @@ class RenaultBinarySensorEntityDescription( ): """Class describing Renault binary sensor entities.""" - on_key: str - on_value: StateType + on_key: str | None = None + on_value: StateType | None = None + value_lambda: Callable[[RenaultBinarySensor], bool | None] | None = None async def async_setup_entry( @@ -59,20 +71,40 @@ class RenaultBinarySensor( @property def is_on(self) -> bool | None: """Return true if the binary sensor is on.""" + + if self.entity_description.value_lambda is not None: + return self.entity_description.value_lambda(self) + if self.entity_description.on_key is None: + raise NotImplementedError("Either value_lambda or on_key must be set") if (data := self._get_data_attr(self.entity_description.on_key)) is None: return None return data == self.entity_description.on_value +def _plugged_in_value_lambda(self: RenaultBinarySensor) -> bool | None: + """Return true if the vehicle is plugged in.""" + + data = self.coordinator.data + plug_status = data.get_plug_status() if data else None + + if plug_status is not None: + return plug_status == PlugState.PLUGGED + + charging_status = data.get_charging_status() if data else None + if charging_status is not None and charging_status in _PLUG_FROM_CHARGE_STATUS: + return True + + return None + + BINARY_SENSOR_TYPES: tuple[RenaultBinarySensorEntityDescription, ...] = tuple( [ RenaultBinarySensorEntityDescription( key="plugged_in", coordinator="battery", device_class=BinarySensorDeviceClass.PLUG, - on_key="plugStatus", - on_value=PlugState.PLUGGED.value, + value_lambda=_plugged_in_value_lambda, ), RenaultBinarySensorEntityDescription( key="charging", diff --git a/tests/components/renault/snapshots/test_binary_sensor.ambr b/tests/components/renault/snapshots/test_binary_sensor.ambr index 688e9bf6aba..b8dd54697d4 100644 --- a/tests/components/renault/snapshots/test_binary_sensor.ambr +++ b/tests/components/renault/snapshots/test_binary_sensor.ambr @@ -1289,7 +1289,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_binary_sensors[twingo_3_electric][binary_sensor.reg_number_rear_left_door-entry]