"""SigMesh Gateway 传感器平台.""" from __future__ import annotations import logging from typing import Any from homeassistant import config_entries from homeassistant.components.sensor import ( SensorDeviceClass, SensorEntity, SensorStateClass, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN from .coordinator import SigMeshGatewayCoordinator from .protocol_parser import DeviceState _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """设置传感器平台.""" coordinator: SigMeshGatewayCoordinator = hass.data[DOMAIN][entry.entry_id][ "coordinator" ] # 创建传感器实体 entities: list[SigMeshSensor] = [] # 从协调器获取设备 for device in coordinator.data.values(): # 根据设备状态创建相应的传感器 if device.states.get("property_id") is not None: entities.append(SigMeshSensor(coordinator, device)) if device.states.get("battery_level") is not None: entities.append(SigMeshBatterySensor(coordinator, device)) async_add_entities(entities) class SigMeshSensor(CoordinatorEntity, SensorEntity): """SigMesh 传感器实体.""" _attr_has_entity_name = True def __init__( self, coordinator: SigMeshGatewayCoordinator, device: DeviceState, ) -> None: """初始化传感器.""" super().__init__(coordinator) self._device = device self._mac = device.mac_address # 设置实体 ID self._attr_unique_id = f"{DOMAIN}_sensor_{self._mac}" self._attr_name = f"SigMesh Sensor {self._mac}" # 根据属性 ID 设置设备类别 property_id = device.states.get("property_id", 0) self._attr_device_class = self._get_device_class(property_id) self._attr_native_unit_of_measurement = self._get_unit(property_id) self._attr_state_class = SensorStateClass.MEASUREMENT def _get_device_class(self, property_id: int) -> SensorDeviceClass | None: """获取设备类别.""" from .const import MeshPropertyId if property_id == MeshPropertyId.AMBIENT_TEMPERATURE: return SensorDeviceClass.TEMPERATURE elif property_id == MeshPropertyId.AMBIENT_HUMIDITY: return SensorDeviceClass.HUMIDITY elif property_id == MeshPropertyId.LIGHT_INTENSITY: return SensorDeviceClass.ILLUMINANCE elif property_id == MeshPropertyId.CO2_CONCENTRATION: return SensorDeviceClass.CO2 elif property_id == MeshPropertyId.PM2_5_CONCENTRATION: return SensorDeviceClass.PM25 return None def _get_unit(self, property_id: int) -> str | None: """获取单位.""" from .const import MeshPropertyId units = { MeshPropertyId.AMBIENT_TEMPERATURE: "°C", MeshPropertyId.AMBIENT_HUMIDITY: "%", MeshPropertyId.LIGHT_INTENSITY: "lx", MeshPropertyId.CO2_CONCENTRATION: "ppm", MeshPropertyId.PM2_5_CONCENTRATION: "μg/m³", } return units.get(property_id) @property def native_value(self) -> Any: """返回传感器值.""" property_id = self._device.states.get("property_id", 0) value = self._device.states.get("value", 0) # 根据属性类型格式化值 if property_id in (0x0059, 0x005A): # 温度/湿度 return value / 100 return value @property def extra_state_attributes(self) -> dict[str, Any]: """返回额外状态属性.""" return { "mac_address": self._device.mac_address, "model_id": self._device.model_id, "last_update": self._device.last_update, } @property def device_info(self) -> DeviceInfo: """返回设备信息.""" return DeviceInfo( identifiers={(DOMAIN, self._device.mac_address)}, name=f"SigMesh Device {self._device.mac_address}", manufacturer="SigMesh", model=f"Model 0x{self._device.model_id:04X}" if self._device.model_id else None, ) class SigMeshBatterySensor(CoordinatorEntity, SensorEntity): """SigMesh 电池传感器实体.""" _attr_has_entity_name = True _attr_device_class = SensorDeviceClass.BATTERY _attr_native_unit_of_measurement = "%" _attr_state_class = SensorStateClass.MEASUREMENT def __init__( self, coordinator: SigMeshGatewayCoordinator, device: DeviceState, ) -> None: """初始化电池传感器.""" super().__init__(coordinator) self._device = device self._mac = device.mac_address self._attr_unique_id = f"{DOMAIN}_battery_{self._mac}" self._attr_name = f"Battery {self._mac}" @property def native_value(self) -> int | None: """返回电池百分比.""" return self._device.states.get("battery_level") @property def device_info(self) -> DeviceInfo: """返回设备信息.""" return DeviceInfo( identifiers={(DOMAIN, self._device.mac_address)}, name=f"SigMesh Device {self._device.mac_address}", manufacturer="SigMesh", model=f"Model 0x{self._device.model_id:04X}" if self._device.model_id else None, )