From a6d5891e8a23ea6719d4241217a3d31267f665e3 Mon Sep 17 00:00:00 2001 From: Brett Adams Date: Thu, 1 May 2025 03:19:34 +1000 Subject: [PATCH] Add more sensors to Teslemetry (#143386) * Add more sensors * first batch * first batch finished * Sensors * Clean up * Remove comment * Updates * Fix translation * Other small fixes * [%key:common::state::enabled%] * enabled * More translation improvements * Small tweaks * reconnect * Add Icons * fault * faults * Fix bad merge * review feedback * uom fixes * Translate units --- .../components/teslemetry/icons.json | 319 +++++ homeassistant/components/teslemetry/sensor.py | 1030 ++++++++++++++++- .../components/teslemetry/strings.json | 361 ++++++ 3 files changed, 1681 insertions(+), 29 deletions(-) diff --git a/homeassistant/components/teslemetry/icons.json b/homeassistant/components/teslemetry/icons.json index 1a9a9b9f09d..06ac1595a80 100644 --- a/homeassistant/components/teslemetry/icons.json +++ b/homeassistant/components/teslemetry/icons.json @@ -249,6 +249,7 @@ "default": "mdi:ev-plug-ccs2" } }, + "sensor": { "battery_power": { "default": "mdi:home-battery" @@ -383,6 +384,324 @@ "panic": "mdi:shield-alert-outline", "quiet": "mdi:shield-half-full" } + }, + "bms_state": { + "default": "mdi:battery-heart-variant", + "state": { + "standby": "mdi:battery-clock", + "drive": "mdi:car-electric", + "support": "mdi:battery-check", + "charge": "mdi:battery-charging", + "full_electric_in_motion": "mdi:battery-arrow-up", + "clear_fault": "mdi:battery-alert-variant-outline", + "fault": "mdi:battery-alert", + "weld": "mdi:battery-lock", + "test": "mdi:battery-sync", + "system_not_available": "mdi:battery-off" + } + }, + "brake_pedal_position": { + "default": "mdi:car-brake-alert" + }, + "brick_voltage_max": { + "default": "mdi:battery-high" + }, + "brick_voltage_min": { + "default": "mdi:battery-low" + }, + "cruise_follow_distance": { + "default": "mdi:car-cruise-control" + }, + "cruise_set_speed": { + "default": "mdi:speedometer" + }, + "current_limit_mph": { + "default": "mdi:car-cruise-control" + }, + "dc_charging_energy_in": { + "default": "mdi:ev-station" + }, + "dc_charging_power": { + "default": "mdi:lightning-bolt" + }, + "di_axle_speed_f": { + "default": "mdi:speedometer" + }, + "di_axle_speed_r": { + "default": "mdi:speedometer" + }, + "di_axle_speed_rel": { + "default": "mdi:speedometer" + }, + "di_axle_speed_rer": { + "default": "mdi:speedometer" + }, + "di_heatsink_tf": { + "default": "mdi:thermometer" + }, + "di_heatsink_tr": { + "default": "mdi:thermometer" + }, + "di_heatsink_trel": { + "default": "mdi:thermometer" + }, + "di_heatsink_trer": { + "default": "mdi:thermometer" + }, + "di_inverter_tf": { + "default": "mdi:sine-wave" + }, + "di_inverter_tr": { + "default": "mdi:sine-wave" + }, + "di_inverter_trel": { + "default": "mdi:sine-wave" + }, + "di_inverter_trer": { + "default": "mdi:sine-wave" + }, + "di_motor_current_f": { + "default": "mdi:current-ac" + }, + "di_motor_current_r": { + "default": "mdi:current-ac" + }, + "di_motor_current_rel": { + "default": "mdi:current-ac" + }, + "di_motor_current_rer": { + "default": "mdi:current-ac" + }, + "di_slave_torque_cmd": { + "default": "mdi:engine" + }, + "di_state_f": { + "default": "mdi:car-electric", + "state": { + "unavailable": "mdi:car-off", + "standby": "mdi:power-sleep", + "fault": "mdi:alert-circle", + "abort": "mdi:stop-circle", + "enabled": "mdi:check-circle" + } + }, + "di_state_r": { + "default": "mdi:car-electric", + "state": { + "unavailable": "mdi:car-off", + "standby": "mdi:power-sleep", + "fault": "mdi:alert-circle", + "abort": "mdi:stop-circle", + "enabled": "mdi:check-circle" + } + }, + "di_state_rel": { + "default": "mdi:car-electric", + "state": { + "unavailable": "mdi:car-off", + "standby": "mdi:power-sleep", + "fault": "mdi:alert-circle", + "abort": "mdi:stop-circle", + "enabled": "mdi:check-circle" + } + }, + "di_state_rer": { + "default": "mdi:car-electric", + "state": { + "unavailable": "mdi:car-off", + "standby": "mdi:power-sleep", + "fault": "mdi:alert-circle", + "abort": "mdi:stop-circle", + "enabled": "mdi:check-circle" + } + }, + "di_stator_temp_f": { + "default": "mdi:thermometer" + }, + "di_stator_temp_r": { + "default": "mdi:thermometer" + }, + "di_stator_temp_rel": { + "default": "mdi:thermometer" + }, + "di_stator_temp_rer": { + "default": "mdi:thermometer" + }, + "energy_remaining": { + "default": "mdi:battery-medium" + }, + "estimated_hours_to_charge_termination": { + "default": "mdi:battery-clock" + }, + "forward_collision_warning": { + "default": "mdi:car-crash", + "state": { + "off": "mdi:car-off", + "late": "mdi:alert", + "average": "mdi:alert-circle", + "early": "mdi:alert-octagon" + } + }, + "gps_heading": { + "default": "mdi:compass" + }, + "guest_mode_mobile_access_state": { + "default": "mdi:account-key", + "state": { + "init": "mdi:cog-refresh", + "not_authenticated": "mdi:account-off", + "authenticated": "mdi:account-check", + "aborted_driving": "mdi:car-off", + "aborted_using_remote_start": "mdi:remote-off", + "aborted_using_ble_keys": "mdi:bluetooth-off", + "aborted_valet_mode": "mdi:car-key", + "aborted_guest_mode_off": "mdi:power-off", + "aborted_drive_auth_time_exceeded": "mdi:timer-off", + "aborted_no_data_received": "mdi:network-off", + "requesting_from_mothership": "mdi:cloud-download", + "requesting_from_auth_d": "mdi:shield-key", + "aborted_fetch_failed": "mdi:wifi-off", + "aborted_bad_data_received": "mdi:file-alert", + "showing_qr_code": "mdi:qrcode", + "swiped_away": "mdi:gesture-swipe", + "dismissed_qr_code_expired": "mdi:clock-alert", + "succeeded_paired_new_ble_key": "mdi:bluetooth-connect" + } + }, + "homelink_device_count": { + "default": "mdi:garage" + }, + "hvac_fan_speed": { + "default": "mdi:fan" + }, + "hvac_fan_status": { + "default": "mdi:fan" + }, + "isolation_resistance": { + "default": "mdi:resistor" + }, + "lane_departure_avoidance": { + "default": "mdi:road-variant", + "state": { + "warning": "mdi:alert", + "assist": "mdi:steering" + } + }, + "lateral_acceleration": { + "default": "mdi:axis-arrow" + }, + "lifetime_energy_used": { + "default": "mdi:lightning-bolt" + }, + "lifetime_energy_used_drive": { + "default": "mdi:lightning-bolt" + }, + "longitudinal_acceleration": { + "default": "mdi:axis-arrow" + }, + "module_temp_max": { + "default": "mdi:thermometer-high" + }, + "module_temp_min": { + "default": "mdi:thermometer-low" + }, + "pack_current": { + "default": "mdi:current-dc" + }, + "pack_voltage": { + "default": "mdi:lightning-bolt" + }, + "paired_phone_key_and_key_fob_qty": { + "default": "mdi:key" + }, + "pedal_position": { + "default": "mdi:pedestal" + }, + "powershare_hours_left": { + "default": "mdi:clock-time-eight-outline" + }, + "powershare_instantaneous_power_kw": { + "default": "mdi:flash" + }, + "powershare_status": { + "default": "mdi:power-socket", + "state": { + "inactive": "mdi:power-plug-off-outline", + "handshaking": "mdi:handshake", + "init": "mdi:cog-refresh", + "enabled": "mdi:check-circle", + "reconnecting": "mdi:wifi-refresh", + "stopped": "mdi:stop-circle" + } + }, + "powershare_stop_reason": { + "default": "mdi:stop-circle", + "state": { + "soc_too_low": "mdi:battery-low", + "retry": "mdi:refresh", + "fault": "mdi:alert-circle", + "user": "mdi:account", + "reconnecting": "mdi:wifi-refresh", + "authentication": "mdi:shield-key" + } + }, + "powershare_type": { + "default": "mdi:power-socket", + "state": { + "load": "mdi:power-plug", + "home": "mdi:home" + } + }, + "rated_range": { + "default": "mdi:map-marker-distance" + }, + "route_last_updated": { + "default": "mdi:map-clock" + }, + "scheduled_charging_mode": { + "default": "mdi:calendar-clock", + "state": { + "off": "mdi:calendar" + } + }, + "software_update_expected_duration_minutes": { + "default": "mdi:update" + }, + "speed_limit_warning": { + "default": "mdi:car-cruise-control" + }, + "tonneau_tent_mode": { + "default": "mdi:tent", + "state": { + "moving": "mdi:sync", + "failed": "mdi:alert" + } + }, + "tpms_hard_warnings": { + "default": "mdi:car-tire-alert" + }, + "tpms_soft_warnings": { + "default": "mdi:car-tire-alert" + }, + "lights_turn_signal": { + "default": "mdi:car-light-dimmed", + "state": { + "left": "mdi:arrow-left-bold-box", + "right": "mdi:arrow-right-bold-box", + "both": "mdi:hazard-lights" + } + }, + "charge_rate_mile_per_hour": { + "default": "mdi:speedometer" + }, + "hvac_power_state": { + "default": "mdi:hvac", + "state": { + "precondition": "mdi:sun-thermometer", + "overheat_protection": "mdi:thermometer-alert", + "off": "mdi:hvac-off", + "on": "mdi:hvac" + } } }, "switch": { diff --git a/homeassistant/components/teslemetry/sensor.py b/homeassistant/components/teslemetry/sensor.py index a507c4ca07e..b87bd334e8c 100644 --- a/homeassistant/components/teslemetry/sensor.py +++ b/homeassistant/components/teslemetry/sensor.py @@ -16,6 +16,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.const import ( + DEGREE, PERCENTAGE, EntityCategory, UnitOfElectricCurrent, @@ -48,6 +49,18 @@ from .models import TeslemetryEnergyData, TeslemetryVehicleData PARALLEL_UPDATES = 0 +BMS_STATES = { + "Standby": "standby", + "Drive": "drive", + "Support": "support", + "Charge": "charge", + "FEIM": "full_electric_in_motion", + "ClearFault": "clear_fault", + "Fault": "fault", + "Weld": "weld", + "Test": "test", + "SNA": "system_not_available", +} CHARGE_STATES = { "Starting": "starting", @@ -58,6 +71,14 @@ CHARGE_STATES = { "NoPower": "no_power", } +DRIVE_INVERTER_STATES = { + "Unavailable": "unavailable", + "Standby": "standby", + "Fault": "fault", + "Abort": "abort", + "Enable": "enabled", +} + SHIFT_STATES = {"P": "p", "D": "d", "R": "r", "N": "n"} SENTRY_MODE_STATES = { @@ -69,6 +90,98 @@ SENTRY_MODE_STATES = { "Quiet": "quiet", } +POWER_SHARE_STATES = { + "Inactive": "inactive", + "Handshaking": "handshaking", + "Init": "init", + "Enabled": "enabled", + "EnabledReconnectingSoon": "reconnecting", + "Stopped": "stopped", +} + +POWER_SHARE_STOP_REASONS = { + "None": "none", + "SOCTooLow": "soc_too_low", + "Retry": "retry", + "Fault": "fault", + "User": "user", + "Reconnecting": "reconnecting", + "Authentication": "authentication", +} + +POWER_SHARE_TYPES = { + "None": "none", + "Load": "load", + "Home": "home", +} + +FORWARD_COLLISION_SENSITIVITIES = { + "Off": "off", + "Late": "late", + "Average": "average", + "Early": "early", +} + +GUEST_MODE_MOBILE_ACCESS_STATES = { + "Init": "init", + "NotAuthenticated": "not_authenticated", + "Authenticated": "authenticated", + "AbortedDriving": "aborted_driving", + "AbortedUsingRemoteStart": "aborted_using_remote_start", + "AbortedUsingBLEKeys": "aborted_using_ble_keys", + "AbortedValetMode": "aborted_valet_mode", + "AbortedGuestModeOff": "aborted_guest_mode_off", + "AbortedDriveAuthTimeExceeded": "aborted_drive_auth_time_exceeded", + "AbortedNoDataReceived": "aborted_no_data_received", + "RequestingFromMothership": "requesting_from_mothership", + "RequestingFromAuthD": "requesting_from_auth_d", + "AbortedFetchFailed": "aborted_fetch_failed", + "AbortedBadDataReceived": "aborted_bad_data_received", + "ShowingQRCode": "showing_qr_code", + "SwipedAway": "swiped_away", + "DismissedQRCodeExpired": "dismissed_qr_code_expired", + "SucceededPairedNewBLEKey": "succeeded_paired_new_ble_key", +} + +HVAC_POWER_STATES = { + "Off": "off", + "On": "on", + "Precondition": "precondition", + "OverheatProtect": "overheat_protection", +} + +LANE_ASSIST_LEVELS = { + "None": "off", + "Warning": "warning", + "Assist": "assist", +} + +SCHEDULED_CHARGING_MODES = { + "Off": "off", + "StartAt": "start_at", + "DepartBy": "depart_by", +} + +SPEED_ASSIST_LEVELS = { + "None": "none", + "Display": "display", + "Chime": "chime", +} + +TONNEAU_TENT_MODE_STATES = { + "Inactive": "inactive", + "Moving": "moving", + "Failed": "failed", + "Active": "active", +} + +TURN_SIGNAL_STATES = { + "Off": "off", + "Left": "left", + "Right": "right", + "Both": "both", +} + @dataclass(frozen=True, kw_only=True) class TeslemetryVehicleSensorEntityDescription(SensorEntityDescription): @@ -91,8 +204,8 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_charging_state", polling=True, - streaming_listener=lambda x, y: x.listen_DetailedChargeState( - lambda z: None if z is None else y(z.lower()) + streaming_listener=lambda vehicle, callback: vehicle.listen_DetailedChargeState( + lambda value: None if value is None else callback(value.lower()) ), polling_value_fn=lambda value: CHARGE_STATES.get(str(value)), options=list(CHARGE_STATES.values()), @@ -101,7 +214,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_battery_level", polling=True, - streaming_listener=lambda x, y: x.listen_BatteryLevel(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_BatteryLevel( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=PERCENTAGE, device_class=SensorDeviceClass.BATTERY, @@ -110,7 +225,7 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_usable_battery_level", polling=True, - streaming_listener=lambda x, y: x.listen_Soc(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_Soc(callback), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=PERCENTAGE, device_class=SensorDeviceClass.BATTERY, @@ -120,7 +235,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_charge_energy_added", polling=True, - streaming_listener=lambda x, y: x.listen_ACChargingEnergyIn(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_ACChargingEnergyIn( + callback + ), state_class=SensorStateClass.TOTAL_INCREASING, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, device_class=SensorDeviceClass.ENERGY, @@ -129,7 +246,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_charger_power", polling=True, - streaming_listener=lambda x, y: x.listen_ACChargingPower(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_ACChargingPower( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfPower.KILO_WATT, device_class=SensorDeviceClass.POWER, @@ -137,7 +256,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_charger_voltage", polling=True, - streaming_listener=lambda x, y: x.listen_ChargerVoltage(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_ChargerVoltage( + callback + ), streaming_firmware="2024.44.32", state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfElectricPotential.VOLT, @@ -147,7 +268,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_charger_actual_current", polling=True, - streaming_listener=lambda x, y: x.listen_ChargeAmps(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_ChargeAmps( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, device_class=SensorDeviceClass.CURRENT, @@ -164,14 +287,18 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_conn_charge_cable", polling=True, - streaming_listener=lambda x, y: x.listen_ChargingCableType(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_ChargingCableType( + callback + ), entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, ), TeslemetryVehicleSensorEntityDescription( key="charge_state_fast_charger_type", polling=True, - streaming_listener=lambda x, y: x.listen_FastChargerType(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_FastChargerType( + callback + ), entity_category=EntityCategory.DIAGNOSTIC, entity_registry_enabled_default=False, ), @@ -186,7 +313,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_est_battery_range", polling=True, - streaming_listener=lambda x, y: x.listen_EstBatteryRange(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_EstBatteryRange( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfLength.MILES, device_class=SensorDeviceClass.DISTANCE, @@ -196,7 +325,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="charge_state_ideal_battery_range", polling=True, - streaming_listener=lambda x, y: x.listen_IdealBatteryRange(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_IdealBatteryRange( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfLength.MILES, device_class=SensorDeviceClass.DISTANCE, @@ -207,7 +338,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( key="drive_state_speed", polling=True, polling_value_fn=lambda value: value or 0, - streaming_listener=lambda x, y: x.listen_VehicleSpeed(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_VehicleSpeed( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR, device_class=SensorDeviceClass.SPEED, @@ -228,8 +361,8 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( polling=True, polling_value_fn=lambda x: SHIFT_STATES.get(str(x), "p"), nullable=True, - streaming_listener=lambda x, y: x.listen_Gear( - lambda z: y("p" if z is None else z.lower()) + streaming_listener=lambda vehicle, callback: vehicle.listen_Gear( + lambda value: callback("p" if value is None else value.lower()) ), options=list(SHIFT_STATES.values()), device_class=SensorDeviceClass.ENUM, @@ -238,7 +371,7 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="vehicle_state_odometer", polling=True, - streaming_listener=lambda x, y: x.listen_Odometer(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_Odometer(callback), state_class=SensorStateClass.TOTAL_INCREASING, native_unit_of_measurement=UnitOfLength.MILES, device_class=SensorDeviceClass.DISTANCE, @@ -249,7 +382,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="vehicle_state_tpms_pressure_fl", polling=True, - streaming_listener=lambda x, y: x.listen_TpmsPressureFl(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_TpmsPressureFl( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfPressure.BAR, suggested_unit_of_measurement=UnitOfPressure.PSI, @@ -261,7 +396,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="vehicle_state_tpms_pressure_fr", polling=True, - streaming_listener=lambda x, y: x.listen_TpmsPressureFr(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_TpmsPressureFr( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfPressure.BAR, suggested_unit_of_measurement=UnitOfPressure.PSI, @@ -273,7 +410,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="vehicle_state_tpms_pressure_rl", polling=True, - streaming_listener=lambda x, y: x.listen_TpmsPressureRl(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_TpmsPressureRl( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfPressure.BAR, suggested_unit_of_measurement=UnitOfPressure.PSI, @@ -285,7 +424,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="vehicle_state_tpms_pressure_rr", polling=True, - streaming_listener=lambda x, y: x.listen_TpmsPressureRr(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_TpmsPressureRr( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfPressure.BAR, suggested_unit_of_measurement=UnitOfPressure.PSI, @@ -297,7 +438,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="climate_state_inside_temp", polling=True, - streaming_listener=lambda x, y: x.listen_InsideTemp(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_InsideTemp( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, @@ -306,7 +449,9 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="climate_state_outside_temp", polling=True, - streaming_listener=lambda x, y: x.listen_OutsideTemp(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_OutsideTemp( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, @@ -335,7 +480,8 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="drive_state_active_route_traffic_minutes_delay", polling=True, - streaming_listener=lambda x, y: x.listen_RouteTrafficMinutesDelay(y), + streaming_listener=lambda vehicle, + callback: vehicle.listen_RouteTrafficMinutesDelay(callback), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfTime.MINUTES, device_class=SensorDeviceClass.DURATION, @@ -344,7 +490,8 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="drive_state_active_route_energy_at_arrival", polling=True, - streaming_listener=lambda x, y: x.listen_ExpectedEnergyPercentAtTripArrival(y), + streaming_listener=lambda vehicle, + callback: vehicle.listen_ExpectedEnergyPercentAtTripArrival(callback), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=PERCENTAGE, device_class=SensorDeviceClass.BATTERY, @@ -354,19 +501,840 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = ( TeslemetryVehicleSensorEntityDescription( key="drive_state_active_route_miles_to_arrival", polling=True, - streaming_listener=lambda x, y: x.listen_MilesToArrival(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_MilesToArrival( + callback + ), state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfLength.MILES, device_class=SensorDeviceClass.DISTANCE, ), + TeslemetryVehicleSensorEntityDescription( + key="bms_state", + streaming_listener=lambda vehicle, callback: vehicle.listen_BMSState( + lambda value: None if value is None else callback(BMS_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(BMS_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="brake_pedal_position", + streaming_listener=lambda vehicle, callback: vehicle.listen_BrakePedalPos( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="brick_voltage_max", + streaming_listener=lambda vehicle, callback: vehicle.listen_BrickVoltageMax( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="brick_voltage_min", + streaming_listener=lambda vehicle, callback: vehicle.listen_BrickVoltageMin( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="cruise_follow_distance", + streaming_listener=lambda vehicle, + callback: vehicle.listen_CruiseFollowDistance(callback), + device_class=SensorDeviceClass.DURATION, + native_unit_of_measurement=UnitOfTime.SECONDS, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="cruise_set_speed", + streaming_listener=lambda vehicle, callback: vehicle.listen_CruiseSetSpeed( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR, + device_class=SensorDeviceClass.SPEED, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="current_limit_mph", + streaming_listener=lambda vehicle, callback: vehicle.listen_CurrentLimitMph( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR, + device_class=SensorDeviceClass.SPEED, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="dc_charging_energy_in", + streaming_listener=lambda vehicle, callback: vehicle.listen_DCChargingEnergyIn( + callback + ), + state_class=SensorStateClass.TOTAL_INCREASING, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="dc_charging_power", + streaming_listener=lambda vehicle, callback: vehicle.listen_DCChargingPower( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfPower.KILO_WATT, + device_class=SensorDeviceClass.POWER, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_axle_speed_f", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiAxleSpeedF( + callback + ), + native_unit_of_measurement="rad/s", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_axle_speed_r", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiAxleSpeedR( + callback + ), + native_unit_of_measurement="rad/s", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_axle_speed_rel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiAxleSpeedREL( + callback + ), + native_unit_of_measurement="rad/s", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_axle_speed_rer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiAxleSpeedRER( + callback + ), + native_unit_of_measurement="rad/s", + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_heatsink_tf", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiHeatsinkTF( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_heatsink_tr", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiHeatsinkTR( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_heatsink_trel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiHeatsinkTREL( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_heatsink_trer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiHeatsinkTRER( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_inverter_tf", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiInverterTF( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_inverter_tr", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiInverterTR( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_inverter_trel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiInverterTREL( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_inverter_trer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiInverterTRER( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_motor_current_f", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiMotorCurrentF( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_motor_current_r", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiMotorCurrentR( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_motor_current_rel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiMotorCurrentREL( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_motor_current_rer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiMotorCurrentRER( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_slave_torque_cmd", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiSlaveTorqueCmd( + callback + ), + native_unit_of_measurement="Nm", # Newton-meters + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_state_f", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStateF( + lambda value: None + if value is None + else callback(DRIVE_INVERTER_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(DRIVE_INVERTER_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_state_r", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStateR( + lambda value: None + if value is None + else callback(DRIVE_INVERTER_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(DRIVE_INVERTER_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_state_rel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStateREL( + lambda value: None + if value is None + else callback(DRIVE_INVERTER_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(DRIVE_INVERTER_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_state_rer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStateRER( + lambda value: None + if value is None + else callback(DRIVE_INVERTER_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(DRIVE_INVERTER_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_stator_temp_f", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStatorTempF( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_stator_temp_r", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStatorTempR( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_stator_temp_rel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStatorTempREL( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_stator_temp_rer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiStatorTempRER( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_torque_actual_f", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiTorqueActualF( + callback + ), + native_unit_of_measurement="Nm", # Newton-meters + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_torque_actual_r", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiTorqueActualR( + callback + ), + native_unit_of_measurement="Nm", # Newton-meters + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_torque_actual_rel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiTorqueActualREL( + callback + ), + native_unit_of_measurement="Nm", # Newton-meters + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_torque_actual_rer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiTorqueActualRER( + callback + ), + native_unit_of_measurement="Nm", # Newton-meters + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_torquemotor", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiTorquemotor( + callback + ), + native_unit_of_measurement="Nm", # Newton-meters + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_vbat_f", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiVBatF(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_vbat_r", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiVBatR(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_vbat_rel", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiVBatREL(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="di_vbat_rer", + streaming_listener=lambda vehicle, callback: vehicle.listen_DiVBatRER(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), TeslemetryVehicleSensorEntityDescription( key="sentry_mode", - streaming_listener=lambda x, y: x.listen_SentryMode( - lambda z: None if z is None else y(SENTRY_MODE_STATES.get(z)) + streaming_listener=lambda vehicle, callback: vehicle.listen_SentryMode( + lambda value: None + if value is None + else callback(SENTRY_MODE_STATES.get(value)) ), options=list(SENTRY_MODE_STATES.values()), device_class=SensorDeviceClass.ENUM, ), + TeslemetryVehicleSensorEntityDescription( + key="energy_remaining", + streaming_listener=lambda vehicle, callback: vehicle.listen_EnergyRemaining( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY_STORAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="estimated_hours_to_charge_termination", + streaming_listener=lambda vehicle, + callback: vehicle.listen_EstimatedHoursToChargeTermination(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTime.HOURS, + device_class=SensorDeviceClass.DURATION, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="forward_collision_warning", + streaming_listener=lambda vehicle, + callback: vehicle.listen_ForwardCollisionWarning( + lambda value: None + if value is None + else callback(FORWARD_COLLISION_SENSITIVITIES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(FORWARD_COLLISION_SENSITIVITIES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="gps_heading", + streaming_listener=lambda vehicle, callback: vehicle.listen_GpsHeading( + callback + ), + native_unit_of_measurement=DEGREE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="guest_mode_mobile_access_state", + streaming_listener=lambda vehicle, + callback: vehicle.listen_GuestModeMobileAccessState( + lambda value: None + if value is None + else callback(GUEST_MODE_MOBILE_ACCESS_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(GUEST_MODE_MOBILE_ACCESS_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="homelink_device_count", + streaming_listener=lambda vehicle, callback: vehicle.listen_HomelinkDeviceCount( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="hvac_fan_speed", + streaming_listener=lambda vehicle, callback: vehicle.listen_HvacFanSpeed( + lambda x: callback(None) if x is None else callback(x * 10) + ), + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="hvac_fan_status", + streaming_listener=lambda vehicle, callback: vehicle.listen_HvacFanStatus( + lambda x: callback(None) if x is None else callback(x * 10) + ), + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="isolation_resistance", + streaming_listener=lambda vehicle, callback: vehicle.listen_IsolationResistance( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement="Ω", + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="lane_departure_avoidance", + streaming_listener=lambda vehicle, + callback: vehicle.listen_LaneDepartureAvoidance( + lambda value: None + if value is None + else callback(LANE_ASSIST_LEVELS.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(LANE_ASSIST_LEVELS.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="lateral_acceleration", + streaming_listener=lambda vehicle, callback: vehicle.listen_LateralAcceleration( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement="g", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="lifetime_energy_used", + streaming_listener=lambda vehicle, callback: vehicle.listen_LifetimeEnergyUsed( + callback + ), + state_class=SensorStateClass.TOTAL_INCREASING, + native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, + device_class=SensorDeviceClass.ENERGY, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="longitudinal_acceleration", + streaming_listener=lambda vehicle, + callback: vehicle.listen_LongitudinalAcceleration(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement="g", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="module_temp_max", + streaming_listener=lambda vehicle, callback: vehicle.listen_ModuleTempMax( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="module_temp_min", + streaming_listener=lambda vehicle, callback: vehicle.listen_ModuleTempMin( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="pack_current", + streaming_listener=lambda vehicle, callback: vehicle.listen_PackCurrent( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, + device_class=SensorDeviceClass.CURRENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="pack_voltage", + streaming_listener=lambda vehicle, callback: vehicle.listen_PackVoltage( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfElectricPotential.VOLT, + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="paired_phone_key_and_key_fob_qty", + streaming_listener=lambda vehicle, + callback: vehicle.listen_PairedPhoneKeyAndKeyFobQty(callback), + state_class=SensorStateClass.MEASUREMENT, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="pedal_position", + streaming_listener=lambda vehicle, callback: vehicle.listen_PedalPosition( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="powershare_hours_left", + streaming_listener=lambda vehicle, callback: vehicle.listen_PowershareHoursLeft( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTime.HOURS, + device_class=SensorDeviceClass.DURATION, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="powershare_instantaneous_power_kw", + streaming_listener=lambda vehicle, + callback: vehicle.listen_PowershareInstantaneousPowerKW(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfPower.KILO_WATT, + device_class=SensorDeviceClass.POWER, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="powershare_status", + streaming_listener=lambda vehicle, callback: vehicle.listen_PowershareStatus( + lambda value: None + if value is None + else callback(POWER_SHARE_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(POWER_SHARE_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="powershare_stop_reason", + streaming_listener=lambda vehicle, + callback: vehicle.listen_PowershareStopReason( + lambda value: None + if value is None + else callback(POWER_SHARE_STOP_REASONS.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(POWER_SHARE_STOP_REASONS.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="powershare_type", + streaming_listener=lambda vehicle, callback: vehicle.listen_PowershareType( + lambda value: None + if value is None + else callback(POWER_SHARE_TYPES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(POWER_SHARE_TYPES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="rated_range", + streaming_listener=lambda vehicle, callback: vehicle.listen_RatedRange( + callback + ), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfLength.MILES, + device_class=SensorDeviceClass.DISTANCE, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="scheduled_charging_mode", + streaming_listener=lambda vehicle, + callback: vehicle.listen_ScheduledChargingMode( + lambda value: None + if value is None + else callback(SCHEDULED_CHARGING_MODES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(SCHEDULED_CHARGING_MODES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="software_update_expected_duration_minutes", + streaming_listener=lambda vehicle, + callback: vehicle.listen_SoftwareUpdateExpectedDurationMinutes(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTime.MINUTES, + device_class=SensorDeviceClass.DURATION, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="speed_limit_warning", + streaming_listener=lambda vehicle, callback: vehicle.listen_SpeedLimitWarning( + lambda value: None + if value is None + else callback(SPEED_ASSIST_LEVELS.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(SPEED_ASSIST_LEVELS.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="tonneau_tent_mode", + streaming_listener=lambda vehicle, callback: vehicle.listen_TonneauTentMode( + lambda value: None + if value is None + else callback(TONNEAU_TENT_MODE_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(TONNEAU_TENT_MODE_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="tpms_hard_warnings", + streaming_listener=lambda vehicle, callback: vehicle.listen_TpmsHardWarnings( + callback + ), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="tpms_soft_warnings", + streaming_listener=lambda vehicle, callback: vehicle.listen_TpmsSoftWarnings( + callback + ), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="lights_turn_signal", + streaming_listener=lambda vehicle, callback: vehicle.listen_LightsTurnSignal( + lambda value: None + if value is None + else callback(TURN_SIGNAL_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(TURN_SIGNAL_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="charge_rate_mile_per_hour", + streaming_listener=lambda vehicle, + callback: vehicle.listen_ChargeRateMilePerHour(callback), + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfSpeed.MILES_PER_HOUR, + device_class=SensorDeviceClass.SPEED, + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + TeslemetryVehicleSensorEntityDescription( + key="hvac_power_state", + streaming_listener=lambda vehicle, callback: vehicle.listen_HvacPower( + lambda value: None + if value is None + else callback(HVAC_POWER_STATES.get(value)) + ), + device_class=SensorDeviceClass.ENUM, + options=list(HVAC_POWER_STATES.values()), + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), ) @@ -386,7 +1354,9 @@ class TeslemetryTimeEntityDescription(SensorEntityDescription): VEHICLE_TIME_DESCRIPTIONS: tuple[TeslemetryTimeEntityDescription, ...] = ( TeslemetryTimeEntityDescription( key="charge_state_minutes_to_full_charge", - streaming_listener=lambda x, y: x.listen_TimeToFullCharge(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_TimeToFullCharge( + callback + ), streaming_unit="hours", device_class=SensorDeviceClass.TIMESTAMP, entity_category=EntityCategory.DIAGNOSTIC, @@ -394,7 +1364,9 @@ VEHICLE_TIME_DESCRIPTIONS: tuple[TeslemetryTimeEntityDescription, ...] = ( ), TeslemetryTimeEntityDescription( key="drive_state_active_route_minutes_to_arrival", - streaming_listener=lambda x, y: x.listen_MinutesToArrival(y), + streaming_listener=lambda vehicle, callback: vehicle.listen_MinutesToArrival( + callback + ), streaming_unit="minutes", device_class=SensorDeviceClass.TIMESTAMP, variance=1, diff --git a/homeassistant/components/teslemetry/strings.json b/homeassistant/components/teslemetry/strings.json index 1135efa04eb..25b979b2fef 100644 --- a/homeassistant/components/teslemetry/strings.json +++ b/homeassistant/components/teslemetry/strings.json @@ -645,6 +645,7 @@ "total_grid_energy_exported": { "name": "Grid exported" }, + "sentry_mode": { "name": "Sentry mode", "state": { @@ -655,6 +656,366 @@ "panic": "Panic", "quiet": "Quiet" } + }, + "bms_state": { + "name": "BMS state", + "state": { + "standby": "[%key:common::state::standby%]", + "drive": "Drive", + "support": "Support", + "charge": "Charge", + "full_electric_in_motion": "Full electric in motion", + "clear_fault": "Clear fault", + "fault": "[%key:common::state::fault%]", + "weld": "Weld", + "test": "Test", + "system_not_available": "System not available" + } + }, + "brake_pedal_position": { + "name": "Brake pedal position" + }, + "brick_voltage_max": { + "name": "Brick voltage max" + }, + "brick_voltage_min": { + "name": "Brick voltage min" + }, + "cruise_follow_distance": { + "name": "Cruise follow distance" + }, + "cruise_set_speed": { + "name": "Cruise set speed" + }, + "current_limit_mph": { + "name": "Current speed limit" + }, + "dc_charging_energy_in": { + "name": "DC charging energy in" + }, + "dc_charging_power": { + "name": "DC charging power" + }, + "di_axle_speed_f": { + "name": "Front drive inverter axle speed" + }, + "di_axle_speed_r": { + "name": "Rear drive inverter axle speed" + }, + "di_axle_speed_rel": { + "name": "Rear left drive inverter axle speed" + }, + "di_axle_speed_rer": { + "name": "Rear right drive inverter axle speed" + }, + "di_heatsink_tf": { + "name": "Front drive inverter heatsink temperature" + }, + "di_heatsink_tr": { + "name": "Rear drive inverter heatsink temperature" + }, + "di_heatsink_trel": { + "name": "Rear left drive inverter heatsink temperature" + }, + "di_heatsink_trer": { + "name": "Rear right drive inverter heatsink temperature" + }, + "di_inverter_tf": { + "name": "Front drive inverter temperature" + }, + "di_inverter_tr": { + "name": "Rear drive inverter temperature" + }, + "di_inverter_trel": { + "name": "Rear left drive inverter temperature" + }, + "di_inverter_trer": { + "name": "Rear right drive inverter temperature" + }, + "di_motor_current_f": { + "name": "Front drive inverter motor current" + }, + "di_motor_current_r": { + "name": "Rear drive inverter motor current" + }, + "di_motor_current_rel": { + "name": "Rear left drive inverter motor current" + }, + "di_motor_current_rer": { + "name": "Rear right drive inverter motor current" + }, + "di_slave_torque_cmd": { + "name": "Secondary drive unit torque" + }, + "di_state_f": { + "name": "Front drive inverter", + "state": { + "unavailable": "Unavailable", + "standby": "[%key:common::state::standby%]", + "fault": "[%key:common::state::fault%]", + "abort": "Abort", + "enabled": "[%key:common::state::enabled%]" + } + }, + "di_state_r": { + "name": "Rear drive inverter", + "state": { + "unavailable": "[%key:component::teslemetry:sensor:di_state_f:unavailable]", + "standby": "[%key:common::state::standby%]", + "fault": "[%key:common::state::fault%]", + "abort": "[%key:component::teslemetry:sensor:di_state_f:abort]", + "enabled": "[%key:common::state::enabled%]" + } + }, + "di_state_rel": { + "name": "Rear left drive inverter", + "state": { + "unavailable": "[%key:component::teslemetry:sensor:di_state_f:unavailable]", + "standby": "[%key:common::state::standby%]", + "fault": "[%key:common::state::fault%]", + "abort": "[%key:component::teslemetry:sensor:di_state_f:abort]", + "enabled": "[%key:common::state::enabled%]" + } + }, + "di_state_rer": { + "name": "Rear right drive inverter", + "state": { + "unavailable": "[%key:component::teslemetry:sensor:di_state_f:unavailable]", + "standby": "[%key:common::state::standby%]", + "fault": "[%key:common::state::fault%]", + "abort": "[%key:component::teslemetry:sensor:di_state_f:abort]", + "enabled": "[%key:common::state::enabled%]" + } + }, + "di_stator_temp_f": { + "name": "Front drive unit stator temperature" + }, + "di_stator_temp_r": { + "name": "Rear drive unit stator temperature" + }, + "di_stator_temp_rel": { + "name": "Rear left drive unit stator temperature" + }, + "di_stator_temp_rer": { + "name": "Rear right drive unit stator temperature" + }, + "di_torque_actual_f": { + "name": "Front drive unit actual torque" + }, + "di_torque_actual_r": { + "name": "Rear drive unit actual torque" + }, + "di_torque_actual_rel": { + "name": "Rear left drive unit actual torque" + }, + "di_torque_actual_rer": { + "name": "Rear right drive unit actual torque" + }, + "di_torquemotor": { + "name": "Drive unit torque" + }, + "di_vbat_f": { + "name": "Front drive inverter battery voltage" + }, + "di_vbat_r": { + "name": "Rear drive inverter battery voltage" + }, + "di_vbat_rel": { + "name": "Rear left drive inverter battery voltage" + }, + "di_vbat_rer": { + "name": "Rear right drive inverter battery voltage" + }, + "energy_remaining": { + "name": "Energy remaining" + }, + "estimated_hours_to_charge_termination": { + "name": "Estimated hours to charge termination" + }, + "forward_collision_warning": { + "name": "Forward collision warning", + "state": { + "off": "[%key:common::state::off%]", + "late": "Late", + "average": "Average", + "early": "Early" + } + }, + "gps_heading": { + "name": "GPS heading" + }, + "guest_mode_mobile_access_state": { + "name": "Guest mode mobile access", + "state": { + "init": "Init", + "not_authenticated": "Not authenticated", + "authenticated": "Authenticated", + "aborted_driving": "Aborted driving", + "aborted_using_remote_start": "Aborted using remote start", + "aborted_using_ble_keys": "Aborted using BLE keys", + "aborted_valet_mode": "Aborted valet mode", + "aborted_guest_mode_off": "Aborted guest mode off", + "aborted_drive_auth_time_exceeded": "Aborted drive auth time exceeded", + "aborted_no_data_received": "Aborted no data received", + "requesting_from_mothership": "Requesting from mothership", + "requesting_from_auth_d": "Requesting from Authd", + "aborted_fetch_failed": "Aborted fetch failed", + "aborted_bad_data_received": "Aborted bad data received", + "showing_qr_code": "Showing QR code", + "swiped_away": "Swiped away", + "dismissed_qr_code_expired": "Dismissed QR code expired", + "succeeded_paired_new_ble_key": "Succeeded paired new BLE key" + } + }, + "homelink_device_count": { + "name": "Homelink devices", + "unit_of_measurement": "devices" + }, + "hvac_fan_speed": { + "name": "HVAC fan speed setting" + }, + "hvac_fan_status": { + "name": "HVAC fan speed" + }, + "isolation_resistance": { + "name": "Isolation resistance" + }, + "lane_departure_avoidance": { + "name": "Lane departure avoidance", + "state": { + "off": "[%key:common::state::off%]", + "warning": "Warning", + "assist": "Assist" + } + }, + "lateral_acceleration": { + "name": "Lateral acceleration" + }, + "lifetime_energy_used": { + "name": "Lifetime energy used" + }, + "lifetime_energy_used_drive": { + "name": "Lifetime energy used drive" + }, + "longitudinal_acceleration": { + "name": "Longitudinal acceleration" + }, + "module_temp_max": { + "name": "Module temperature maximum" + }, + "module_temp_min": { + "name": "Module temperature minimum" + }, + "pack_current": { + "name": "Pack current" + }, + "pack_voltage": { + "name": "Pack voltage" + }, + "paired_phone_key_and_key_fob_qty": { + "name": "Paired phone key and key fob quantity" + }, + "pedal_position": { + "name": "Pedal position" + }, + "powershare_hours_left": { + "name": "Powershare hours left" + }, + "powershare_instantaneous_power_kw": { + "name": "Powershare instantaneous power" + }, + "powershare_status": { + "name": "Powershare status", + "state": { + "inactive": "Inactive", + "handshaking": "Handshaking", + "init": "Initializing", + "enabled": "[%key:common::state::enabled%]", + "reconnecting": "Reconnecting", + "stopped": "[%key:common::state::stopped%]" + } + }, + "powershare_stop_reason": { + "name": "Powershare stop reason", + "state": { + "soc_too_low": "SOC too low", + "retry": "Retry", + "fault": "[%key:common::state::fault%]", + "user": "User", + "reconnecting": "Reconnecting", + "authentication": "Authentication" + } + }, + "powershare_type": { + "name": "Powershare type", + "state": { + "none": "None", + "load": "Load", + "home": "Home" + } + }, + "rated_range": { + "name": "Rated range" + }, + "route_last_updated": { + "name": "Route last updated" + }, + "scheduled_charging_mode": { + "name": "Scheduled charging mode", + "state": { + "off": "[%key:common::state::off%]", + "departure": "Departure", + "start_at": "Start at" + } + }, + "software_update_expected_duration_minutes": { + "name": "Software update expected duration" + }, + "speed_limit_warning": { + "name": "Speed limit warning", + "state": { + "none": "None", + "display": "Display", + "chime": "Chime" + } + }, + "tonneau_tent_mode": { + "name": "Tonneau tent mode", + "state": { + "inactive": "Inactive", + "moving": "Moving", + "failed": "Failed", + "active": "Active" + } + }, + "tpms_hard_warnings": { + "name": "Tire pressure hard warnings", + "unit_of_measurement": "warnings" + }, + "tpms_soft_warnings": { + "name": "Tire pressure soft warnings", + "unit_of_measurement": "warnings" + }, + "lights_turn_signal": { + "name": "Turn signal", + "state": { + "off": "[%key:common::state::off%]", + "left": "Left", + "right": "Right", + "both": "Both" + } + }, + "charge_rate_mile_per_hour": { + "name": "Charge rate" + }, + "hvac_power_state": { + "name": "HVAC power state", + "state": { + "precondition": "Precondition", + "overheat_protection": "Overheat protection", + "off": "[%key:common::state::off%]", + "on": "[%key:common::state::on%]" + } } }, "switch": {