1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-30 12:14:20 +01:00
Files
2026-04-30 21:14:48 +02:00

130 lines
4.0 KiB
Python

"""Battery Charge and Range Support for the Nissan Leaf."""
import logging
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.const import PERCENTAGE, UnitOfLength
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.icon import icon_for_battery_level
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
from homeassistant.util.unit_conversion import DistanceConverter
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
from . import LeafDataStore
from .const import (
DATA_BATTERY,
DATA_CHARGING,
DATA_LEAF,
DATA_RANGE_AC,
DATA_RANGE_AC_OFF,
)
from .entity import LeafEntity
_LOGGER = logging.getLogger(__name__)
def setup_platform(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Sensors setup."""
if discovery_info is None:
return
entities: list[LeafEntity] = []
for vin, datastore in hass.data[DATA_LEAF].items():
_LOGGER.debug("Adding sensors for vin=%s", vin)
entities.append(LeafBatterySensor(datastore))
entities.append(LeafRangeSensor(datastore, True))
entities.append(LeafRangeSensor(datastore, False))
add_entities(entities, True)
class LeafBatterySensor(LeafEntity, SensorEntity):
"""Nissan Leaf Battery Sensor."""
_attr_device_class = SensorDeviceClass.BATTERY
_attr_native_unit_of_measurement = PERCENTAGE
def __init__(self, car: LeafDataStore) -> None:
"""Set up battery sensor."""
super().__init__(car)
self._attr_unique_id = f"{self.car.leaf.vin.lower()}_soc"
@property
def name(self) -> str:
"""Sensor Name."""
return f"{self.car.leaf.nickname} Charge"
@property
def native_value(self) -> StateType:
"""Battery state percentage."""
if self.car.data[DATA_BATTERY] is None:
return None
return round(self.car.data[DATA_BATTERY]) # type: ignore[no-any-return]
@property
def icon(self) -> str:
"""Battery state icon handling."""
chargestate = self.car.data[DATA_CHARGING]
return icon_for_battery_level(battery_level=self.state, charging=chargestate)
class LeafRangeSensor(LeafEntity, SensorEntity):
"""Nissan Leaf Range Sensor."""
_attr_icon = "mdi:speedometer"
def __init__(self, car: LeafDataStore, ac_on: bool) -> None:
"""Set up range sensor. Store if AC on."""
self._ac_on = ac_on
super().__init__(car)
if ac_on:
self._attr_unique_id = f"{self.car.leaf.vin.lower()}_range_ac"
else:
self._attr_unique_id = f"{self.car.leaf.vin.lower()}_range"
@property
def name(self) -> str:
"""Update sensor name depending on AC."""
if self._ac_on is True:
return f"{self.car.leaf.nickname} Range (AC)"
return f"{self.car.leaf.nickname} Range"
def log_registration(self) -> None:
"""Log registration."""
_LOGGER.debug(
"Registered LeafRangeSensor integration with Home Assistant for VIN %s",
self.car.leaf.vin,
)
@property
def native_value(self) -> float | None:
"""Battery range in miles or kms."""
ret: float | None
if self._ac_on:
ret = self.car.data[DATA_RANGE_AC]
else:
ret = self.car.data[DATA_RANGE_AC_OFF]
if ret is None:
return None
if self.car.hass.config.units is US_CUSTOMARY_SYSTEM or self.car.force_miles:
ret = DistanceConverter.convert(
ret, UnitOfLength.KILOMETERS, UnitOfLength.MILES
)
return round(ret)
@property
def native_unit_of_measurement(self) -> str:
"""Battery range unit."""
if self.car.hass.config.units is US_CUSTOMARY_SYSTEM or self.car.force_miles:
return UnitOfLength.MILES
return UnitOfLength.KILOMETERS