diff --git a/homeassistant/components/alarm_control_panel/device_trigger.py b/homeassistant/components/alarm_control_panel/device_trigger.py index 9106942c5e5..fc3850dce30 100644 --- a/homeassistant/components/alarm_control_panel/device_trigger.py +++ b/homeassistant/components/alarm_control_panel/device_trigger.py @@ -46,7 +46,7 @@ TRIGGER_TYPES: Final[set[str]] = BASIC_TRIGGER_TYPES | { TRIGGER_SCHEMA: Final = DEVICE_TRIGGER_BASE_SCHEMA.extend( { - vol.Required(CONF_ENTITY_ID): cv.entity_id, + vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid, vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES), vol.Optional(CONF_FOR): cv.positive_time_period_dict, } @@ -72,7 +72,7 @@ async def async_get_triggers( CONF_PLATFORM: "device", CONF_DEVICE_ID: device_id, CONF_DOMAIN: DOMAIN, - CONF_ENTITY_ID: entry.entity_id, + CONF_ENTITY_ID: entry.id, } triggers += [ diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 15f05e2bd42..29a9def5673 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -470,13 +470,15 @@ class EntityRegistry: return entity_id in self.entities @callback - def async_get(self, entity_id: str) -> RegistryEntry | None: - """Get EntityEntry for an entity_id. + def async_get(self, entity_id_or_uuid: str) -> RegistryEntry | None: + """Get EntityEntry for an entity_id or entity entry id. We retrieve the RegistryEntry from the underlying dict to avoid the overhead of the UserDict __getitem__. """ - return self._entities_data.get(entity_id) + return self._entities_data.get(entity_id_or_uuid) or self.entities.get_entry( + entity_id_or_uuid + ) @callback def async_get_entity_id( diff --git a/tests/components/alarm_control_panel/test_device_trigger.py b/tests/components/alarm_control_panel/test_device_trigger.py index d81c83702d8..99270f8747a 100644 --- a/tests/components/alarm_control_panel/test_device_trigger.py +++ b/tests/components/alarm_control_panel/test_device_trigger.py @@ -96,7 +96,7 @@ async def test_get_triggers( config_entry_id=config_entry.entry_id, connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - entity_registry.async_get_or_create( + entry = entity_registry.async_get_or_create( DOMAIN, "test", "5678", @@ -105,7 +105,7 @@ async def test_get_triggers( ) if set_state: hass.states.async_set( - "alarm_control_panel.test_5678", + entry.entity_id, "attributes", {"supported_features": features_state}, ) @@ -117,7 +117,7 @@ async def test_get_triggers( "domain": DOMAIN, "type": trigger, "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", + "entity_id": entry.id, "metadata": {"secondary": False}, } for trigger in expected_trigger_types @@ -151,7 +151,7 @@ async def test_get_triggers_hidden_auxiliary( config_entry_id=config_entry.entry_id, connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) - entity_registry.async_get_or_create( + entry = entity_registry.async_get_or_create( DOMAIN, "test", "5678", @@ -165,7 +165,7 @@ async def test_get_triggers_hidden_auxiliary( "domain": DOMAIN, "type": trigger, "device_id": device_entry.id, - "entity_id": f"{DOMAIN}.test_5678", + "entity_id": entry.id, "metadata": {"secondary": True}, } for trigger in ["triggered", "disarmed", "arming"] @@ -211,10 +211,12 @@ async def test_get_trigger_capabilities( async def test_if_fires_on_state_change( - hass: HomeAssistant, calls: list[ServiceCall] -) -> None: + hass: HomeAssistant, entity_registry: er.EntityRegistry, calls: list[ServiceCall] +): """Test for turn_on and turn_off triggers firing.""" - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_PENDING) + entry = entity_registry.async_get_or_create(DOMAIN, "test", "5678") + + hass.states.async_set(entry.entity_id, STATE_ALARM_PENDING) assert await async_setup_component( hass, @@ -226,7 +228,7 @@ async def test_if_fires_on_state_change( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": "alarm_control_panel.entity", + "entity_id": entry.id, "type": "triggered", }, "action": { @@ -248,7 +250,7 @@ async def test_if_fires_on_state_change( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": "alarm_control_panel.entity", + "entity_id": entry.id, "type": "disarmed", }, "action": { @@ -270,7 +272,7 @@ async def test_if_fires_on_state_change( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": "alarm_control_panel.entity", + "entity_id": entry.id, "type": "armed_home", }, "action": { @@ -292,7 +294,7 @@ async def test_if_fires_on_state_change( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": "alarm_control_panel.entity", + "entity_id": entry.id, "type": "armed_away", }, "action": { @@ -314,7 +316,7 @@ async def test_if_fires_on_state_change( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": "alarm_control_panel.entity", + "entity_id": entry.id, "type": "armed_night", }, "action": { @@ -336,7 +338,7 @@ async def test_if_fires_on_state_change( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": "alarm_control_panel.entity", + "entity_id": entry.id, "type": "armed_vacation", }, "action": { @@ -358,72 +360,67 @@ async def test_if_fires_on_state_change( ) # Fake that the entity is triggered. - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_TRIGGERED) + hass.states.async_set(entry.entity_id, STATE_ALARM_TRIGGERED) await hass.async_block_till_done() assert len(calls) == 1 assert ( calls[0].data["some"] - == "triggered - device - alarm_control_panel.entity - pending - triggered -" - " None" + == f"triggered - device - {entry.entity_id} - pending - triggered - None" ) # Fake that the entity is disarmed. - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_DISARMED) + hass.states.async_set(entry.entity_id, STATE_ALARM_DISARMED) await hass.async_block_till_done() assert len(calls) == 2 assert ( calls[1].data["some"] - == "disarmed - device - alarm_control_panel.entity - triggered - disarmed -" - " None" + == f"disarmed - device - {entry.entity_id} - triggered - disarmed - None" ) # Fake that the entity is armed home. - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_ARMED_HOME) + hass.states.async_set(entry.entity_id, STATE_ALARM_ARMED_HOME) await hass.async_block_till_done() assert len(calls) == 3 assert ( calls[2].data["some"] - == "armed_home - device - alarm_control_panel.entity - disarmed - armed_home -" - " None" + == f"armed_home - device - {entry.entity_id} - disarmed - armed_home - None" ) # Fake that the entity is armed away. - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_ARMED_AWAY) + hass.states.async_set(entry.entity_id, STATE_ALARM_ARMED_AWAY) await hass.async_block_till_done() assert len(calls) == 4 assert ( calls[3].data["some"] - == "armed_away - device - alarm_control_panel.entity - armed_home - armed_away" - " - None" + == f"armed_away - device - {entry.entity_id} - armed_home - armed_away - None" ) # Fake that the entity is armed night. - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_ARMED_NIGHT) + hass.states.async_set(entry.entity_id, STATE_ALARM_ARMED_NIGHT) await hass.async_block_till_done() assert len(calls) == 5 assert ( calls[4].data["some"] - == "armed_night - device - alarm_control_panel.entity - armed_away -" - " armed_night - None" + == f"armed_night - device - {entry.entity_id} - armed_away - armed_night - None" ) # Fake that the entity is armed vacation. - hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_ARMED_VACATION) + hass.states.async_set(entry.entity_id, STATE_ALARM_ARMED_VACATION) await hass.async_block_till_done() assert len(calls) == 6 assert ( calls[5].data["some"] - == "armed_vacation - device - alarm_control_panel.entity - armed_night -" - " armed_vacation - None" + == f"armed_vacation - device - {entry.entity_id} - armed_night - armed_vacation - None" ) async def test_if_fires_on_state_change_with_for( - hass: HomeAssistant, calls: list[ServiceCall] + hass: HomeAssistant, entity_registry: er.EntityRegistry, calls: list[ServiceCall] ) -> None: """Test for triggers firing with delay.""" - entity_id = f"{DOMAIN}.entity" - hass.states.async_set(entity_id, STATE_ALARM_DISARMED) + entry = entity_registry.async_get_or_create(DOMAIN, "test", "5678") + + hass.states.async_set(entry.entity_id, STATE_ALARM_DISARMED) assert await async_setup_component( hass, @@ -435,7 +432,7 @@ async def test_if_fires_on_state_change_with_for( "platform": "device", "domain": DOMAIN, "device_id": "", - "entity_id": entity_id, + "entity_id": entry.id, "type": "triggered", "for": {"seconds": 5}, }, @@ -459,10 +456,9 @@ async def test_if_fires_on_state_change_with_for( }, ) await hass.async_block_till_done() - assert hass.states.get(entity_id).state == STATE_ALARM_DISARMED assert len(calls) == 0 - hass.states.async_set(entity_id, STATE_ALARM_TRIGGERED) + hass.states.async_set(entry.entity_id, STATE_ALARM_TRIGGERED) await hass.async_block_till_done() assert len(calls) == 0 async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10)) @@ -471,5 +467,5 @@ async def test_if_fires_on_state_change_with_for( await hass.async_block_till_done() assert ( calls[0].data["some"] - == f"turn_off device - {entity_id} - disarmed - triggered - 0:00:05" + == f"turn_off device - {entry.entity_id} - disarmed - triggered - 0:00:05" ) diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index a0425065775..f1801f181cf 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -34,6 +34,16 @@ def update_events(hass): return events +async def test_get(hass: HomeAssistant, entity_registry: er.EntityRegistry): + """Test we can get an item.""" + entry = entity_registry.async_get_or_create("light", "hue", "1234") + + assert entity_registry.async_get(entry.entity_id) is entry + assert entity_registry.async_get(entry.id) is entry + assert entity_registry.async_get("blah") is None + assert entity_registry.async_get("blah.blah") is None + + async def test_get_or_create_returns_same_entry( hass: HomeAssistant, entity_registry: er.EntityRegistry, update_events ) -> None: