Skip to content

Commit 5a4c837

Browse files
authored
Fix entity_id should be based on object_id the first time an entity is added (home-assistant#148484)
1 parent cd73824 commit 5a4c837

File tree

2 files changed

+69
-12
lines changed

2 files changed

+69
-12
lines changed

homeassistant/components/mqtt/entity.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -389,16 +389,6 @@ def _async_setup_entities() -> None:
389389
_async_setup_entities()
390390

391391

392-
def init_entity_id_from_config(
393-
hass: HomeAssistant, entity: Entity, config: ConfigType, entity_id_format: str
394-
) -> None:
395-
"""Set entity_id from object_id if defined in config."""
396-
if CONF_OBJECT_ID in config:
397-
entity.entity_id = async_generate_entity_id(
398-
entity_id_format, config[CONF_OBJECT_ID], None, hass
399-
)
400-
401-
402392
class MqttAttributesMixin(Entity):
403393
"""Mixin used for platforms that support JSON attributes."""
404394

@@ -1312,6 +1302,7 @@ class MqttEntity(
13121302
_attr_should_poll = False
13131303
_default_name: str | None
13141304
_entity_id_format: str
1305+
_update_registry_entity_id: str | None = None
13151306

13161307
def __init__(
13171308
self,
@@ -1346,13 +1337,33 @@ def __init__(
13461337

13471338
def _init_entity_id(self) -> None:
13481339
"""Set entity_id from object_id if defined in config."""
1349-
init_entity_id_from_config(
1350-
self.hass, self, self._config, self._entity_id_format
1340+
if CONF_OBJECT_ID not in self._config:
1341+
return
1342+
self.entity_id = async_generate_entity_id(
1343+
self._entity_id_format, self._config[CONF_OBJECT_ID], None, self.hass
13511344
)
1345+
if self.unique_id is None:
1346+
return
1347+
# Check for previous deleted entities
1348+
entity_registry = er.async_get(self.hass)
1349+
entity_platform = self._entity_id_format.split(".")[0]
1350+
if (
1351+
deleted_entry := entity_registry.deleted_entities.get(
1352+
(entity_platform, DOMAIN, self.unique_id)
1353+
)
1354+
) and deleted_entry.entity_id != self.entity_id:
1355+
# Plan to update the entity_id basis on `object_id` if a deleted entity was found
1356+
self._update_registry_entity_id = self.entity_id
13521357

13531358
@final
13541359
async def async_added_to_hass(self) -> None:
13551360
"""Subscribe to MQTT events."""
1361+
if self._update_registry_entity_id is not None:
1362+
entity_registry = er.async_get(self.hass)
1363+
entity_registry.async_update_entity(
1364+
self.entity_id, new_entity_id=self._update_registry_entity_id
1365+
)
1366+
13561367
await super().async_added_to_hass()
13571368
self._subscriptions = {}
13581369
self._prepare_subscribe_topics()

tests/components/mqtt/test_discovery.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,52 @@ async def test_discovery_with_object_id(
14961496
assert (domain, "object bla") in hass.data["mqtt"].discovery_already_discovered
14971497

14981498

1499+
async def test_discovery_with_object_id_for_previous_deleted_entity(
1500+
hass: HomeAssistant,
1501+
mqtt_mock_entry: MqttMockHAClientGenerator,
1502+
) -> None:
1503+
"""Test discovering an MQTT entity with object_id and unique_id."""
1504+
1505+
topic = "homeassistant/sensor/object/bla/config"
1506+
config = (
1507+
'{ "name": "Hello World 11", "unique_id": "very_unique", '
1508+
'"obj_id": "hello_id", "state_topic": "test-topic" }'
1509+
)
1510+
new_config = (
1511+
'{ "name": "Hello World 11", "unique_id": "very_unique", '
1512+
'"obj_id": "updated_hello_id", "state_topic": "test-topic" }'
1513+
)
1514+
initial_entity_id = "sensor.hello_id"
1515+
new_entity_id = "sensor.updated_hello_id"
1516+
name = "Hello World 11"
1517+
domain = "sensor"
1518+
1519+
await mqtt_mock_entry()
1520+
async_fire_mqtt_message(hass, topic, config)
1521+
await hass.async_block_till_done()
1522+
1523+
state = hass.states.get(initial_entity_id)
1524+
1525+
assert state is not None
1526+
assert state.name == name
1527+
assert (domain, "object bla") in hass.data["mqtt"].discovery_already_discovered
1528+
1529+
# Delete the entity
1530+
async_fire_mqtt_message(hass, topic, "")
1531+
await hass.async_block_till_done()
1532+
assert (domain, "object bla") not in hass.data["mqtt"].discovery_already_discovered
1533+
1534+
# Rediscover with new object_id
1535+
async_fire_mqtt_message(hass, topic, new_config)
1536+
await hass.async_block_till_done()
1537+
1538+
state = hass.states.get(new_entity_id)
1539+
1540+
assert state is not None
1541+
assert state.name == name
1542+
assert (domain, "object bla") in hass.data["mqtt"].discovery_already_discovered
1543+
1544+
14991545
async def test_discovery_incl_nodeid(
15001546
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
15011547
) -> None:

0 commit comments

Comments
 (0)