Files
homeassistant/config/custom_components/heweather/__init__.py
T
2026-08-24 21:55:33 +08:00

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