diff --git a/homeassistant/components/proximity/__init__.py b/homeassistant/components/proximity/__init__.py index c4ab915b577..fabbcaec51a 100644 --- a/homeassistant/components/proximity/__init__.py +++ b/homeassistant/components/proximity/__init__.py @@ -5,6 +5,8 @@ import logging import voluptuous as vol +from homeassistant.components.automation import automations_with_entity +from homeassistant.components.script import scripts_with_entity from homeassistant.const import ( CONF_DEVICES, CONF_NAME, @@ -15,6 +17,7 @@ from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv from homeassistant.helpers.discovery import async_load_platform from homeassistant.helpers.event import async_track_state_change +from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -80,6 +83,26 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: {CONF_NAME: friendly_name, **proximity_config}, config, ) + + # deprecate proximity entity - can be removed in 2024.8 + used_in = automations_with_entity(hass, f"{DOMAIN}.{friendly_name}") + used_in += scripts_with_entity(hass, f"{DOMAIN}.{friendly_name}") + if used_in: + async_create_issue( + hass, + DOMAIN, + f"deprecated_proximity_entity_{friendly_name}", + breaks_in_ha_version="2024.8.0", + is_fixable=True, + is_persistent=True, + severity=IssueSeverity.WARNING, + translation_key="deprecated_proximity_entity", + translation_placeholders={ + "entity": f"{DOMAIN}.{friendly_name}", + "used_in": "\n- ".join([f"`{x}`" for x in used_in]), + }, + ) + return True diff --git a/homeassistant/components/proximity/strings.json b/homeassistant/components/proximity/strings.json index 56802e08051..de2c3443998 100644 --- a/homeassistant/components/proximity/strings.json +++ b/homeassistant/components/proximity/strings.json @@ -13,5 +13,18 @@ }, "nearest": { "name": "Nearest device" } } + }, + "issues": { + "deprecated_proximity_entity": { + "title": "The proximity entity is deprecated", + "fix_flow": { + "step": { + "confirm": { + "title": "[%key:component::proximity::issues::deprecated_proximity_entity::title%]", + "description": "The proximity entity `{entity}` is deprecated and will be removed in `2024.8`. However it is used within the following configurations:\n- {used_in}\n\nPlease adjust any automations or scripts that use this deprecated Proximity entity.\nFor each tracked person or device one sensor for the distance and the direction of travel to/from the monitored zone is created. Additionally for each Proximity configuration one sensor which shows the nearest device or person to the monitored zone is created. With this you can use the Min/Max integration to determine the nearest and furthest distance." + } + } + } + } } } diff --git a/tests/components/proximity/test_init.py b/tests/components/proximity/test_init.py index 5a3fee629ac..b3a83624952 100644 --- a/tests/components/proximity/test_init.py +++ b/tests/components/proximity/test_init.py @@ -2,9 +2,13 @@ import pytest +from homeassistant.components import automation, script +from homeassistant.components.automation import automations_with_entity from homeassistant.components.proximity import DOMAIN +from homeassistant.components.script import scripts_with_entity from homeassistant.const import STATE_UNKNOWN from homeassistant.core import HomeAssistant +import homeassistant.helpers.issue_registry as ir from homeassistant.setup import async_setup_component from homeassistant.util import slugify @@ -877,6 +881,71 @@ async def test_device_tracker_test1_nearest_after_test2_in_ignored_zone( assert state.state == "away_from" +async def test_create_issue( + hass: HomeAssistant, + issue_registry: ir.IssueRegistry, +) -> None: + """Test we create an issue for deprecated proximity entities used in automations and scripts.""" + assert await async_setup_component( + hass, + automation.DOMAIN, + { + automation.DOMAIN: { + "alias": "test", + "trigger": {"platform": "state", "entity_id": "proximity.home"}, + "action": { + "service": "automation.turn_on", + "target": {"entity_id": "automation.test"}, + }, + } + }, + ) + assert await async_setup_component( + hass, + script.DOMAIN, + { + script.DOMAIN: { + "test": { + "sequence": [ + { + "condition": "state", + "entity_id": "proximity.home", + "state": "home", + }, + ], + } + } + }, + ) + config = { + "proximity": { + "home": { + "ignored_zones": ["work"], + "devices": ["device_tracker.test1", "device_tracker.test2"], + "tolerance": "1", + }, + "work": {"tolerance": "1", "zone": "work"}, + } + } + + assert await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + + automation_entities = automations_with_entity(hass, "proximity.home") + assert len(automation_entities) == 1 + assert automation_entities[0] == "automation.test" + + script_entites = scripts_with_entity(hass, "proximity.home") + + assert len(script_entites) == 1 + assert script_entites[0] == "script.test" + assert issue_registry.async_get_issue(DOMAIN, "deprecated_proximity_entity_home") + + assert not issue_registry.async_get_issue( + DOMAIN, "deprecated_proximity_entity_work" + ) + + def config_zones(hass): """Set up zones for test.""" hass.config.components.add("zone")