Calculate data using all sections for here_travel_time (#86576)

Calculate data using all sections
This commit is contained in:
Kevin Stillhammer 2023-01-25 10:33:43 +01:00 committed by GitHub
parent 7bd56ad7d6
commit 781a4267cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 309 additions and 13 deletions

View file

@ -117,25 +117,43 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator[HERETravelTimeData]
def _parse_routing_response(self, response: dict[str, Any]) -> HERETravelTimeData:
"""Parse the routing response dict to a HERETravelTimeData."""
section: dict[str, Any] = response["routes"][0]["sections"][0]
summary: dict[str, int] = section["summary"]
mapped_origin_lat: float = section["departure"]["place"]["location"]["lat"]
mapped_origin_lon: float = section["departure"]["place"]["location"]["lng"]
mapped_destination_lat: float = section["arrival"]["place"]["location"]["lat"]
mapped_destination_lon: float = section["arrival"]["place"]["location"]["lng"]
distance: float = DistanceConverter.convert(
summary["length"], UnitOfLength.METERS, UnitOfLength.KILOMETERS
)
distance: float = 0.0
duration: float = 0.0
duration_in_traffic: float = 0.0
for section in response["routes"][0]["sections"]:
distance += DistanceConverter.convert(
section["summary"]["length"],
UnitOfLength.METERS,
UnitOfLength.KILOMETERS,
)
duration += section["summary"]["baseDuration"]
duration_in_traffic += section["summary"]["duration"]
first_section = response["routes"][0]["sections"][0]
last_section = response["routes"][0]["sections"][-1]
mapped_origin_lat: float = first_section["departure"]["place"]["location"][
"lat"
]
mapped_origin_lon: float = first_section["departure"]["place"]["location"][
"lng"
]
mapped_destination_lat: float = last_section["arrival"]["place"]["location"][
"lat"
]
mapped_destination_lon: float = last_section["arrival"]["place"]["location"][
"lng"
]
origin_name: str | None = None
if (names := section["spans"][0].get("names")) is not None:
if (names := first_section["spans"][0].get("names")) is not None:
origin_name = names[0]["value"]
destination_name: str | None = None
if (names := section["spans"][-1].get("names")) is not None:
if (names := last_section["spans"][-1].get("names")) is not None:
destination_name = names[0]["value"]
return HERETravelTimeData(
attribution=None,
duration=round(summary["baseDuration"] / 60),
duration_in_traffic=round(summary["duration"] / 60),
duration=round(duration / 60),
duration_in_traffic=round(duration_in_traffic / 60),
distance=distance,
origin=f"{mapped_origin_lat},{mapped_origin_lon}",
destination=f"{mapped_destination_lat},{mapped_destination_lon}",

View file

@ -13,6 +13,7 @@ TRANSIT_RESPONSE = json.loads(
NO_ATTRIBUTION_TRANSIT_RESPONSE = json.loads(
load_fixture("here_travel_time/no_attribution_transit_route_response.json")
)
BIKE_RESPONSE = json.loads(load_fixture("here_travel_time/bike_response.json"))
@pytest.fixture(name="valid_response")
@ -27,6 +28,18 @@ def valid_response_fixture():
yield mock
@pytest.fixture(name="bike_response")
def bike_response_fixture():
"""Return valid api response."""
with patch(
"here_transit.HERETransitApi.route", return_value=TRANSIT_RESPONSE
), patch(
"here_routing.HERERoutingApi.route",
return_value=BIKE_RESPONSE,
) as mock:
yield mock
@pytest.fixture(name="no_attribution_response")
def no_attribution_response_fixture():
"""Return valid api response without attribution."""

View file

@ -0,0 +1,214 @@
{
"routes": [
{
"id": "6d8ae729-3b30-4d81-adaf-6a485b15b70a",
"sections": [
{
"id": "c8d12b37-05e1-47f0-a5c2-43f5fb589768",
"type": "pedestrian",
"departure": {
"time": "2023-01-23T18:26:12+01:00",
"place": {
"type": "place",
"location": {
"lat": 49.1260894,
"lng": 6.1843356
},
"originalLocation": {
"lat": 49.1264093,
"lng": 6.1841419
}
}
},
"arrival": {
"time": "2023-01-23T18:29:09+01:00",
"place": {
"type": "place",
"location": {
"lat": 49.12547,
"lng": 6.18242
}
}
},
"summary": {
"duration": 177,
"length": 157,
"baseDuration": 177
},
"polyline": "BGyst29Cg5u5LpOj2BjIzZnQ_nB",
"spans": [
{
"offset": 0,
"names": [
{
"value": "Chemin de Halage",
"language": "fr"
}
]
}
],
"transport": {
"mode": "pedestrian"
}
},
{
"id": "d37123f4-034a-4c46-8678-596f999e8eae",
"type": "vehicle",
"departure": {
"time": "2023-01-23T18:29:09+01:00",
"place": {
"type": "place",
"location": {
"lat": 49.12547,
"lng": 6.18242
}
}
},
"arrival": {
"time": "2023-01-23T18:44:41+01:00",
"place": {
"type": "place",
"location": {
"lat": 49.1025668,
"lng": 6.1768518
},
"originalLocation": {
"lat": 49.1025784,
"lng": 6.1770297
}
}
},
"summary": {
"duration": 932,
"length": 3426,
"baseDuration": 932
},
"polyline": "BG8ls29Cohr5L0UjXgFvH4DnGgFrJ7G3IvHrJrJvMnB7B_JjN_JzPvH_JjDsJjD8G7B4DrEkIvHwMzF4I7GgKjDgF7BwC7G0KjN0U3I4D7GsEvHkDzK4D7a4I3IwCzesJvH8B7GoBjDU7LsEjIwC_JkDrJkD_JsEvH4DvH4DvHsE3IgFrEkD_E4DvH0F7G0FrJ4IzFsErE4DjDgFnGsE_EwCrEoB3DUzFUnGAvHT7GTjDTvHT7GU7BArJUjD4DvCwCzFgF_EsE_EgF_JoLzF0F_EsEzFsErEkD3DwC3D8B3D8BrE8B3DoBvH8BjI8BzFoBzFUjIUnGAjSAzFTnLvC_E7BzF7B_E7B_EjD7G3D7G7B_ETnpBvCnQTzUnB3DAvMT7B7BnGvCzFrErEvCzFjDzF3DnGzF_EzF3I7LnV3cnG3IzF0K7LsTrE8G3I4NvC4DvC4D7BwC7BwCvCwCjD4DvCkDjD4D3D4DjDkDzFsEvCA3DUjDUrEUrEUrEU_ETrEvCnGrErd_nB3DnGnLnQ_JzP7Q_Y7G_JvR7ajI7Lrd3rBvH7LzZrnBnL3SnLjSjI7Lna7pBjN_T_EjIvCrE7GnL7GjNrE3IjDrEjDrEvCjDzF3IvCrE_JzU3Nrd_J_TvCrEvC3DT7BnBvC7B3D3XvvB7kBjuCoB7BoB7BUnBU7BU7BU3DAvCTjDT7BnBjDnBvC7BvCnBnB7BT7BTnBA7BU7BoBnBoBnB8BnB8BnBkDTwC_vC0PzoBwMvb8GnB0jB7B4cUgP4D0oB7foGZE",
"spans": [
{
"offset": 0
},
{
"offset": 4,
"names": [
{
"value": "Avenue de Blida",
"language": "fr"
}
]
},
{
"offset": 11,
"names": [
{
"value": "Pont des Grilles",
"language": "fr"
}
]
},
{
"offset": 22,
"names": [
{
"value": "Boulevard Paixhans",
"language": "fr"
}
]
},
{
"offset": 49,
"names": [
{
"value": "Boulevard André Maginot",
"language": "fr"
}
]
},
{
"offset": 97,
"names": [
{
"value": "Boulevard André Maginot",
"language": "fr"
},
{
"value": "Place Jean Cocteau",
"language": "fr"
}
]
},
{
"offset": 98,
"names": [
{
"value": "Place Mazelle",
"language": "fr"
}
]
},
{
"offset": 110,
"names": [
{
"value": "Passage de Plantières",
"language": "fr"
}
]
},
{
"offset": 119
},
{
"offset": 127,
"names": [
{
"value": "Avenue de lAmphithéâtre",
"language": "fr"
}
]
},
{
"offset": 146,
"names": [
{
"value": "Rue aux Arènes",
"language": "fr"
}
]
},
{
"offset": 192,
"names": [
{
"value": "Rue Saint-Pierre",
"language": "fr"
}
]
},
{
"offset": 195,
"names": [
{
"value": "Rue Émile Boilvin",
"language": "fr"
}
]
},
{
"offset": 199,
"names": [
{
"value": "Rue Charles Sadoul",
"language": "fr"
}
]
}
],
"transport": {
"mode": "bicycle"
}
}
]
}
]
}

View file

@ -749,3 +749,54 @@ async def test_transit_rate_limit(hass: HomeAssistant, caplog):
await hass.async_block_till_done()
assert hass.states.get("sensor.test_distance").state == "1.883"
assert "Resetting update interval to" in caplog.text
@pytest.mark.usefixtures("bike_response")
async def test_multiple_sections(
hass: HomeAssistant,
):
"""Test that multiple sections are handled correctly."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="0123456789",
data={
CONF_ORIGIN_LATITUDE: float(ORIGIN_LATITUDE),
CONF_ORIGIN_LONGITUDE: float(ORIGIN_LONGITUDE),
CONF_DESTINATION_LATITUDE: float(DESTINATION_LATITUDE),
CONF_DESTINATION_LONGITUDE: float(DESTINATION_LONGITUDE),
CONF_API_KEY: API_KEY,
CONF_MODE: TRAVEL_MODE_BICYCLE,
CONF_NAME: "test",
},
options=DEFAULT_OPTIONS,
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done()
duration = hass.states.get("sensor.test_duration")
assert duration.state == "18"
assert float(hass.states.get("sensor.test_distance").state) == pytest.approx(3.583)
assert hass.states.get("sensor.test_duration_in_traffic").state == "18"
assert hass.states.get("sensor.test_origin").state == "Chemin de Halage"
assert (
hass.states.get("sensor.test_origin").attributes.get(ATTR_LATITUDE)
== "49.1260894"
)
assert (
hass.states.get("sensor.test_origin").attributes.get(ATTR_LONGITUDE)
== "6.1843356"
)
assert hass.states.get("sensor.test_destination").state == "Rue Charles Sadoul"
assert (
hass.states.get("sensor.test_destination").attributes.get(ATTR_LATITUDE)
== "49.1025668"
)
assert (
hass.states.get("sensor.test_destination").attributes.get(ATTR_LONGITUDE)
== "6.1768518"
)