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

This commit is contained in:
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 import asyncio
from collections.abc import Collection from collections.abc import Collection
import logging import logging
from typing import Literal
from pywaze.route_calculator import CalcRoutesResponse, WazeRouteCalculator, WRCError from pywaze.route_calculator import CalcRoutesResponse, WazeRouteCalculator, WRCError
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ConfigEntry 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 ( from homeassistant.core import (
HomeAssistant, HomeAssistant,
ServiceCall, ServiceCall,
@ -22,7 +23,10 @@ from homeassistant.helpers.selector import (
SelectSelectorConfig, SelectSelectorConfig,
SelectSelectorMode, SelectSelectorMode,
TextSelector, TextSelector,
TextSelectorConfig,
TextSelectorType,
) )
from homeassistant.util.unit_conversion import DistanceConverter
from .const import ( from .const import (
CONF_AVOID_FERRIES, CONF_AVOID_FERRIES,
@ -38,6 +42,7 @@ from .const import (
DEFAULT_FILTER, DEFAULT_FILTER,
DEFAULT_VEHICLE_TYPE, DEFAULT_VEHICLE_TYPE,
DOMAIN, DOMAIN,
IMPERIAL_UNITS,
METRIC_UNITS, METRIC_UNITS,
REGIONS, REGIONS,
SEMAPHORE, 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_TOLL_ROADS, default=False): BooleanSelector(),
vol.Optional(CONF_AVOID_SUBSCRIPTION_ROADS, default=False): BooleanSelector(), vol.Optional(CONF_AVOID_SUBSCRIPTION_ROADS, default=False): BooleanSelector(),
vol.Optional(CONF_AVOID_FERRIES, 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_subscription_roads=service.data[CONF_AVOID_SUBSCRIPTION_ROADS],
avoid_ferries=service.data[CONF_AVOID_FERRIES], avoid_ferries=service.data[CONF_AVOID_FERRIES],
realtime=service.data[CONF_REALTIME], 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 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_subscription_roads: bool,
avoid_ferries: bool, avoid_ferries: bool,
realtime: bool, realtime: bool,
units: Literal["metric", "imperial"] = "metric",
incl_filters: Collection[str] | None = None, incl_filters: Collection[str] | None = None,
excl_filters: Collection[str] | None = None, excl_filters: Collection[str] | None = None,
) -> list[CalcRoutesResponse] | 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) 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: if len(filtered_routes) < 1:
_LOGGER.warning("No routes found") _LOGGER.warning("No routes found")
return None return None

View File

@ -20,7 +20,6 @@ from homeassistant.const import (
CONF_NAME, CONF_NAME,
CONF_REGION, CONF_REGION,
EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STARTED,
UnitOfLength,
UnitOfTime, UnitOfTime,
) )
from homeassistant.core import CoreState, HomeAssistant 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.entity_platform import AddEntitiesCallback
from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.helpers.location import find_coordinates from homeassistant.helpers.location import find_coordinates
from homeassistant.util.unit_conversion import DistanceConverter
from . import async_get_travel_times from . import async_get_travel_times
from .const import ( from .const import (
@ -44,7 +42,6 @@ from .const import (
CONF_VEHICLE_TYPE, CONF_VEHICLE_TYPE,
DEFAULT_NAME, DEFAULT_NAME,
DOMAIN, DOMAIN,
IMPERIAL_UNITS,
SEMAPHORE, SEMAPHORE,
) )
@ -201,6 +198,7 @@ class WazeTravelTimeData:
avoid_subscription_roads, avoid_subscription_roads,
avoid_ferries, avoid_ferries,
realtime, realtime,
self.config_entry.options[CONF_UNITS],
incl_filter, incl_filter,
excl_filter, excl_filter,
) )
@ -211,14 +209,5 @@ class WazeTravelTimeData:
return return
self.duration = route.duration self.duration = route.duration
distance = route.distance self.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.route = route.name self.route = route.name

View File

@ -55,3 +55,13 @@ get_travel_times:
required: false required: false
selector: selector:
boolean: 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": { "avoid_subscription_roads": {
"name": "[%key:component::waze_travel_time::options::step::init::data::avoid_subscription_roads%]", "name": "[%key:component::waze_travel_time::options::step::init::data::avoid_subscription_roads%]",
"description": "Whether to 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", "destination": "location2",
"vehicle_type": "car", "vehicle_type": "car",
"region": "us", "region": "us",
"units": "imperial",
"incl_filter": ["IncludeThis"],
}, },
blocking=True, blocking=True,
return_response=True, return_response=True,
@ -51,17 +53,11 @@ async def test_service_get_travel_times(hass: HomeAssistant) -> None:
assert response_data == { assert response_data == {
"routes": [ "routes": [
{ {
"distance": 300, "distance": pytest.approx(186.4113),
"duration": 150, "duration": 150,
"name": "E1337 - Teststreet", "name": "E1337 - Teststreet",
"street_names": ["E1337", "IncludeThis", "Teststreet"], "street_names": ["E1337", "IncludeThis", "Teststreet"],
}, },
{
"distance": 500,
"duration": 600,
"name": "E0815 - Otherstreet",
"street_names": ["E0815", "ExcludeThis", "Otherstreet"],
},
] ]
} }