Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 55 additions & 20 deletions homeassistant/components/here_travel_time/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
CONF_UNIT_SYSTEM,
CONF_UNIT_SYSTEM_IMPERIAL,
CONF_UNIT_SYSTEM_METRIC,
EVENT_HOMEASSISTANT_START,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.core import HomeAssistant, State, callback
from homeassistant.helpers import location
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
Expand Down Expand Up @@ -89,8 +90,6 @@

SCAN_INTERVAL = timedelta(minutes=5)

TRACKABLE_DOMAINS = ["device_tracker", "sensor", "zone", "person"]

NO_ROUTE_ERROR_MESSAGE = "HERE could not find a route based on the input"

PLATFORM_SCHEMA = vol.All(
Expand Down Expand Up @@ -146,15 +145,19 @@ async def async_setup_platform(

if config.get(CONF_ORIGIN_LATITUDE) is not None:
origin = f"{config[CONF_ORIGIN_LATITUDE]},{config[CONF_ORIGIN_LONGITUDE]}"
origin_entity_id = None
else:
origin = config[CONF_ORIGIN_ENTITY_ID]
origin = None
origin_entity_id = config[CONF_ORIGIN_ENTITY_ID]

if config.get(CONF_DESTINATION_LATITUDE) is not None:
destination = (
f"{config[CONF_DESTINATION_LATITUDE]},{config[CONF_DESTINATION_LONGITUDE]}"
)
destination_entity_id = None
else:
destination = config[CONF_DESTINATION_ENTITY_ID]
destination = None
destination_entity_id = config[CONF_DESTINATION_ENTITY_ID]

travel_mode = config[CONF_MODE]
traffic_mode = config[CONF_TRAFFIC_MODE]
Expand All @@ -166,9 +169,11 @@ async def async_setup_platform(
here_client, travel_mode, traffic_mode, route_mode, units
)

sensor = HERETravelTimeSensor(name, origin, destination, here_data)
sensor = HERETravelTimeSensor(
name, origin, destination, origin_entity_id, destination_entity_id, here_data
)

async_add_entities([sensor], True)
async_add_entities([sensor])


def _are_valid_client_credentials(here_client: herepy.RoutingApi) -> bool:
Expand All @@ -194,31 +199,43 @@ class HERETravelTimeSensor(Entity):
"""Representation of a HERE travel time sensor."""

def __init__(
self, name: str, origin: str, destination: str, here_data: "HERETravelTimeData"
self,
name: str,
origin: str,
destination: str,
origin_entity_id: str,
destination_entity_id: str,
here_data: "HERETravelTimeData",
) -> None:
"""Initialize the sensor."""
self._name = name
self._origin_entity_id = origin_entity_id
self._destination_entity_id = destination_entity_id
self._here_data = here_data
self._unit_of_measurement = UNIT_OF_MEASUREMENT
self._origin_entity_id = None
self._destination_entity_id = None
self._attrs = {
ATTR_UNIT_SYSTEM: self._here_data.units,
ATTR_MODE: self._here_data.travel_mode,
ATTR_TRAFFIC_MODE: self._here_data.traffic_mode,
}

# Check if location is a trackable entity
if origin.split(".", 1)[0] in TRACKABLE_DOMAINS:
self._origin_entity_id = origin
else:
if self._origin_entity_id is None:
self._here_data.origin = origin

if destination.split(".", 1)[0] in TRACKABLE_DOMAINS:
self._destination_entity_id = destination
else:
if self._destination_entity_id is None:
self._here_data.destination = destination

async def async_added_to_hass(self) -> None:
"""Delay the sensor update to avoid entity not found warnings."""

@callback
def delayed_sensor_update(event):
Comment thread
MartinHjelmare marked this conversation as resolved.
"""Update sensor after homeassistant started."""
self.async_schedule_update_ha_state(True)

self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, delayed_sensor_update
)

@property
def state(self) -> Optional[str]:
"""Return the state of the sensor."""
Expand Down Expand Up @@ -309,10 +326,28 @@ async def _get_location_from_entity(self, entity_id: str) -> Optional[str]:
)
return self._get_location_from_attributes(zone_entity)

# If zone was not found in state then use the state as the location
if entity_id.startswith("sensor."):
# Check if state is valid coordinate set
if self._entity_state_is_valid_coordinate_set(entity.state):
return entity.state

_LOGGER.error(
"The state of %s is not a valid set of coordinates: %s",
entity_id,
entity.state,
)
return None

@staticmethod
def _entity_state_is_valid_coordinate_set(state: str) -> bool:
"""Check that the given string is a valid set of coordinates."""
schema = vol.Schema(cv.gps)
try:
coordinates = state.split(",")
schema(coordinates)
return True
except (vol.MultipleInvalid):
return False

@staticmethod
def _get_location_from_attributes(entity: State) -> str:
"""Get the lat/long string from an entities attributes."""
Expand Down
Loading