sim-hw 快速开始¶
本指南引导你完成 sim-hw 设备模拟器的安装和运行。
前置条件¶
- Python 3.11+ --- sim-hw 使用了现代 Python 特性和类型标注
- AWS IoT Core --- 已配置 Fleet Provisioning 的 IoT Core 端点
- Claim 证书 --- 用于 Fleet Provisioning 的 claim 证书、私钥和根 CA
- sim-dashboard 已运行 --- Fastify 服务器(端口 3001)和 React 前端(端口 5173)需要正在运行
- 后端已运行 --- Go 后端(端口 4000)需要正在运行,以处理心跳和命令
安装¶
克隆仓库并以可编辑模式安装:
虚拟环境
建议使用虚拟环境以避免与系统包冲突:
配置¶
在项目根目录创建 .env 文件:
INKLET_IOT_ENDPOINT=xxxx-ats.iot.us-east-1.amazonaws.com
INKLET_CLAIM_DIR=/path/to/awsiot/.secrets/claim
FACTORY_SECRET=your-32-byte-hex-secret
INKLET_SIM_URL=http://localhost:3001
INKLET_UI_URL=http://localhost:5173
| 变量 | 描述 |
|---|---|
INKLET_IOT_ENDPOINT |
AWS IoT Core 数据端点(可在 AWS 控制台 IoT Core > Settings 中找到) |
INKLET_CLAIM_DIR |
包含 Fleet Provisioning claim 证书的目录(claim.cert.pem、claim.private.key、root.pem) |
FACTORY_SECRET |
用于 NFC 签名生成的 32 字节十六进制字符串 HMAC 密钥 |
INKLET_SIM_URL |
sim-dashboard Fastify 服务器的 URL,用于帧缓冲推送 |
INKLET_UI_URL |
sim-dashboard React 前端的 URL(用于自动打开浏览器) |
运行模拟器¶
启动一个模拟设备:
这将创建一个具有唯一硬件 ID 的设备,数据存储在 devices/kitchen/ 中。目录名可以任意选择 --- 使用有意义的名称来区分模拟设备(例如 devices/kitchen、devices/bedroom、devices/office)。
首次运行:配网流程¶
使用新的 --data-dir 首次运行时,sim-hw 会执行 Fleet Provisioning:
1. 使用 claim 证书连接到 AWS IoT Core
2. 通过 Fleet Provisioning 请求新的设备证书
3. 接收:设备证书、私钥和 thingName
4. 将凭据存储到 {data-dir}/certs/
5. 将状态保存到 {data-dir}/state.json
6. 生成 NFC 载荷到 {data-dir}/nfc-payload
7. 断开连接并使用新的设备证书重新连接
8. 开始正常运行
配网仅需一次
Fleet Provisioning 在每个数据目录中只执行一次。生成的证书和 Thing 名称会存储在本地,后续运行时直接复用。
你将看到类似以下的输出:
INFO Fleet Provisioning started...
INFO Certificate created: certs/cert.pem
INFO Thing registered: inklet-a1b2c3d4
INFO Provisioning complete. Reconnecting with device certificate...
INFO Connected as inklet-a1b2c3d4
INFO NFC payload: inklet:1:a1b2c3d4-5678-9012-abcd-ef0123456789:3f7a8b2c1d9e0f4a
INFO Sending heartbeat...
INFO Subscribed to inklet/dev/inklet-a1b2c3d4/down/cmd
后续运行¶
后续运行时,sim-hw 检测到已有凭据后会跳过配网:
INFO Found existing credentials for inklet-a1b2c3d4
INFO Connected as inklet-a1b2c3d4
INFO NFC payload: inklet:1:a1b2c3d4-5678-9012-abcd-ef0123456789:3f7a8b2c1d9e0f4a
INFO Sending heartbeat...
INFO Subscribed to inklet/dev/inklet-a1b2c3d4/down/cmd
命令行参数¶
所有参数也可通过环境变量或 .env 文件设置。
| 参数 | 默认值 | 描述 |
|---|---|---|
--data-dir |
(必填) | 每个设备的工作目录,用于存储证书、状态和 NFC 载荷 |
--hw-id |
自动生成 UUID | 覆盖硬件 UUID(用于测试特定设备 ID) |
--iot-endpoint |
$INKLET_IOT_ENDPOINT |
AWS IoT Core 端点 |
--claim-dir |
$INKLET_CLAIM_DIR |
claim 证书目录路径 |
--heartbeat-interval |
30 |
心跳间隔(秒) |
--factory-secret |
$FACTORY_SECRET |
用于 NFC 载荷签名的 HMAC 密钥 |
--sim-url |
http://localhost:3001 |
sim-dashboard Fastify 服务器 URL |
--ui-url |
http://localhost:5173 |
sim-dashboard 前端 URL |
--no-browser |
false |
不自动打开浏览器 |
--once |
false |
发送一次心跳后退出(用于脚本和测试) |
示例:
# 使用自定义心跳间隔运行
python -m eink_hw --data-dir devices/kitchen --heartbeat-interval 10
# 使用指定的硬件 ID 运行
python -m eink_hw --data-dir devices/test --hw-id "00000000-0000-0000-0000-000000000001"
# 不打开浏览器运行
python -m eink_hw --data-dir devices/kitchen --no-browser
# 发送一次心跳后退出
python -m eink_hw --data-dir devices/kitchen --once
数据目录结构¶
每个 --data-dir 代表一个模拟设备,包含以下内容:
devices/kitchen/
├── hw-id # 硬件 UUID(纯文本)
├── state.json # 配网状态
├── nfc-payload # NFC 绑定载荷
└── certs/
├── cert.pem # 设备证书(来自 Fleet Provisioning)
├── private.key # 设备私钥(来自 Fleet Provisioning)
└── root.pem # AWS IoT 根 CA
hw-id¶
包含设备硬件 UUID 的纯文本文件。首次运行时自动生成,或通过 --hw-id 指定。
state.json¶
记录配网状态和分配的 Thing 名称。
nfc-payload¶
NFC 绑定字符串,每次启动时生成。
certs/¶
Fleet Provisioning 期间获取的 X.509 证书。用于后续所有 MQTT 连接。
证书安全
certs/ 目录包含私钥材料。请勿将其提交到版本控制。sim-hw 仓库中的 .gitignore 默认排除了 devices/ 目录。
运行多个设备¶
要模拟多个设备,使用不同的数据目录运行多个实例:
每个实例拥有自己的硬件 ID、Thing 名称、证书和 NFC 载荷。所有设备在 sim-dashboard 和后端中独立显示。
故障排除¶
连接被拒绝¶
请确认 AWS IoT Core 端点正确,且你的网络允许端口 8883 的出站连接。
配网失败¶
请检查:
--claim-dir中的 claim 证书是否有效且未过期- AWS IoT Core 中是否已配置 Fleet Provisioning 模板
- claim 证书是否已附加
inklet-claim-policy
sim-dashboard 未接收到帧¶
请确认 sim-dashboard 在预期端口上运行(默认:3001)。检查 --sim-url 参数。