Skip to content

Commit 8003a49

Browse files
authored
Add guest mode switch to Teslemetry (home-assistant#151550)
1 parent e438b11 commit 8003a49

File tree

3 files changed

+56
-27
lines changed

3 files changed

+56
-27
lines changed

homeassistant/components/teslemetry/icons.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,9 @@
752752
},
753753
"vehicle_state_valet_mode": {
754754
"default": "mdi:speedometer-slow"
755+
},
756+
"guest_mode_enabled": {
757+
"default": "mdi:account-group"
755758
}
756759
}
757760
},

homeassistant/components/teslemetry/strings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,9 @@
10841084
},
10851085
"vehicle_state_valet_mode": {
10861086
"name": "Valet mode"
1087+
},
1088+
"guest_mode_enabled": {
1089+
"name": "Guest mode"
10871090
}
10881091
},
10891092
"update": {

homeassistant/components/teslemetry/switch.py

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
from collections.abc import Awaitable, Callable
66
from dataclasses import dataclass
7-
from itertools import chain
87
from typing import Any
98

109
from tesla_fleet_api.const import AutoSeat, Scope
@@ -38,6 +37,7 @@
3837
class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
3938
"""Describes Teslemetry Switch entity."""
4039

40+
polling: bool = False
4141
on_func: Callable[[Vehicle], Awaitable[dict[str, Any]]]
4242
off_func: Callable[[Vehicle], Awaitable[dict[str, Any]]]
4343
scopes: list[Scope]
@@ -53,6 +53,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
5353
VEHICLE_DESCRIPTIONS: tuple[TeslemetrySwitchEntityDescription, ...] = (
5454
TeslemetrySwitchEntityDescription(
5555
key="vehicle_state_sentry_mode",
56+
polling=True,
5657
streaming_listener=lambda vehicle, callback: vehicle.listen_SentryMode(
5758
lambda value: callback(None if value is None else value != "Off")
5859
),
@@ -62,6 +63,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
6263
),
6364
TeslemetrySwitchEntityDescription(
6465
key="vehicle_state_valet_mode",
66+
polling=True,
6567
streaming_listener=lambda vehicle, value: vehicle.listen_ValetModeEnabled(
6668
value
6769
),
@@ -72,6 +74,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
7274
),
7375
TeslemetrySwitchEntityDescription(
7476
key="climate_state_auto_seat_climate_left",
77+
polling=True,
7578
streaming_listener=lambda vehicle, callback: vehicle.listen_AutoSeatClimateLeft(
7679
callback
7780
),
@@ -85,6 +88,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
8588
),
8689
TeslemetrySwitchEntityDescription(
8790
key="climate_state_auto_seat_climate_right",
91+
polling=True,
8892
streaming_listener=lambda vehicle,
8993
callback: vehicle.listen_AutoSeatClimateRight(callback),
9094
on_func=lambda api: api.remote_auto_seat_climate_request(
@@ -97,6 +101,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
97101
),
98102
TeslemetrySwitchEntityDescription(
99103
key="climate_state_auto_steering_wheel_heat",
104+
polling=True,
100105
streaming_listener=lambda vehicle,
101106
callback: vehicle.listen_HvacSteeringWheelHeatAuto(callback),
102107
on_func=lambda api: api.remote_auto_steering_wheel_heat_climate_request(
@@ -109,6 +114,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
109114
),
110115
TeslemetrySwitchEntityDescription(
111116
key="climate_state_defrost_mode",
117+
polling=True,
112118
streaming_listener=lambda vehicle, callback: vehicle.listen_DefrostMode(
113119
lambda value: callback(None if value is None else value != "Off")
114120
),
@@ -120,6 +126,7 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
120126
),
121127
TeslemetrySwitchEntityDescription(
122128
key="charge_state_charging_state",
129+
polling=True,
123130
unique_id="charge_state_user_charge_enable_request",
124131
value_func=lambda state: state in {"Starting", "Charging"},
125132
streaming_listener=lambda vehicle, callback: vehicle.listen_DetailedChargeState(
@@ -131,6 +138,17 @@ class TeslemetrySwitchEntityDescription(SwitchEntityDescription):
131138
off_func=lambda api: api.charge_stop(),
132139
scopes=[Scope.VEHICLE_CMDS, Scope.VEHICLE_CHARGING_CMDS],
133140
),
141+
TeslemetrySwitchEntityDescription(
142+
key="guest_mode_enabled",
143+
polling=False,
144+
unique_id="guest_mode_enabled",
145+
streaming_listener=lambda vehicle, callback: vehicle.listen_GuestModeEnabled(
146+
callback
147+
),
148+
on_func=lambda api: api.guest_mode(True),
149+
off_func=lambda api: api.guest_mode(False),
150+
scopes=[Scope.VEHICLE_CMDS],
151+
),
134152
)
135153

136154

@@ -141,35 +159,40 @@ async def async_setup_entry(
141159
) -> None:
142160
"""Set up the Teslemetry Switch platform from a config entry."""
143161

144-
async_add_entities(
145-
chain(
146-
(
147-
TeslemetryVehiclePollingVehicleSwitchEntity(
148-
vehicle, description, entry.runtime_data.scopes
162+
entities: list[SwitchEntity] = []
163+
164+
for vehicle in entry.runtime_data.vehicles:
165+
for description in VEHICLE_DESCRIPTIONS:
166+
if vehicle.poll or vehicle.firmware < description.streaming_firmware:
167+
if description.polling:
168+
entities.append(
169+
TeslemetryVehiclePollingVehicleSwitchEntity(
170+
vehicle, description, entry.runtime_data.scopes
171+
)
172+
)
173+
else:
174+
entities.append(
175+
TeslemetryStreamingVehicleSwitchEntity(
176+
vehicle, description, entry.runtime_data.scopes
177+
)
149178
)
150-
if vehicle.poll or vehicle.firmware < description.streaming_firmware
151-
else TeslemetryStreamingVehicleSwitchEntity(
152-
vehicle, description, entry.runtime_data.scopes
153-
)
154-
for vehicle in entry.runtime_data.vehicles
155-
for description in VEHICLE_DESCRIPTIONS
156-
),
157-
(
158-
TeslemetryChargeFromGridSwitchEntity(
159-
energysite,
160-
entry.runtime_data.scopes,
161-
)
162-
for energysite in entry.runtime_data.energysites
163-
if energysite.info_coordinator.data.get("components_battery")
164-
and energysite.info_coordinator.data.get("components_solar")
165-
),
166-
(
167-
TeslemetryStormModeSwitchEntity(energysite, entry.runtime_data.scopes)
168-
for energysite in entry.runtime_data.energysites
169-
if energysite.info_coordinator.data.get("components_storm_mode_capable")
170-
),
179+
180+
entities.extend(
181+
TeslemetryChargeFromGridSwitchEntity(
182+
energysite,
183+
entry.runtime_data.scopes,
171184
)
185+
for energysite in entry.runtime_data.energysites
186+
if energysite.info_coordinator.data.get("components_battery")
187+
and energysite.info_coordinator.data.get("components_solar")
172188
)
189+
entities.extend(
190+
TeslemetryStormModeSwitchEntity(energysite, entry.runtime_data.scopes)
191+
for energysite in entry.runtime_data.energysites
192+
if energysite.info_coordinator.data.get("components_storm_mode_capable")
193+
)
194+
195+
async_add_entities(entities)
173196

174197

175198
class TeslemetryVehicleSwitchEntity(TeslemetryRootEntity, SwitchEntity):

0 commit comments

Comments
 (0)