Support units and filters in async_get_travel_times_service for waze_travel_time (#130776)

pull/119120/head^2
Kevin Stillhammer 2024-12-17 18:00:23 +01:00 committed by GitHub
parent da85c497bf
commit 98d5020690
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 21 deletions

View File

@ -3,12 +3,13 @@
import asyncio
from collections.abc import Collection
import logging
from typing import Literal
from pywaze.route_calculator import CalcRoutesResponse, WazeRouteCalculator, WRCError
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_REGION, Platform
from homeassistant.const import CONF_REGION, Platform, UnitOfLength
from homeassistant.core import (
HomeAssistant,
ServiceCall,
@ -22,7 +23,10 @@ from homeassistant.helpers.selector import (
SelectSelectorConfig,
SelectSelectorMode,
TextSelector,
TextSelectorConfig,
TextSelectorType,
)
from homeassistant.util.unit_conversion import DistanceConverter
from .const import (
CONF_AVOID_FERRIES,
@ -38,6 +42,7 @@ from .const import (
DEFAULT_FILTER,
DEFAULT_VEHICLE_TYPE,
DOMAIN,
IMPERIAL_UNITS,
METRIC_UNITS,
REGIONS,
SEMAPHORE,
@ -80,6 +85,18 @@ SERVICE_GET_TRAVEL_TIMES_SCHEMA = vol.Schema(
vol.Optional(CONF_AVOID_TOLL_ROADS, default=False): BooleanSelector(),
vol.Optional(CONF_AVOID_SUBSCRIPTION_ROADS, default=False): BooleanSelector(),
vol.Optional(CONF_AVOID_FERRIES, default=False): BooleanSelector(),
vol.Optional(CONF_INCL_FILTER): TextSelector(
TextSelectorConfig(
type=TextSelectorType.TEXT,
multiple=True,
),
),
vol.Optional(CONF_EXCL_FILTER): TextSelector(
TextSelectorConfig(
type=TextSelectorType.TEXT,
multiple=True,
),
),
}
)
@ -107,6 +124,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
avoid_subscription_roads=service.data[CONF_AVOID_SUBSCRIPTION_ROADS],
avoid_ferries=service.data[CONF_AVOID_FERRIES],
realtime=service.data[CONF_REALTIME],
units=service.data[CONF_UNITS],
incl_filters=service.data.get(CONF_INCL_FILTER, DEFAULT_FILTER),
excl_filters=service.data.get(CONF_EXCL_FILTER, DEFAULT_FILTER),
)
return {"routes": [vars(route) for route in response]} if response else None
@ -129,6 +149,7 @@ async def async_get_travel_times(
avoid_subscription_roads: bool,
avoid_ferries: bool,
realtime: bool,
units: Literal["metric", "imperial"] = "metric",
incl_filters: Collection[str] | None = None,
excl_filters: Collection[str] | None = None,
) -> list[CalcRoutesResponse] | None:
@ -194,6 +215,20 @@ async def async_get_travel_times(
route for route in incl_routes if not should_exclude_route(route)
]
if units == IMPERIAL_UNITS:
filtered_routes = [
CalcRoutesResponse(
name=route.name,
distance=DistanceConverter.convert(
route.distance, UnitOfLength.KILOMETERS, UnitOfLength.MILES
),
duration=route.duration,
street_names=route.street_names,
)
for route in filtered_routes
if route.distance is not None
]
if len(filtered_routes) < 1:
_LOGGER.warning("No routes found")
return None

View File

@ -20,7 +20,6 @@ from homeassistant.const import (
CONF_NAME,
CONF_REGION,
EVENT_HOMEASSISTANT_STARTED,
UnitOfLength,
UnitOfTime,
)
from homeassistant.core import CoreState, HomeAssistant
@ -28,7 +27,6 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.helpers.location import find_coordinates
from homeassistant.util.unit_conversion import DistanceConverter
from . import async_get_travel_times
from .const import (
@ -44,7 +42,6 @@ from .const import (
CONF_VEHICLE_TYPE,
DEFAULT_NAME,
DOMAIN,
IMPERIAL_UNITS,
SEMAPHORE,
)
@ -201,6 +198,7 @@ class WazeTravelTimeData:
avoid_subscription_roads,
avoid_ferries,
realtime,
self.config_entry.options[CONF_UNITS],
incl_filter,
excl_filter,
)
@ -211,14 +209,5 @@ class WazeTravelTimeData:
return
self.duration = route.duration
distance = route.distance
if self.config_entry.options[CONF_UNITS] == IMPERIAL_UNITS:
# Convert to miles.
self.distance = DistanceConverter.convert(
distance, UnitOfLength.KILOMETERS, UnitOfLength.MILES
)
else:
self.distance = distance
self.distance = route.distance
self.route = route.name

View File

@ -55,3 +55,13 @@ get_travel_times:
required: false
selector:
boolean:
incl_filter:
required: false
selector:
text:
multiple: true
excl_filter:
required: false
selector:
text:
multiple: true

View File

@ -101,6 +101,14 @@
"avoid_subscription_roads": {
"name": "[%key:component::waze_travel_time::options::step::init::data::avoid_subscription_roads%]",
"description": "Whether to avoid subscription roads."
},
"incl_filter": {
"name": "[%key:component::waze_travel_time::options::step::init::data::incl_filter%]",
"description": "Exact streetname which must be part of the selected route."
},
"excl_filter": {
"name": "[%key:component::waze_travel_time::options::step::init::data::excl_filter%]",
"description": "Exact streetname which must NOT be part of the selected route."
}
}
}

View File

@ -44,6 +44,8 @@ async def test_service_get_travel_times(hass: HomeAssistant) -> None:
"destination": "location2",
"vehicle_type": "car",
"region": "us",
"units": "imperial",
"incl_filter": ["IncludeThis"],
},
blocking=True,
return_response=True,
@ -51,17 +53,11 @@ async def test_service_get_travel_times(hass: HomeAssistant) -> None:
assert response_data == {
"routes": [
{
"distance": 300,
"distance": pytest.approx(186.4113),
"duration": 150,
"name": "E1337 - Teststreet",
"street_names": ["E1337", "IncludeThis", "Teststreet"],
},
{
"distance": 500,
"duration": 600,
"name": "E0815 - Otherstreet",
"street_names": ["E0815", "ExcludeThis", "Otherstreet"],
},
]
}