1 """Location helpers for Home Assistant."""
3 from __future__
import annotations
5 from collections.abc
import Iterable
12 _LOGGER = logging.getLogger(__name__)
16 """Test if state contains a valid location.
21 isinstance(state, State)
22 and isinstance(state.attributes.get(ATTR_LATITUDE), float)
23 and isinstance(state.attributes.get(ATTR_LONGITUDE), float)
27 def closest(latitude: float, longitude: float, states: Iterable[State]) -> State |
None:
28 """Return closest state to point.
32 with_location = [state
for state
in states
if has_location(state)]
39 key=
lambda state: loc_util.distance(
40 state.attributes.get(ATTR_LATITUDE),
41 state.attributes.get(ATTR_LONGITUDE),
50 hass: HomeAssistant, name: str, recursion_history: list |
None =
None
52 """Try to resolve the a location from a supplied name or entity_id.
54 Will recursively resolve an entity if pointed to by the state of the supplied
57 Returns coordinates in the form of '90.000,180.000', an address or
58 the state of the last resolved entity.
61 if (zone_coords :=
resolve_zone(hass, name))
is not None:
65 if (entity_state := hass.states.get(name))
is None:
66 _LOGGER.debug(
"Unable to find entity %s", name)
74 zone_entity = hass.states.get(f
"zone.{entity_state.state}")
77 "%s is in %s, getting zone location",
79 zone_entity.entity_id,
84 if (zone_coords :=
resolve_zone(hass, entity_state.state))
is not None:
88 if recursion_history
is None:
89 recursion_history = []
90 recursion_history.append(name)
91 if entity_state.state
in recursion_history:
94 "Circular reference detected while trying to find coordinates of an"
95 " entity. The state of %s has already been checked"
100 _LOGGER.debug(
"Getting nested entity for state: %s", entity_state.state)
101 nested_entity = hass.states.get(entity_state.state)
102 if nested_entity
is not None:
103 _LOGGER.debug(
"Resolving nested entity_id: %s", entity_state.state)
108 return entity_state.state
112 """Get a lat/long from a zones friendly_name.
114 None is returned if no zone is found by that friendly_name.
116 states = hass.states.async_all(
"zone")
118 if state.name == zone_name:
125 """Get the lat/long string from an entities attributes."""
126 attr = entity_state.attributes
127 return f
"{attr.get(ATTR_LATITUDE)},{attr.get(ATTR_LONGITUDE)}"
str _get_location_from_attributes(State entity_state)
bool has_location(State state)
State|None closest(float latitude, float longitude, Iterable[State] states)
str|None find_coordinates(HomeAssistant hass, str name, list|None recursion_history=None)
str|None resolve_zone(HomeAssistant hass, str zone_name)