Add better typing to Teslemetry switch platform (#144168)

This commit is contained in:
Brett Adams 2025-05-04 21:41:45 +10:00 committed by GitHub
parent de496c693e
commit 8c6edd8b81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,12 +2,13 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Awaitable, Callable
from dataclasses import dataclass from dataclasses import dataclass
from itertools import chain from itertools import chain
from typing import Any from typing import Any
from tesla_fleet_api.const import AutoSeat, Scope from tesla_fleet_api.const import AutoSeat, Scope
from tesla_fleet_api.teslemetry.vehicles import TeslemetryVehicle
from teslemetry_stream import TeslemetryStreamVehicle from teslemetry_stream import TeslemetryStreamVehicle
from homeassistant.components.switch import ( from homeassistant.components.switch import (
@ -37,15 +38,14 @@ PARALLEL_UPDATES = 0
class TeslemetrySwitchEntityDescription(SwitchEntityDescription): class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
"""Describes Teslemetry Switch entity.""" """Describes Teslemetry Switch entity."""
on_func: Callable on_func: Callable[[TeslemetryVehicle], Awaitable[dict[str, Any]]]
off_func: Callable off_func: Callable[[TeslemetryVehicle], Awaitable[dict[str, Any]]]
scopes: list[Scope] scopes: list[Scope]
value_func: Callable[[StateType], bool] = bool value_func: Callable[[StateType], bool] = bool
streaming_listener: Callable[ streaming_listener: Callable[
[TeslemetryStreamVehicle, Callable[[StateType], None]], [TeslemetryStreamVehicle, Callable[[bool | None], None]],
Callable[[], None], Callable[[], None],
] ]
streaming_value_fn: Callable[[StateType], bool] = bool
streaming_firmware: str = "2024.26" streaming_firmware: str = "2024.26"
unique_id: str | None = None unique_id: str | None = None
@ -53,15 +53,18 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = ( VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = (
TeslemetrySwitchEntityDescription( TeslemetrySwitchEntityDescription(
key="vehicle_state_sentry_mode", key="vehicle_state_sentry_mode",
streaming_listener=lambda x, y: x.listen_SentryMode(y), streaming_listener=lambda vehicle, callback: vehicle.listen_SentryMode(
streaming_value_fn=lambda x: x != "Off", lambda value: callback(None if value is None else value != "Off")
),
on_func=lambda api: api.set_sentry_mode(on=True), on_func=lambda api: api.set_sentry_mode(on=True),
off_func=lambda api: api.set_sentry_mode(on=False), off_func=lambda api: api.set_sentry_mode(on=False),
scopes=[Scope.VEHICLE_CMDS], scopes=[Scope.VEHICLE_CMDS],
), ),
TeslemetrySwitchEntityDescription( TeslemetrySwitchEntityDescription(
key="climate_state_auto_seat_climate_left", key="climate_state_auto_seat_climate_left",
streaming_listener=lambda x, y: x.listen_AutoSeatClimateLeft(y), streaming_listener=lambda vehicle, callback: vehicle.listen_AutoSeatClimateLeft(
callback
),
on_func=lambda api: api.remote_auto_seat_climate_request( on_func=lambda api: api.remote_auto_seat_climate_request(
AutoSeat.FRONT_LEFT, True AutoSeat.FRONT_LEFT, True
), ),
@ -72,7 +75,8 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = (
), ),
TeslemetrySwitchEntityDescription( TeslemetrySwitchEntityDescription(
key="climate_state_auto_seat_climate_right", key="climate_state_auto_seat_climate_right",
streaming_listener=lambda x, y: x.listen_AutoSeatClimateRight(y), streaming_listener=lambda vehicle,
callback: vehicle.listen_AutoSeatClimateRight(callback),
on_func=lambda api: api.remote_auto_seat_climate_request( on_func=lambda api: api.remote_auto_seat_climate_request(
AutoSeat.FRONT_RIGHT, True AutoSeat.FRONT_RIGHT, True
), ),
@ -83,7 +87,8 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = (
), ),
TeslemetrySwitchEntityDescription( TeslemetrySwitchEntityDescription(
key="climate_state_auto_steering_wheel_heat", key="climate_state_auto_steering_wheel_heat",
streaming_listener=lambda x, y: x.listen_HvacSteeringWheelHeatAuto(y), streaming_listener=lambda vehicle,
callback: vehicle.listen_HvacSteeringWheelHeatAuto(callback),
on_func=lambda api: api.remote_auto_steering_wheel_heat_climate_request( on_func=lambda api: api.remote_auto_steering_wheel_heat_climate_request(
on=True on=True
), ),
@ -94,8 +99,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = (
), ),
TeslemetrySwitchEntityDescription( TeslemetrySwitchEntityDescription(
key="climate_state_defrost_mode", key="climate_state_defrost_mode",
streaming_listener=lambda x, y: x.listen_DefrostMode(y), streaming_listener=lambda vehicle, callback: vehicle.listen_DefrostMode(
streaming_value_fn=lambda x: x != "Off", lambda value: callback(None if value is None else value != "Off")
),
on_func=lambda api: api.set_preconditioning_max(on=True, manual_override=False), on_func=lambda api: api.set_preconditioning_max(on=True, manual_override=False),
off_func=lambda api: api.set_preconditioning_max( off_func=lambda api: api.set_preconditioning_max(
on=False, manual_override=False on=False, manual_override=False
@ -106,8 +112,11 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = (
key="charge_state_charging_state", key="charge_state_charging_state",
unique_id="charge_state_user_charge_enable_request", unique_id="charge_state_user_charge_enable_request",
value_func=lambda state: state in {"Starting", "Charging"}, value_func=lambda state: state in {"Starting", "Charging"},
streaming_listener=lambda x, y: x.listen_DetailedChargeState(y), streaming_listener=lambda vehicle, callback: vehicle.listen_DetailedChargeState(
streaming_value_fn=lambda x: x in {"Starting", "Charging"}, lambda value: callback(
None if value is None else value in {"Starting", "Charging"}
)
),
on_func=lambda api: api.charge_start(), on_func=lambda api: api.charge_start(),
off_func=lambda api: api.charge_stop(), off_func=lambda api: api.charge_stop(),
scopes=[Scope.VEHICLE_CMDS, Scope.VEHICLE_CHARGING_CMDS], scopes=[Scope.VEHICLE_CMDS, Scope.VEHICLE_CHARGING_CMDS],
@ -239,11 +248,9 @@ class TeslemetryStreamingVehicleSwitchEntity(
) )
) )
def _value_callback(self, value: StateType) -> None: def _value_callback(self, value: bool | None) -> None:
"""Update the value of the entity.""" """Update the value of the entity."""
self._attr_is_on = ( self._attr_is_on = value
None if value is None else self.entity_description.streaming_value_fn(value)
)
self.async_write_ha_state() self.async_write_ha_state()