impress_sig_mesh_hacs/custom_components/sigmesh_gateway/services.py
2026-04-17 11:09:56 +08:00

218 lines
7.4 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 服务定义(保留用于向后兼容)。
注意:配网功能已迁移到 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,
}
SERVICE_SCHEMA_SEND_RAW_COMMAND = {
vol.Required("hex_data"): 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
)
async def handle_send_raw_command(call) -> None:
"""处理发送原始串口命令服务调用."""
hex_data = call.data.get("hex_data")
try:
raw_data = bytes.fromhex(hex_data)
for coordinator in coordinators.values():
if coordinator.serial_reader.is_connected:
await coordinator.serial_reader.write(raw_data)
_LOGGER.info("已发送原始命令:%s", hex_data)
else:
_LOGGER.warning("串口未连接,无法发送命令")
except ValueError as e:
_LOGGER.error("无效的十六进制数据:%s, 错误:%s", hex_data, e)
# 注册服务
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),
)
hass.services.async_register(
DOMAIN,
"send_raw_command",
handle_send_raw_command,
schema=vol.Schema(SERVICE_SCHEMA_SEND_RAW_COMMAND),
)