11from __future__ import annotations
2+
23from typing import TYPE_CHECKING , Any
34
4- from tesla_fleet_api .const import Method
5+ from tesla_fleet_api .const import Method , ClosureState , SeatHeaterLevel
56from tesla_fleet_api .tesla .vehicle .vehicles import Vehicles
67from tesla_fleet_api .tesla .vehicle .fleet import VehicleFleet
8+ from tesla_fleet_api .const import LOGGER
79
810if TYPE_CHECKING :
911 pass
@@ -15,6 +17,7 @@ async def server_side_polling(
1517 self , value : bool | None = None
1618 ) -> bool | None :
1719 """Get or set Auto mode."""
20+ LOGGER .warning ("This method is deprecated and will be removed in a future release." )
1821 if value is True :
1922 return (
2023 await self ._request (
@@ -43,6 +46,220 @@ async def data_refresh(self) -> dict[str, Any]:
4346 f"api/refresh/{ self .vin } " ,
4447 )
4548
49+ async def ping (self ) -> dict [str , Any ]:
50+ """Performs a no-op on the vehicle."""
51+ return await self ._request (
52+ Method .POST ,
53+ f"api/1/vehicles/{ self .vin } /custom_command/ping" ,
54+ )
55+
56+ async def closure (
57+ self ,
58+ front_driver_door : ClosureState = ClosureState .NONE ,
59+ front_passenger_door : ClosureState = ClosureState .NONE ,
60+ rear_driver_door : ClosureState = ClosureState .NONE ,
61+ rear_passenger_door : ClosureState = ClosureState .NONE ,
62+ rear_trunk : ClosureState = ClosureState .NONE ,
63+ front_trunk : ClosureState = ClosureState .NONE ,
64+ charge_port : ClosureState = ClosureState .NONE ,
65+ tonneau : ClosureState = ClosureState .NONE ,
66+ ) -> dict [str , Any ]:
67+ """Open, Close, Move and Stop the vehicle's windows, doors, and frunk/trunk.
68+
69+ Args:
70+ front_driver_door: Action for front driver door
71+ front_passenger_door: Action for front passenger door
72+ rear_driver_door: Action for rear driver door
73+ rear_passenger_door: Action for rear passenger door
74+ rear_trunk: Action for rear trunk
75+ front_trunk: Action for front trunk
76+ charge_port: Action for charge port
77+ tonneau: Action for tonneau
78+
79+ Example:
80+ # Open the front trunk
81+ await vehicle.closure(front_trunk=ClosureState.OPEN)
82+
83+ # Close all doors
84+ await vehicle.closure(
85+ front_driver_door=ClosureState.CLOSE,
86+ front_passenger_door=ClosureState.CLOSE,
87+ rear_driver_door=ClosureState.CLOSE,
88+ rear_passenger_door=ClosureState.CLOSE
89+ )
90+ """
91+ data = {}
92+ if front_driver_door != ClosureState .NONE :
93+ data ["frontDriverDoor" ] = front_driver_door .value
94+ if front_passenger_door != ClosureState .NONE :
95+ data ["frontPassengerDoor" ] = front_passenger_door .value
96+ if rear_driver_door != ClosureState .NONE :
97+ data ["rearDriverDoor" ] = rear_driver_door .value
98+ if rear_passenger_door != ClosureState .NONE :
99+ data ["rearPassengerDoor" ] = rear_passenger_door .value
100+ if rear_trunk != ClosureState .NONE :
101+ data ["rearTrunk" ] = rear_trunk .value
102+ if front_trunk != ClosureState .NONE :
103+ data ["frontTrunk" ] = front_trunk .value
104+ if charge_port != ClosureState .NONE :
105+ data ["chargePort" ] = charge_port .value
106+ if tonneau != ClosureState .NONE :
107+ data ["tonneau" ] = tonneau .value
108+
109+ return await self ._request (
110+ Method .POST ,
111+ f"api/1/vehicles/{ self .vin } /custom_command/closure" ,
112+ json = data ,
113+ )
114+
115+ async def seat_heater (
116+ self ,
117+ front_left : SeatHeaterLevel | None = None ,
118+ front_right : SeatHeaterLevel | None = None ,
119+ rear_left : SeatHeaterLevel | None = None ,
120+ rear_right : SeatHeaterLevel | None = None ,
121+ rear_left_back : SeatHeaterLevel | None = None ,
122+ rear_center : SeatHeaterLevel | None = None ,
123+ rear_right_back : SeatHeaterLevel | None = None ,
124+ third_row_left : SeatHeaterLevel | None = None ,
125+ third_row_right : SeatHeaterLevel | None = None ,
126+ ) -> dict [str , Any ]:
127+ """Sets multiple seat heaters at once.
128+
129+ Args:
130+ front_left: Front left seat heater level
131+ front_right: Front right seat heater level
132+ rear_left: Rear left seat heater level
133+ rear_right: Rear right seat heater level
134+ rear_left_back: Rear left back seat heater level
135+ rear_center: Rear center seat heater level
136+ rear_right_back: Rear right back seat heater level
137+ third_row_left: Third row left seat heater level
138+ third_row_right: Third row right seat heater level
139+
140+ Example:
141+ # Set front seats to high heat
142+ await vehicle.seat_heater(
143+ front_left=SeatHeaterLevel.HIGH,
144+ front_right=SeatHeaterLevel.HIGH
145+ )
146+
147+ # Turn off all seat heaters
148+ await vehicle.seat_heater(
149+ front_left=SeatHeaterLevel.OFF,
150+ front_right=SeatHeaterLevel.OFF,
151+ rear_left=SeatHeaterLevel.OFF,
152+ rear_right=SeatHeaterLevel.OFF
153+ )
154+ """
155+ data = {}
156+ if front_left is not None :
157+ data ["frontLeft" ] = front_left .value
158+ if front_right is not None :
159+ data ["frontRight" ] = front_right .value
160+ if rear_left is not None :
161+ data ["rearLeft" ] = rear_left .value
162+ if rear_right is not None :
163+ data ["rearRight" ] = rear_right .value
164+ if rear_left_back is not None :
165+ data ["rearLeftBack" ] = rear_left_back .value
166+ if rear_center is not None :
167+ data ["rearCenter" ] = rear_center .value
168+ if rear_right_back is not None :
169+ data ["rearRightBack" ] = rear_right_back .value
170+ if third_row_left is not None :
171+ data ["thirdRowLeft" ] = third_row_left .value
172+ if third_row_right is not None :
173+ data ["thirdRowRight" ] = third_row_right .value
174+
175+ return await self ._request (
176+ Method .POST ,
177+ f"api/1/vehicles/{ self .vin } /custom_command/seat_heater" ,
178+ json = data ,
179+ )
180+
181+ async def charge_on_solar (
182+ self ,
183+ enabled : bool | None = None ,
184+ lower_charge_limit : int | None = None ,
185+ upper_charge_limit : int | None = None ,
186+ ) -> dict [str , Any ]:
187+ """Enable or disable charging on solar, set lower and upper charge limits.
188+
189+ Args:
190+ enabled: Enable or disable charging on solar
191+ lower_charge_limit: Lower charge limit (0 - upper_charge_limit)
192+ upper_charge_limit: Upper charge limit (lower_charge_limit - 100)
193+ """
194+ data = {}
195+ if enabled is not None :
196+ data ["enabled" ] = enabled
197+ if lower_charge_limit is not None :
198+ data ["lowerChargeLimit" ] = lower_charge_limit
199+ if upper_charge_limit is not None :
200+ data ["upperChargeLimit" ] = upper_charge_limit
201+
202+ return await self ._request (
203+ Method .POST ,
204+ f"api/1/vehicles/{ self .vin } /custom_command/charge_on_solar" ,
205+ json = data ,
206+ )
207+
208+ async def dashcam_save (self ) -> dict [str , Any ]:
209+ """Save the last 10 minutes of dashcam footage."""
210+ return await self ._request (
211+ Method .POST ,
212+ f"api/1/vehicles/{ self .vin } /custom_command/dashcam_save" ,
213+ )
214+
215+ async def play_video (self , url : str ) -> dict [str , Any ]:
216+ """Play a supported video URL in the vehicle.
217+
218+ Args:
219+ url: Video URL to play (e.g., YouTube URL)
220+ """
221+ return await self ._request (
222+ Method .POST ,
223+ f"api/1/vehicles/{ self .vin } /custom_command/play_video" ,
224+ json = {"url" : url },
225+ )
226+
227+ async def stop_light_show (self ) -> dict [str , Any ]:
228+ """Stop the currently playing light show."""
229+ return await self ._request (
230+ Method .POST ,
231+ f"api/1/vehicles/{ self .vin } /custom_command/stop_light_show" ,
232+ )
233+
234+ async def start_light_show (
235+ self ,
236+ show_index : int ,
237+ start_time : int | None = None ,
238+ volume : float | None = None ,
239+ dance_moves : bool | None = None ,
240+ ) -> dict [str , Any ]:
241+ """Start a light show on the vehicle.
242+
243+ Args:
244+ show_index: Index of the light show to play
245+ start_time: Start time in milliseconds since epoch
246+ volume: Volume level for the light show
247+ dance_moves: Enable dance moves during the light show
248+ """
249+ data : dict [str , Any ] = {"show_index" : show_index }
250+ if start_time is not None :
251+ data ["start_time" ] = start_time
252+ if volume is not None :
253+ data ["volume" ] = volume
254+ if dance_moves is not None :
255+ data ["dance_moves" ] = dance_moves
256+
257+ return await self ._request (
258+ Method .POST ,
259+ f"api/1/vehicles/{ self .vin } /custom_command/start_light_show" ,
260+ json = data ,
261+ )
262+
46263
47264class TeslemetryVehicles (Vehicles ):
48265 """Class containing and creating vehicles."""
0 commit comments