impress_sig_mesh_hacs/custom_components/sigmesh_gateway/sensor.py
impressionyang 311cfbbe7e fix: 修复平台文件和 OptionsFlow 错误
修复内容:
1. 所有平台文件添加 coordinator.data None 检查
   - sensor.py, binary_sensor.py, switch.py, light.py, device_tracker.py
2. 修复 async_get_options_flow 签名
   - 改为实例方法,移除 config_entry 参数
   - 移除 @staticmethod 装饰器
3. OptionsFlow 添加正确的 __init__ 方法

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:48:00 +08:00

174 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""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] = []
# 从协调器获取设备(检查 data 是否为 None
if coordinator.data is None:
_LOGGER.debug("协调器数据为空,等待设备数据")
return
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,
)