diff --git a/custom_components/xiaomi_home/__init__.py b/custom_components/xiaomi_home/__init__.py index b26cf0a6..7bef0a83 100644 --- a/custom_components/xiaomi_home/__init__.py +++ b/custom_components/xiaomi_home/__init__.py @@ -125,6 +125,14 @@ def ha_persistent_notify( await manufacturer.init_async() miot_devices: list[MIoTDevice] = [] er = entity_registry.async_get(hass=hass) + for entry in entity_registry.async_entries_for_config_entry( + er, config_entry.entry_id + ): + if ( + entry.entity_id.startswith(f'{DOMAIN}.') + or entry.entity_id.split('.', 1)[0] not in SUPPORTED_PLATFORMS + ): + er.async_remove(entity_id=entry.entity_id) for did, info in miot_client.device_list.items(): spec_instance = await spec_parser.parse(urn=info['urn']) if not isinstance(spec_instance, MIoTSpecInstance): @@ -154,12 +162,22 @@ def ha_persistent_notify( device.entity_list[platform])) for entity in filter_entities: device.entity_list[platform].remove(entity) - entity_id = device.gen_service_entity_id( - ha_domain=platform, - siid=entity.spec.iid, - description=entity.spec.description) - if er.async_get(entity_id_or_uuid=entity_id): - er.async_remove(entity_id=entity_id) + entity_ids = [ + device.gen_service_entity_id( + ha_domain=platform, + siid=entity.spec.iid, + description=entity.spec.description, + slugify_description=False, + ), + device.gen_service_entity_id( + ha_domain=platform, + siid=entity.spec.iid, + description=entity.spec.description, + ), + ] + for entity_id in set(entity_ids): + if er.async_get(entity_id_or_uuid=entity_id): + er.async_remove(entity_id=entity_id) if platform in device.prop_list: filter_props = list(filter( lambda prop: ( diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index 6698c261..b502656b 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -73,18 +73,23 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, new_entities = [] for miot_device in device_list: for data in miot_device.entity_list.get('air-conditioner', []): + data.platform = 'climate' new_entities.append( AirConditioner(miot_device=miot_device, entity_data=data)) for data in miot_device.entity_list.get('heater', []): + data.platform = 'climate' new_entities.append( Heater(miot_device=miot_device, entity_data=data)) for data in miot_device.entity_list.get('bath-heater', []): + data.platform = 'climate' new_entities.append( PtcBathHeater(miot_device=miot_device, entity_data=data)) for data in miot_device.entity_list.get('thermostat', []): + data.platform = 'climate' new_entities.append( Thermostat(miot_device=miot_device, entity_data=data)) for data in miot_device.entity_list.get('electric-blanket', []): + data.platform = 'climate' new_entities.append( ElectricBlanket(miot_device=miot_device, entity_data=data)) diff --git a/custom_components/xiaomi_home/humidifier.py b/custom_components/xiaomi_home/humidifier.py index ef9cc234..62383ecd 100644 --- a/custom_components/xiaomi_home/humidifier.py +++ b/custom_components/xiaomi_home/humidifier.py @@ -76,10 +76,12 @@ async def async_setup_entry( new_entities = [] for miot_device in device_list: for data in miot_device.entity_list.get('humidifier', []): + data.platform = 'humidifier' data.device_class = HumidifierDeviceClass.HUMIDIFIER new_entities.append( Humidifier(miot_device=miot_device, entity_data=data)) for data in miot_device.entity_list.get('dehumidifier', []): + data.platform = 'humidifier' data.device_class = HumidifierDeviceClass.DEHUMIDIFIER new_entities.append( Humidifier(miot_device=miot_device, entity_data=data)) diff --git a/custom_components/xiaomi_home/media_player.py b/custom_components/xiaomi_home/media_player.py index ecc17ed6..d183db3d 100644 --- a/custom_components/xiaomi_home/media_player.py +++ b/custom_components/xiaomi_home/media_player.py @@ -73,9 +73,11 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, new_entities = [] for miot_device in device_list: for data in miot_device.entity_list.get('wifi-speaker', []): + data.platform = 'media_player' new_entities.append( WifiSpeaker(miot_device=miot_device, entity_data=data)) for data in miot_device.entity_list.get('television', []): + data.platform = 'media_player' new_entities.append( Television(miot_device=miot_device, entity_data=data)) diff --git a/custom_components/xiaomi_home/miot/miot_device.py b/custom_components/xiaomi_home/miot/miot_device.py index 8ed6fca3..064b3f20 100644 --- a/custom_components/xiaomi_home/miot/miot_device.py +++ b/custom_components/xiaomi_home/miot/miot_device.py @@ -348,11 +348,21 @@ def gen_device_entity_id(self, ha_domain: str) -> str: f'{ha_domain}.{self._model_strs[0][:9]}_{self.did_tag}_' f'{self._model_strs[-1][:20]}') - def gen_service_entity_id(self, ha_domain: str, siid: int, - description: str) -> str: + def gen_service_entity_id( + self, + ha_domain: str, + siid: int, + description: str, + slugify_description: bool = True, + ) -> str: + description_slug = description + if slugify_description: + description_slug = slugify_name(description) + if not description_slug: + description_slug = f'service_{siid}' return ( f'{ha_domain}.{self._model_strs[0][:9]}_{self.did_tag}_' - f'{self._model_strs[-1][:20]}_s_{siid}_{description}') + f'{self._model_strs[-1][:20]}_s_{siid}_{description_slug}') def gen_prop_entity_id( self, ha_domain: str, spec_name: str, siid: int, piid: int @@ -918,7 +928,10 @@ class MIoTServiceEntity(Entity): _pending_write_ha_state_timer: Optional[asyncio.TimerHandle] def __init__( - self, miot_device: MIoTDevice, entity_data: MIoTEntityData + self, + miot_device: MIoTDevice, + entity_data: MIoTEntityData, + ha_domain: str | None = None, ) -> None: if ( miot_device is None @@ -934,11 +947,14 @@ def __init__( self._value_sub_ids = {} # Gen entity id if isinstance(self.entity_data.spec, MIoTSpecInstance): - self.entity_id = miot_device.gen_device_entity_id(DOMAIN) + entity_id_domain = ha_domain or self.entity_data.platform + self.entity_id = miot_device.gen_device_entity_id( + entity_id_domain) self._attr_name = f' {self.entity_data.spec.description_trans}' elif isinstance(self.entity_data.spec, MIoTSpecService): + entity_id_domain = ha_domain or self.entity_data.platform self.entity_id = miot_device.gen_service_entity_id( - DOMAIN, siid=self.entity_data.spec.iid, + entity_id_domain, siid=self.entity_data.spec.iid, description=self.entity_data.spec.description) self._attr_name = ( f'{"* "if self.entity_data.spec.proprietary else " "}' @@ -1241,7 +1257,7 @@ def __init__(self, miot_device: MIoTDevice, spec: MIoTSpecProperty) -> None: self._pending_write_ha_state_timer = None # Gen entity_id self.entity_id = self.miot_device.gen_prop_entity_id( - ha_domain=DOMAIN, spec_name=spec.name, + ha_domain=spec.platform, spec_name=spec.name, siid=spec.service.iid, piid=spec.iid) # Set entity attr self._attr_unique_id = self.entity_id @@ -1383,7 +1399,7 @@ def __init__(self, miot_device: MIoTDevice, spec: MIoTSpecEvent) -> None: self._main_loop = miot_device.miot_client.main_loop # Gen entity_id self.entity_id = self.miot_device.gen_event_entity_id( - ha_domain=DOMAIN, spec_name=spec.name, + ha_domain=spec.platform, spec_name=spec.name, siid=spec.service.iid, eiid=spec.iid) # Set entity attr self._attr_unique_id = self.entity_id @@ -1494,7 +1510,7 @@ def __init__(self, miot_device: MIoTDevice, spec: MIoTSpecAction) -> None: self._state_sub_id = 0 # Gen entity_id self.entity_id = self.miot_device.gen_action_entity_id( - ha_domain=DOMAIN, spec_name=spec.name, + ha_domain=spec.platform, spec_name=spec.name, siid=spec.service.iid, aiid=spec.iid) # Set entity attr self._attr_unique_id = self.entity_id