112 lines
4.1 KiB
Python
112 lines
4.1 KiB
Python
import asyncio
|
|
import logging
|
|
from typing import Optional
|
|
from .heweather.heweather_cert import HeWeatherCert
|
|
from .heweather.const import (
|
|
DOMAIN,
|
|
CONF_STORAGE_PATH,
|
|
)
|
|
|
|
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import Platform
|
|
from homeassistant.helpers import entity_registry as er
|
|
|
|
SUPPORTED_PLATFORMS = [Platform.WEATHER, Platform.SENSOR]
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def cleanup_duplicate_entities_on_startup(hass: HomeAssistant, config_entry: ConfigEntry):
|
|
"""在启动时清理重复的实体"""
|
|
entity_registry = er.async_get(hass)
|
|
|
|
# 获取所有与此集成相关的实体,按传感器类型分组
|
|
entities_by_type = {}
|
|
|
|
for entity_id, entity in entity_registry.entities.items():
|
|
if entity.config_entry_id == config_entry.entry_id and entity.platform == DOMAIN:
|
|
if entity.unique_id:
|
|
# 提取传感器类型(unique_id的第一部分)
|
|
try:
|
|
sensor_type = entity.unique_id.split('_')[0] + '_' + entity.unique_id.split('_')[1]
|
|
if sensor_type not in entities_by_type:
|
|
entities_by_type[sensor_type] = []
|
|
entities_by_type[sensor_type].append((entity_id, entity))
|
|
except IndexError:
|
|
# 如果unique_id格式不符合预期,跳过
|
|
continue
|
|
|
|
# 检查每种传感器类型是否有重复
|
|
entities_to_remove = []
|
|
for sensor_type, entities in entities_by_type.items():
|
|
if len(entities) > 1:
|
|
# 有重复实体,保留最新的(通过entity_id排序,通常较新的ID会更大)
|
|
entities.sort(key=lambda x: x[0]) # 按entity_id排序
|
|
# 删除除最后一个之外的所有实体
|
|
for entity_id, entity in entities[:-1]:
|
|
entities_to_remove.append(entity_id)
|
|
_LOGGER.info(f"Found duplicate entity for {sensor_type}: {entity_id}")
|
|
|
|
# 删除重复实体
|
|
for entity_id in entities_to_remove:
|
|
_LOGGER.info(f"Removing duplicate entity on startup: {entity_id}")
|
|
entity_registry.async_remove(entity_id)
|
|
|
|
if entities_to_remove:
|
|
_LOGGER.info(f"Cleaned up {len(entities_to_remove)} duplicate entities on startup")
|
|
|
|
|
|
async def async_setup(hass: HomeAssistant, hass_config: dict) -> bool:
|
|
# pylint: disable=unused-argument
|
|
hass.data.setdefault(DOMAIN, {})
|
|
return True
|
|
|
|
|
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
|
# Get running loop
|
|
loop: asyncio.AbstractEventLoop = asyncio.get_running_loop()
|
|
if not loop:
|
|
raise Exception('loop is None')
|
|
# HeWeather Certification
|
|
cert: Optional[HeWeatherCert] = hass.data[DOMAIN].get("heweather_cert", None)
|
|
if not cert:
|
|
cert = HeWeatherCert(root_path=config_entry.data.get(CONF_STORAGE_PATH), loop=loop)
|
|
hass.data[DOMAIN]["heweather_cert"] = cert
|
|
_LOGGER.info("create heweather cert instance")
|
|
|
|
await hass.config_entries.async_forward_entry_setups(config_entry, SUPPORTED_PLATFORMS)
|
|
|
|
# 清理重复的实体(在平台设置完成后)
|
|
await cleanup_duplicate_entities_on_startup(hass, config_entry)
|
|
|
|
return True
|
|
|
|
|
|
async def async_update_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
|
"""Update a given config entry."""
|
|
await hass.config_entries.async_reload(config_entry.entry_id)
|
|
|
|
# 在重新加载后清理重复实体
|
|
await cleanup_duplicate_entities_on_startup(hass, config_entry)
|
|
|
|
return True
|
|
|
|
|
|
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
|
unload_ok = await hass.config_entries.async_unload_platforms(
|
|
config_entry, SUPPORTED_PLATFORMS
|
|
)
|
|
|
|
return unload_ok
|
|
|
|
async def async_remove_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
|
heweather_cert: HeWeatherCert = hass.data[DOMAIN]['heweather_cert']
|
|
|
|
await heweather_cert.del_key_async()
|
|
|
|
hass.data.pop(DOMAIN, None)
|
|
|
|
return True
|