2016-02-21 19:13:40 +00:00
|
|
|
"""Location helpers for Home Assistant."""
|
|
|
|
|
2018-10-28 19:12:52 +00:00
|
|
|
from typing import Optional, Sequence
|
2016-08-07 23:26:35 +00:00
|
|
|
|
2016-02-21 19:13:40 +00:00
|
|
|
from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE
|
|
|
|
from homeassistant.core import State
|
|
|
|
from homeassistant.util import location as loc_util
|
|
|
|
|
|
|
|
|
2016-08-07 23:26:35 +00:00
|
|
|
def has_location(state: State) -> bool:
|
2016-11-18 22:35:08 +00:00
|
|
|
"""Test if state contains a valid location.
|
|
|
|
|
|
|
|
Async friendly.
|
|
|
|
"""
|
2019-07-16 22:11:38 +00:00
|
|
|
# type ignore: https://github.com/python/mypy/issues/7207
|
2019-07-31 19:25:30 +00:00
|
|
|
return (
|
2019-07-31 20:08:31 +00:00
|
|
|
isinstance(state, State) # type: ignore
|
|
|
|
and isinstance(state.attributes.get(ATTR_LATITUDE), float)
|
2019-07-31 19:25:30 +00:00
|
|
|
and isinstance(state.attributes.get(ATTR_LONGITUDE), float)
|
|
|
|
)
|
2016-02-21 19:13:40 +00:00
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
def closest(
|
|
|
|
latitude: float, longitude: float, states: Sequence[State]
|
|
|
|
) -> Optional[State]:
|
2016-11-18 22:35:08 +00:00
|
|
|
"""Return closest state to point.
|
|
|
|
|
|
|
|
Async friendly.
|
|
|
|
"""
|
2016-02-21 19:13:40 +00:00
|
|
|
with_location = [state for state in states if has_location(state)]
|
|
|
|
|
|
|
|
if not with_location:
|
|
|
|
return None
|
|
|
|
|
|
|
|
return min(
|
|
|
|
with_location,
|
|
|
|
key=lambda state: loc_util.distance(
|
2018-10-28 19:12:52 +00:00
|
|
|
state.attributes.get(ATTR_LATITUDE),
|
|
|
|
state.attributes.get(ATTR_LONGITUDE),
|
2019-07-31 19:25:30 +00:00
|
|
|
latitude,
|
|
|
|
longitude,
|
|
|
|
),
|
2016-02-21 19:13:40 +00:00
|
|
|
)
|