11"""The waze_travel_time component."""
22
33import asyncio
4- from collections .abc import Collection
54import logging
6- from typing import Literal
75
8- from pywaze .route_calculator import CalcRoutesResponse , WazeRouteCalculator , WRCError
6+ from pywaze .route_calculator import WazeRouteCalculator
97import voluptuous as vol
108
119from homeassistant .config_entries import ConfigEntry
12- from homeassistant .const import CONF_REGION , Platform , UnitOfLength
10+ from homeassistant .const import CONF_REGION , Platform
1311from homeassistant .core import (
1412 HomeAssistant ,
1513 ServiceCall ,
2725 TextSelectorConfig ,
2826 TextSelectorType ,
2927)
30- from homeassistant .util .unit_conversion import DistanceConverter
3128
3229from .const import (
3330 CONF_AVOID_FERRIES ,
4340 DEFAULT_FILTER ,
4441 DEFAULT_VEHICLE_TYPE ,
4542 DOMAIN ,
46- IMPERIAL_UNITS ,
4743 METRIC_UNITS ,
4844 REGIONS ,
4945 SEMAPHORE ,
5046 UNITS ,
5147 VEHICLE_TYPES ,
5248)
49+ from .coordinator import WazeTravelTimeCoordinator , async_get_travel_times
5350
5451PLATFORMS = [Platform .SENSOR ]
5552
@@ -109,6 +106,16 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
109106 if SEMAPHORE not in hass .data .setdefault (DOMAIN , {}):
110107 hass .data .setdefault (DOMAIN , {})[SEMAPHORE ] = asyncio .Semaphore (1 )
111108
109+ httpx_client = get_async_client (hass )
110+ client = WazeRouteCalculator (
111+ region = config_entry .data [CONF_REGION ].upper (), client = httpx_client
112+ )
113+
114+ coordinator = WazeTravelTimeCoordinator (hass , config_entry , client )
115+ config_entry .runtime_data = coordinator
116+
117+ await coordinator .async_config_entry_first_refresh ()
118+
112119 await hass .config_entries .async_forward_entry_setups (config_entry , PLATFORMS )
113120
114121 async def async_get_travel_times_service (service : ServiceCall ) -> ServiceResponse :
@@ -140,7 +147,7 @@ async def async_get_travel_times_service(service: ServiceCall) -> ServiceRespons
140147 incl_filters = service .data .get (CONF_INCL_FILTER , DEFAULT_FILTER ),
141148 excl_filters = service .data .get (CONF_EXCL_FILTER , DEFAULT_FILTER ),
142149 )
143- return {"routes" : [vars (route ) for route in response ]} if response else None
150+ return {"routes" : [vars (route ) for route in response ]}
144151
145152 hass .services .async_register (
146153 DOMAIN ,
@@ -152,106 +159,6 @@ async def async_get_travel_times_service(service: ServiceCall) -> ServiceRespons
152159 return True
153160
154161
155- async def async_get_travel_times (
156- client : WazeRouteCalculator ,
157- origin : str ,
158- destination : str ,
159- vehicle_type : str ,
160- avoid_toll_roads : bool ,
161- avoid_subscription_roads : bool ,
162- avoid_ferries : bool ,
163- realtime : bool ,
164- units : Literal ["metric" , "imperial" ] = "metric" ,
165- incl_filters : Collection [str ] | None = None ,
166- excl_filters : Collection [str ] | None = None ,
167- ) -> list [CalcRoutesResponse ] | None :
168- """Get all available routes."""
169-
170- incl_filters = incl_filters or ()
171- excl_filters = excl_filters or ()
172-
173- _LOGGER .debug (
174- "Getting update for origin: %s destination: %s" ,
175- origin ,
176- destination ,
177- )
178- routes = []
179- vehicle_type = "" if vehicle_type .upper () == "CAR" else vehicle_type .upper ()
180- try :
181- routes = await client .calc_routes (
182- origin ,
183- destination ,
184- vehicle_type = vehicle_type ,
185- avoid_toll_roads = avoid_toll_roads ,
186- avoid_subscription_roads = avoid_subscription_roads ,
187- avoid_ferries = avoid_ferries ,
188- real_time = realtime ,
189- alternatives = 3 ,
190- )
191- _LOGGER .debug ("Got routes: %s" , routes )
192-
193- incl_routes : list [CalcRoutesResponse ] = []
194-
195- def should_include_route (route : CalcRoutesResponse ) -> bool :
196- if len (incl_filters ) < 1 :
197- return True
198- should_include = any (
199- street_name in incl_filters or "" in incl_filters
200- for street_name in route .street_names
201- )
202- if not should_include :
203- _LOGGER .debug (
204- "Excluding route [%s], because no inclusive filter matched any streetname" ,
205- route .name ,
206- )
207- return False
208- return True
209-
210- incl_routes = [route for route in routes if should_include_route (route )]
211-
212- filtered_routes : list [CalcRoutesResponse ] = []
213-
214- def should_exclude_route (route : CalcRoutesResponse ) -> bool :
215- for street_name in route .street_names :
216- for excl_filter in excl_filters :
217- if excl_filter == street_name :
218- _LOGGER .debug (
219- "Excluding route, because exclusive filter [%s] matched streetname: %s" ,
220- excl_filter ,
221- route .name ,
222- )
223- return True
224- return False
225-
226- filtered_routes = [
227- route for route in incl_routes if not should_exclude_route (route )
228- ]
229-
230- if units == IMPERIAL_UNITS :
231- filtered_routes = [
232- CalcRoutesResponse (
233- name = route .name ,
234- distance = DistanceConverter .convert (
235- route .distance , UnitOfLength .KILOMETERS , UnitOfLength .MILES
236- ),
237- duration = route .duration ,
238- street_names = route .street_names ,
239- )
240- for route in filtered_routes
241- if route .distance is not None
242- ]
243-
244- if len (filtered_routes ) < 1 :
245- _LOGGER .warning ("No routes found" )
246- return None
247- except WRCError as exp :
248- _LOGGER .warning ("Error on retrieving data: %s" , exp )
249- return None
250-
251- else :
252- return filtered_routes
253-
254-
255162async def async_unload_entry (hass : HomeAssistant , config_entry : ConfigEntry ) -> bool :
256163 """Unload a config entry."""
257164 return await hass .config_entries .async_unload_platforms (config_entry , PLATFORMS )
0 commit comments