diff --git a/homeassistant/components/waze_travel_time/helpers.py b/homeassistant/components/waze_travel_time/helpers.py index c9273c1b774..c6fe4d0c9bd 100644 --- a/homeassistant/components/waze_travel_time/helpers.py +++ b/homeassistant/components/waze_travel_time/helpers.py @@ -20,7 +20,7 @@ async def is_valid_config_entry( httpx_client = get_async_client(hass) client = WazeRouteCalculator(region=region, client=httpx_client) try: - await client.calc_all_routes_info(resolved_origin, resolved_destination) + await client.calc_routes(resolved_origin, resolved_destination) except WRCError as error: _LOGGER.error("Error trying to validate entry: %s", error) return False diff --git a/homeassistant/components/waze_travel_time/manifest.json b/homeassistant/components/waze_travel_time/manifest.json index 728a91e4933..4fc08cf983d 100644 --- a/homeassistant/components/waze_travel_time/manifest.json +++ b/homeassistant/components/waze_travel_time/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/waze_travel_time", "iot_class": "cloud_polling", "loggers": ["pywaze", "homeassistant.helpers.location"], - "requirements": ["pywaze==0.5.1"] + "requirements": ["pywaze==1.0.0"] } diff --git a/homeassistant/components/waze_travel_time/sensor.py b/homeassistant/components/waze_travel_time/sensor.py index e759c06bf10..518de269bc5 100644 --- a/homeassistant/components/waze_travel_time/sensor.py +++ b/homeassistant/components/waze_travel_time/sensor.py @@ -196,7 +196,7 @@ class WazeTravelTimeData: routes = {} try: - routes = await self.client.calc_all_routes_info( + routes = await self.client.calc_routes( self.origin, self.destination, vehicle_type=vehicle_type, @@ -204,29 +204,37 @@ class WazeTravelTimeData: avoid_subscription_roads=avoid_subscription_roads, avoid_ferries=avoid_ferries, real_time=realtime, + alternatives=3, ) if incl_filter not in {None, ""}: - routes = { - k: v - for k, v in routes.items() - if incl_filter.lower() in k.lower() - } + routes = [ + r + for r in routes + if any( + incl_filter.lower() == street_name.lower() + for street_name in r.street_names + ) + ] if excl_filter not in {None, ""}: - routes = { - k: v - for k, v in routes.items() - if excl_filter.lower() not in k.lower() - } + routes = [ + r + for r in routes + if not any( + excl_filter.lower() == street_name.lower() + for street_name in r.street_names + ) + ] - if routes: - route = list(routes)[0] - else: + if len(routes) < 1: _LOGGER.warning("No routes found") return - self.duration, distance = routes[route] + route = routes[0] + + self.duration = route.duration + distance = route.distance if units == IMPERIAL_UNITS: # Convert to miles. @@ -236,10 +244,7 @@ class WazeTravelTimeData: else: self.distance = distance - self.route = route + self.route = route.name except WRCError as exp: _LOGGER.warning("Error on retrieving data: %s", exp) return - except KeyError: - _LOGGER.error("Error retrieving data from server") - return diff --git a/homeassistant/components/waze_travel_time/strings.json b/homeassistant/components/waze_travel_time/strings.json index 61b93f13f17..2a5017a5b9f 100644 --- a/homeassistant/components/waze_travel_time/strings.json +++ b/homeassistant/components/waze_travel_time/strings.json @@ -26,8 +26,8 @@ "data": { "units": "Units", "vehicle_type": "Vehicle Type", - "incl_filter": "Substring in Description of Selected Route", - "excl_filter": "Substring NOT in Description of Selected Route", + "incl_filter": "Streetname which must be part of the Selected Route", + "excl_filter": "Streetname which must NOT be part of the Selected Route", "realtime": "Realtime Travel Time?", "avoid_toll_roads": "Avoid Toll Roads?", "avoid_ferries": "Avoid Ferries?", diff --git a/requirements_all.txt b/requirements_all.txt index 70ad107d49e..d58d6351d8e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2360,7 +2360,7 @@ pyvlx==0.2.21 pyvolumio==0.1.5 # homeassistant.components.waze_travel_time -pywaze==0.5.1 +pywaze==1.0.0 # homeassistant.components.weatherflow pyweatherflowudp==1.4.5 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7df7000a5de..601e9770b60 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1821,7 +1821,7 @@ pyvlx==0.2.21 pyvolumio==0.1.5 # homeassistant.components.waze_travel_time -pywaze==0.5.1 +pywaze==1.0.0 # homeassistant.components.weatherflow pyweatherflowudp==1.4.5 diff --git a/tests/components/waze_travel_time/conftest.py b/tests/components/waze_travel_time/conftest.py index 012657bdd8d..01642ace86a 100644 --- a/tests/components/waze_travel_time/conftest.py +++ b/tests/components/waze_travel_time/conftest.py @@ -3,15 +3,28 @@ from unittest.mock import patch import pytest -from pywaze.route_calculator import WRCError +from pywaze.route_calculator import CalcRoutesResponse, WRCError @pytest.fixture(name="mock_update") def mock_update_fixture(): """Mock an update to the sensor.""" with patch( - "pywaze.route_calculator.WazeRouteCalculator.calc_all_routes_info", - return_value={"My route": (150, 300)}, + "pywaze.route_calculator.WazeRouteCalculator.calc_routes", + return_value=[ + CalcRoutesResponse( + distance=300, + duration=150, + name="E1337 - Teststreet", + street_names=["E1337", "IncludeThis", "Teststreet"], + ), + CalcRoutesResponse( + distance=500, + duration=600, + name="E0815 - Otherstreet", + street_names=["E0815", "ExcludeThis", "Otherstreet"], + ), + ], ) as mock_wrc: yield mock_wrc diff --git a/tests/components/waze_travel_time/test_sensor.py b/tests/components/waze_travel_time/test_sensor.py index 0b2ec4297e6..db0ece32cae 100644 --- a/tests/components/waze_travel_time/test_sensor.py +++ b/tests/components/waze_travel_time/test_sensor.py @@ -7,12 +7,15 @@ from homeassistant.components.waze_travel_time.const import ( CONF_AVOID_FERRIES, CONF_AVOID_SUBSCRIPTION_ROADS, CONF_AVOID_TOLL_ROADS, + CONF_EXCL_FILTER, + CONF_INCL_FILTER, CONF_REALTIME, CONF_UNITS, CONF_VEHICLE_TYPE, DEFAULT_OPTIONS, DOMAIN, IMPERIAL_UNITS, + METRIC_UNITS, ) from homeassistant.core import HomeAssistant @@ -22,7 +25,7 @@ from tests.common import MockConfigEntry @pytest.fixture(name="mock_config") -async def mock_config_fixture(hass, data, options): +async def mock_config_fixture(hass: HomeAssistant, data, options): """Mock a Waze Travel Time config entry.""" config_entry = MockConfigEntry( domain=DOMAIN, @@ -42,13 +45,6 @@ def mock_update_wrcerror_fixture(mock_update): return mock_update -@pytest.fixture(name="mock_update_keyerror") -def mock_update_keyerror_fixture(mock_update): - """Mock an update to the sensor failed with KeyError.""" - mock_update.side_effect = KeyError("test") - return mock_update - - @pytest.mark.parametrize( ("data", "options"), [(MOCK_CONFIG, DEFAULT_OPTIONS)], @@ -63,7 +59,10 @@ async def test_sensor(hass: HomeAssistant) -> None: ) assert hass.states.get("sensor.waze_travel_time").attributes["duration"] == 150 assert hass.states.get("sensor.waze_travel_time").attributes["distance"] == 300 - assert hass.states.get("sensor.waze_travel_time").attributes["route"] == "My route" + assert ( + hass.states.get("sensor.waze_travel_time").attributes["route"] + == "E1337 - Teststreet" + ) assert ( hass.states.get("sensor.waze_travel_time").attributes["origin"] == "location1" ) @@ -101,6 +100,52 @@ async def test_imperial(hass: HomeAssistant) -> None: ] == pytest.approx(186.4113) +@pytest.mark.parametrize( + ("data", "options"), + [ + ( + MOCK_CONFIG, + { + CONF_UNITS: METRIC_UNITS, + CONF_REALTIME: True, + CONF_VEHICLE_TYPE: "car", + CONF_AVOID_TOLL_ROADS: True, + CONF_AVOID_SUBSCRIPTION_ROADS: True, + CONF_AVOID_FERRIES: True, + CONF_INCL_FILTER: "IncludeThis", + }, + ) + ], +) +@pytest.mark.usefixtures("mock_update", "mock_config") +async def test_incl_filter(hass: HomeAssistant) -> None: + """Test that incl_filter only includes route with the wanted street name.""" + assert hass.states.get("sensor.waze_travel_time").attributes["distance"] == 300 + + +@pytest.mark.parametrize( + ("data", "options"), + [ + ( + MOCK_CONFIG, + { + CONF_UNITS: METRIC_UNITS, + CONF_REALTIME: True, + CONF_VEHICLE_TYPE: "car", + CONF_AVOID_TOLL_ROADS: True, + CONF_AVOID_SUBSCRIPTION_ROADS: True, + CONF_AVOID_FERRIES: True, + CONF_EXCL_FILTER: "ExcludeThis", + }, + ) + ], +) +@pytest.mark.usefixtures("mock_update", "mock_config") +async def test_excl_filter(hass: HomeAssistant) -> None: + """Test that excl_filter only includes route without the street name.""" + assert hass.states.get("sensor.waze_travel_time").attributes["distance"] == 300 + + @pytest.mark.usefixtures("mock_update_wrcerror") async def test_sensor_failed_wrcerror( hass: HomeAssistant, caplog: pytest.LogCaptureFixture @@ -115,19 +160,3 @@ async def test_sensor_failed_wrcerror( assert hass.states.get("sensor.waze_travel_time").state == "unknown" assert "Error on retrieving data: " in caplog.text - - -@pytest.mark.usefixtures("mock_update_keyerror") -async def test_sensor_failed_keyerror( - hass: HomeAssistant, caplog: pytest.LogCaptureFixture -) -> None: - """Test that sensor update fails with log message.""" - config_entry = MockConfigEntry( - domain=DOMAIN, data=MOCK_CONFIG, options=DEFAULT_OPTIONS, entry_id="test" - ) - config_entry.add_to_hass(hass) - await hass.config_entries.async_setup(config_entry.entry_id) - await hass.async_block_till_done() - - assert hass.states.get("sensor.waze_travel_time").state == "unknown" - assert "Error retrieving data from server" in caplog.text