1 """Support for Renault sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from datetime
import datetime
8 from typing
import TYPE_CHECKING, Any, Generic, cast
10 from renault_api.kamereon.models
import (
11 KamereonVehicleBatteryStatusData,
12 KamereonVehicleCockpitData,
13 KamereonVehicleHvacStatusData,
14 KamereonVehicleLocationData,
15 KamereonVehicleResStateData,
21 SensorEntityDescription,
38 from .
import RenaultConfigEntry
39 from .coordinator
import T
40 from .entity
import RenaultDataEntity, RenaultDataEntityDescription
41 from .renault_vehicle
import RenaultVehicleProxy
44 @dataclass(frozen=True, kw_only=True)
46 SensorEntityDescription, RenaultDataEntityDescription, Generic[T]
48 """Class describing Renault sensor entities."""
51 entity_class: type[RenaultSensor[T]]
52 condition_lambda: Callable[[RenaultVehicleProxy], bool] |
None =
None
53 requires_fuel: bool =
False
54 value_lambda: Callable[[RenaultSensor[T]], StateType | datetime] |
None =
None
59 config_entry: RenaultConfigEntry,
60 async_add_entities: AddEntitiesCallback,
62 """Set up the Renault entities from config entry."""
63 entities: list[RenaultSensor[Any]] = [
64 description.entity_class(vehicle, description)
65 for vehicle
in config_entry.runtime_data.vehicles.values()
66 for description
in SENSOR_TYPES
67 if description.coordinator
in vehicle.coordinators
68 and (
not description.requires_fuel
or vehicle.details.uses_fuel())
69 and (
not description.condition_lambda
or description.condition_lambda(vehicle))
75 """Mixin for sensor specific attributes."""
77 entity_description: RenaultSensorEntityDescription[T]
80 def data(self) -> StateType:
81 """Return the state of this entity."""
86 """Return the state of this entity."""
95 """Return the charging_power of this entity."""
96 return cast(float, entity.data) / 1000
100 """Return the charging_status of this entity."""
101 data = cast(KamereonVehicleBatteryStatusData, entity.coordinator.data)
102 charging_status = data.get_charging_status()
if data
else None
103 return charging_status.name.lower()
if charging_status
else None
107 """Return the plug_status of this entity."""
108 data = cast(KamereonVehicleBatteryStatusData, entity.coordinator.data)
109 plug_status = data.get_plug_status()
if data
else None
110 return plug_status.name.lower()
if plug_status
else None
114 """Return the rounded value of this entity."""
115 return round(cast(float, entity.data))
119 """Return the UTC value of this entity."""
122 assert original_dt
is not None
123 return as_utc(original_dt)
126 SENSOR_TYPES: tuple[RenaultSensorEntityDescription[Any], ...] = (
129 coordinator=
"battery",
130 data_key=
"batteryLevel",
131 device_class=SensorDeviceClass.BATTERY,
132 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
133 native_unit_of_measurement=PERCENTAGE,
134 state_class=SensorStateClass.MEASUREMENT,
138 coordinator=
"battery",
139 data_key=
"chargingStatus",
140 translation_key=
"charge_state",
141 device_class=SensorDeviceClass.ENUM,
142 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
145 "waiting_for_a_planned_charge",
147 "waiting_for_current_charge",
148 "energy_flap_opened",
149 "charge_in_progress",
153 value_lambda=_get_charge_state_formatted,
156 key=
"charging_remaining_time",
157 coordinator=
"battery",
158 data_key=
"chargingRemainingTime",
159 device_class=SensorDeviceClass.DURATION,
160 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
161 native_unit_of_measurement=UnitOfTime.MINUTES,
162 state_class=SensorStateClass.MEASUREMENT,
163 translation_key=
"charging_remaining_time",
169 key=
"charging_power",
170 condition_lambda=
lambda a:
not a.details.reports_charging_power_in_watts(),
171 coordinator=
"battery",
172 data_key=
"chargingInstantaneousPower",
173 device_class=SensorDeviceClass.POWER,
174 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
175 native_unit_of_measurement=UnitOfPower.KILO_WATT,
176 state_class=SensorStateClass.MEASUREMENT,
177 translation_key=
"admissible_charging_power",
182 key=
"charging_power",
183 condition_lambda=
lambda a: a.details.reports_charging_power_in_watts(),
184 coordinator=
"battery",
185 data_key=
"chargingInstantaneousPower",
186 device_class=SensorDeviceClass.POWER,
187 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
188 native_unit_of_measurement=UnitOfPower.KILO_WATT,
189 state_class=SensorStateClass.MEASUREMENT,
190 value_lambda=_get_charging_power,
191 translation_key=
"charging_power",
195 coordinator=
"battery",
196 data_key=
"plugStatus",
197 translation_key=
"plug_state",
198 device_class=SensorDeviceClass.ENUM,
199 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
203 "plugged_waiting_for_charge",
207 value_lambda=_get_plug_state_formatted,
210 key=
"battery_autonomy",
211 coordinator=
"battery",
212 data_key=
"batteryAutonomy",
213 device_class=SensorDeviceClass.DISTANCE,
214 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
215 native_unit_of_measurement=UnitOfLength.KILOMETERS,
216 state_class=SensorStateClass.MEASUREMENT,
217 translation_key=
"battery_autonomy",
220 key=
"battery_available_energy",
221 coordinator=
"battery",
222 data_key=
"batteryAvailableEnergy",
223 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
224 device_class=SensorDeviceClass.ENERGY,
225 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
226 state_class=SensorStateClass.TOTAL,
227 translation_key=
"battery_available_energy",
230 key=
"battery_temperature",
231 coordinator=
"battery",
232 data_key=
"batteryTemperature",
233 device_class=SensorDeviceClass.TEMPERATURE,
234 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
235 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
236 state_class=SensorStateClass.MEASUREMENT,
237 translation_key=
"battery_temperature",
240 key=
"battery_last_activity",
241 coordinator=
"battery",
242 device_class=SensorDeviceClass.TIMESTAMP,
243 data_key=
"timestamp",
244 entity_class=RenaultSensor[KamereonVehicleBatteryStatusData],
245 entity_registry_enabled_default=
False,
246 value_lambda=_get_utc_value,
247 translation_key=
"battery_last_activity",
251 coordinator=
"cockpit",
252 data_key=
"totalMileage",
253 device_class=SensorDeviceClass.DISTANCE,
254 entity_class=RenaultSensor[KamereonVehicleCockpitData],
255 native_unit_of_measurement=UnitOfLength.KILOMETERS,
256 state_class=SensorStateClass.TOTAL_INCREASING,
257 value_lambda=_get_rounded_value,
258 translation_key=
"mileage",
262 coordinator=
"cockpit",
263 data_key=
"fuelAutonomy",
264 device_class=SensorDeviceClass.DISTANCE,
265 entity_class=RenaultSensor[KamereonVehicleCockpitData],
266 native_unit_of_measurement=UnitOfLength.KILOMETERS,
267 state_class=SensorStateClass.MEASUREMENT,
269 value_lambda=_get_rounded_value,
270 translation_key=
"fuel_autonomy",
274 coordinator=
"cockpit",
275 data_key=
"fuelQuantity",
276 device_class=SensorDeviceClass.VOLUME,
277 entity_class=RenaultSensor[KamereonVehicleCockpitData],
278 native_unit_of_measurement=UnitOfVolume.LITERS,
279 state_class=SensorStateClass.TOTAL,
281 value_lambda=_get_rounded_value,
282 translation_key=
"fuel_quantity",
285 key=
"outside_temperature",
286 coordinator=
"hvac_status",
287 device_class=SensorDeviceClass.TEMPERATURE,
288 data_key=
"externalTemperature",
289 entity_class=RenaultSensor[KamereonVehicleHvacStatusData],
290 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
291 state_class=SensorStateClass.MEASUREMENT,
292 translation_key=
"outside_temperature",
295 key=
"hvac_soc_threshold",
296 coordinator=
"hvac_status",
297 data_key=
"socThreshold",
298 entity_class=RenaultSensor[KamereonVehicleHvacStatusData],
299 native_unit_of_measurement=PERCENTAGE,
300 translation_key=
"hvac_soc_threshold",
303 key=
"hvac_last_activity",
304 coordinator=
"hvac_status",
305 device_class=SensorDeviceClass.TIMESTAMP,
306 data_key=
"lastUpdateTime",
307 entity_class=RenaultSensor[KamereonVehicleHvacStatusData],
308 entity_registry_enabled_default=
False,
309 translation_key=
"hvac_last_activity",
310 value_lambda=_get_utc_value,
313 key=
"location_last_activity",
314 coordinator=
"location",
315 device_class=SensorDeviceClass.TIMESTAMP,
316 data_key=
"lastUpdateTime",
317 entity_class=RenaultSensor[KamereonVehicleLocationData],
318 entity_registry_enabled_default=
False,
319 translation_key=
"location_last_activity",
320 value_lambda=_get_utc_value,
324 coordinator=
"res_state",
326 entity_class=RenaultSensor[KamereonVehicleResStateData],
327 translation_key=
"res_state",
330 key=
"res_state_code",
331 coordinator=
"res_state",
333 entity_class=RenaultSensor[KamereonVehicleResStateData],
334 entity_registry_enabled_default=
False,
335 translation_key=
"res_state_code",
StateType _get_data_attr(self, str key)
StateType|datetime native_value(self)
datetime|None parse_datetime(str|None value)
float _get_rounded_value(RenaultSensor[T] entity)
None async_setup_entry(HomeAssistant hass, RenaultConfigEntry config_entry, AddEntitiesCallback async_add_entities)
StateType _get_charging_power(RenaultSensor[T] entity)
datetime _get_utc_value(RenaultSensor[T] entity)
str|None _get_plug_state_formatted(RenaultSensor[T] entity)
str|None _get_charge_state_formatted(RenaultSensor[T] entity)
dt.datetime as_utc(dt.datetime dattim)