1
0
mirror of https://github.com/home-assistant/core.git synced 2026-06-02 21:54:27 +01:00
Files
core/homeassistant/components/renault/binary_sensor.py
T

191 lines
6.6 KiB
Python

"""Support for Renault binary sensors."""
from collections.abc import Callable
from dataclasses import dataclass
from renault_api.kamereon.enums import ChargeState, PlugState
from renault_api.kamereon.models import (
KamereonVehicleBatteryStatusData,
KamereonVehicleDataAttributes,
KamereonVehicleHvacStatusData,
KamereonVehicleLockStatusData,
)
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import RenaultConfigEntry
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[T: KamereonVehicleDataAttributes](
BinarySensorEntityDescription,
RenaultDataEntityDescription,
):
"""Class describing Renault binary sensor entities."""
value_lambda: Callable[[RenaultBinarySensor[T]], bool | None]
async def async_setup_entry(
hass: HomeAssistant,
config_entry: RenaultConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Renault entities from config entry."""
entities: list[RenaultBinarySensor] = [
RenaultBinarySensor(vehicle, description)
for vehicle in config_entry.runtime_data.vehicles.values()
for description in BINARY_SENSOR_TYPES
if description.coordinator in vehicle.coordinators
]
async_add_entities(entities)
class RenaultBinarySensor[T: KamereonVehicleDataAttributes](
RenaultDataEntity[T], BinarySensorEntity
):
"""Mixin for binary sensor specific attributes."""
entity_description: RenaultBinarySensorEntityDescription[T]
@property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self.entity_description.value_lambda(self)
def _plugged_in_value_lambda(
self: RenaultBinarySensor[KamereonVehicleBatteryStatusData],
) -> bool | None:
"""Return true if the vehicle is plugged in."""
if (plug_status := self.coordinator.data.get_plug_status()) is not None:
return plug_status is PlugState.PLUGGED
if (
charging_status := self.coordinator.data.get_charging_status()
) is not None and charging_status in _PLUG_FROM_CHARGE_STATUS:
return True
return None
BINARY_SENSOR_TYPES: tuple[RenaultBinarySensorEntityDescription, ...] = (
RenaultBinarySensorEntityDescription[KamereonVehicleBatteryStatusData](
key="plugged_in",
coordinator="battery",
device_class=BinarySensorDeviceClass.PLUG,
value_lambda=_plugged_in_value_lambda,
),
RenaultBinarySensorEntityDescription[KamereonVehicleBatteryStatusData](
key="charging",
coordinator="battery",
device_class=BinarySensorDeviceClass.BATTERY_CHARGING,
value_lambda=lambda e: (
e.coordinator.data.chargingStatus == ChargeState.CHARGE_IN_PROGRESS.value
if e.coordinator.data.chargingStatus is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleHvacStatusData](
key="hvac_status",
coordinator="hvac_status",
translation_key="hvac_status",
value_lambda=lambda e: (
e.coordinator.data.hvacStatus == "on"
if e.coordinator.data.hvacStatus is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleLockStatusData](
key="lock_status",
coordinator="lock_status",
# lock: on means open (unlocked), off means closed (locked)
device_class=BinarySensorDeviceClass.LOCK,
value_lambda=lambda e: (
e.coordinator.data.lockStatus == "unlocked"
if e.coordinator.data.lockStatus is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleLockStatusData](
key="hatch_status",
coordinator="lock_status",
# On means open, Off means closed
device_class=BinarySensorDeviceClass.DOOR,
translation_key="hatch_status",
value_lambda=lambda e: (
e.coordinator.data.hatchStatus == "open"
if e.coordinator.data.hatchStatus is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleLockStatusData](
key="rear_left_door_status",
coordinator="lock_status",
# On means open, Off means closed
device_class=BinarySensorDeviceClass.DOOR,
translation_key="rear_left_door_status",
value_lambda=lambda e: (
e.coordinator.data.doorStatusRearLeft == "open"
if e.coordinator.data.doorStatusRearLeft is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleLockStatusData](
key="rear_right_door_status",
coordinator="lock_status",
# On means open, Off means closed
device_class=BinarySensorDeviceClass.DOOR,
translation_key="rear_right_door_status",
value_lambda=lambda e: (
e.coordinator.data.doorStatusRearRight == "open"
if e.coordinator.data.doorStatusRearRight is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleLockStatusData](
key="driver_door_status",
coordinator="lock_status",
# On means open, Off means closed
device_class=BinarySensorDeviceClass.DOOR,
translation_key="driver_door_status",
value_lambda=lambda e: (
e.coordinator.data.doorStatusDriver == "open"
if e.coordinator.data.doorStatusDriver is not None
else None
),
),
RenaultBinarySensorEntityDescription[KamereonVehicleLockStatusData](
key="passenger_door_status",
coordinator="lock_status",
# On means open, Off means closed
device_class=BinarySensorDeviceClass.DOOR,
translation_key="passenger_door_status",
value_lambda=lambda e: (
e.coordinator.data.doorStatusPassenger == "open"
if e.coordinator.data.doorStatusPassenger is not None
else None
),
),
)