From efe33d815f387ed0fa6b52deb09e7e6c34dd5563 Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Sun, 12 Nov 2023 21:36:54 +0100 Subject: [PATCH] Address late proximity coordinator review comments (#103879) --- .../components/proximity/__init__.py | 14 ++++- .../components/proximity/coordinator.py | 59 ++++++++----------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/proximity/__init__.py b/homeassistant/components/proximity/__init__.py index d2db7632b52..4012d6e8ea1 100644 --- a/homeassistant/components/proximity/__init__.py +++ b/homeassistant/components/proximity/__init__.py @@ -8,6 +8,7 @@ import voluptuous as vol from homeassistant.const import CONF_DEVICES, CONF_UNIT_OF_MEASUREMENT, CONF_ZONE from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -47,12 +48,21 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: hass.data.setdefault(DOMAIN, {}) for zone, proximity_config in config[DOMAIN].items(): _LOGGER.debug("setup %s with config:%s", zone, proximity_config) + coordinator = ProximityDataUpdateCoordinator(hass, zone, proximity_config) - await coordinator.async_config_entry_first_refresh() + + async_track_state_change( + hass, + proximity_config[CONF_DEVICES], + coordinator.async_check_proximity_state_change, + ) + + await coordinator.async_refresh() hass.data[DOMAIN][zone] = coordinator + proximity = Proximity(hass, zone, coordinator) - proximity.async_write_ha_state() await proximity.async_added_to_hass() + proximity.async_write_ha_state() return True diff --git a/homeassistant/components/proximity/coordinator.py b/homeassistant/components/proximity/coordinator.py index 1b5770378dd..1f1c96c9490 100644 --- a/homeassistant/components/proximity/coordinator.py +++ b/homeassistant/components/proximity/coordinator.py @@ -13,7 +13,6 @@ from homeassistant.const import ( UnitOfLength, ) from homeassistant.core import HomeAssistant, State -from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util.location import distance @@ -77,9 +76,6 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): } self.state_change_data: StateChangedData | None = None - async_track_state_change( - hass, self.proximity_devices, self.async_check_proximity_state_change - ) async def async_check_proximity_state_change( self, entity: str, old_state: State | None, new_state: State | None @@ -89,22 +85,19 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): _LOGGER.debug("no new_state -> abort") return - # We can't check proximity because latitude and longitude don't exist. - if "latitude" not in new_state.attributes: - _LOGGER.debug("no latitude and longitude -> abort") - return - self.state_change_data = StateChangedData(entity, old_state, new_state) await self.async_refresh() async def _async_update_data(self) -> ProximityData: """Calculate Proximity data.""" - if self.state_change_data is None or self.state_change_data.new_state is None: + if ( + state_change_data := self.state_change_data + ) is None or state_change_data.new_state is None: return self.data - entity_name = self.state_change_data.new_state.name + entity_name = state_change_data.new_state.name devices_to_calculate = False - devices_in_zone = "" + devices_in_zone = [] zone_state = self.hass.states.get(f"zone.{self.proximity_zone}") proximity_latitude = ( @@ -126,9 +119,7 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): # Check the location of all devices. if (device_state.state).lower() == (self.proximity_zone).lower(): device_friendly = device_state.name - if devices_in_zone != "": - devices_in_zone = f"{devices_in_zone}, " - devices_in_zone = devices_in_zone + device_friendly + devices_in_zone.append(device_friendly) # No-one to track so reset the entity. if not devices_to_calculate: @@ -140,14 +131,19 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): } # At least one device is in the monitored zone so update the entity. - if devices_in_zone != "": - _LOGGER.debug("at least on device is in zone -> arrived") + if devices_in_zone: + _LOGGER.debug("at least one device is in zone -> arrived") return { "dist_to_zone": 0, "dir_of_travel": "arrived", - "nearest": devices_in_zone, + "nearest": ", ".join(devices_in_zone), } + # We can't check proximity because latitude and longitude don't exist. + if "latitude" not in state_change_data.new_state.attributes: + _LOGGER.debug("no latitude and longitude -> reset") + return self.data + # Collect distances to the zone for all devices. distances_to_zone: dict[str, float] = {} for device in self.proximity_devices: @@ -169,7 +165,7 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): ) # Add the device and distance to a dictionary. - if not proximity: + if proximity is None: continue distances_to_zone[device] = round( DistanceConverter.convert( @@ -189,10 +185,7 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): dist_to_zone = zone # If the closest device is one of the other devices. - if ( - closest_device is not None - and closest_device != self.state_change_data.entity_id - ): + if closest_device is not None and closest_device != state_change_data.entity_id: _LOGGER.debug("closest device is one of the other devices -> unknown") device_state = self.hass.states.get(closest_device) assert device_state @@ -205,14 +198,12 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): # Stop if we cannot calculate the direction of travel (i.e. we don't # have a previous state and a current LAT and LONG). if ( - self.state_change_data.old_state is None - or "latitude" not in self.state_change_data.old_state.attributes + state_change_data.old_state is None + or "latitude" not in state_change_data.old_state.attributes ): _LOGGER.debug("no lat and lon in old_state -> unknown") return { - "dist_to_zone": round( - distances_to_zone[self.state_change_data.entity_id] - ), + "dist_to_zone": round(distances_to_zone[state_change_data.entity_id]), "dir_of_travel": "unknown", "nearest": entity_name, } @@ -224,14 +215,14 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): old_distance = distance( proximity_latitude, proximity_longitude, - self.state_change_data.old_state.attributes[ATTR_LATITUDE], - self.state_change_data.old_state.attributes[ATTR_LONGITUDE], + state_change_data.old_state.attributes[ATTR_LATITUDE], + state_change_data.old_state.attributes[ATTR_LONGITUDE], ) new_distance = distance( proximity_latitude, proximity_longitude, - self.state_change_data.new_state.attributes[ATTR_LATITUDE], - self.state_change_data.new_state.attributes[ATTR_LONGITUDE], + state_change_data.new_state.attributes[ATTR_LATITUDE], + state_change_data.new_state.attributes[ATTR_LONGITUDE], ) assert new_distance is not None and old_distance is not None distance_travelled = round(new_distance - old_distance, 1) @@ -252,15 +243,13 @@ class ProximityDataUpdateCoordinator(DataUpdateCoordinator[ProximityData]): dist_to = DEFAULT_DIST_TO_ZONE _LOGGER.debug( - "proximity.%s update entity: distance=%s: direction=%s: device=%s", + "%s updated: distance=%s: direction=%s: device=%s", self.friendly_name, dist_to, direction_of_travel, entity_name, ) - _LOGGER.info("%s: proximity calculation complete", entity_name) - return { "dist_to_zone": dist_to, "dir_of_travel": direction_of_travel, -- GitLab