From 0e71ef3861ff4cd0c6b51d72eeb6485da4c3d074 Mon Sep 17 00:00:00 2001 From: Kevin Stillhammer Date: Wed, 11 Jun 2025 18:17:11 +0200 Subject: [PATCH] Fix stale options in here_travel_time (#145911) --- .../components/here_travel_time/__init__.py | 33 +--- .../here_travel_time/coordinator.py | 144 +++++++++++------- .../components/here_travel_time/model.py | 18 +-- 3 files changed, 94 insertions(+), 101 deletions(-) diff --git a/homeassistant/components/here_travel_time/__init__.py b/homeassistant/components/here_travel_time/__init__.py index 525da15bd74..5393dfa5050 100644 --- a/homeassistant/components/here_travel_time/__init__.py +++ b/homeassistant/components/here_travel_time/__init__.py @@ -5,26 +5,13 @@ from __future__ import annotations from homeassistant.const import CONF_API_KEY, CONF_MODE, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.start import async_at_started -from homeassistant.util import dt as dt_util -from .const import ( - CONF_ARRIVAL_TIME, - CONF_DEPARTURE_TIME, - CONF_DESTINATION_ENTITY_ID, - CONF_DESTINATION_LATITUDE, - CONF_DESTINATION_LONGITUDE, - CONF_ORIGIN_ENTITY_ID, - CONF_ORIGIN_LATITUDE, - CONF_ORIGIN_LONGITUDE, - CONF_ROUTE_MODE, - TRAVEL_MODE_PUBLIC, -) +from .const import TRAVEL_MODE_PUBLIC from .coordinator import ( HereConfigEntry, HERERoutingDataUpdateCoordinator, HERETransitDataUpdateCoordinator, ) -from .model import HERETravelTimeConfig PLATFORMS = [Platform.SENSOR] @@ -33,29 +20,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: HereConfigEntry) """Set up HERE Travel Time from a config entry.""" api_key = config_entry.data[CONF_API_KEY] - arrival = dt_util.parse_time(config_entry.options.get(CONF_ARRIVAL_TIME, "")) - departure = dt_util.parse_time(config_entry.options.get(CONF_DEPARTURE_TIME, "")) - - here_travel_time_config = HERETravelTimeConfig( - destination_latitude=config_entry.data.get(CONF_DESTINATION_LATITUDE), - destination_longitude=config_entry.data.get(CONF_DESTINATION_LONGITUDE), - destination_entity_id=config_entry.data.get(CONF_DESTINATION_ENTITY_ID), - origin_latitude=config_entry.data.get(CONF_ORIGIN_LATITUDE), - origin_longitude=config_entry.data.get(CONF_ORIGIN_LONGITUDE), - origin_entity_id=config_entry.data.get(CONF_ORIGIN_ENTITY_ID), - travel_mode=config_entry.data[CONF_MODE], - route_mode=config_entry.options[CONF_ROUTE_MODE], - arrival=arrival, - departure=departure, - ) - cls: type[HERETransitDataUpdateCoordinator | HERERoutingDataUpdateCoordinator] if config_entry.data[CONF_MODE] in {TRAVEL_MODE_PUBLIC, "publicTransportTimeTable"}: cls = HERETransitDataUpdateCoordinator else: cls = HERERoutingDataUpdateCoordinator - data_coordinator = cls(hass, config_entry, api_key, here_travel_time_config) + data_coordinator = cls(hass, config_entry, api_key) config_entry.runtime_data = data_coordinator async def _async_update_at_start(_: HomeAssistant) -> None: diff --git a/homeassistant/components/here_travel_time/coordinator.py b/homeassistant/components/here_travel_time/coordinator.py index aa36404c584..447a45f5d2b 100644 --- a/homeassistant/components/here_travel_time/coordinator.py +++ b/homeassistant/components/here_travel_time/coordinator.py @@ -26,7 +26,7 @@ from here_transit import ( import voluptuous as vol from homeassistant.config_entries import ConfigEntry -from homeassistant.const import UnitOfLength +from homeassistant.const import CONF_MODE, UnitOfLength from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.location import find_coordinates @@ -34,8 +34,21 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from homeassistant.util import dt as dt_util from homeassistant.util.unit_conversion import DistanceConverter -from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, ROUTE_MODE_FASTEST -from .model import HERETravelTimeConfig, HERETravelTimeData +from .const import ( + CONF_ARRIVAL_TIME, + CONF_DEPARTURE_TIME, + CONF_DESTINATION_ENTITY_ID, + CONF_DESTINATION_LATITUDE, + CONF_DESTINATION_LONGITUDE, + CONF_ORIGIN_ENTITY_ID, + CONF_ORIGIN_LATITUDE, + CONF_ORIGIN_LONGITUDE, + CONF_ROUTE_MODE, + DEFAULT_SCAN_INTERVAL, + DOMAIN, + ROUTE_MODE_FASTEST, +) +from .model import HERETravelTimeAPIParams, HERETravelTimeData BACKOFF_MULTIPLIER = 1.1 @@ -47,7 +60,7 @@ type HereConfigEntry = ConfigEntry[ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData]): - """here_routing DataUpdateCoordinator.""" + """HERETravelTime DataUpdateCoordinator for the routing API.""" config_entry: HereConfigEntry @@ -56,7 +69,6 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData] hass: HomeAssistant, config_entry: HereConfigEntry, api_key: str, - config: HERETravelTimeConfig, ) -> None: """Initialize.""" super().__init__( @@ -67,41 +79,34 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData] update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL), ) self._api = HERERoutingApi(api_key) - self.config = config async def _async_update_data(self) -> HERETravelTimeData: """Get the latest data from the HERE Routing API.""" - origin, destination, arrival, departure = prepare_parameters( - self.hass, self.config - ) - - route_mode = ( - RoutingMode.FAST - if self.config.route_mode == ROUTE_MODE_FASTEST - else RoutingMode.SHORT - ) + params = prepare_parameters(self.hass, self.config_entry) _LOGGER.debug( ( "Requesting route for origin: %s, destination: %s, route_mode: %s," " mode: %s, arrival: %s, departure: %s" ), - origin, - destination, - route_mode, - TransportMode(self.config.travel_mode), - arrival, - departure, + params.origin, + params.destination, + params.route_mode, + TransportMode(params.travel_mode), + params.arrival, + params.departure, ) try: response = await self._api.route( - transport_mode=TransportMode(self.config.travel_mode), - origin=here_routing.Place(origin[0], origin[1]), - destination=here_routing.Place(destination[0], destination[1]), - routing_mode=route_mode, - arrival_time=arrival, - departure_time=departure, + transport_mode=TransportMode(params.travel_mode), + origin=here_routing.Place(params.origin[0], params.origin[1]), + destination=here_routing.Place( + params.destination[0], params.destination[1] + ), + routing_mode=params.route_mode, + arrival_time=params.arrival, + departure_time=params.departure, return_values=[Return.POLYINE, Return.SUMMARY], spans=[Spans.NAMES], ) @@ -175,7 +180,7 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData] class HERETransitDataUpdateCoordinator( DataUpdateCoordinator[HERETravelTimeData | None] ): - """HERETravelTime DataUpdateCoordinator.""" + """HERETravelTime DataUpdateCoordinator for the transit API.""" config_entry: HereConfigEntry @@ -184,7 +189,6 @@ class HERETransitDataUpdateCoordinator( hass: HomeAssistant, config_entry: HereConfigEntry, api_key: str, - config: HERETravelTimeConfig, ) -> None: """Initialize.""" super().__init__( @@ -195,32 +199,31 @@ class HERETransitDataUpdateCoordinator( update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL), ) self._api = HERETransitApi(api_key) - self.config = config async def _async_update_data(self) -> HERETravelTimeData | None: """Get the latest data from the HERE Routing API.""" - origin, destination, arrival, departure = prepare_parameters( - self.hass, self.config - ) + params = prepare_parameters(self.hass, self.config_entry) _LOGGER.debug( ( "Requesting transit route for origin: %s, destination: %s, arrival: %s," " departure: %s" ), - origin, - destination, - arrival, - departure, + params.origin, + params.destination, + params.arrival, + params.departure, ) try: response = await self._api.route( - origin=here_transit.Place(latitude=origin[0], longitude=origin[1]), - destination=here_transit.Place( - latitude=destination[0], longitude=destination[1] + origin=here_transit.Place( + latitude=params.origin[0], longitude=params.origin[1] ), - arrival_time=arrival, - departure_time=departure, + destination=here_transit.Place( + latitude=params.destination[0], longitude=params.destination[1] + ), + arrival_time=params.arrival, + departure_time=params.departure, return_values=[ here_transit.Return.POLYLINE, here_transit.Return.TRAVEL_SUMMARY, @@ -285,8 +288,8 @@ class HERETransitDataUpdateCoordinator( def prepare_parameters( hass: HomeAssistant, - config: HERETravelTimeConfig, -) -> tuple[list[str], list[str], str | None, str | None]: + config_entry: HereConfigEntry, +) -> HERETravelTimeAPIParams: """Prepare parameters for the HERE api.""" def _from_entity_id(entity_id: str) -> list[str]: @@ -305,32 +308,55 @@ def prepare_parameters( return formatted_coordinates # Destination - if config.destination_entity_id is not None: - destination = _from_entity_id(config.destination_entity_id) + if ( + destination_entity_id := config_entry.data.get(CONF_DESTINATION_ENTITY_ID) + ) is not None: + destination = _from_entity_id(str(destination_entity_id)) else: destination = [ - str(config.destination_latitude), - str(config.destination_longitude), + str(config_entry.data[CONF_DESTINATION_LATITUDE]), + str(config_entry.data[CONF_DESTINATION_LONGITUDE]), ] # Origin - if config.origin_entity_id is not None: - origin = _from_entity_id(config.origin_entity_id) + if (origin_entity_id := config_entry.data.get(CONF_ORIGIN_ENTITY_ID)) is not None: + origin = _from_entity_id(str(origin_entity_id)) else: origin = [ - str(config.origin_latitude), - str(config.origin_longitude), + str(config_entry.data[CONF_ORIGIN_LATITUDE]), + str(config_entry.data[CONF_ORIGIN_LONGITUDE]), ] # Arrival/Departure - arrival: str | None = None - departure: str | None = None - if config.arrival is not None: - arrival = next_datetime(config.arrival).isoformat() - if config.departure is not None: - departure = next_datetime(config.departure).isoformat() + arrival: datetime | None = None + if ( + conf_arrival := dt_util.parse_time( + config_entry.options.get(CONF_ARRIVAL_TIME, "") + ) + ) is not None: + arrival = next_datetime(conf_arrival) + departure: datetime | None = None + if ( + conf_departure := dt_util.parse_time( + config_entry.options.get(CONF_DEPARTURE_TIME, "") + ) + ) is not None: + departure = next_datetime(conf_departure) - return (origin, destination, arrival, departure) + route_mode = ( + RoutingMode.FAST + if config_entry.options[CONF_ROUTE_MODE] == ROUTE_MODE_FASTEST + else RoutingMode.SHORT + ) + + return HERETravelTimeAPIParams( + destination=destination, + origin=origin, + travel_mode=config_entry.data[CONF_MODE], + route_mode=route_mode, + arrival=arrival, + departure=departure, + ) def build_hass_attribution(sections: list[dict[str, Any]]) -> str | None: diff --git a/homeassistant/components/here_travel_time/model.py b/homeassistant/components/here_travel_time/model.py index 178c0d8c805..cbac2b1c353 100644 --- a/homeassistant/components/here_travel_time/model.py +++ b/homeassistant/components/here_travel_time/model.py @@ -3,7 +3,7 @@ from __future__ import annotations from dataclasses import dataclass -from datetime import time +from datetime import datetime from typing import TypedDict @@ -21,16 +21,12 @@ class HERETravelTimeData(TypedDict): @dataclass -class HERETravelTimeConfig: - """Configuration for HereTravelTimeDataUpdateCoordinator.""" +class HERETravelTimeAPIParams: + """Configuration for polling the HERE API.""" - destination_latitude: float | None - destination_longitude: float | None - destination_entity_id: str | None - origin_latitude: float | None - origin_longitude: float | None - origin_entity_id: str | None + destination: list[str] + origin: list[str] travel_mode: str route_mode: str - arrival: time | None - departure: time | None + arrival: datetime | None + departure: datetime | None