impress_sig_mesh_hacs/custom_components/sigmesh_gateway/const.py
impressionyang d21e7f1b3f feat: 添加配网和分组管理功能
新增功能:
- 配网管理模块 (provisioning.py): 支持设备扫描、配网、超时处理
- 配网配置步骤: UI 配置流程增加配网参数配置(Network Key, App Key 等)
- 分组管理:支持 SIG 分组和 VENDOR 分组的加入/删除操作
- HA 服务调用:7 个配网和分组相关的服务

文件变更:
- const.py: 添加配网相关常量(CONF_NETWORK_KEY, PROV_TIMEOUT 等)
- config_flow.py: 增加 prov_config 配置步骤和 OptionsFlow 菜单
- provisioning.py: 新建配网管理器(ProvisioningManager 类)
- coordinator.py: 集成配网管理器,添加配网状态管理方法
- services.py: 新建服务定义和注册
- services.yaml: HA 服务定义文件
- __init__.py: 集成服务注册和卸载
- PRD.md: 更新服务调用接口和配置参数文档

配网功能说明:
- 首次使用需配置 Network Key, App Key, Network ID, IV Index
- 配网超时时间:180 秒
- 组地址范围:0xC000 - 0xCFFF
- 支持 SIG 标准分组和 VENDOR 自定义分组
2026-04-16 12:05:13 +08:00

180 lines
4.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 enum import IntEnum, StrEnum
from typing import Final
# 集成配置
DOMAIN = "sigmesh_gateway"
DEFAULT_NAME = "SigMesh Gateway"
DEFAULT_BAUDRATE = 115200
DEFAULT_BYTESIZE = 8
DEFAULT_PARITY = "N"
DEFAULT_STOPBITS = 1
DEFAULT_TIMEOUT = 5
# 串口配置常量
CONF_SERIAL_DEVICE = "serial_device"
CONF_BAUDRATE = "baudrate"
# 配网配置USB dongle 首次使用需要)
CONF_NETWORK_KEY = "network_key" # 16 字节网络密钥
CONF_APP_KEY = "app_key" # 16 字节应用密钥
CONF_NETWORK_ID = "network_id" # 2 字节网络 ID
CONF_IV_INDEX = "iv_index" # 4 字节 IV Index
# 默认配网参数
DEFAULT_NETWORK_KEY = "00000000000000000000000000000000" # 32 字符十六进制
DEFAULT_APP_KEY = "00000000000000000000000000000000"
DEFAULT_NETWORK_ID = "0000"
DEFAULT_IV_INDEX = 0
# 配网超时
PROV_TIMEOUT = 180 # 配网超时时间(秒)
PROV_POLL_INTERVAL = 2 # 配网轮询间隔(秒)
# 组地址配置
CONF_GROUP_ADDRESS = "group_address"
DEFAULT_GROUP_ADDRESS_START = 0xC000 # 组地址起始值
DEFAULT_GROUP_ADDRESS_END = 0xCFFF # 组地址结束值
class MeshModelId(IntEnum):
"""蓝牙 Mesh 模型 ID."""
# 开关模型
ONOFF_SERVER = 0x1000
ONOFF_CLIENT = 0x1001
# 灯模型
LIGHT_LIGHTNESS_SERVER = 0x1300
LIGHT_HSL_SERVER = 0x1307
LIGHT_COLOR_SERVER = 0x130C
LIGHT_CTL_SERVER = 0x130D
# 传感器模型
SENSOR_SERVER = 0x1100
SENSOR_SETUP_SERVER = 0x1101
# 二进制传感器
SENSOR_ONOFF_SERVER = 0x1104
class MeshOpcode(IntEnum):
"""蓝牙 Mesh Opcode."""
# 开关相关
ONOFF_GET = 0x8201
ONOFF_SET = 0x8202
ONOFF_SET_UNACK = 0x8203
ONOFF_STATUS = 0x8204
# 灯泡相关
LIGHT_LIGHTNESS_GET = 0x8229
LIGHT_LIGHTNESS_SET = 0x822B
LIGHT_LIGHTNESS_STATUS = 0x822C
LIGHT_HSL_SET = 0x8231
LIGHT_HSL_STATUS = 0x8232
LIGHT_CTL_SET = 0x825D
LIGHT_CTL_STATUS = 0x825E
LIGHT_COLOR_SET = 0x8200
LIGHT_COLOR_STATUS = 0x8201
# 传感器相关
SENSOR_GET = 0x8230
SENSOR_STATUS = 0x8231
SENSOR_CADENCE = 0x8237
SENSOR_SETTINGS = 0x8238
SENSOR_SETTING_GET = 0x8239
SENSOR_SETTING_STATUS = 0x823A
SENSOR_SERIES_GET = 0x823B
SENSOR_SERIES_STATUS = 0x823C
# 时间相关
TIME_GET = 0x1200
TIME_STATUS = 0x1201
TIME_SET = 0x1202
# 电池
BATTERY_STATUS = 0x820C
# 配网相关
PROV_LINK_OPEN = 0x00
PROV_LINK_CLOSE = 0x01
PROV_INVITE = 0x02
PROV_START = 0x03
PROV_AUTH_START = 0x04
PROV_COMPLETE = 0x05
PROV_FAILED = 0x06
# 配置相关
CFG_NETKEY_ADD = 0x8000
CFG_NETKEY_UPDATE = 0x8001
CFG_APPKEY_ADD = 0x8003
CFG_APPKEY_UPDATE = 0x8004
CFG_MODEL_APP_BIND = 0x8006
CFG_MODEL_SUBSCRIBE = 0x8007
CFG_MODEL_PUBLISH = 0x8008
class MeshSigOp(IntEnum):
"""SIG 操作码(用于分组等)。"""
# 组管理
SIG_GROUP_ADD = 0x801B # 加入组
SIG_GROUP_DELETE = 0x801D # 删除组
SIG_GROUP_STATUS = 0x801C # 组状态(预留)
class MeshPropertyId(IntEnum):
"""Mesh 属性 ID - 用于解析传感器数据."""
PRESENCE_DETECTED = 0x0050 # 存在检测
MOTION_DETECTED = 0x0051 # 运动检测
AMBIENT_TEMPERATURE = 0x0059 # 环境温度
AMBIENT_HUMIDITY = 0x005A # 环境湿度
LIGHT_INTENSITY = 0x005D # 光照强度
BATTERY_LEVEL = 0x0075 # 电池电量
CO2_CONCENTRATION = 0x0092 # CO2 浓度
PM2_5_CONCENTRATION = 0x00B4 # PM2.5 浓度
TVOC_CONCENTRATION = 0x00B9 # TVOC 浓度
class SensorUnit(StrEnum):
"""传感器单位."""
NONE = ""
CELSIUS = "°C"
PERCENTAGE = "%"
LUX = "lx"
PPM = "ppm"
UG_M3 = "μg/m³"
PPB = "ppb"
MV = "mV"
VOLTAGE = "V"
# Mesh 属性 ID 到单位的映射
PROPERTY_UNIT_MAP: Final[dict[int, SensorUnit]] = {
MeshPropertyId.AMBIENT_TEMPERATURE: SensorUnit.CELSIUS,
MeshPropertyId.AMBIENT_HUMIDITY: SensorUnit.PERCENTAGE,
MeshPropertyId.LIGHT_INTENSITY: SensorUnit.LUX,
MeshPropertyId.BATTERY_LEVEL: SensorUnit.PERCENTAGE,
MeshPropertyId.CO2_CONCENTRATION: SensorUnit.PPM,
MeshPropertyId.PM2_5_CONCENTRATION: SensorUnit.UG_M3,
MeshPropertyId.TVOC_CONCENTRATION: SensorUnit.PPB,
MeshPropertyId.PRESENCE_DETECTED: SensorUnit.NONE,
MeshPropertyId.MOTION_DETECTED: SensorUnit.NONE,
}
# 事件类型
EVENT_SERIAL_DATA: Final = f"{DOMAIN}_serial_data"
EVENT_MESH_MESSAGE: Final = f"{DOMAIN}_mesh_message"
EVENT_DEVICE_JOINED: Final = f"{DOMAIN}_device_joined"
EVENT_DEVICE_LEFT: Final = f"{DOMAIN}_device_left"
# 串口通信
SERIAL_EVENT_PREFIX = "+EVENT="
SERIAL_MESH_RECV = "+EVENT=MESH,recv"
SERIAL_PROV_DEVICE_JOINED = "+EVENT=PROV,device_joined"
SERIAL_PROV_DEVICE_LEFT = "+EVENT=PROV,device_left"