From b7c7571a39e2d6f9dc1af7c760770fab72476e1c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 31 Jan 2022 17:04:46 -0800 Subject: [PATCH] I zone, you zone, we zoning (#65344) --- homeassistant/components/zone/__init__.py | 66 +------------ tests/components/zone/test_init.py | 115 +--------------------- 2 files changed, 7 insertions(+), 174 deletions(-) diff --git a/homeassistant/components/zone/__init__.py b/homeassistant/components/zone/__init__.py index 41fdd8c32d3..dd327acbf75 100644 --- a/homeassistant/components/zone/__init__.py +++ b/homeassistant/components/zone/__init__.py @@ -1,7 +1,6 @@ """Support for the definition of zones.""" from __future__ import annotations -from collections.abc import Callable import logging from typing import Any, cast @@ -10,7 +9,6 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.const import ( ATTR_EDITABLE, - ATTR_GPS_ACCURACY, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_ICON, @@ -29,7 +27,6 @@ from homeassistant.helpers import ( config_validation as cv, entity, entity_component, - event, service, storage, ) @@ -287,10 +284,7 @@ class Zone(entity.Entity): """Initialize the zone.""" self._config = config self.editable = True - self._attrs: dict | None = None - self._remove_listener: Callable[[], None] | None = None self._generate_attrs() - self._persons_in_zone: set[str] = set() @classmethod def from_yaml(cls, config: dict) -> Zone: @@ -301,9 +295,9 @@ class Zone(entity.Entity): return zone @property - def state(self) -> int: + def state(self) -> str: """Return the state property really does nothing for a zone.""" - return len(self._persons_in_zone) + return "zoning" @property def name(self) -> str: @@ -320,11 +314,6 @@ class Zone(entity.Entity): """Return the icon if any.""" return self._config.get(CONF_ICON) - @property - def extra_state_attributes(self) -> dict | None: - """Return the state attributes of the zone.""" - return self._attrs - @property def should_poll(self) -> bool: """Zone does not poll.""" @@ -338,59 +327,10 @@ class Zone(entity.Entity): self._generate_attrs() self.async_write_ha_state() - @callback - def _person_state_change_listener(self, evt: Event) -> None: - person_entity_id = evt.data["entity_id"] - cur_count = len(self._persons_in_zone) - if ( - (state := evt.data["new_state"]) - and (latitude := state.attributes.get(ATTR_LATITUDE)) is not None - and (longitude := state.attributes.get(ATTR_LONGITUDE)) is not None - and (accuracy := state.attributes.get(ATTR_GPS_ACCURACY)) is not None - and ( - zone_state := async_active_zone( - self.hass, latitude, longitude, accuracy - ) - ) - and zone_state.entity_id == self.entity_id - ): - self._persons_in_zone.add(person_entity_id) - elif person_entity_id in self._persons_in_zone: - self._persons_in_zone.remove(person_entity_id) - - if len(self._persons_in_zone) != cur_count: - self.async_write_ha_state() - - async def async_added_to_hass(self) -> None: - """Run when entity about to be added to hass.""" - await super().async_added_to_hass() - person_domain = "person" # avoid circular import - persons = self.hass.states.async_entity_ids(person_domain) - for person in persons: - state = self.hass.states.get(person) - if ( - state is None - or (latitude := state.attributes.get(ATTR_LATITUDE)) is None - or (longitude := state.attributes.get(ATTR_LONGITUDE)) is None - or (accuracy := state.attributes.get(ATTR_GPS_ACCURACY)) is None - ): - continue - zone_state = async_active_zone(self.hass, latitude, longitude, accuracy) - if zone_state is not None and zone_state.entity_id == self.entity_id: - self._persons_in_zone.add(person) - - self.async_on_remove( - event.async_track_state_change_filtered( - self.hass, - event.TrackStates(False, set(), {person_domain}), - self._person_state_change_listener, - ).async_remove - ) - @callback def _generate_attrs(self) -> None: """Generate new attrs based on config.""" - self._attrs = { + self._attr_extra_state_attributes = { ATTR_LATITUDE: self._config[CONF_LATITUDE], ATTR_LONGITUDE: self._config[CONF_LONGITUDE], ATTR_RADIUS: self._config[CONF_RADIUS], diff --git a/tests/components/zone/test_init.py b/tests/components/zone/test_init.py index 54cb87aa772..8d0fddb921c 100644 --- a/tests/components/zone/test_init.py +++ b/tests/components/zone/test_init.py @@ -316,7 +316,7 @@ async def test_load_from_storage(hass, storage_setup): """Test set up from storage.""" assert await storage_setup() state = hass.states.get(f"{DOMAIN}.from_storage") - assert state.state == "0" + assert state.state == "zoning" assert state.name == "from storage" assert state.attributes.get(ATTR_EDITABLE) @@ -328,12 +328,12 @@ async def test_editable_state_attribute(hass, storage_setup): ) state = hass.states.get(f"{DOMAIN}.from_storage") - assert state.state == "0" + assert state.state == "zoning" assert state.attributes.get(ATTR_FRIENDLY_NAME) == "from storage" assert state.attributes.get(ATTR_EDITABLE) state = hass.states.get(f"{DOMAIN}.yaml_option") - assert state.state == "0" + assert state.state == "zoning" assert not state.attributes.get(ATTR_EDITABLE) @@ -457,7 +457,7 @@ async def test_ws_create(hass, hass_ws_client, storage_setup): assert resp["success"] state = hass.states.get(input_entity_id) - assert state.state == "0" + assert state.state == "zoning" assert state.attributes["latitude"] == 3 assert state.attributes["longitude"] == 4 assert state.attributes["passive"] is True @@ -503,110 +503,3 @@ async def test_unavailable_zone(hass): assert zone.async_active_zone(hass, 0.0, 0.01) is None assert zone.in_zone(hass.states.get("zone.bla"), 0, 0) is False - - -async def test_state(hass): - """Test the state of a zone.""" - info = { - "name": "Test Zone", - "latitude": 32.880837, - "longitude": -117.237561, - "radius": 250, - "passive": False, - } - assert await setup.async_setup_component(hass, zone.DOMAIN, {"zone": info}) - - assert len(hass.states.async_entity_ids("zone")) == 2 - state = hass.states.get("zone.test_zone") - assert state.state == "0" - - # Person entity enters zone - hass.states.async_set( - "person.person1", - "Test Zone", - {"latitude": 32.880837, "longitude": -117.237561, "gps_accuracy": 0}, - ) - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "1" - assert hass.states.get("zone.home").state == "0" - - # Person entity enters zone - hass.states.async_set( - "person.person2", - "Test Zone", - {"latitude": 32.880837, "longitude": -117.237561, "gps_accuracy": 0}, - ) - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "2" - assert hass.states.get("zone.home").state == "0" - - # Person entity enters another zone - hass.states.async_set( - "person.person1", - "home", - {"latitude": 32.87336, "longitude": -117.22743, "gps_accuracy": 0}, - ) - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "1" - assert hass.states.get("zone.home").state == "1" - - # Person entity removed - hass.states.async_remove("person.person2") - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "0" - assert hass.states.get("zone.home").state == "1" - - -async def test_state_2(hass): - """Test the state of a zone.""" - hass.states.async_set("person.person1", "unknown") - hass.states.async_set("person.person2", "unknown") - - info = { - "name": "Test Zone", - "latitude": 32.880837, - "longitude": -117.237561, - "radius": 250, - "passive": False, - } - assert await setup.async_setup_component(hass, zone.DOMAIN, {"zone": info}) - - assert len(hass.states.async_entity_ids("zone")) == 2 - state = hass.states.get("zone.test_zone") - assert state.state == "0" - - # Person entity enters zone - hass.states.async_set( - "person.person1", - "Test Zone", - {"latitude": 32.880837, "longitude": -117.237561, "gps_accuracy": 0}, - ) - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "1" - assert hass.states.get("zone.home").state == "0" - - # Person entity enters zone - hass.states.async_set( - "person.person2", - "Test Zone", - {"latitude": 32.880837, "longitude": -117.237561, "gps_accuracy": 0}, - ) - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "2" - assert hass.states.get("zone.home").state == "0" - - # Person entity enters another zone - hass.states.async_set( - "person.person1", - "home", - {"latitude": 32.87336, "longitude": -117.22743, "gps_accuracy": 0}, - ) - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "1" - assert hass.states.get("zone.home").state == "1" - - # Person entity removed - hass.states.async_remove("person.person2") - await hass.async_block_till_done() - assert hass.states.get("zone.test_zone").state == "0" - assert hass.states.get("zone.home").state == "1"