@@ -29,6 +29,15 @@ def __init__(
2929 vin : str | None = None ,
3030 parse_timestamp : bool = False ,
3131 ):
32+ """
33+ Initialize the TeslemetryStream client.
34+
35+ :param session: An aiohttp ClientSession.
36+ :param access_token: Access token for authentication.
37+ :param server: Teslemetry server to connect to.
38+ :param vin: Vehicle Identification Number.
39+ :param parse_timestamp: Whether to parse timestamps.
40+ """
3241 if server and not server .endswith (".teslemetry.com" ):
3342 raise ValueError ("Server must be on the teslemetry.com domain" )
3443
@@ -44,7 +53,12 @@ def __init__(
4453 self .vehicle = self .get_vehicle (self .vin )
4554
4655 def get_vehicle (self , vin : str ) -> TeslemetryStreamVehicle :
47- """Create a vehicle stream."""
56+ """
57+ Create a vehicle stream.
58+
59+ :param vin: Vehicle Identification Number.
60+ :return: TeslemetryStreamVehicle instance.
61+ """
4862 if self .vin is not None and self .vin != vin :
4963 raise AttributeError ("Stream started in single vehicle mode" )
5064 if vin not in self .vehicles :
@@ -53,19 +67,28 @@ def get_vehicle(self, vin: str) -> TeslemetryStreamVehicle:
5367
5468 @property
5569 def connected (self ) -> bool :
56- """Return if connected."""
70+ """
71+ Return if connected.
72+
73+ :return: True if connected, False otherwise.
74+ """
5775 return self ._response is not None
5876
5977 async def get_config (self , vin : str | None = None ) -> None :
60- """Get the current stream config."""
78+ """
79+ Get the current stream config.
80+
81+ :param vin: Vehicle Identification Number.
82+ """
6183 if not self .server :
6284 await self .find_server ()
6385 if hasattr (self , 'vehicle' ):
6486 await self .vehicle .get_config ()
6587
6688 async def find_server (self ) -> None :
67- """Find the server using metadata."""
68-
89+ """
90+ Find the server using metadata.
91+ """
6992 req = await self ._session .get (
7093 "https://api.teslemetry.com/api/metadata" ,
7194 headers = self ._headers ,
@@ -74,10 +97,14 @@ async def find_server(self) -> None:
7497 response = await req .json ()
7598 self .server = f"{ response ["region" ].lower ()} .teslemetry.com"
7699
77-
78-
79100 async def update_fields (self , fields : dict , vin : str ) -> dict :
80- """Update Fleet Telemetry configuration"""
101+ """
102+ Update Fleet Telemetry configuration.
103+
104+ :param fields: Dictionary of fields to update.
105+ :param vin: Vehicle Identification Number.
106+ :return: Response JSON as a dictionary.
107+ """
81108 resp = await self ._session .patch (
82109 f"https://api.teslemetry.com/api/config/{ self .vin } " ,
83110 headers = self ._headers ,
@@ -89,7 +116,13 @@ async def update_fields(self, fields: dict, vin: str) -> dict:
89116 return await resp .json ()
90117
91118 async def replace_fields (self , fields : dict , vin : str ) -> dict :
92- """Replace Fleet Telemetry configuration"""
119+ """
120+ Replace Fleet Telemetry configuration.
121+
122+ :param fields: Dictionary of fields to replace.
123+ :param vin: Vehicle Identification Number.
124+ :return: Response JSON as a dictionary.
125+ """
93126 resp = await self ._session .post (
94127 f"https://api.teslemetry.com/api/config/{ self .vin } " ,
95128 headers = self ._headers ,
@@ -102,13 +135,19 @@ async def replace_fields(self, fields: dict, vin: str) -> dict:
102135
103136 @property
104137 def config (self ) -> dict :
105- """Return current configuration."""
138+ """
139+ Return current configuration.
140+
141+ :return: Configuration dictionary.
142+ """
106143 return {
107144 "hostname" : self .server ,
108145 }
109146
110147 async def connect (self ) -> None :
111- """Connect to the telemetry stream."""
148+ """
149+ Connect to the telemetry stream.
150+ """
112151 self .active = True
113152 if not self .server :
114153 await self .get_config ()
@@ -127,18 +166,30 @@ async def connect(self) -> None:
127166 )
128167
129168 def close (self ) -> None :
130- """Close connection."""
169+ """
170+ Close connection.
171+ """
131172 if self ._response is not None :
132173 LOGGER .debug ("Disconnecting from %s" , self .server )
133174 self ._response .close ()
134175 self ._response = None
135176
136177 def __aiter__ (self ):
137- """Return"""
178+ """
179+ Return an asynchronous iterator.
180+
181+ :return: Asynchronous iterator.
182+ """
138183 return self
139184
140185 async def __anext__ (self ) -> dict :
141- """Return next event."""
186+ """
187+ Return next event.
188+
189+ :return: Next event as a dictionary.
190+ :raises StopAsyncIteration: If the stream is stopped.
191+ :raises TeslemetryStreamEnded: If the stream is ended by the server.
192+ """
142193 try :
143194 if self .active is False :
144195 # Stop the stream and loop
@@ -172,11 +223,19 @@ async def __anext__(self) -> dict:
172223 def async_add_listener (
173224 self , callback : Callable , filters : dict | None = None
174225 ) -> Callable [[], None ]:
175- """Listen for data updates."""
226+ """
227+ Listen for data updates.
228+
229+ :param callback: Callback function to handle updates.
230+ :param filters: Filters to apply to the updates.
231+ :return: Function to remove the listener.
232+ """
176233 schedule_refresh = not self ._listeners
177234
178235 def remove_listener () -> None :
179- """Remove update listener."""
236+ """
237+ Remove update listener.
238+ """
180239 self ._listeners .pop (remove_listener )
181240 if not self ._listeners :
182241 self .active = False
@@ -190,8 +249,9 @@ def remove_listener() -> None:
190249 return remove_listener
191250
192251 async def listen (self ):
193- """Listen to the telemetry stream."""
194-
252+ """
253+ Listen to the telemetry stream.
254+ """
195255 async for event in self :
196256 if event :
197257 for listener , filters in self ._listeners .values ():
@@ -203,23 +263,37 @@ async def listen(self):
203263 LOGGER .debug ("Listen has finished" )
204264
205265 def listen_Credits (self , callback : Callable [[dict [str , str | int ]], None ]) -> Callable [[], None ]:
206- """Listen for credits update."""
266+ """
267+ Listen for credits update.
207268
269+ :param callback: Callback function to handle credits update.
270+ :return: Function to remove the listener.
271+ """
208272 return self .async_add_listener (
209273 lambda x : callback (x ["credits" ]),
210274 {"credits" : None }
211275 )
212276
213277 def listen_Balance (self , callback : Callable [[int ], None ]) -> Callable [[], None ]:
214- """Listen for credits balance."""
278+ """
279+ Listen for credits balance.
215280
281+ :param callback: Callback function to handle credits balance.
282+ :return: Function to remove the listener.
283+ """
216284 return self .async_add_listener (
217285 lambda x : callback (x ["credits" ]["balance" ]),
218286 {"credits" : {"balance" : None }}
219287 )
220288
221289def recursive_match (dict1 , dict2 ):
222- """Recursively match dict1 with dict2."""
290+ """
291+ Recursively match dict1 with dict2.
292+
293+ :param dict1: First dictionary.
294+ :param dict2: Second dictionary.
295+ :return: True if dict1 matches dict2, False otherwise.
296+ """
223297 if dict1 is not None :
224298 for key , value1 in dict1 .items ():
225299 if key not in dict2 :
0 commit comments