mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add Here travel time arrival departure (#29909)
* here_travel_time: Add modes arrival and departure * convert arrival/departure from datetime to time * Default departure is set by external lib on None * Use cv.key_value_schemas
This commit is contained in:
parent
7ac014744c
commit
2cda7bf1e7
@ -1,5 +1,5 @@
|
|||||||
"""Support for HERE travel time sensors."""
|
"""Support for HERE travel time sensors."""
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Callable, Dict, Optional, Union
|
from typing import Callable, Dict, Optional, Union
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ from homeassistant.core import HomeAssistant, State, callback
|
|||||||
from homeassistant.helpers import location
|
from homeassistant.helpers import location
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
import homeassistant.util.dt as dt
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -36,6 +37,8 @@ CONF_ORIGIN_ENTITY_ID = "origin_entity_id"
|
|||||||
CONF_API_KEY = "api_key"
|
CONF_API_KEY = "api_key"
|
||||||
CONF_TRAFFIC_MODE = "traffic_mode"
|
CONF_TRAFFIC_MODE = "traffic_mode"
|
||||||
CONF_ROUTE_MODE = "route_mode"
|
CONF_ROUTE_MODE = "route_mode"
|
||||||
|
CONF_ARRIVAL = "arrival"
|
||||||
|
CONF_DEPARTURE = "departure"
|
||||||
|
|
||||||
DEFAULT_NAME = "HERE Travel Time"
|
DEFAULT_NAME = "HERE Travel Time"
|
||||||
|
|
||||||
@ -90,32 +93,49 @@ SCAN_INTERVAL = timedelta(minutes=5)
|
|||||||
|
|
||||||
NO_ROUTE_ERROR_MESSAGE = "HERE could not find a route based on the input"
|
NO_ROUTE_ERROR_MESSAGE = "HERE could not find a route based on the input"
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_API_KEY): cv.string,
|
||||||
|
vol.Inclusive(
|
||||||
|
CONF_DESTINATION_LATITUDE, "destination_coordinates"
|
||||||
|
): cv.latitude,
|
||||||
|
vol.Inclusive(
|
||||||
|
CONF_DESTINATION_LONGITUDE, "destination_coordinates"
|
||||||
|
): cv.longitude,
|
||||||
|
vol.Exclusive(CONF_DESTINATION_LATITUDE, "destination"): cv.latitude,
|
||||||
|
vol.Exclusive(CONF_DESTINATION_ENTITY_ID, "destination"): cv.entity_id,
|
||||||
|
vol.Inclusive(CONF_ORIGIN_LATITUDE, "origin_coordinates"): cv.latitude,
|
||||||
|
vol.Inclusive(CONF_ORIGIN_LONGITUDE, "origin_coordinates"): cv.longitude,
|
||||||
|
vol.Exclusive(CONF_ORIGIN_LATITUDE, "origin"): cv.latitude,
|
||||||
|
vol.Exclusive(CONF_ORIGIN_ENTITY_ID, "origin"): cv.entity_id,
|
||||||
|
vol.Optional(CONF_DEPARTURE): cv.time,
|
||||||
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||||
|
vol.Optional(CONF_MODE, default=TRAVEL_MODE_CAR): vol.In(TRAVEL_MODE),
|
||||||
|
vol.Optional(CONF_ROUTE_MODE, default=ROUTE_MODE_FASTEST): vol.In(ROUTE_MODE),
|
||||||
|
vol.Optional(CONF_TRAFFIC_MODE, default=False): cv.boolean,
|
||||||
|
vol.Optional(CONF_UNIT_SYSTEM): vol.In(UNITS),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
PLATFORM_SCHEMA = vol.All(
|
PLATFORM_SCHEMA = vol.All(
|
||||||
cv.has_at_least_one_key(CONF_DESTINATION_LATITUDE, CONF_DESTINATION_ENTITY_ID),
|
cv.has_at_least_one_key(CONF_DESTINATION_LATITUDE, CONF_DESTINATION_ENTITY_ID),
|
||||||
cv.has_at_least_one_key(CONF_ORIGIN_LATITUDE, CONF_ORIGIN_ENTITY_ID),
|
cv.has_at_least_one_key(CONF_ORIGIN_LATITUDE, CONF_ORIGIN_ENTITY_ID),
|
||||||
PLATFORM_SCHEMA.extend(
|
cv.key_value_schemas(
|
||||||
|
CONF_MODE,
|
||||||
{
|
{
|
||||||
vol.Required(CONF_API_KEY): cv.string,
|
None: PLATFORM_SCHEMA,
|
||||||
vol.Inclusive(
|
TRAVEL_MODE_BICYCLE: PLATFORM_SCHEMA,
|
||||||
CONF_DESTINATION_LATITUDE, "destination_coordinates"
|
TRAVEL_MODE_CAR: PLATFORM_SCHEMA,
|
||||||
): cv.latitude,
|
TRAVEL_MODE_PEDESTRIAN: PLATFORM_SCHEMA,
|
||||||
vol.Inclusive(
|
TRAVEL_MODE_PUBLIC: PLATFORM_SCHEMA,
|
||||||
CONF_DESTINATION_LONGITUDE, "destination_coordinates"
|
TRAVEL_MODE_TRUCK: PLATFORM_SCHEMA,
|
||||||
): cv.longitude,
|
TRAVEL_MODE_PUBLIC_TIME_TABLE: PLATFORM_SCHEMA.extend(
|
||||||
vol.Exclusive(CONF_DESTINATION_LATITUDE, "destination"): cv.latitude,
|
{
|
||||||
vol.Exclusive(CONF_DESTINATION_ENTITY_ID, "destination"): cv.entity_id,
|
vol.Exclusive(CONF_ARRIVAL, "arrival_departure"): cv.time,
|
||||||
vol.Inclusive(CONF_ORIGIN_LATITUDE, "origin_coordinates"): cv.latitude,
|
vol.Exclusive(CONF_DEPARTURE, "arrival_departure"): cv.time,
|
||||||
vol.Inclusive(CONF_ORIGIN_LONGITUDE, "origin_coordinates"): cv.longitude,
|
}
|
||||||
vol.Exclusive(CONF_ORIGIN_LATITUDE, "origin"): cv.latitude,
|
|
||||||
vol.Exclusive(CONF_ORIGIN_ENTITY_ID, "origin"): cv.entity_id,
|
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_MODE, default=TRAVEL_MODE_CAR): vol.In(TRAVEL_MODE),
|
|
||||||
vol.Optional(CONF_ROUTE_MODE, default=ROUTE_MODE_FASTEST): vol.In(
|
|
||||||
ROUTE_MODE
|
|
||||||
),
|
),
|
||||||
vol.Optional(CONF_TRAFFIC_MODE, default=False): cv.boolean,
|
},
|
||||||
vol.Optional(CONF_UNIT_SYSTEM): vol.In(UNITS),
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -160,9 +180,11 @@ async def async_setup_platform(
|
|||||||
route_mode = config[CONF_ROUTE_MODE]
|
route_mode = config[CONF_ROUTE_MODE]
|
||||||
name = config[CONF_NAME]
|
name = config[CONF_NAME]
|
||||||
units = config.get(CONF_UNIT_SYSTEM, hass.config.units.name)
|
units = config.get(CONF_UNIT_SYSTEM, hass.config.units.name)
|
||||||
|
arrival = config.get(CONF_ARRIVAL)
|
||||||
|
departure = config.get(CONF_DEPARTURE)
|
||||||
|
|
||||||
here_data = HERETravelTimeData(
|
here_data = HERETravelTimeData(
|
||||||
here_client, travel_mode, traffic_mode, route_mode, units
|
here_client, travel_mode, traffic_mode, route_mode, units, arrival, departure
|
||||||
)
|
)
|
||||||
|
|
||||||
sensor = HERETravelTimeSensor(
|
sensor = HERETravelTimeSensor(
|
||||||
@ -361,6 +383,8 @@ class HERETravelTimeData:
|
|||||||
traffic_mode: bool,
|
traffic_mode: bool,
|
||||||
route_mode: str,
|
route_mode: str,
|
||||||
units: str,
|
units: str,
|
||||||
|
arrival: datetime,
|
||||||
|
departure: datetime,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize herepy."""
|
"""Initialize herepy."""
|
||||||
self.origin = None
|
self.origin = None
|
||||||
@ -368,6 +392,8 @@ class HERETravelTimeData:
|
|||||||
self.travel_mode = travel_mode
|
self.travel_mode = travel_mode
|
||||||
self.traffic_mode = traffic_mode
|
self.traffic_mode = traffic_mode
|
||||||
self.route_mode = route_mode
|
self.route_mode = route_mode
|
||||||
|
self.arrival = arrival
|
||||||
|
self.departure = departure
|
||||||
self.attribution = None
|
self.attribution = None
|
||||||
self.traffic_time = None
|
self.traffic_time = None
|
||||||
self.distance = None
|
self.distance = None
|
||||||
@ -377,6 +403,7 @@ class HERETravelTimeData:
|
|||||||
self.destination_name = None
|
self.destination_name = None
|
||||||
self.units = units
|
self.units = units
|
||||||
self._client = here_client
|
self._client = here_client
|
||||||
|
self.combine_change = True
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
"""Get the latest data from HERE."""
|
"""Get the latest data from HERE."""
|
||||||
@ -389,24 +416,36 @@ class HERETravelTimeData:
|
|||||||
# Convert location to HERE friendly location
|
# Convert location to HERE friendly location
|
||||||
destination = self.destination.split(",")
|
destination = self.destination.split(",")
|
||||||
origin = self.origin.split(",")
|
origin = self.origin.split(",")
|
||||||
|
arrival = self.arrival
|
||||||
|
if arrival is not None:
|
||||||
|
arrival = convert_time_to_isodate(arrival)
|
||||||
|
departure = self.departure
|
||||||
|
if departure is not None:
|
||||||
|
departure = convert_time_to_isodate(departure)
|
||||||
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Requesting route for origin: %s, destination: %s, route_mode: %s, mode: %s, traffic_mode: %s",
|
"Requesting route for origin: %s, destination: %s, route_mode: %s, mode: %s, traffic_mode: %s, arrival: %s, departure: %s",
|
||||||
origin,
|
origin,
|
||||||
destination,
|
destination,
|
||||||
herepy.RouteMode[self.route_mode],
|
herepy.RouteMode[self.route_mode],
|
||||||
herepy.RouteMode[self.travel_mode],
|
herepy.RouteMode[self.travel_mode],
|
||||||
herepy.RouteMode[traffic_mode],
|
herepy.RouteMode[traffic_mode],
|
||||||
|
arrival,
|
||||||
|
departure,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = self._client.car_route(
|
response = self._client.public_transport_timetable(
|
||||||
origin,
|
origin,
|
||||||
destination,
|
destination,
|
||||||
|
self.combine_change,
|
||||||
[
|
[
|
||||||
herepy.RouteMode[self.route_mode],
|
herepy.RouteMode[self.route_mode],
|
||||||
herepy.RouteMode[self.travel_mode],
|
herepy.RouteMode[self.travel_mode],
|
||||||
herepy.RouteMode[traffic_mode],
|
herepy.RouteMode[traffic_mode],
|
||||||
],
|
],
|
||||||
|
arrival=arrival,
|
||||||
|
departure=departure,
|
||||||
)
|
)
|
||||||
except herepy.NoRouteFoundError:
|
except herepy.NoRouteFoundError:
|
||||||
# Better error message for cryptic no route error codes
|
# Better error message for cryptic no route error codes
|
||||||
@ -453,3 +492,11 @@ class HERETravelTimeData:
|
|||||||
joined_supplier_titles = ",".join(supplier_titles)
|
joined_supplier_titles = ",".join(supplier_titles)
|
||||||
attribution = f"With the support of {joined_supplier_titles}. All information is provided without warranty of any kind."
|
attribution = f"With the support of {joined_supplier_titles}. All information is provided without warranty of any kind."
|
||||||
return attribution
|
return attribution
|
||||||
|
|
||||||
|
|
||||||
|
def convert_time_to_isodate(timestr: str) -> str:
|
||||||
|
"""Take a string like 08:00:00 and combine it with the current date."""
|
||||||
|
combined = datetime.combine(dt.start_of_local_day(), dt.parse_time(timestr))
|
||||||
|
if combined < datetime.now():
|
||||||
|
combined = combined + timedelta(days=1)
|
||||||
|
return combined.isoformat()
|
||||||
|
@ -37,6 +37,7 @@ from homeassistant.components.here_travel_time.sensor import (
|
|||||||
TRAVEL_MODE_PUBLIC,
|
TRAVEL_MODE_PUBLIC,
|
||||||
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
TRAVEL_MODE_TRUCK,
|
TRAVEL_MODE_TRUCK,
|
||||||
|
convert_time_to_isodate,
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_ICON, EVENT_HOMEASSISTANT_START
|
from homeassistant.const import ATTR_ICON, EVENT_HOMEASSISTANT_START
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
@ -66,7 +67,7 @@ CAR_DESTINATION_LATITUDE = "39.0"
|
|||||||
CAR_DESTINATION_LONGITUDE = "-77.1"
|
CAR_DESTINATION_LONGITUDE = "-77.1"
|
||||||
|
|
||||||
|
|
||||||
def _build_mock_url(origin, destination, modes, api_key, departure):
|
def _build_mock_url(origin, destination, modes, api_key, departure=None, arrival=None):
|
||||||
"""Construct a url for HERE."""
|
"""Construct a url for HERE."""
|
||||||
base_url = "https://route.ls.hereapi.com/routing/7.2/calculateroute.json?"
|
base_url = "https://route.ls.hereapi.com/routing/7.2/calculateroute.json?"
|
||||||
parameters = {
|
parameters = {
|
||||||
@ -74,9 +75,13 @@ def _build_mock_url(origin, destination, modes, api_key, departure):
|
|||||||
"waypoint1": f"geo!{destination}",
|
"waypoint1": f"geo!{destination}",
|
||||||
"mode": ";".join(str(herepy.RouteMode[mode]) for mode in modes),
|
"mode": ";".join(str(herepy.RouteMode[mode]) for mode in modes),
|
||||||
"apikey": api_key,
|
"apikey": api_key,
|
||||||
"departure": departure,
|
|
||||||
}
|
}
|
||||||
|
if arrival is not None:
|
||||||
|
parameters["arrival"] = arrival
|
||||||
|
if departure is not None:
|
||||||
|
parameters["departure"] = departure
|
||||||
url = base_url + urllib.parse.urlencode(parameters)
|
url = base_url + urllib.parse.urlencode(parameters)
|
||||||
|
print(url)
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
|
||||||
@ -117,7 +122,6 @@ def requests_mock_credentials_check(requests_mock):
|
|||||||
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
||||||
modes,
|
modes,
|
||||||
API_KEY,
|
API_KEY,
|
||||||
"now",
|
|
||||||
)
|
)
|
||||||
requests_mock.get(
|
requests_mock.get(
|
||||||
response_url, text=load_fixture("here_travel_time/car_response.json")
|
response_url, text=load_fixture("here_travel_time/car_response.json")
|
||||||
@ -134,7 +138,6 @@ def requests_mock_truck_response(requests_mock_credentials_check):
|
|||||||
",".join([TRUCK_DESTINATION_LATITUDE, TRUCK_DESTINATION_LONGITUDE]),
|
",".join([TRUCK_DESTINATION_LATITUDE, TRUCK_DESTINATION_LONGITUDE]),
|
||||||
modes,
|
modes,
|
||||||
API_KEY,
|
API_KEY,
|
||||||
"now",
|
|
||||||
)
|
)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/truck_response.json")
|
response_url, text=load_fixture("here_travel_time/truck_response.json")
|
||||||
@ -150,7 +153,6 @@ def requests_mock_car_disabled_response(requests_mock_credentials_check):
|
|||||||
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
||||||
modes,
|
modes,
|
||||||
API_KEY,
|
API_KEY,
|
||||||
"now",
|
|
||||||
)
|
)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/car_response.json")
|
response_url, text=load_fixture("here_travel_time/car_response.json")
|
||||||
@ -214,7 +216,6 @@ async def test_traffic_mode_enabled(hass, requests_mock_credentials_check):
|
|||||||
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
||||||
modes,
|
modes,
|
||||||
API_KEY,
|
API_KEY,
|
||||||
"now",
|
|
||||||
)
|
)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/car_enabled_response.json")
|
response_url, text=load_fixture("here_travel_time/car_enabled_response.json")
|
||||||
@ -272,7 +273,7 @@ async def test_route_mode_shortest(hass, requests_mock_credentials_check):
|
|||||||
origin = "38.902981,-77.048338"
|
origin = "38.902981,-77.048338"
|
||||||
destination = "39.042158,-77.119116"
|
destination = "39.042158,-77.119116"
|
||||||
modes = [ROUTE_MODE_SHORTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
|
modes = [ROUTE_MODE_SHORTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/car_shortest_response.json")
|
response_url, text=load_fixture("here_travel_time/car_shortest_response.json")
|
||||||
)
|
)
|
||||||
@ -303,7 +304,7 @@ async def test_route_mode_fastest(hass, requests_mock_credentials_check):
|
|||||||
origin = "38.902981,-77.048338"
|
origin = "38.902981,-77.048338"
|
||||||
destination = "39.042158,-77.119116"
|
destination = "39.042158,-77.119116"
|
||||||
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_ENABLED]
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_ENABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/car_enabled_response.json")
|
response_url, text=load_fixture("here_travel_time/car_enabled_response.json")
|
||||||
)
|
)
|
||||||
@ -357,7 +358,7 @@ async def test_public_transport(hass, requests_mock_credentials_check):
|
|||||||
origin = "41.9798,-87.8801"
|
origin = "41.9798,-87.8801"
|
||||||
destination = "41.9043,-87.9216"
|
destination = "41.9043,-87.9216"
|
||||||
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC, TRAFFIC_MODE_DISABLED]
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC, TRAFFIC_MODE_DISABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/public_response.json")
|
response_url, text=load_fixture("here_travel_time/public_response.json")
|
||||||
)
|
)
|
||||||
@ -406,7 +407,7 @@ async def test_public_transport_time_table(hass, requests_mock_credentials_check
|
|||||||
origin = "41.9798,-87.8801"
|
origin = "41.9798,-87.8801"
|
||||||
destination = "41.9043,-87.9216"
|
destination = "41.9043,-87.9216"
|
||||||
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_DISABLED]
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_DISABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url,
|
response_url,
|
||||||
text=load_fixture("here_travel_time/public_time_table_response.json"),
|
text=load_fixture("here_travel_time/public_time_table_response.json"),
|
||||||
@ -456,7 +457,7 @@ async def test_pedestrian(hass, requests_mock_credentials_check):
|
|||||||
origin = "41.9798,-87.8801"
|
origin = "41.9798,-87.8801"
|
||||||
destination = "41.9043,-87.9216"
|
destination = "41.9043,-87.9216"
|
||||||
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PEDESTRIAN, TRAFFIC_MODE_DISABLED]
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PEDESTRIAN, TRAFFIC_MODE_DISABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/pedestrian_response.json")
|
response_url, text=load_fixture("here_travel_time/pedestrian_response.json")
|
||||||
)
|
)
|
||||||
@ -508,7 +509,7 @@ async def test_bicycle(hass, requests_mock_credentials_check):
|
|||||||
origin = "41.9798,-87.8801"
|
origin = "41.9798,-87.8801"
|
||||||
destination = "41.9043,-87.9216"
|
destination = "41.9043,-87.9216"
|
||||||
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_BICYCLE, TRAFFIC_MODE_DISABLED]
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_BICYCLE, TRAFFIC_MODE_DISABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/bike_response.json")
|
response_url, text=load_fixture("here_travel_time/bike_response.json")
|
||||||
)
|
)
|
||||||
@ -841,7 +842,7 @@ async def test_route_not_found(hass, requests_mock_credentials_check, caplog):
|
|||||||
origin = "52.516,13.3779"
|
origin = "52.516,13.3779"
|
||||||
destination = "47.013399,-10.171986"
|
destination = "47.013399,-10.171986"
|
||||||
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_CAR, TRAFFIC_MODE_DISABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url,
|
response_url,
|
||||||
text=load_fixture("here_travel_time/routing_error_no_route_found.json"),
|
text=load_fixture("here_travel_time/routing_error_no_route_found.json"),
|
||||||
@ -914,7 +915,6 @@ async def test_invalid_credentials(hass, requests_mock, caplog):
|
|||||||
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
",".join([CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]),
|
||||||
modes,
|
modes,
|
||||||
API_KEY,
|
API_KEY,
|
||||||
"now",
|
|
||||||
)
|
)
|
||||||
requests_mock.get(
|
requests_mock.get(
|
||||||
response_url,
|
response_url,
|
||||||
@ -942,7 +942,7 @@ async def test_attribution(hass, requests_mock_credentials_check):
|
|||||||
origin = "50.037751372637686,14.39233448220898"
|
origin = "50.037751372637686,14.39233448220898"
|
||||||
destination = "50.07993838201255,14.42582157361062"
|
destination = "50.07993838201255,14.42582157361062"
|
||||||
modes = [ROUTE_MODE_SHORTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_ENABLED]
|
modes = [ROUTE_MODE_SHORTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_ENABLED]
|
||||||
response_url = _build_mock_url(origin, destination, modes, API_KEY, "now")
|
response_url = _build_mock_url(origin, destination, modes, API_KEY)
|
||||||
requests_mock_credentials_check.get(
|
requests_mock_credentials_check.get(
|
||||||
response_url, text=load_fixture("here_travel_time/attribution_response.json")
|
response_url, text=load_fixture("here_travel_time/attribution_response.json")
|
||||||
)
|
)
|
||||||
@ -1051,3 +1051,123 @@ async def test_delayed_update(hass, requests_mock_truck_response, caplog):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert "Unable to find entity" not in caplog.text
|
assert "Unable to find entity" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
async def test_arrival(hass, requests_mock_credentials_check):
|
||||||
|
"""Test that arrival works."""
|
||||||
|
origin = "41.9798,-87.8801"
|
||||||
|
destination = "41.9043,-87.9216"
|
||||||
|
arrival = "01:00:00"
|
||||||
|
arrival_isodate = convert_time_to_isodate(arrival)
|
||||||
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_DISABLED]
|
||||||
|
response_url = _build_mock_url(
|
||||||
|
origin, destination, modes, API_KEY, arrival=arrival_isodate
|
||||||
|
)
|
||||||
|
requests_mock_credentials_check.get(
|
||||||
|
response_url,
|
||||||
|
text=load_fixture("here_travel_time/public_time_table_response.json"),
|
||||||
|
)
|
||||||
|
|
||||||
|
config = {
|
||||||
|
DOMAIN: {
|
||||||
|
"platform": PLATFORM,
|
||||||
|
"name": "test",
|
||||||
|
"origin_latitude": origin.split(",")[0],
|
||||||
|
"origin_longitude": origin.split(",")[1],
|
||||||
|
"destination_latitude": destination.split(",")[0],
|
||||||
|
"destination_longitude": destination.split(",")[1],
|
||||||
|
"api_key": API_KEY,
|
||||||
|
"mode": TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
|
"arrival": arrival,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
|
||||||
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
sensor = hass.states.get("sensor.test")
|
||||||
|
assert sensor.state == "80"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_departure(hass, requests_mock_credentials_check):
|
||||||
|
"""Test that arrival works."""
|
||||||
|
origin = "41.9798,-87.8801"
|
||||||
|
destination = "41.9043,-87.9216"
|
||||||
|
departure = "23:00:00"
|
||||||
|
departure_isodate = convert_time_to_isodate(departure)
|
||||||
|
modes = [ROUTE_MODE_FASTEST, TRAVEL_MODE_PUBLIC_TIME_TABLE, TRAFFIC_MODE_DISABLED]
|
||||||
|
response_url = _build_mock_url(
|
||||||
|
origin, destination, modes, API_KEY, departure=departure_isodate
|
||||||
|
)
|
||||||
|
requests_mock_credentials_check.get(
|
||||||
|
response_url,
|
||||||
|
text=load_fixture("here_travel_time/public_time_table_response.json"),
|
||||||
|
)
|
||||||
|
|
||||||
|
config = {
|
||||||
|
DOMAIN: {
|
||||||
|
"platform": PLATFORM,
|
||||||
|
"name": "test",
|
||||||
|
"origin_latitude": origin.split(",")[0],
|
||||||
|
"origin_longitude": origin.split(",")[1],
|
||||||
|
"destination_latitude": destination.split(",")[0],
|
||||||
|
"destination_longitude": destination.split(",")[1],
|
||||||
|
"api_key": API_KEY,
|
||||||
|
"mode": TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
|
"departure": departure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
|
||||||
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
sensor = hass.states.get("sensor.test")
|
||||||
|
assert sensor.state == "80"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_arrival_only_allowed_for_timetable(hass, caplog):
|
||||||
|
"""Test that arrival is only allowed when mode is publicTransportTimeTable."""
|
||||||
|
caplog.set_level(logging.ERROR)
|
||||||
|
origin = "41.9798,-87.8801"
|
||||||
|
destination = "41.9043,-87.9216"
|
||||||
|
config = {
|
||||||
|
DOMAIN: {
|
||||||
|
"platform": PLATFORM,
|
||||||
|
"name": "test",
|
||||||
|
"origin_latitude": origin.split(",")[0],
|
||||||
|
"origin_longitude": origin.split(",")[1],
|
||||||
|
"destination_latitude": destination.split(",")[0],
|
||||||
|
"destination_longitude": destination.split(",")[1],
|
||||||
|
"api_key": API_KEY,
|
||||||
|
"arrival": "01:00:00",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
assert len(caplog.records) == 1
|
||||||
|
assert "[arrival] is an invalid option" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
async def test_exclusive_arrival_and_departure(hass, caplog):
|
||||||
|
"""Test that arrival and departure are exclusive."""
|
||||||
|
caplog.set_level(logging.ERROR)
|
||||||
|
origin = "41.9798,-87.8801"
|
||||||
|
destination = "41.9043,-87.9216"
|
||||||
|
config = {
|
||||||
|
DOMAIN: {
|
||||||
|
"platform": PLATFORM,
|
||||||
|
"name": "test",
|
||||||
|
"origin_latitude": origin.split(",")[0],
|
||||||
|
"origin_longitude": origin.split(",")[1],
|
||||||
|
"destination_latitude": destination.split(",")[0],
|
||||||
|
"destination_longitude": destination.split(",")[1],
|
||||||
|
"api_key": API_KEY,
|
||||||
|
"arrival": "01:00:00",
|
||||||
|
"mode": TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
|
"departure": "01:00:00",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
assert len(caplog.records) == 1
|
||||||
|
assert "two or more values in the same group of exclusion" in caplog.text
|
||||||
|
Loading…
x
Reference in New Issue
Block a user