Exchange WazeRouteCalculator with pywaze in waze_travel_time (#98169)

* exchange WazeRouteCalculator with pywaze

* directly use async is_valid_config_entry

* store pywaze client as property

* fix tests

* Remove obsolete error logs

* Reuse existing httpx client

* Remove redundant typing

* Do not clcose common httpx client
This commit is contained in:
Kevin Stillhammer 2023-08-14 10:02:30 +02:00 committed by GitHub
parent 96f9b852a2
commit 066db11620
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 58 additions and 59 deletions

View File

@ -129,8 +129,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if user_input:
user_input[CONF_REGION] = user_input[CONF_REGION].upper()
if await self.hass.async_add_executor_job(
is_valid_config_entry,
if await is_valid_config_entry(
self.hass,
user_input[CONF_ORIGIN],
user_input[CONF_DESTINATION],

View File

@ -1,19 +1,25 @@
"""Helpers for Waze Travel Time integration."""
import logging
from WazeRouteCalculator import WazeRouteCalculator, WRCError
from pywaze.route_calculator import WazeRouteCalculator, WRCError
from homeassistant.core import HomeAssistant
from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.helpers.location import find_coordinates
_LOGGER = logging.getLogger(__name__)
def is_valid_config_entry(hass, origin, destination, region):
async def is_valid_config_entry(
hass: HomeAssistant, origin: str, destination: str, region: str
) -> bool:
"""Return whether the config entry data is valid."""
origin = find_coordinates(hass, origin)
destination = find_coordinates(hass, destination)
resolved_origin = find_coordinates(hass, origin)
resolved_destination = find_coordinates(hass, destination)
httpx_client = get_async_client(hass)
client = WazeRouteCalculator(region=region, client=httpx_client)
try:
WazeRouteCalculator(origin, destination, region).calc_all_routes_info()
await client.calc_all_routes_info(resolved_origin, resolved_destination)
except WRCError as error:
_LOGGER.error("Error trying to validate entry: %s", error)
return False

View File

@ -5,6 +5,6 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/waze_travel_time",
"iot_class": "cloud_polling",
"loggers": ["WazeRouteCalculator", "homeassistant.helpers.location"],
"requirements": ["WazeRouteCalculator==0.14"]
"loggers": ["pywaze", "homeassistant.helpers.location"],
"requirements": ["pywaze==0.3.0"]
}

View File

@ -5,7 +5,8 @@ from datetime import timedelta
import logging
from typing import Any
from WazeRouteCalculator import WazeRouteCalculator, WRCError
import httpx
from pywaze.route_calculator import WazeRouteCalculator, WRCError
from homeassistant.components.sensor import (
SensorDeviceClass,
@ -23,6 +24,7 @@ from homeassistant.const import (
from homeassistant.core import CoreState, HomeAssistant
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
@ -60,6 +62,7 @@ async def async_setup_entry(
data = WazeTravelTimeData(
region,
get_async_client(hass),
config_entry,
)
@ -132,31 +135,33 @@ class WazeTravelTime(SensorEntity):
async def first_update(self, _=None) -> None:
"""Run first update and write state."""
await self.hass.async_add_executor_job(self.update)
await self.async_update()
self.async_write_ha_state()
def update(self) -> None:
async def async_update(self) -> None:
"""Fetch new state data for the sensor."""
_LOGGER.debug("Fetching Route for %s", self._attr_name)
self._waze_data.origin = find_coordinates(self.hass, self._origin)
self._waze_data.destination = find_coordinates(self.hass, self._destination)
self._waze_data.update()
await self._waze_data.async_update()
class WazeTravelTimeData:
"""WazeTravelTime Data object."""
def __init__(self, region: str, config_entry: ConfigEntry) -> None:
def __init__(
self, region: str, client: httpx.AsyncClient, config_entry: ConfigEntry
) -> None:
"""Set up WazeRouteCalculator."""
self.region = region
self.config_entry = config_entry
self.client = WazeRouteCalculator(region=region, client=client)
self.origin: str | None = None
self.destination: str | None = None
self.duration = None
self.distance = None
self.route = None
def update(self):
async def async_update(self):
"""Update WazeRouteCalculator Sensor."""
_LOGGER.debug(
"Getting update for origin: %s destination: %s",
@ -177,17 +182,17 @@ class WazeTravelTimeData:
avoid_ferries = self.config_entry.options[CONF_AVOID_FERRIES]
units = self.config_entry.options[CONF_UNITS]
routes = {}
try:
params = WazeRouteCalculator(
routes = await self.client.calc_all_routes_info(
self.origin,
self.destination,
self.region,
vehicle_type,
avoid_toll_roads,
avoid_subscription_roads,
avoid_ferries,
vehicle_type=vehicle_type,
avoid_toll_roads=avoid_toll_roads,
avoid_subscription_roads=avoid_subscription_roads,
avoid_ferries=avoid_ferries,
real_time=realtime,
)
routes = params.calc_all_routes_info(real_time=realtime)
if incl_filter not in {None, ""}:
routes = {

View File

@ -139,9 +139,6 @@ TwitterAPI==2.7.12
# homeassistant.components.onvif
WSDiscovery==2.0.0
# homeassistant.components.waze_travel_time
WazeRouteCalculator==0.14
# homeassistant.components.accuweather
accuweather==1.0.0
@ -2226,6 +2223,9 @@ pyvlx==0.2.20
# homeassistant.components.volumio
pyvolumio==0.1.5
# homeassistant.components.waze_travel_time
pywaze==0.3.0
# homeassistant.components.html5
pywebpush==1.9.2

View File

@ -120,9 +120,6 @@ SQLAlchemy==2.0.15
# homeassistant.components.onvif
WSDiscovery==2.0.0
# homeassistant.components.waze_travel_time
WazeRouteCalculator==0.14
# homeassistant.components.accuweather
accuweather==1.0.0
@ -1634,6 +1631,9 @@ pyvizio==0.1.61
# homeassistant.components.volumio
pyvolumio==0.1.5
# homeassistant.components.waze_travel_time
pywaze==0.3.0
# homeassistant.components.html5
pywebpush==1.9.2

View File

@ -2,42 +2,31 @@
from unittest.mock import patch
import pytest
from WazeRouteCalculator import WRCError
@pytest.fixture(name="mock_wrc", autouse=True)
def mock_wrc_fixture():
"""Mock out WazeRouteCalculator."""
with patch(
"homeassistant.components.waze_travel_time.sensor.WazeRouteCalculator"
) as mock_wrc:
yield mock_wrc
from pywaze.route_calculator import WRCError
@pytest.fixture(name="mock_update")
def mock_update_fixture(mock_wrc):
def mock_update_fixture():
"""Mock an update to the sensor."""
obj = mock_wrc.return_value
obj.calc_all_routes_info.return_value = {"My route": (150, 300)}
with patch(
"pywaze.route_calculator.WazeRouteCalculator.calc_all_routes_info",
return_value={"My route": (150, 300)},
) as mock_wrc:
yield mock_wrc
@pytest.fixture(name="validate_config_entry")
def validate_config_entry_fixture():
def validate_config_entry_fixture(mock_update):
"""Return valid config entry."""
with patch(
"homeassistant.components.waze_travel_time.helpers.WazeRouteCalculator"
) as mock_wrc:
obj = mock_wrc.return_value
obj.calc_all_routes_info.return_value = None
yield mock_wrc
mock_update.return_value = None
return mock_update
@pytest.fixture(name="invalidate_config_entry")
def invalidate_config_entry_fixture(validate_config_entry):
"""Return invalid config entry."""
obj = validate_config_entry.return_value
obj.calc_all_routes_info.return_value = {}
obj.calc_all_routes_info.side_effect = WRCError("test")
validate_config_entry.side_effect = WRCError("test")
return validate_config_entry
@pytest.fixture(name="bypass_platform_setup")

View File

@ -1,6 +1,6 @@
"""Test Waze Travel Time sensors."""
import pytest
from WazeRouteCalculator import WRCError
from pywaze.route_calculator import WRCError
from homeassistant.components.waze_travel_time.const import (
CONF_AVOID_FERRIES,
@ -35,17 +35,17 @@ async def mock_config_fixture(hass, data, options):
@pytest.fixture(name="mock_update_wrcerror")
def mock_update_wrcerror_fixture(mock_wrc):
def mock_update_wrcerror_fixture(mock_update):
"""Mock an update to the sensor failed with WRCError."""
obj = mock_wrc.return_value
obj.calc_all_routes_info.side_effect = WRCError("test")
mock_update.side_effect = WRCError("test")
return mock_update
@pytest.fixture(name="mock_update_keyerror")
def mock_update_keyerror_fixture(mock_wrc):
def mock_update_keyerror_fixture(mock_update):
"""Mock an update to the sensor failed with KeyError."""
obj = mock_wrc.return_value
obj.calc_all_routes_info.side_effect = KeyError("test")
mock_update.side_effect = KeyError("test")
return mock_update
@pytest.mark.parametrize(