Migrate mqtt mixin async_added_to_hass inner functions to bound methods (#118280)

This commit is contained in:
J. Nick Koston 2024-05-27 22:45:40 -10:00 committed by GitHub
parent fb95b91507
commit a3c3f938a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -823,105 +823,99 @@ class MqttDiscoveryUpdateMixin(Entity):
"""Subscribe to discovery updates.""" """Subscribe to discovery updates."""
await super().async_added_to_hass() await super().async_added_to_hass()
self._removed_from_hass = False self._removed_from_hass = False
discovery_hash: tuple[str, str] | None = ( if not self._discovery_data:
self._discovery_data[ATTR_DISCOVERY_HASH] if self._discovery_data else None return
discovery_hash: tuple[str, str] = self._discovery_data[ATTR_DISCOVERY_HASH]
debug_info.add_entity_discovery_data(
self.hass, self._discovery_data, self.entity_id
)
# Set in case the entity has been removed and is re-added,
# for example when changing entity_id
set_discovery_hash(self.hass, discovery_hash)
self._remove_discovery_updated = async_dispatcher_connect(
self.hass,
MQTT_DISCOVERY_UPDATED.format(*discovery_hash),
self._async_discovery_callback,
) )
async def _async_remove_state_and_registry_entry( async def _async_remove_state_and_registry_entry(
self: MqttDiscoveryUpdateMixin, self: MqttDiscoveryUpdateMixin,
) -> None: ) -> None:
"""Remove entity's state and entity registry entry. """Remove entity's state and entity registry entry.
Remove entity from entity registry if it is registered, Remove entity from entity registry if it is registered,
this also removes the state. If the entity is not in the entity this also removes the state. If the entity is not in the entity
registry, just remove the state. registry, just remove the state.
""" """
entity_registry = er.async_get(self.hass) entity_registry = er.async_get(self.hass)
if entity_entry := entity_registry.async_get(self.entity_id): if entity_entry := entity_registry.async_get(self.entity_id):
entity_registry.async_remove(self.entity_id) entity_registry.async_remove(self.entity_id)
await cleanup_device_registry( await cleanup_device_registry(
self.hass, entity_entry.device_id, entity_entry.config_entry_id self.hass, entity_entry.device_id, entity_entry.config_entry_id
) )
else: else:
await self.async_remove(force_remove=True) await self.async_remove(force_remove=True)
async def _async_process_discovery_update( async def _async_process_discovery_update(
payload: MQTTDiscoveryPayload, self,
discovery_update: Callable[ payload: MQTTDiscoveryPayload,
[MQTTDiscoveryPayload], Coroutine[Any, Any, None] discovery_update: Callable[[MQTTDiscoveryPayload], Coroutine[Any, Any, None]],
], discovery_data: DiscoveryInfoType,
discovery_data: DiscoveryInfoType, ) -> None:
) -> None: """Process discovery update."""
"""Process discovery update.""" try:
try: await discovery_update(payload)
await discovery_update(payload) finally:
finally:
send_discovery_done(self.hass, discovery_data)
async def _async_process_discovery_update_and_remove(
payload: MQTTDiscoveryPayload, discovery_data: DiscoveryInfoType
) -> None:
"""Process discovery update and remove entity."""
self._cleanup_discovery_on_remove()
await _async_remove_state_and_registry_entry(self)
send_discovery_done(self.hass, discovery_data) send_discovery_done(self.hass, discovery_data)
@callback async def _async_process_discovery_update_and_remove(self) -> None:
def discovery_callback(payload: MQTTDiscoveryPayload) -> None: """Process discovery update and remove entity."""
"""Handle discovery update. if TYPE_CHECKING:
assert self._discovery_data
self._cleanup_discovery_on_remove()
await self._async_remove_state_and_registry_entry()
send_discovery_done(self.hass, self._discovery_data)
If the payload has changed we will create a task to @callback
do the discovery update. def _async_discovery_callback(self, payload: MQTTDiscoveryPayload) -> None:
"""Handle discovery update.
As this callback can fire when nothing has changed, this If the payload has changed we will create a task to
is a normal function to avoid task creation until it is needed. do the discovery update.
"""
_LOGGER.debug( As this callback can fire when nothing has changed, this
"Got update for entity with hash: %s '%s'", is a normal function to avoid task creation until it is needed.
discovery_hash, """
payload, if TYPE_CHECKING:
assert self._discovery_data
discovery_hash: tuple[str, str] = self._discovery_data[ATTR_DISCOVERY_HASH]
_LOGGER.debug(
"Got update for entity with hash: %s '%s'",
discovery_hash,
payload,
)
old_payload: DiscoveryInfoType
old_payload = self._discovery_data[ATTR_DISCOVERY_PAYLOAD]
debug_info.update_entity_discovery_data(self.hass, payload, self.entity_id)
if not payload:
# Empty payload: Remove component
_LOGGER.info("Removing component: %s", self.entity_id)
self.hass.async_create_task(
self._async_process_discovery_update_and_remove()
) )
if TYPE_CHECKING: elif self._discovery_update:
assert self._discovery_data if old_payload != payload:
old_payload: DiscoveryInfoType # Non-empty, changed payload: Notify component
old_payload = self._discovery_data[ATTR_DISCOVERY_PAYLOAD] _LOGGER.info("Updating component: %s", self.entity_id)
debug_info.update_entity_discovery_data(self.hass, payload, self.entity_id)
if not payload:
# Empty payload: Remove component
_LOGGER.info("Removing component: %s", self.entity_id)
self.hass.async_create_task( self.hass.async_create_task(
_async_process_discovery_update_and_remove( self._async_process_discovery_update(
payload, self._discovery_data payload, self._discovery_update, self._discovery_data
) )
) )
elif self._discovery_update: else:
if old_payload != self._discovery_data[ATTR_DISCOVERY_PAYLOAD]: # Non-empty, unchanged payload: Ignore to avoid changing states
# Non-empty, changed payload: Notify component _LOGGER.debug("Ignoring unchanged update for: %s", self.entity_id)
_LOGGER.info("Updating component: %s", self.entity_id) send_discovery_done(self.hass, self._discovery_data)
self.hass.async_create_task(
_async_process_discovery_update(
payload, self._discovery_update, self._discovery_data
)
)
else:
# Non-empty, unchanged payload: Ignore to avoid changing states
_LOGGER.debug("Ignoring unchanged update for: %s", self.entity_id)
send_discovery_done(self.hass, self._discovery_data)
if discovery_hash:
if TYPE_CHECKING:
assert self._discovery_data is not None
debug_info.add_entity_discovery_data(
self.hass, self._discovery_data, self.entity_id
)
# Set in case the entity has been removed and is re-added,
# for example when changing entity_id
set_discovery_hash(self.hass, discovery_hash)
self._remove_discovery_updated = async_dispatcher_connect(
self.hass,
MQTT_DISCOVERY_UPDATED.format(*discovery_hash),
discovery_callback,
)
async def async_removed_from_registry(self) -> None: async def async_removed_from_registry(self) -> None:
"""Clear retained discovery topic in broker.""" """Clear retained discovery topic in broker."""