From 9db56a8119c82cda49ceabbeb63f93a7e335e148 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Sun, 27 Feb 2022 00:14:12 +0100 Subject: [PATCH] Don't trigger device removal for non rfxtrx devices (#67315) --- homeassistant/components/rfxtrx/__init__.py | 33 ++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/rfxtrx/__init__.py b/homeassistant/components/rfxtrx/__init__.py index 2dcfe639a64..8dda4d32644 100644 --- a/homeassistant/components/rfxtrx/__init__.py +++ b/homeassistant/components/rfxtrx/__init__.py @@ -6,7 +6,7 @@ import binascii from collections.abc import Callable import copy import logging -from typing import NamedTuple +from typing import NamedTuple, cast import RFXtrx as rfxtrxmod import async_timeout @@ -229,11 +229,7 @@ async def async_setup_internal(hass, entry: config_entries.ConfigEntry): devices[device_id] = config @callback - def _remove_device(event: Event): - if event.data["action"] != "remove": - return - device_entry = device_registry.deleted_devices[event.data["device_id"]] - device_id = next(iter(device_entry.identifiers))[1:] + def _remove_device(device_id: DeviceTuple): data = { **entry.data, CONF_DEVICES: { @@ -245,8 +241,19 @@ async def async_setup_internal(hass, entry: config_entries.ConfigEntry): hass.config_entries.async_update_entry(entry=entry, data=data) devices.pop(device_id) + @callback + def _updated_device(event: Event): + if event.data["action"] != "remove": + return + device_entry = device_registry.deleted_devices[event.data["device_id"]] + if entry.entry_id not in device_entry.config_entries: + return + device_id = get_device_tuple_from_identifiers(device_entry.identifiers) + if device_id: + _remove_device(device_id) + entry.async_on_unload( - hass.bus.async_listen(EVENT_DEVICE_REGISTRY_UPDATED, _remove_device) + hass.bus.async_listen(EVENT_DEVICE_REGISTRY_UPDATED, _updated_device) ) def _shutdown_rfxtrx(event): @@ -413,6 +420,18 @@ def get_device_id( return DeviceTuple(f"{device.packettype:x}", f"{device.subtype:x}", id_string) +def get_device_tuple_from_identifiers( + identifiers: set[tuple[str, str]] +) -> DeviceTuple | None: + """Calculate the device tuple from a device entry.""" + identifier = next((x for x in identifiers if x[0] == DOMAIN), None) + if not identifier: + return None + # work around legacy identifier, being a multi tuple value + identifier2 = cast(tuple[str, str, str, str], identifier) + return DeviceTuple(identifier2[1], identifier2[2], identifier2[3]) + + async def async_remove_config_entry_device( hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry ) -> bool: