Split attributes into sensors for here_travel_time (#72405)
parent
555e9c6762
commit
bef512c425
|
@ -187,8 +187,8 @@ class HereTravelTimeDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
return HERERoutingData(
|
return HERERoutingData(
|
||||||
{
|
{
|
||||||
ATTR_ATTRIBUTION: attribution,
|
ATTR_ATTRIBUTION: attribution,
|
||||||
ATTR_DURATION: summary["baseTime"] / 60, # type: ignore[misc]
|
ATTR_DURATION: round(summary["baseTime"] / 60), # type: ignore[misc]
|
||||||
ATTR_DURATION_IN_TRAFFIC: traffic_time / 60,
|
ATTR_DURATION_IN_TRAFFIC: round(traffic_time / 60),
|
||||||
ATTR_DISTANCE: distance,
|
ATTR_DISTANCE: distance,
|
||||||
ATTR_ROUTE: response.route_short,
|
ATTR_ROUTE: response.route_short,
|
||||||
ATTR_ORIGIN: ",".join(origin),
|
ATTR_ORIGIN: ",".join(origin),
|
||||||
|
|
|
@ -24,8 +24,6 @@ CONF_DEPARTURE_TIME = "departure_time"
|
||||||
|
|
||||||
DEFAULT_NAME = "HERE Travel Time"
|
DEFAULT_NAME = "HERE Travel Time"
|
||||||
|
|
||||||
TRACKABLE_DOMAINS = ["device_tracker", "sensor", "zone", "person"]
|
|
||||||
|
|
||||||
TRAVEL_MODE_BICYCLE = "bicycle"
|
TRAVEL_MODE_BICYCLE = "bicycle"
|
||||||
TRAVEL_MODE_CAR = "car"
|
TRAVEL_MODE_CAR = "car"
|
||||||
TRAVEL_MODE_PEDESTRIAN = "pedestrian"
|
TRAVEL_MODE_PEDESTRIAN = "pedestrian"
|
||||||
|
@ -41,7 +39,6 @@ TRAVEL_MODES = [
|
||||||
TRAVEL_MODE_TRUCK,
|
TRAVEL_MODE_TRUCK,
|
||||||
]
|
]
|
||||||
|
|
||||||
TRAVEL_MODES_PUBLIC = [TRAVEL_MODE_PUBLIC, TRAVEL_MODE_PUBLIC_TIME_TABLE]
|
|
||||||
TRAVEL_MODES_VEHICLE = [TRAVEL_MODE_CAR, TRAVEL_MODE_TRUCK]
|
TRAVEL_MODES_VEHICLE = [TRAVEL_MODE_CAR, TRAVEL_MODE_TRUCK]
|
||||||
|
|
||||||
TRAFFIC_MODE_ENABLED = "traffic_enabled"
|
TRAFFIC_MODE_ENABLED = "traffic_enabled"
|
||||||
|
@ -58,6 +55,14 @@ ICON_PEDESTRIAN = "mdi:walk"
|
||||||
ICON_PUBLIC = "mdi:bus"
|
ICON_PUBLIC = "mdi:bus"
|
||||||
ICON_TRUCK = "mdi:truck"
|
ICON_TRUCK = "mdi:truck"
|
||||||
|
|
||||||
|
ICONS = {
|
||||||
|
TRAVEL_MODE_BICYCLE: ICON_BICYCLE,
|
||||||
|
TRAVEL_MODE_PEDESTRIAN: ICON_PEDESTRIAN,
|
||||||
|
TRAVEL_MODE_PUBLIC: ICON_PUBLIC,
|
||||||
|
TRAVEL_MODE_PUBLIC_TIME_TABLE: ICON_PUBLIC,
|
||||||
|
TRAVEL_MODE_TRUCK: ICON_TRUCK,
|
||||||
|
}
|
||||||
|
|
||||||
UNITS = [CONF_UNIT_SYSTEM_METRIC, CONF_UNIT_SYSTEM_IMPERIAL]
|
UNITS = [CONF_UNIT_SYSTEM_METRIC, CONF_UNIT_SYSTEM_IMPERIAL]
|
||||||
|
|
||||||
ATTR_DURATION = "duration"
|
ATTR_DURATION = "duration"
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
"""Support for HERE travel time sensors."""
|
"""Support for HERE travel time sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import (
|
||||||
|
PLATFORM_SCHEMA,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ATTRIBUTION,
|
ATTR_ATTRIBUTION,
|
||||||
ATTR_MODE,
|
ATTR_LATITUDE,
|
||||||
|
ATTR_LONGITUDE,
|
||||||
CONF_API_KEY,
|
CONF_API_KEY,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
|
@ -28,10 +36,14 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from . import HereTravelTimeDataUpdateCoordinator
|
from . import HereTravelTimeDataUpdateCoordinator
|
||||||
from .const import (
|
from .const import (
|
||||||
|
ATTR_DESTINATION,
|
||||||
|
ATTR_DESTINATION_NAME,
|
||||||
|
ATTR_DISTANCE,
|
||||||
ATTR_DURATION,
|
ATTR_DURATION,
|
||||||
ATTR_DURATION_IN_TRAFFIC,
|
ATTR_DURATION_IN_TRAFFIC,
|
||||||
ATTR_TRAFFIC_MODE,
|
ATTR_ORIGIN,
|
||||||
ATTR_UNIT_SYSTEM,
|
ATTR_ORIGIN_NAME,
|
||||||
|
ATTR_ROUTE,
|
||||||
CONF_ARRIVAL,
|
CONF_ARRIVAL,
|
||||||
CONF_DEPARTURE,
|
CONF_DEPARTURE,
|
||||||
CONF_DESTINATION_ENTITY_ID,
|
CONF_DESTINATION_ENTITY_ID,
|
||||||
|
@ -44,14 +56,10 @@ from .const import (
|
||||||
CONF_TRAFFIC_MODE,
|
CONF_TRAFFIC_MODE,
|
||||||
DEFAULT_NAME,
|
DEFAULT_NAME,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
ICON_BICYCLE,
|
|
||||||
ICON_CAR,
|
ICON_CAR,
|
||||||
ICON_PEDESTRIAN,
|
ICONS,
|
||||||
ICON_PUBLIC,
|
|
||||||
ICON_TRUCK,
|
|
||||||
ROUTE_MODE_FASTEST,
|
ROUTE_MODE_FASTEST,
|
||||||
ROUTE_MODES,
|
ROUTE_MODES,
|
||||||
TRAFFIC_MODE_ENABLED,
|
|
||||||
TRAVEL_MODE_BICYCLE,
|
TRAVEL_MODE_BICYCLE,
|
||||||
TRAVEL_MODE_CAR,
|
TRAVEL_MODE_CAR,
|
||||||
TRAVEL_MODE_PEDESTRIAN,
|
TRAVEL_MODE_PEDESTRIAN,
|
||||||
|
@ -59,7 +67,6 @@ from .const import (
|
||||||
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
TRAVEL_MODE_TRUCK,
|
TRAVEL_MODE_TRUCK,
|
||||||
TRAVEL_MODES,
|
TRAVEL_MODES,
|
||||||
TRAVEL_MODES_PUBLIC,
|
|
||||||
UNITS,
|
UNITS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -115,6 +122,69 @@ PLATFORM_SCHEMA = vol.All(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sensor_descriptions(travel_mode: str) -> tuple[SensorEntityDescription, ...]:
|
||||||
|
"""Construct SensorEntityDescriptions."""
|
||||||
|
return (
|
||||||
|
SensorEntityDescription(
|
||||||
|
name="Duration",
|
||||||
|
icon=ICONS.get(travel_mode, ICON_CAR),
|
||||||
|
key=ATTR_DURATION,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=TIME_MINUTES,
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
name="Duration in Traffic",
|
||||||
|
icon=ICONS.get(travel_mode, ICON_CAR),
|
||||||
|
key=ATTR_DURATION_IN_TRAFFIC,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=TIME_MINUTES,
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
name="Distance",
|
||||||
|
icon=ICONS.get(travel_mode, ICON_CAR),
|
||||||
|
key=ATTR_DISTANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
name="Route",
|
||||||
|
icon="mdi:directions",
|
||||||
|
key=ATTR_ROUTE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_origin_sensor(
|
||||||
|
config_entry: ConfigEntry, hass: HomeAssistant
|
||||||
|
) -> OriginSensor:
|
||||||
|
"""Create a origin sensor."""
|
||||||
|
return OriginSensor(
|
||||||
|
config_entry.entry_id,
|
||||||
|
config_entry.data[CONF_NAME],
|
||||||
|
SensorEntityDescription(
|
||||||
|
name="Origin",
|
||||||
|
icon="mdi:store-marker",
|
||||||
|
key=ATTR_ORIGIN_NAME,
|
||||||
|
),
|
||||||
|
hass.data[DOMAIN][config_entry.entry_id],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_destination_sensor(
|
||||||
|
config_entry: ConfigEntry, hass: HomeAssistant
|
||||||
|
) -> DestinationSensor:
|
||||||
|
"""Create a destination sensor."""
|
||||||
|
return DestinationSensor(
|
||||||
|
config_entry.entry_id,
|
||||||
|
config_entry.data[CONF_NAME],
|
||||||
|
SensorEntityDescription(
|
||||||
|
name="Destination",
|
||||||
|
icon="mdi:store-marker",
|
||||||
|
key=ATTR_DESTINATION_NAME,
|
||||||
|
),
|
||||||
|
hass.data[DOMAIN][config_entry.entry_id],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
|
@ -143,16 +213,20 @@ async def async_setup_entry(
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add HERE travel time entities from a config_entry."""
|
"""Add HERE travel time entities from a config_entry."""
|
||||||
async_add_entities(
|
|
||||||
[
|
sensors: list[HERETravelTimeSensor] = []
|
||||||
|
for sensor_description in sensor_descriptions(config_entry.data[CONF_MODE]):
|
||||||
|
sensors.append(
|
||||||
HERETravelTimeSensor(
|
HERETravelTimeSensor(
|
||||||
config_entry.entry_id,
|
config_entry.entry_id,
|
||||||
config_entry.data[CONF_NAME],
|
config_entry.data[CONF_NAME],
|
||||||
config_entry.options[CONF_TRAFFIC_MODE],
|
sensor_description,
|
||||||
hass.data[DOMAIN][config_entry.entry_id],
|
hass.data[DOMAIN][config_entry.entry_id],
|
||||||
)
|
)
|
||||||
],
|
)
|
||||||
)
|
sensors.append(create_origin_sensor(config_entry, hass))
|
||||||
|
sensors.append(create_destination_sensor(config_entry, hass))
|
||||||
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
class HERETravelTimeSensor(SensorEntity, CoordinatorEntity):
|
class HERETravelTimeSensor(SensorEntity, CoordinatorEntity):
|
||||||
|
@ -162,15 +236,14 @@ class HERETravelTimeSensor(SensorEntity, CoordinatorEntity):
|
||||||
self,
|
self,
|
||||||
unique_id_prefix: str,
|
unique_id_prefix: str,
|
||||||
name: str,
|
name: str,
|
||||||
traffic_mode: str,
|
sensor_description: SensorEntityDescription,
|
||||||
coordinator: HereTravelTimeDataUpdateCoordinator,
|
coordinator: HereTravelTimeDataUpdateCoordinator,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._traffic_mode = traffic_mode == TRAFFIC_MODE_ENABLED
|
self.entity_description = sensor_description
|
||||||
self._attr_native_unit_of_measurement = TIME_MINUTES
|
self._attr_name = f"{name} {sensor_description.name}"
|
||||||
self._attr_name = name
|
self._attr_unique_id = f"{unique_id_prefix}_{sensor_description.key}"
|
||||||
self._attr_unique_id = unique_id_prefix
|
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, unique_id_prefix)},
|
identifiers={(DOMAIN, unique_id_prefix)},
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
|
@ -188,34 +261,10 @@ class HERETravelTimeSensor(SensorEntity, CoordinatorEntity):
|
||||||
self.async_on_remove(async_at_start(self.hass, _update_at_start))
|
self.async_on_remove(async_at_start(self.hass, _update_at_start))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> str | None:
|
def native_value(self) -> str | float | None:
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
if self.coordinator.data is not None:
|
if self.coordinator.data is not None:
|
||||||
return str(
|
return self.coordinator.data.get(self.entity_description.key)
|
||||||
round(
|
|
||||||
self.coordinator.data.get(
|
|
||||||
ATTR_DURATION_IN_TRAFFIC
|
|
||||||
if self._traffic_mode
|
|
||||||
else ATTR_DURATION
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def extra_state_attributes(
|
|
||||||
self,
|
|
||||||
) -> dict[str, None | float | str | bool] | None:
|
|
||||||
"""Return the state attributes."""
|
|
||||||
if self.coordinator.data is not None:
|
|
||||||
res = {
|
|
||||||
ATTR_UNIT_SYSTEM: self.coordinator.config.units,
|
|
||||||
ATTR_MODE: self.coordinator.config.travel_mode,
|
|
||||||
ATTR_TRAFFIC_MODE: self._traffic_mode,
|
|
||||||
**self.coordinator.data,
|
|
||||||
}
|
|
||||||
res.pop(ATTR_ATTRIBUTION)
|
|
||||||
return res
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -225,15 +274,30 @@ class HERETravelTimeSensor(SensorEntity, CoordinatorEntity):
|
||||||
return self.coordinator.data.get(ATTR_ATTRIBUTION)
|
return self.coordinator.data.get(ATTR_ATTRIBUTION)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class OriginSensor(HERETravelTimeSensor):
|
||||||
|
"""Sensor holding information about the route origin."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self) -> str:
|
def extra_state_attributes(self) -> Mapping[str, Any] | None:
|
||||||
"""Icon to use in the frontend depending on travel_mode."""
|
"""GPS coordinates."""
|
||||||
if self.coordinator.config.travel_mode == TRAVEL_MODE_BICYCLE:
|
if self.coordinator.data is not None:
|
||||||
return ICON_BICYCLE
|
return {
|
||||||
if self.coordinator.config.travel_mode == TRAVEL_MODE_PEDESTRIAN:
|
ATTR_LATITUDE: self.coordinator.data[ATTR_ORIGIN].split(",")[0],
|
||||||
return ICON_PEDESTRIAN
|
ATTR_LONGITUDE: self.coordinator.data[ATTR_ORIGIN].split(",")[1],
|
||||||
if self.coordinator.config.travel_mode in TRAVEL_MODES_PUBLIC:
|
}
|
||||||
return ICON_PUBLIC
|
return None
|
||||||
if self.coordinator.config.travel_mode == TRAVEL_MODE_TRUCK:
|
|
||||||
return ICON_TRUCK
|
|
||||||
return ICON_CAR
|
class DestinationSensor(HERETravelTimeSensor):
|
||||||
|
"""Sensor holding information about the route destination."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_state_attributes(self) -> Mapping[str, Any] | None:
|
||||||
|
"""GPS coordinates."""
|
||||||
|
if self.coordinator.data is not None:
|
||||||
|
return {
|
||||||
|
ATTR_LATITUDE: self.coordinator.data[ATTR_DESTINATION].split(",")[0],
|
||||||
|
ATTR_LONGITUDE: self.coordinator.data[ATTR_DESTINATION].split(",")[1],
|
||||||
|
}
|
||||||
|
return None
|
||||||
|
|
|
@ -7,14 +7,6 @@ import pytest
|
||||||
|
|
||||||
from homeassistant.components.here_travel_time.config_flow import default_options
|
from homeassistant.components.here_travel_time.config_flow import default_options
|
||||||
from homeassistant.components.here_travel_time.const import (
|
from homeassistant.components.here_travel_time.const import (
|
||||||
ATTR_DESTINATION,
|
|
||||||
ATTR_DESTINATION_NAME,
|
|
||||||
ATTR_DISTANCE,
|
|
||||||
ATTR_DURATION,
|
|
||||||
ATTR_DURATION_IN_TRAFFIC,
|
|
||||||
ATTR_ORIGIN,
|
|
||||||
ATTR_ORIGIN_NAME,
|
|
||||||
ATTR_ROUTE,
|
|
||||||
CONF_ARRIVAL_TIME,
|
CONF_ARRIVAL_TIME,
|
||||||
CONF_DEPARTURE_TIME,
|
CONF_DEPARTURE_TIME,
|
||||||
CONF_DESTINATION_ENTITY_ID,
|
CONF_DESTINATION_ENTITY_ID,
|
||||||
|
@ -24,7 +16,6 @@ from homeassistant.components.here_travel_time.const import (
|
||||||
CONF_ORIGIN_LATITUDE,
|
CONF_ORIGIN_LATITUDE,
|
||||||
CONF_ORIGIN_LONGITUDE,
|
CONF_ORIGIN_LONGITUDE,
|
||||||
CONF_ROUTE_MODE,
|
CONF_ROUTE_MODE,
|
||||||
CONF_TRAFFIC_MODE,
|
|
||||||
CONF_UNIT_SYSTEM,
|
CONF_UNIT_SYSTEM,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
ICON_BICYCLE,
|
ICON_BICYCLE,
|
||||||
|
@ -34,18 +25,18 @@ from homeassistant.components.here_travel_time.const import (
|
||||||
ICON_TRUCK,
|
ICON_TRUCK,
|
||||||
NO_ROUTE_ERROR_MESSAGE,
|
NO_ROUTE_ERROR_MESSAGE,
|
||||||
ROUTE_MODE_FASTEST,
|
ROUTE_MODE_FASTEST,
|
||||||
TRAFFIC_MODE_DISABLED,
|
|
||||||
TRAFFIC_MODE_ENABLED,
|
TRAFFIC_MODE_ENABLED,
|
||||||
TRAVEL_MODE_BICYCLE,
|
TRAVEL_MODE_BICYCLE,
|
||||||
TRAVEL_MODE_CAR,
|
TRAVEL_MODE_CAR,
|
||||||
TRAVEL_MODE_PEDESTRIAN,
|
TRAVEL_MODE_PEDESTRIAN,
|
||||||
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
TRAVEL_MODE_TRUCK,
|
TRAVEL_MODE_TRUCK,
|
||||||
TRAVEL_MODES_VEHICLE,
|
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ATTRIBUTION,
|
ATTR_ATTRIBUTION,
|
||||||
ATTR_ICON,
|
ATTR_ICON,
|
||||||
|
ATTR_LATITUDE,
|
||||||
|
ATTR_LONGITUDE,
|
||||||
CONF_API_KEY,
|
CONF_API_KEY,
|
||||||
CONF_MODE,
|
CONF_MODE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
|
@ -67,62 +58,57 @@ from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"mode,icon,traffic_mode,unit_system,arrival_time,departure_time,expected_state,expected_distance,expected_duration_in_traffic",
|
"mode,icon,unit_system,arrival_time,departure_time,expected_duration,expected_distance,expected_duration_in_traffic",
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
TRAVEL_MODE_CAR,
|
TRAVEL_MODE_CAR,
|
||||||
ICON_CAR,
|
ICON_CAR,
|
||||||
TRAFFIC_MODE_ENABLED,
|
|
||||||
"metric",
|
"metric",
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
"30",
|
||||||
|
"23.903",
|
||||||
"31",
|
"31",
|
||||||
23.903,
|
|
||||||
31.016666666666666,
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
TRAVEL_MODE_BICYCLE,
|
TRAVEL_MODE_BICYCLE,
|
||||||
ICON_BICYCLE,
|
ICON_BICYCLE,
|
||||||
TRAFFIC_MODE_DISABLED,
|
|
||||||
"metric",
|
"metric",
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
"30",
|
"30",
|
||||||
23.903,
|
"23.903",
|
||||||
30.05,
|
"30",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
TRAVEL_MODE_PEDESTRIAN,
|
TRAVEL_MODE_PEDESTRIAN,
|
||||||
ICON_PEDESTRIAN,
|
ICON_PEDESTRIAN,
|
||||||
TRAFFIC_MODE_DISABLED,
|
|
||||||
"imperial",
|
"imperial",
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
"30",
|
"30",
|
||||||
14.852631013,
|
"14.852631013",
|
||||||
30.05,
|
"30",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
TRAVEL_MODE_PUBLIC_TIME_TABLE,
|
||||||
ICON_PUBLIC,
|
ICON_PUBLIC,
|
||||||
TRAFFIC_MODE_DISABLED,
|
|
||||||
"imperial",
|
"imperial",
|
||||||
"08:00:00",
|
"08:00:00",
|
||||||
None,
|
None,
|
||||||
"30",
|
"30",
|
||||||
14.852631013,
|
"14.852631013",
|
||||||
30.05,
|
"30",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
TRAVEL_MODE_TRUCK,
|
TRAVEL_MODE_TRUCK,
|
||||||
ICON_TRUCK,
|
ICON_TRUCK,
|
||||||
TRAFFIC_MODE_ENABLED,
|
|
||||||
"metric",
|
"metric",
|
||||||
None,
|
None,
|
||||||
"08:00:00",
|
"08:00:00",
|
||||||
|
"30",
|
||||||
|
"23.903",
|
||||||
"31",
|
"31",
|
||||||
23.903,
|
|
||||||
31.016666666666666,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -131,11 +117,10 @@ async def test_sensor(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mode,
|
mode,
|
||||||
icon,
|
icon,
|
||||||
traffic_mode,
|
|
||||||
unit_system,
|
unit_system,
|
||||||
arrival_time,
|
arrival_time,
|
||||||
departure_time,
|
departure_time,
|
||||||
expected_state,
|
expected_duration,
|
||||||
expected_distance,
|
expected_distance,
|
||||||
expected_duration_in_traffic,
|
expected_duration_in_traffic,
|
||||||
):
|
):
|
||||||
|
@ -153,7 +138,6 @@ async def test_sensor(
|
||||||
CONF_NAME: "test",
|
CONF_NAME: "test",
|
||||||
},
|
},
|
||||||
options={
|
options={
|
||||||
CONF_TRAFFIC_MODE: traffic_mode,
|
|
||||||
CONF_ROUTE_MODE: ROUTE_MODE_FASTEST,
|
CONF_ROUTE_MODE: ROUTE_MODE_FASTEST,
|
||||||
CONF_ARRIVAL_TIME: arrival_time,
|
CONF_ARRIVAL_TIME: arrival_time,
|
||||||
CONF_DEPARTURE_TIME: departure_time,
|
CONF_DEPARTURE_TIME: departure_time,
|
||||||
|
@ -166,44 +150,57 @@ async def test_sensor(
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
sensor = hass.states.get("sensor.test")
|
duration = hass.states.get("sensor.test_duration")
|
||||||
assert sensor.attributes.get("unit_of_measurement") == TIME_MINUTES
|
assert duration.attributes.get("unit_of_measurement") == TIME_MINUTES
|
||||||
assert (
|
assert (
|
||||||
sensor.attributes.get(ATTR_ATTRIBUTION)
|
duration.attributes.get(ATTR_ATTRIBUTION)
|
||||||
== "With the support of HERE Technologies. All information is provided without warranty of any kind."
|
== "With the support of HERE Technologies. All information is provided without warranty of any kind."
|
||||||
)
|
)
|
||||||
assert sensor.state == expected_state
|
assert duration.attributes.get(ATTR_ICON) == icon
|
||||||
|
assert duration.state == expected_duration
|
||||||
|
|
||||||
assert sensor.attributes.get(ATTR_DURATION) == 30.05
|
assert (
|
||||||
assert sensor.attributes.get(ATTR_DISTANCE) == expected_distance
|
hass.states.get("sensor.test_duration_in_traffic").state
|
||||||
assert sensor.attributes.get(ATTR_ROUTE) == (
|
== expected_duration_in_traffic
|
||||||
|
)
|
||||||
|
assert hass.states.get("sensor.test_distance").state == expected_distance
|
||||||
|
assert hass.states.get("sensor.test_route").state == (
|
||||||
"US-29 - K St NW; US-29 - Whitehurst Fwy; "
|
"US-29 - K St NW; US-29 - Whitehurst Fwy; "
|
||||||
"I-495 N - Capital Beltway; MD-187 S - Old Georgetown Rd"
|
"I-495 N - Capital Beltway; MD-187 S - Old Georgetown Rd"
|
||||||
)
|
)
|
||||||
assert sensor.attributes.get(CONF_UNIT_SYSTEM) == unit_system
|
|
||||||
assert (
|
assert (
|
||||||
sensor.attributes.get(ATTR_DURATION_IN_TRAFFIC) == expected_duration_in_traffic
|
hass.states.get("sensor.test_duration_in_traffic").state
|
||||||
|
== expected_duration_in_traffic
|
||||||
)
|
)
|
||||||
assert sensor.attributes.get(ATTR_ORIGIN) == ",".join(
|
assert hass.states.get("sensor.test_origin").state == "22nd St NW"
|
||||||
[CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE]
|
assert (
|
||||||
|
hass.states.get("sensor.test_origin").attributes.get(ATTR_LATITUDE)
|
||||||
|
== CAR_ORIGIN_LATITUDE
|
||||||
)
|
)
|
||||||
assert sensor.attributes.get(ATTR_DESTINATION) == ",".join(
|
assert (
|
||||||
[CAR_DESTINATION_LATITUDE, CAR_DESTINATION_LONGITUDE]
|
hass.states.get("sensor.test_origin").attributes.get(ATTR_LONGITUDE)
|
||||||
)
|
== CAR_ORIGIN_LONGITUDE
|
||||||
assert sensor.attributes.get(ATTR_ORIGIN_NAME) == "22nd St NW"
|
|
||||||
assert sensor.attributes.get(ATTR_DESTINATION_NAME) == "Service Rd S"
|
|
||||||
assert sensor.attributes.get(CONF_MODE) == mode
|
|
||||||
assert sensor.attributes.get(CONF_TRAFFIC_MODE) is (
|
|
||||||
traffic_mode == TRAFFIC_MODE_ENABLED
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert sensor.attributes.get(ATTR_ICON) == icon
|
assert hass.states.get("sensor.test_origin").state == "22nd St NW"
|
||||||
|
assert (
|
||||||
|
hass.states.get("sensor.test_origin").attributes.get(ATTR_LATITUDE)
|
||||||
|
== CAR_ORIGIN_LATITUDE
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
hass.states.get("sensor.test_origin").attributes.get(ATTR_LONGITUDE)
|
||||||
|
== CAR_ORIGIN_LONGITUDE
|
||||||
|
)
|
||||||
|
|
||||||
# Test traffic mode disabled for vehicles
|
assert hass.states.get("sensor.test_destination").state == "Service Rd S"
|
||||||
if mode in TRAVEL_MODES_VEHICLE:
|
assert (
|
||||||
assert sensor.attributes.get(ATTR_DURATION) != sensor.attributes.get(
|
hass.states.get("sensor.test_destination").attributes.get(ATTR_LATITUDE)
|
||||||
ATTR_DURATION_IN_TRAFFIC
|
== CAR_DESTINATION_LATITUDE
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
hass.states.get("sensor.test_destination").attributes.get(ATTR_LONGITUDE)
|
||||||
|
== CAR_DESTINATION_LONGITUDE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("valid_response")
|
@pytest.mark.usefixtures("valid_response")
|
||||||
|
@ -261,7 +258,9 @@ async def test_no_attribution(hass: HomeAssistant):
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert hass.states.get("sensor.test").attributes.get(ATTR_ATTRIBUTION) is None
|
assert (
|
||||||
|
hass.states.get("sensor.test_duration").attributes.get(ATTR_ATTRIBUTION) is None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_entity_ids(hass: HomeAssistant, valid_response: MagicMock):
|
async def test_entity_ids(hass: HomeAssistant, valid_response: MagicMock):
|
||||||
|
@ -305,8 +304,7 @@ async def test_entity_ids(hass: HomeAssistant, valid_response: MagicMock):
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
sensor = hass.states.get("sensor.test")
|
assert hass.states.get("sensor.test_distance").state == "23.903"
|
||||||
assert sensor.attributes.get(ATTR_DISTANCE) == 23.903
|
|
||||||
|
|
||||||
valid_response.assert_called_with(
|
valid_response.assert_called_with(
|
||||||
[CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE],
|
[CAR_ORIGIN_LATITUDE, CAR_ORIGIN_LONGITUDE],
|
||||||
|
|
Loading…
Reference in New Issue