From 8a1b38ef569ff51941676d053339e50e64be395d Mon Sep 17 00:00:00 2001 From: topsworld Date: Thu, 16 Jan 2025 10:53:13 +0800 Subject: [PATCH] fix: fix device remove error --- custom_components/xiaomi_home/__init__.py | 17 +++-------------- custom_components/xiaomi_home/miot/common.py | 6 ++++++ .../xiaomi_home/miot/miot_client.py | 9 ++++++++- .../xiaomi_home/miot/miot_device.py | 16 ++++++++++------ 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/custom_components/xiaomi_home/__init__.py b/custom_components/xiaomi_home/__init__.py index 694154d8..43f78ae8 100644 --- a/custom_components/xiaomi_home/__init__.py +++ b/custom_components/xiaomi_home/__init__.py @@ -330,21 +330,10 @@ async def async_remove_config_entry_device( 'remove device failed, invalid domain, %s, %s', device_entry.id, device_entry.identifiers) return False - device_info = identifiers[1].split('_') - if len(device_info) != 2: - _LOGGER.error( - 'remove device failed, invalid device info, %s, %s', - device_entry.id, device_entry.identifiers) - return False - did = device_info[1] - if did not in miot_client.device_list: - _LOGGER.error( - 'remove device failed, device not found, %s, %s', - device_entry.id, device_entry.identifiers) - return False + # Remove device - await miot_client.remove_device_async(did) + await miot_client.remove_device2_async(did_tag=identifiers[1]) device_registry.async_get(hass).async_remove_device(device_entry.id) _LOGGER.info( - 'remove device, %s, %s, %s', device_info[0], did, device_entry.id) + 'remove device, %s, %s', identifiers[1], device_entry.id) return True diff --git a/custom_components/xiaomi_home/miot/common.py b/custom_components/xiaomi_home/miot/common.py index dec21c3b..0d17edf4 100644 --- a/custom_components/xiaomi_home/miot/common.py +++ b/custom_components/xiaomi_home/miot/common.py @@ -55,6 +55,7 @@ from urllib.request import Request, urlopen from paho.mqtt.matcher import MQTTMatcher import yaml +from slugify import slugify MIOT_ROOT_PATH: str = path.dirname(path.abspath(__file__)) @@ -92,6 +93,11 @@ def randomize_float(value: float, ratio: float) -> float: return value * (1 - ratio + random.random()*2*ratio) +def slugify_name(name: str, separator: str = '_') -> str: + """Slugify a name.""" + return slugify(name, separator=separator) + + class MIoTMatcher(MQTTMatcher): """MIoT Pub/Sub topic matcher.""" diff --git a/custom_components/xiaomi_home/miot/miot_client.py b/custom_components/xiaomi_home/miot/miot_client.py index 203c377e..ba34d4c5 100644 --- a/custom_components/xiaomi_home/miot/miot_client.py +++ b/custom_components/xiaomi_home/miot/miot_client.py @@ -59,7 +59,7 @@ from homeassistant.components import zeroconf # pylint: disable=relative-beyond-top-level -from .common import MIoTMatcher +from .common import MIoTMatcher, slugify_name from .const import ( DEFAULT_CTRL_MODE, DEFAULT_INTEGRATION_LANGUAGE, DEFAULT_NICK_NAME, DOMAIN, MIHOME_CERT_EXPIRE_MARGIN, NETWORK_REFRESH_INTERVAL, @@ -872,6 +872,13 @@ async def remove_device_async(self, did: str) -> None: # Update notify self.__request_show_devices_changed_notify() + async def remove_device2_async(self, did_tag: str) -> None: + for did in self._device_list_cache: + d_tag = slugify_name(name=f'{self.cloud_server}_{did}') + if did_tag == d_tag: + await self.remove_device_async(did) + break + def __get_exec_error_with_rc(self, rc: int) -> str: err_msg: str = self._i18n.translate(key=f'error.common.{rc}') if not err_msg: diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index c6e12c5d..9dfee3da 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -75,7 +75,7 @@ ) from homeassistant.helpers.entity import DeviceInfo from homeassistant.components.switch import SwitchDeviceClass -from homeassistant.util import slugify + # pylint: disable=relative-beyond-top-level from .specs.specv2entity import ( @@ -85,6 +85,7 @@ SPEC_PROP_TRANS_MAP, SPEC_SERVICE_TRANS_MAP ) +from .common import slugify_name from .const import DOMAIN from .miot_client import MIoTClient from .miot_error import MIoTClientError, MIoTDeviceError @@ -334,11 +335,11 @@ def did(self) -> str: @property def did_tag(self) -> str: - return slugify(f'{self.miot_client.cloud_server}_{self._did}') + return slugify_name(f'{self.miot_client.cloud_server}_{self._did}') @staticmethod def gen_did_tag(cloud_server: str, did: str) -> str: - return slugify(f'{cloud_server}_{did}') + return slugify_name(f'{cloud_server}_{did}') def gen_device_entity_id(self, ha_domain: str) -> str: return ( @@ -355,21 +356,24 @@ def gen_prop_entity_id( ) -> str: return ( f'{ha_domain}.{self._model_strs[0][:9]}_{self.did_tag}_' - f'{self._model_strs[-1][:20]}_{slugify(spec_name)}_p_{siid}_{piid}') + f'{self._model_strs[-1][:20]}_{slugify_name(spec_name)}' + f'_p_{siid}_{piid}') def gen_event_entity_id( self, ha_domain: str, spec_name: str, siid: int, eiid: int ) -> str: return ( f'{ha_domain}.{self._model_strs[0][:9]}_{self.did_tag}_' - f'{self._model_strs[-1][:20]}_{slugify(spec_name)}_e_{siid}_{eiid}') + f'{self._model_strs[-1][:20]}_{slugify_name(spec_name)}' + f'_e_{siid}_{eiid}') def gen_action_entity_id( self, ha_domain: str, spec_name: str, siid: int, aiid: int ) -> str: return ( f'{ha_domain}.{self._model_strs[0][:9]}_{self.did_tag}_' - f'{self._model_strs[-1][:20]}_{slugify(spec_name)}_a_{siid}_{aiid}') + f'{self._model_strs[-1][:20]}_{slugify_name(spec_name)}' + f'_a_{siid}_{aiid}') @property def name(self) -> str: