"""SigMesh Gateway 服务定义(保留用于向后兼容)。 注意:配网功能已迁移到 Web UI,服务调用接口保留用于自动化脚本。 """ import voluptuous as vol from homeassistant.helpers import config_validation as cv from .const import CONF_GROUP_ADDRESS, CONF_NETWORK_KEY, DOMAIN # 服务常量 SERVICE_START_SCAN = "start_scan" SERVICE_STOP_PROVISIONING = "stop_provisioning" SERVICE_START_PROVISIONING = "start_provisioning" SERVICE_BIND_APPKEY = "bind_appkey" SERVICE_ADD_TO_GROUP = "add_to_group" SERVICE_REMOVE_FROM_GROUP = "remove_from_group" SERVICE_SEND_VENDOR_COMMAND = "send_vendor_command" # 服务 Schema SERVICE_SCHEMA_START_SCAN = {} SERVICE_SCHEMA_STOP_PROVISIONING = {} SERVICE_SCHEMA_START_PROVISIONING = { vol.Required("device_address"): cv.string, } SERVICE_SCHEMA_BIND_APPKEY = { vol.Required("device_address"): cv.string, vol.Required("element_address", default=0): vol.Coerce(int), } SERVICE_SCHEMA_ADD_TO_GROUP = { vol.Required("target_address"): cv.string, vol.Required("element_address", default=0): vol.Coerce(int), vol.Required("group_address"): cv.string, vol.Required("model_id", default=4352): vol.Coerce(int), vol.Optional("is_sig", default=True): cv.boolean, } SERVICE_SCHEMA_REMOVE_FROM_GROUP = { vol.Required("target_address"): cv.string, vol.Required("element_address", default=0): vol.Coerce(int), vol.Required("group_address"): cv.string, vol.Required("model_id", default=4352): vol.Coerce(int), vol.Optional("is_sig", default=True): cv.boolean, } SERVICE_SCHEMA_SEND_VENDOR_COMMAND = { vol.Required("target_address"): cv.string, vol.Required("element_address", default=0): vol.Coerce(int), vol.Required("opcode"): cv.string, vol.Required("payload"): cv.string, } def setup_services(hass, coordinators: dict) -> None: """设置 HA 服务。 注意:配网功能已迁移到 Web UI,服务调用接口保留用于自动化脚本。 推荐使用 Web UI 进行配网和分组管理操作。 Args: hass: HomeAssistant 实例 coordinators: 协调器字典 {entry_id: coordinator} """ async def handle_start_scan(call) -> None: """处理开始扫描服务调用.""" for coordinator in coordinators.values(): await coordinator.start_scanning() async def handle_stop_provisioning(call) -> None: """处理停止配网服务调用.""" for coordinator in coordinators.values(): await coordinator.stop_provisioning() async def handle_start_provisioning(call) -> None: """处理开始配网服务调用.""" device_address = call.data.get("device_address") for coordinator in coordinators.values(): await coordinator.start_provisioning(device_address) async def handle_bind_appkey(call) -> None: """处理绑定 App Key 服务调用.""" device_address = call.data.get("device_address") element_address = call.data.get("element_address", 0) for coordinator in coordinators.values(): await coordinator.bind_app_key(device_address, element_address) async def handle_add_to_group(call) -> None: """处理添加设备到组服务调用.""" target_address = call.data.get("target_address") element_address = call.data.get("element_address", 0) group_address = call.data.get("group_address") model_id = call.data.get("model_id", 4352) is_sig = call.data.get("is_sig", True) # 解析组地址(支持 hex 字符串) if isinstance(group_address, str): group_address = int(group_address, 16) for coordinator in coordinators.values(): await coordinator.add_device_to_group( target_address, element_address, group_address, model_id, is_sig ) async def handle_remove_from_group(call) -> None: """处理从组中移除设备服务调用.""" target_address = call.data.get("target_address") element_address = call.data.get("element_address", 0) group_address = call.data.get("group_address") model_id = call.data.get("model_id", 4352) is_sig = call.data.get("is_sig", True) # 解析组地址(支持 hex 字符串) if isinstance(group_address, str): group_address = int(group_address, 16) for coordinator in coordinators.values(): await coordinator.remove_device_from_group( target_address, element_address, group_address, model_id, is_sig ) async def handle_send_vendor_command(call) -> None: """处理发送 VENDOR 命令服务调用.""" target_address = call.data.get("target_address") element_address = call.data.get("element_address", 0) opcode = call.data.get("opcode") payload = call.data.get("payload") # 解析操作码和负载 if isinstance(opcode, str): opcode = int(opcode, 16) if isinstance(payload, str): payload = bytes.fromhex(payload) for coordinator in coordinators.values(): await coordinator.prov_manager.send_vendor_command( target_address, element_address, opcode, payload ) # 注册服务 hass.services.async_register( DOMAIN, SERVICE_START_SCAN, handle_start_scan, schema=vol.Schema(SERVICE_SCHEMA_START_SCAN), ) hass.services.async_register( DOMAIN, SERVICE_STOP_PROVISIONING, handle_stop_provisioning, schema=vol.Schema(SERVICE_SCHEMA_STOP_PROVISIONING), ) hass.services.async_register( DOMAIN, SERVICE_START_PROVISIONING, handle_start_provisioning, schema=vol.Schema(SERVICE_SCHEMA_START_PROVISIONING), ) hass.services.async_register( DOMAIN, SERVICE_BIND_APPKEY, handle_bind_appkey, schema=vol.Schema(SERVICE_SCHEMA_BIND_APPKEY), ) hass.services.async_register( DOMAIN, SERVICE_ADD_TO_GROUP, handle_add_to_group, schema=vol.Schema(SERVICE_SCHEMA_ADD_TO_GROUP), ) hass.services.async_register( DOMAIN, SERVICE_REMOVE_FROM_GROUP, handle_remove_from_group, schema=vol.Schema(SERVICE_SCHEMA_REMOVE_FROM_GROUP), ) hass.services.async_register( DOMAIN, SERVICE_SEND_VENDOR_COMMAND, handle_send_vendor_command, schema=vol.Schema(SERVICE_SCHEMA_SEND_VENDOR_COMMAND), )