impress_sig_mesh_hacs/PRD.md
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

23 KiB
Raw Blame History

SigMesh Gateway HACS 集成 - PRD 产品需求文档

版本号: 1.0.0 创建日期: 2026-04-15 最后更新: 2026-04-15 状态: 草稿 → 评审中


目录

  1. 文档概述
  2. 产品背景
  3. 需求范围
  4. 技术规格
  5. 功能需求
  6. 非功能需求
  7. 数据模型
  8. 接口定义
  9. 配置参数
  10. 错误处理
  11. 日志规范
  12. 测试计划
  13. 调试指南
  14. 版本历史

1. 文档概述

1.1 文档目的

本文档定义 SigMesh Gateway HACS 集成的完整产品需求,用于:

  • 指导开发人员进行参数配置和问题调试
  • 作为功能实现的基准参考
  • 提供测试和验证标准
  • 记录设计决策和接口规范

1.2 适用对象

角色 使用场景
开发工程师 参数调整、功能开发、问题排查
测试工程师 编写测试用例、验证功能
运维人员 部署配置、故障诊断
用户 了解功能、配置参数

1.3 术语定义

术语 定义
HACS Home Assistant Community Store
SigMesh Bluetooth SIG Mesh 协议
HAOS Home Assistant OS
Gateway SigMesh 网关 (E104-BT12NSP 模块)
Opcode Mesh 消息操作码
Entity Home Assistant 实体
Coordinator 数据更新协调器

2. 产品背景

2.1 项目目标

创建 HACS 集成项目,实现:

  1. 通过串口读取 SigMesh 网关数据
  2. 解析 Bluetooth Mesh 协议消息
  3. 在 Home Assistant 中创建和管理实体
  4. 支持最多 200 个 Mesh 设备接入

2.2 使用场景

场景 描述
智能家居 接入蓝牙 Mesh 开关、灯光、传感器
商业照明 大规模 Mesh 灯光控制
环境监测 温湿度、光照等传感器数据采集

2.3 硬件规格

SigMesh 网关 (E104-BT12USP):

  • 芯片Nordic nRF52840
  • 协议Bluetooth 5.4 Mesh
  • 接口USB 直连(内置 USB 转 UART
  • 串口参数115200, 8N1

网关配置工具:

  • 软件:亿佰特 danglo 组网工具
  • 配网方式PROV 配网
  • 组网管理:支持设备扫描、配网、分组
  • 设备控制:支持 ON/OFF、亮度、色温控制

重要配置说明:

  1. 首次使用需通过 danglo 工具配置 USB dongle 参数
  2. 设备配网SCAN 扫描 → 双击设备 → PROV 配网 → 绑定 APP Key
  3. 分组管理:通过 GROUP 设置将设备分配到组地址
  4. 手机 APP 默认订阅0x1307 (SIG_MD_LIGHT_HSL_S)
  5. 天猫精灵默认订阅0x10 (SIG_MD_G_ONOFF_S)
  6. 低功耗节点组传输:需将 Lightness Model 和 Vendor Model 分配到同一组

3. 需求范围

3.1 功能边界

包含的功能:

  • 串口异步数据读取
  • Mesh 协议解析
  • 设备自动发现
  • 多平台实体创建
  • UI 配置界面

不包含的功能:

  • Mesh 配网功能(网关已完成)
  • 设备固件升级
  • 网络拓扑展示
  • 离线缓存

3.2 依赖关系

SigMesh Gateway 集成
├── 依赖Home Assistant ≥ 2024.1.0
├── 依赖HACS ≥ 1.34.0
└── 依赖pyserial-asyncio-fast ≥ 0.6

4. 技术规格

4.1 串口通信规格

参数 可调范围 默认值
设备路径 /dev/ttyUSB0 系统决定 /dev/ttyUSB0
波特率 115200 9600-921600 115200
数据位 8 5-8 8
停止位 1 1, 1.5, 2 1
校验位 None None, E, O, M, S N
超时 0.1s 0.01-10s 0.1
读取间隔 10ms 1-100ms 10

4.2 协议规格

串口消息格式:

事件前缀:+EVENT=
行结束符:\r\n

Mesh 消息:
+EVENT=MESH,recv,<src_addr>,<dst_addr>,<opcode>,<hex_payload>\r\n

设备加入:
+EVENT=PROV,device_joined,<mac>,<element_count>\r\n

设备离开:
+EVENT=PROV,device_left,<mac>\r\n

字段定义:

字段 类型 长度 说明
src_addr string 4-6 字符 源地址 (16 进制)
dst_addr string 4-6 字符 目标地址 (16 进制)
opcode int 1-4 字符 操作码 (16 进制)
hex_payload bytes 变长 数据负载 (16 进制字符串)
mac string 12 字符 MAC 地址
element_count int 1-2 字符 元素数量

协议帧格式 (基于亿佰特文档):

通用帧结构:
[Cmd 头] [固定字段] [目标地址] [操作码] [元素地址] [组地址/参数] [ModelID] [校验/结束]

命令头e8 ff (所有命令以此开头)

常见操作码:

操作码 功能
80 1b 加入组/设置
80 1d 删除组

组网配置要点:

  • 组地址:使用 0xC000 以上的地址作为组地址
  • 手机 APP 默认订阅0x1307 (SIG_MD_LIGHT_HSL_S)
  • 天猫精灵默认订阅0x0010 (SIG_MD_G_ONOFF_S)
  • 低功耗节点:需将 Lightness Model 和 Vendor Model 分配到同一组才能接收组地址传输

4.3 支持的 Opcode 列表

Opcode 名称 模型 ID 数据长度 解析状态
0x8201 ONOFF_GET 0x1000 0
0x8202 ONOFF_SET 0x1000 1
0x8203 ONOFF_SET_UNACK 0x1000 1
0x8204 ONOFF_STATUS 0x1000 1
0x8229 LIGHT_LIGHTNESS_GET 0x1300 0
0x822B LIGHT_LIGHTNESS_SET 0x1300 2-3
0x822C LIGHT_LIGHTNESS_STATUS 0x1300 2-3
0x8231 LIGHT_HSL_SET 0x1307 6-7
0x8232 LIGHT_HSL_STATUS 0x1307 6-7
0x825D LIGHT_CTL_SET 0x130D 4-5
0x825E LIGHT_CTL_STATUS 0x130D 4-5
0x8200 LIGHT_COLOR_SET 0x130C 8-9
0x8201 LIGHT_COLOR_STATUS 0x130C 8-9
0x8230 SENSOR_GET 0x1100 2
0x8231 SENSOR_STATUS 0x1100 2-6
0x820C BATTERY_STATUS 0x1000 1-4

4.4 传感器属性 ID 映射

Property ID 名称 单位 缩放 范围
0x0050 PRESENCE_DETECTED 布尔 ×1 0/1
0x0051 MOTION_DETECTED 布尔 ×1 0/1
0x0059 AMBIENT_TEMPERATURE °C ÷100 -2732~32767
0x005A AMBIENT_HUMIDITY % ÷100 0~10000
0x005D LIGHT_INTENSITY lx ×1 0~65535
0x0075 BATTERY_LEVEL % ×1 0~100
0x0092 CO2_CONCENTRATION ppm ×1 0~65535
0x00B4 PM2_5_CONCENTRATION μg/m³ ×1 0~65535
0x00B9 TVOC_CONCENTRATION ppb ×1 0~65535

5. 功能需求

5.1 FR-001: 串口连接管理

属性
ID FR-001
优先级 P0
模块 serial_reader.py

描述: 管理串口的连接、读取、断开和重连

详细需求:

  1. 支持配置串口设备和波特率
  2. 异步非阻塞读取
  3. 自动处理粘包和断包
  4. 断线后自动重连(间隔 5 秒,最多 3 次)
  5. 支持写入 AT 命令

参数配置:

SERIAL_CONFIG = {
    "device": "/dev/ttyUSB0",      # 可配置
    "baudrate": 115200,            # 可配置
    "bytesize": 8,                 # 固定
    "parity": "N",                 # 固定
    "stopbits": 1,                 # 固定
    "timeout": 0.1,                # 固定
    "reconnect_interval": 5,       # 固定
    "reconnect_attempts": 3,       # 固定
}

调试要点:

  • 检查 dmesg | grep tty 确认串口设备名
  • 使用 ls -l /dev/ttyUSB* 检查权限
  • 使用 screen /dev/ttyUSB0 115200 手动测试

5.2 FR-002: 协议解析

属性
ID FR-002
优先级 P0
模块 protocol_parser.py

描述: 解析串口接收到的 Mesh 协议消息

详细需求:

  1. 解析事件前缀 +EVENT=
  2. 按行分割处理(\r\n 分隔)
  3. 识别消息类型MESH/PROV
  4. 提取并验证字段
  5. 将 16 进制 payload 转为 bytes

调试要点:

  • 启用 debug 日志查看原始数据
  • 检查 opcode 是否在支持列表中
  • 验证 payload 长度是否符合预期

5.3 FR-003: 设备管理

属性
ID FR-003
优先级 P1
模块 protocol_parser.py

描述: 管理已发现的 Mesh 设备状态

详细需求:

  1. 设备加入时创建记录
  2. 设备离开时移除记录
  3. 维护设备状态缓存
  4. 支持设备查询接口

数据结构:

class DeviceState:
    mac_address: str          # MAC 地址
    element_index: int        # 元素索引
    model_id: int | None      # 模型 ID
    states: dict[str, Any]    # 状态字典
    last_update: float        # 最后更新时间戳

5.4 FR-004: 数据协调器

属性
ID FR-004
优先级 P0
模块 coordinator.py

描述: 协调数据更新和实体刷新

详细需求:

  1. 使用 HA DataUpdateCoordinator
  2. 支持定时轮询(可配置间隔)
  3. 支持事件驱动刷新
  4. 防抖处理1 秒冷却)

参数配置:

COORDINATOR_CONFIG = {
    "poll_interval": 30,       # 轮询间隔 (秒),可配置
    "debounce_cooldown": 1,    # 防抖冷却 (秒),固定
    "update_timeout": 10,      # 更新超时 (秒),固定
}

5.5 FR-005: 传感器实体

属性
ID FR-005
优先级 P0
模块 platforms/sensor.py

描述: 创建和管理传感器实体

支持的设备类别:

Device Class 单位 状态类
temperature °C measurement
humidity % measurement
illuminance lx measurement
co2 ppm measurement
pm25 μg/m³ measurement
battery % measurement

实体命名规范:

sensor.sigmesh_sensor_<mac>       # 主传感器
sensor.sigmesh_battery_<mac>      # 电池传感器

5.6 FR-006: 二进制传感器

属性
ID FR-006
优先级 P1
模块 platforms/binary_sensor.py

描述: 创建二进制传感器(人体感应、门窗传感器)

支持的 Device Class:

Device Class 说明
motion 运动检测
door 门窗传感器
presence 存在检测

5.7 FR-007: 开关实体

属性
ID FR-007
优先级 P1
模块 platforms/switch.py

描述: 创建开关控制实体

详细需求:

  1. 显示当前开关状态
  2. 支持开/关操作TODO
  3. 状态同步刷新

5.8 FR-008: 灯光实体

属性
ID FR-008
优先级 P1
模块 platforms/light.py

描述: 创建灯光控制实体

支持的功能:

功能 支持状态
开关
亮度调节
色温调节 TODO
RGB 调色 TODO

5.9 FR-009: 设备追踪

属性
ID FR-009
优先级 P2
模块 platforms/device_tracker.py

描述: 创建设备追踪实体

源类型: bluetooth_le


5.10 FR-010: UI 配置界面

属性
ID FR-010
优先级 P0
模块 config_flow.py

描述: 提供图形化配置界面

配置步骤:

  1. 选择串口设备(下拉列表)
  2. 输入波特率(默认 115200
  3. 验证连接
  4. 完成配置

6. 非功能需求

6.1 性能要求

指标 要求 测量方法
支持设备数 ≥200 模拟测试
消息延迟 <100ms 时间戳对比
内存占用 <50MB HA 监控
CPU 占用 <5% HA 监控
启动时间 <10s 日志计时

6.2 可靠性要求

场景 要求
串口断开 自动重连,最多 3 次
数据异常 跳过异常数据,记录日志
HA 重启 自动恢复连接
网关重启 自动重新发现设备

6.3 兼容性要求

项目 要求
HA 版本 ≥ 2024.1.0
HACS 版本 ≥ 1.34.0
Python 版本 ≥ 3.11
操作系统 Linux (HAOS)

6.4 安全要求

项目 要求
权限 最小权限原则
数据 无敏感数据传输
日志 不记录敏感信息

7. 数据模型

7.1 实体关系图

┌─────────────────┐
│  ConfigEntry    │
│  (配置入口)      │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Coordinator    │
│  (协调器)        │
└────────┬────────┘
         │
    ┌────┼────┬──────────┬────────────┐
    ▼    ▼    ▼          ▼            ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌──────────┐ ┌──────────┐
│ Sensor │ │Binary  │ │ Switch │ │  Light   │ │ Tracker  │
│        │ │Sensor  │ │        │ │          │ │          │
└────────┘ └────────┘ └────────┘ └──────────┘ └──────────┘

7.2 设备状态模型

{
    "mac_address": "AA:BB:CC:DD:EE:FF",
    "element_index": 0,
    "model_id": 4352,           # 0x1100
    "states": {
        "property_id": 89,       # 0x0059 温度
        "property_name": "AMBIENT_TEMPERATURE",
        "value": 2350,           # 23.5°C
        "unit": "°C",
        "formatted": "23.5°C"
    },
    "last_update": 1713187200.0
}

8. 接口定义

8.1 Coordinator 对外接口

class SigMeshGatewayCoordinator:
    # 获取设备
    def get_device(mac_address: str) -> DeviceState | None

    # 按类型获取设备
    def get_devices_by_type(model_id: int) -> list[DeviceState]

    # 启动/停止
    async def start() -> None
    async def stop() -> None

    # 刷新数据
    async def async_request_refresh() -> None

8.2 服务调用接口

已实现的服务调用接口:

# sigmesh_gateway.start_scan - 开始扫描设备
start_scan:
  name: 开始扫描设备
  description: 开始扫描可用的 Bluetooth Mesh 设备

# sigmesh_gateway.stop_provisioning - 停止配网
stop_provisioning:
  name: 停止配网
  description: 停止当前的配网操作

# sigmesh_gateway.start_provisioning - 开始配网
start_provisioning:
  fields:
    device_address:
      description: 要配网的设备地址16 进制字符串)
      example: "001A"

# sigmesh_gateway.bind_appkey - 绑定 App Key
bind_appkey:
  fields:
    device_address:
      description: 设备地址
      example: "001A"
    element_address:
      description: 元素地址(默认为 0
      example: 0

# sigmesh_gateway.add_to_group - 添加到组
add_to_group:
  fields:
    target_address:
      description: 目标设备地址
      example: "001A"
    element_address:
      description: 元素地址
      example: 0
    group_address:
      description: 组地址(建议使用 0xC000 以上)
      example: "C001"
    model_id:
      description: Model ID
      example: 4352
    is_sig:
      description: 是否为 SIG 标准分组
      example: true

# sigmesh_gateway.remove_from_group - 从组移除
remove_from_group:
  fields:
    target_address:
      description: 目标设备地址
      example: "001A"
    element_address:
      description: 元素地址
      example: 0
    group_address:
      description: 组地址
      example: "C001"
    model_id:
      description: Model ID
      example: 4352
    is_sig:
      description: 是否为 SIG 标准分组
      example: true

# sigmesh_gateway.send_vendor_command - 发送 VENDOR 命令
send_vendor_command:
  fields:
    target_address:
      description: 目标设备地址
      example: "001A"
    element_address:
      description: 元素地址
      example: 0
    opcode:
      description: VENDOR 操作码
      example: "1102"
    payload:
      description: 数据负载16 进制)
      example: "0000"

9. 配置参数

9.1 配置入口参数

参数 类型 必填 默认值 说明
serial_device string /dev/ttyUSB0 串口设备路径
baudrate int 115200 波特率
network_key string 32 个 0 网络密钥16 字节32 字符十六进制)
app_key string 32 个 0 应用密钥16 字节32 字符十六进制)
network_id string "0000" 网络 ID2 字节4 字符十六进制)
iv_index int 0 IV Index4 字节)
group_address string "0xC000" 组地址起始值16 进制字符串)

9.2 选项参数

参数 类型 必填 默认值 说明
poll_interval int 30 轮询间隔 (秒)

9.3 调试参数

# configuration.yaml
logger:
  logs:
    custom_components.sigmesh_gateway: debug
    custom_components.sigmesh_gateway.serial_reader: debug
    custom_components.sigmesh_gateway.protocol_parser: debug
    custom_components.sigmesh_gateway.coordinator: debug

10. 错误处理

10.1 错误码定义

错误码 名称 说明 处理
E001 SERIAL_OPEN_FAILED 串口打开失败 检查设备路径和权限
E002 SERIAL_READ_ERROR 串口读取错误 重连或提示用户
E003 PARSE_ERROR 解析错误 跳过并记录日志
E004 DEVICE_NOT_FOUND 设备未找到 返回 None
E005 TIMEOUT 超时 重试或报错

10.2 异常处理流程

串口读取异常
    ↓
记录错误日志
    ↓
尝试重连 (最多 3 次)
    ↓
失败 → 标记集成不可用
成功 → 恢复正常工作

11. 日志规范

11.1 日志级别

级别 使用场景
DEBUG 详细调试信息(原始数据、解析过程)
INFO 正常流程信息(启动、停止、设备加入)
WARNING 警告信息(重连、数据异常)
ERROR 错误信息(解析失败、连接失败)
CRITICAL 严重错误(集成无法运行)

11.2 日志格式

_LOGGER.info("串口已连接:%s, 波特率:%d", device, baudrate)
_LOGGER.debug("串口接收:%s", line)
_LOGGER.error("解析 Mesh 消息失败:%s, 错误:%s", line, e)

11.3 关键日志点

模块 日志内容 级别
serial_reader 串口连接成功/失败 INFO/ERROR
serial_reader 接收原始数据 DEBUG
protocol_parser 解析结果 DEBUG
coordinator 设备加入/离开 INFO
coordinator 数据刷新 DEBUG

12. 测试计划

12.1 单元测试

模块 测试内容 方法
serial_reader 串口连接 Mock serial
protocol_parser 消息解析 构造测试数据
coordinator 数据协调 Mock HA

12.2 集成测试

测试项 步骤 预期结果
串口连接 配置正确串口 连接成功
设备发现 网关上报设备 实体创建
状态更新 发送状态消息 实体状态变化
断线重连 断开串口 自动重连

12.3 压力测试

测试项 方法 通过标准
200 设备 模拟 200 设备数据 无崩溃,内存<50MB
高频数据 100 条/秒 无丢失,延迟<100ms

13. 调试指南

13.1 调试准备

# 1. 启用调试日志
logger:
  default: warning
  logs:
    custom_components.sigmesh_gateway: debug

13.2 常见问题排查

问题 1: 串口无法连接

# 检查串口设备
ls -l /dev/ttyUSB*

# 检查权限
groups homeassistant

# 添加权限
sudo usermod -a -G dialout homeassistant

# 确认串口通信
screen /dev/ttyUSB0 115200
# 发送 AT 测试
AT

问题 2: 收不到数据

# 查看日志
tail -f ~/.homeassistant/home-assistant.log | grep sigmesh

# 检查网关状态
# 确认网关已上电并正常工作

问题 3: 实体不显示

# 检查集成状态
# 设置 → 设备与服务 → 查看 SigMesh Gateway

# 重新加载集成
# 设置 → 设备与服务 → SigMesh Gateway → 重新加载

13.3 数据抓取

# 在 serial_reader.py 中添加调试输出
async def _read_loop(self) -> None:
    while self._running:
        if self._serial and self._serial.in_waiting:
            data = self._serial.read(self._serial.in_waiting)
            print(f"[DEBUG] 原始数据:{data}")  # 添加此行

14. 版本历史

版本 日期 作者 变更内容
1.0.0 2026-04-15 开发团队 初始版本

附录 A: 配置文件模板

# configuration.yaml

# 集成配置(如使用 YAML
sigmesh_gateway:
  serial_device: /dev/ttyUSB0
  baudrate: 115200

# 日志配置
logger:
  default: warning
  logs:
    custom_components.sigmesh_gateway: debug

# 自动化示例
automation:
  - alias: "温度过高告警"
    trigger:
      platform: numeric_state
      entity_id: sensor.sigmesh_sensor_AA_BB_CC_DD_EE_FF
      above: 30
    action:
      - service: notify.notify
        data:
          message: "温度过高!"

附录 B: 快速参考卡

┌────────────────────────────────────────────────────────────┐
│                    SigMesh Gateway 快速参考                 │
├────────────────────────────────────────────────────────────┤
│ 串口:/dev/ttyUSB0                                         │
│ 波特率115200                                             │
│ 协议:+EVENT=MESH,recv,<src>,<dst>,<opcode>,<payload>      │
│                                                            │
│ 调试命令:                                                 │
│   ls -l /dev/ttyUSB*        # 检查串口                     │
│   screen /dev/ttyUSB0 115200 # 手动测试                   │
│   tail -f home-assistant.log | grep sigmesh # 查看日志     │
│                                                            │
│ 实体命名:                                                 │
│   sensor.sigmesh_sensor_<mac>                              │
│   switch.sigmesh_switch_<mac>                              │
│   light.sigmesh_light_<mac>                                │
└────────────────────────────────────────────────────────────┘

文档结束