impress_sig_mesh_hacs/PRD.md
impressionyang f1f2c77af4 docs: 更新网关配置文档
- 新增 docs/网关配置教程.md (基于 E104-BT12+tool 使用教程-V1.0.docx)
- 更新 PRD.md:
  - 更新网关型号为 E104-BT12USP
  - 添加 danglo 组网工具配置步骤
  - 添加协议帧格式详细说明
  - 添加组网配置要点和订阅限制
  - 移除不存在的 bleak-mesh 依赖
- 保存网关配置要点到记忆 (gateway_config.md)
2026-04-16 11:49:49 +08:00

836 lines
21 KiB
Markdown
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 HACS 集成 - PRD 产品需求文档
**版本号**: 1.0.0
**创建日期**: 2026-04-15
**最后更新**: 2026-04-15
**状态**: 草稿 → 评审中
---
## 目录
1. [文档概述](#1-文档概述)
2. [产品背景](#2-产品背景)
3. [需求范围](#3-需求范围)
4. [技术规格](#4-技术规格)
5. [功能需求](#5-功能需求)
6. [非功能需求](#6-非功能需求)
7. [数据模型](#7-数据模型)
8. [接口定义](#8-接口定义)
9. [配置参数](#9-配置参数)
10. [错误处理](#10-错误处理)
11. [日志规范](#11-日志规范)
12. [测试计划](#12-测试计划)
13. [调试指南](#13-调试指南)
14. [版本历史](#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 命令
**参数配置**:
```python
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. 支持设备查询接口
**数据结构**:
```python
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 秒冷却)
**参数配置**:
```python
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 设备状态模型
```python
{
"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 对外接口
```python
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 服务调用接口TODO
```yaml
# service.yaml
sigmesh_gateway.send_command:
fields:
device_id:
description: 设备 ID
example: "AA:BB:CC:DD:EE:FF"
opcode:
description: 操作码
example: "0x8202"
payload:
description: 数据负载
example: "01"
```
---
## 9. 配置参数
### 9.1 配置入口参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| serial_device | string | | /dev/ttyUSB0 | 串口设备路径 |
| baudrate | int | | 115200 | 波特率 |
### 9.2 选项参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| poll_interval | int | | 30 | 轮询间隔 () |
### 9.3 调试参数
```yaml
# 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 日志格式
```python
_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 调试准备
```yaml
# 1. 启用调试日志
logger:
default: warning
logs:
custom_components.sigmesh_gateway: debug
```
### 13.2 常见问题排查
#### 问题 1: 串口无法连接
```bash
# 检查串口设备
ls -l /dev/ttyUSB*
# 检查权限
groups homeassistant
# 添加权限
sudo usermod -a -G dialout homeassistant
# 确认串口通信
screen /dev/ttyUSB0 115200
# 发送 AT 测试
AT
```
#### 问题 2: 收不到数据
```bash
# 查看日志
tail -f ~/.homeassistant/home-assistant.log | grep sigmesh
# 检查网关状态
# 确认网关已上电并正常工作
```
#### 问题 3: 实体不显示
```bash
# 检查集成状态
# 设置 → 设备与服务 → 查看 SigMesh Gateway
# 重新加载集成
# 设置 → 设备与服务 → SigMesh Gateway → 重新加载
```
### 13.3 数据抓取
```python
# 在 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: 配置文件模板
```yaml
# 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> │
└────────────────────────────────────────────────────────────┘
```
---
**文档结束**