connectedhomeip 实战指南:使用 Python CHIP Controller 与 matter-repl 完成 Matter 设备配网、调试与控制
【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip
本指南以 connectedhomeip(Matter SDK)仓库中 docs/development_controllers/matter-repl/python_chip_controller_building.md 为核心,系统讲解 Python CHIP Controller 库与 matter-repl 交互式 REPL 的构建、安装与使用流程。Python CHIP Controller 是一个基于 C++ Chip Device Controller 原生库的 Python 封装,负责创建 Matter fabric(织物)并完成对 Matter 设备的配网(commissioning),而 matter-repl 则提供一个 IPython 交互式终端,让你可以在命令行中直接探索控制器 API、下发命令并与真实设备通信。读完本文,你将掌握从零编译 Python 控制器、通过 Bluetooth LE 配网 Thread/Wi-Fi 设备、执行 Cluster 命令、读写属性以及配置属性订阅上报的完整实战技能。
源码结构:Python CHIP Controller 与 matter-repl 的位置与分工
Python CHIP Controller 的源码位于仓库的 src/controller/python 目录。该目录下几个关键文件决定了工具的整体形态:
- matter-repl.py:REPL 的入口脚本,仅做一件事——调用
matter.repl_main的main()启动 IPython 会话。 - matter/repl_main.py:启动 IPython 并执行 matter/ReplStartup.py 初始化脚本。
- matter/ChipDeviceCtrl.py:核心的
ChipDeviceCtrl类,封装了发现、配网、命令、属性读写等全部控制器能力。 - matter/clusters:Cluster 与 Attribute 的 Python 类定义(
CHIPClusters.py、ClusterObjects.py、Attribute.py等),是 REPL 中Clusters.xxx.Attributes.yyy语法的来源。 - matter/ble:Bluetooth LE 相关的扫描与适配器管理实现。
控制器底层复用通用 CHIP Device Controller 库,该库位于 src/controller 目录,Python 绑定通过ChipDeviceController-ScriptBinding.cpp等 C++ 桥接文件将原生能力暴露给 Python(详见 src/controller/python 下的ChipDeviceController-*.cpp系列文件)。
从源码结构看,Python CHIP Controller 本质上是一个"轻量 Python 壳 + 重量原生内核"的组合:Python 侧负责对象建模与异步封装,最终都通过_ChipStack.Call/_ChipStack.CallAsync调用pychip_DeviceController_*系列 C++ 绑定函数落地执行。
构建与安装:从源码编译 Python CHIP Controller
在开始之前,需要强调一个兼容性前提:请使用 connectedhomeip 仓库同一修订版本分别构建 Python CHIP Controller 与 Matter 设备固件,以确保两者使用的协议与集群定义完全一致。Python 控制器当前支持在 Linux(amd64 / aarch64)或 macOS 上从源码编译。
第一步:安装系统依赖
以 Ubuntu/Debian 为例,安装编译所需的系统包:
sudo apt-get update sudo apt-get upgrade sudo apt-get install git gcc g++ python pkg-config libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev python3-pip unzip libgirepository1.0-dev libcairo2-dev bluez如果要在 Raspberry Pi 上构建(用于蓝牙配网测试非常常见),还需额外安装蓝牙内核包并重启:
sudo apt-get install pi-bluetooth sudo reboot关于构建环境的更多细节可参考 Building Matter。
第二步:获取仓库并初始化子模块
git clone https://github.com/project-chip/connectedhomeip.git cd connectedhomeip git submodule update --init第三步:构建并安装 Python 控制器
构建入口是仓库根目录下的 scripts/build_python.sh:
scripts/build_python.sh -m platform -i out/python_env source out/python_env/bin/activate这条命令完成的工作包括:
- 通过
gn --root="$CHIP_ROOT" gen生成 Ninja 构建文件; - 调用
ninja -C "$output_root" python_wheels编译 Python wheel 包(包括 matter-controller-wheels 与 matter-testing-infrastructure); - 使用
-i out/python_env指定的路径创建 Python 虚拟环境,并把编译好的 wheel 与构建依赖安装进去(对应源码 scripts/build_python.sh 中python -m venv --clear与pip install的逻辑); - 输出
source out/python_env/bin/activate的使用提示。
提示:
-m platform指定 MDNS 后端为平台实现(相对于minimal实现);如需查看全部可用构建参数,运行scripts/build_python.sh --help。
从 scripts/build_python.sh 的帮助信息看,常用的构建选项还包括:
| 参数 | 作用 | 默认值 |
|---|---|---|
-b / --enable_ble <true/false> | 控制器中启用 BLE | true |
-n / --enable_nfc <true/false> | 启用 NFC 配网支持 | false |
-4 / --enable_ipv4 <true/false> | 启用 IPv4 | true |
-d / --chip_detail_logging <true/false> | 是否输出 CHIP 详细日志 | false |
-m / --chip_mdns <platform\|minimal> | MDNS 实现选择 | minimal |
-w / --enable_webrtc <true/false> | 控制器中启用 WebRTC 绑定 | true(Darwin 上自动关闭) |
-i / --install_virtual_env <path> | 指定虚拟环境创建路径 | 无(不创建) |
-c / --clean_virtual_env <yes\|no> | 是否先清空再创建虚拟环境 | yes |
-g / --gn_args ARGS | 追加透传的 GN 参数(可多次指定) | 无 |
-E / --extra_packages PACKAGE | 额外安装的 PyPI 包(可多次指定) | 无 |
-z / --pregen_dir DIRECTORY | 使用预生成的 ZAP 代码目录 | 无 |
-ds / --chip_build_controller_dynamic_server <true/false> | 控制器内启用动态服务器 | true |
-pw / --enable_pw_rpc <true/false> | 构建 Pigweed RPC Python wheel | false |
--enable-ccache | 使用 ccache 加速编译 | 否 |
其中-w会连锁影响加密后端的选择:从 scripts/build_python.sh 可以看到,当 WebRTC 开启时chip_crypto会被切换为openssl,否则默认使用 BoringSSL。此外该脚本固定注入了matter_log_json_payload_hex=true、matter_enable_tracing_support=true等便于调试的配置项,以及chip_project_config_include_dirs=["//config/python"]指向 config/python 下的 CHIP 配置头文件。
运行 matter-repl 并探索 API
激活虚拟环境后即可启动 REPL:
source out/python_env/bin/activate matter-repl若需要更详细的日志,可追加调试标志:
matter-repl --debug从 matter/ReplStartup.py 的main()可以看出,REPL 启动时会在内部依次完成:
- 解析命令行参数(
--debug/-d、--storage-path/-s(默认/tmp/repl-storage.json)、--trust-store/-t(默认credentials/development/paa-root-certs)、--ble-controller/-b(默认 0)、--server-interactions/-i); - 初始化
chipStack与certificateAuthorityManager; - 从持久化存储加载证书权威(Certificate Authority),若无则自动以
vendorId=0xFFF1、fabricId=1创建新 CA 与 FabricAdmin; - 创建默认控制器并注入为内置变量
devCtrl,同时把Clusters、caList等对象注入命名空间。
因此进入 REPL 后,你可以直接使用devCtrl对象,并通过matterhelp()查看其方法签名。注意devCtrl的默认 Node ID 会在启动横幅中打印(例如nodeId=0x...)。
启动横幅还提示了 REPL 内置的几个辅助函数:matterhelp([object])用 rich 渲染对象/类的方法帮助,mattersetlog(level)动态调整日志级别,mattersetdebug(enableDebugMode)切换调试模式(部分模块在调试模式下会抛出异常而非返回格式化结果)。
使用 Python CHIP Controller REPL 测试 Matter 配件设备
下面以 Matter Light Bulb(灯泡)示例设备为例,演示从发现、配网到控制的完整链路。这些步骤依赖你在设备端实现的 Application Cluster,具体命令可能因配件而异。
Step 1:准备 Matter 配件设备
按示例文档编译并烧录 Matter 配件固件(本教程以支持 Bluetooth LE 配网的 Light Bulb 示例为基准,也可替换为仓库 examples 下其他可用示例)。
Step 2:开启配件设备的 BLE 广播
部分示例固件会在启动时自动广播,另一些需要物理触发(如按键)。请查阅具体示例文档确认广播开启方式。
Step 3:发现可配网的 Matter 设备
未配网的配件会通过 Bluetooth LE 广播(若已在网络中则通过 mDNS)。执行以下命令扫描所有广播中的 Matter 设备:
await devCtrl.DiscoverCommissionableNodes()从 matter/ChipDeviceCtrl.py 的实现看,该方法基于 DNS-SD 发现,默认扫描 5 秒(timeoutSecond=5),支持按discovery.FilterType(如SHORT_DISCRIMINATOR、LONG_DISCRIMINATOR、VENDOR_ID、DEVICE_TYPE等)过滤,也支持stopOnFirst=True提前返回。
Step 4:设置网络配网凭据
配网过程需要控制器持有网络凭据,用于在配网后把设备配置到 Thread 或 Wi-Fi 网络。
设置 Thread 网络凭据
首先从 Thread Border Router 获取当前 Active Operational Dataset:
Docker 部署方式:
sudo docker exec -it otbr sh -c "sudo ot-ctl dataset active -x" 0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8 Done原生安装方式:
sudo ot-ctl dataset active -x 0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8 Done
说明:Matter 规范并不规定 Controller 如何获取 Thread/Wi-Fi 凭据,你也可以通过其他带外方式获取,而不必直接从 Border Router 读取。
然后将得到的 Active Operational Dataset 以字节数组形式设置给控制器:
thread_dataset = bytes.fromhex("0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8") devCtrl.SetThreadOperationalDataset(thread_dataset)底层实现见 matter/ChipDeviceCtrl.py,它直接把字节数组连同长度透传给pychip_DeviceController_SetThreadOperationalDataset原生接口。
设置 Wi-Fi 网络凭据
假设 Wi-Fi SSID 为TESTSSID、密码为P455W4RD:
devCtrl.SetWiFiCredentials(<ssid>, <password>)对应源码 matter/ChipDeviceCtrl.py 会调用pychip_DeviceController_SetWiFiCredentials完成凭据写入。
Step 5:通过 Bluetooth LE 配网 Matter 配件设备
控制器使用discriminator(12 位)区分多个可配网广播,并使用setup PIN code(27 位)对设备进行认证。这两个值会打印在设备的日志终端(如 UART)上,例如:
I: 254 [DL]Device Configuration: I: 257 [DL] Serial Number: TEST_SN I: 260 [DL] Vendor Id: 65521 (0xFFF1) I: 263 [DL] Product Id: 32768 (0x8000) I: 270 [DL] Setup Pin Code: 20202021 I: 273 [DL] Setup Discriminator: 3840 (0xF00) I: 278 [DL] Device Type: 65535 (0xFFFF)假设设备 discriminator 为3840、setup PIN 为20202021,执行:
await devCtrl.ConnectBLE(3840, 20202021, 1234)第三个参数是临时 Node ID(1234),可以省略,省略时控制器会随机分配——此时请务必记下返回的 Node ID,后续配置流程还会用到。从 matter/ChipDeviceCtrl.py 的实现看,ConnectBLE实际调用pychip_DeviceController_ConnectBLE发起 PASE 会话,并支持isShortDiscriminator参数指定是否使用短 discriminator。
也可以使用二维码形式的 setup code(通常同样打印在设备终端,例如CHIP:SVR: SetupQRCode: [MT:-24J0AFN00KA0648G00]):
await devCtrl.CommissionWithCode("MT:-24J0AFN00KA0648G00", 1234)CommissionWithCode支持 QR code 或手动 setup code,其实现(matter/ChipDeviceCtrl.py)默认以DiscoveryType.DISCOVERY_ALL发现设备,然后调用pychip_DeviceController_ConnectWithCode完成配网,并返回设备的实际有效 Node ID。
BLE 连接建立后,控制器将依次经历以下配网阶段:
- 建立安全会话(PASE):通过 SPAKE2+ 协议完成 Password-Authenticated Session Establishment,成功时打印日志
Secure Session to Device Established; - 下发网络接口配置:使用 ZCL Network Commissioning 集群命令,把上一步设置的网络凭据写入设备;
- 发现设备 IPv6 地址:Thread 设备通过 SRP(Service Registration Protocol),Wi-Fi/Ethernet 设备通过 mDNS 发现,随后打印日志提示 node address 已更新,IPv6 地址被缓存在控制器中供后续使用;
- 关闭 BLE 连接:配网完成,控制器此后仅通过 IPv6 流量与设备通信。
Step 6:控制 Application Cluster
对灯泡示例,执行以下命令切换 LED 状态:
await devCtrl.SendCommand(1234, 1, Clusters.OnOff.Commands.Toggle())调整 LED 亮度(level 取值 0 到 255):
commandToSend = LevelControl.Commands.MoveToLevel(level=50, transitionTime=Null, optionsMask=0, optionsOverride=0) await devCtrl.SendCommand(1234, 1, commandToSend)Step 7:读取配件的基础信息
每个 Matter 配件都支持 Basic Information 集群,其中保存了供应商名称、产品名称、软件版本等属性。使用ReadAttribute()读取:
attributes = [ (0, Clusters.BasicInformation.Attributes.VendorName), (0, Clusters.BasicInformation.Attributes.ProductName), (0, Clusters.BasicInformation.Attributes.SoftwareVersion), ] await devCtrl.ReadAttribute(1234, attributes)提示:在 REPL 中键入
Clusters.BasicInformation.Attributes.后按 TAB 键,可以自动补全列出所有可用属性。
Python CHIP Controller REPL 常用命令速查
以下命令均以 matter/ChipDeviceCtrl.py 中的实现为准。完整的 CHIP Device Controller API 文档(官方 API 文档站点)可供查阅全部可用命令。
SetThreadOperationalDataset(<thread-dataset>)
为控制器设置 Thread 网络凭据,用于配网时把设备配置进 Thread 网络:
thread_dataset = bytes.fromhex("0e080000000000010000000300001335060004001fffe002084fe76e9a8b5edaf50708fde46f999f0698e20510d47f5027a414ffeebaefa92285cc84fa030f4f70656e5468726561642d653439630102e49c0410b92f8c7fbb4f9f3e08492ee3915fbd2f0c0402a0fff8") devCtrl.SetThreadOperationalDataset(thread_dataset)SetWiFiCredentials(<ssid>: str, <password>: str)
为控制器设置 Wi-Fi 网络凭据:
devCtrl.SetWiFiCredentials('TESTSSID', 'P455W4RD')CommissionWithCode(<setupPayload>: str, <nodeid>: int, <discoveryType>: DiscoveryType)
使用 setupPayload(QR 或 manual setup code)配网指定 nodeid 的设备:
await devCtrl.CommissionWithCode("MT:-24J0AFN00KA0648G00", 1234)SendCommand(<nodeid>: int, <endpoint>: int, Clusters.<cluster>.Commands.<command>(<arguments>))
向设备发送 Matter 命令:
commandToSend = Clusters.LevelControl.Commands.MoveWithOnOff(moveMode=1, rate=2, optionsMask=0, optionsOverride=0) await devCtrl.SendCommand(1234, 1, commandToSend)查看命令可用参数时,直接创建一个不带参数的命令对象:
Clusters.LevelControl.Commands.MoveWithOnOff()REPL 会打印默认参数结构:
MoveWithOnOff( │ moveMode=0, │ rate=Null, │ optionsMask=0, │ optionsOverride=0 )从 matter/ChipDeviceCtrl.py 的实现可以看到,SendCommand底层先通过GetConnectedDevice(nodeId)建立/复用与节点的会话,再经ClusterCommand.SendCommand组装并发送 Interaction Model 请求,最终返回可await的响应 Future。
ReadAttribute(<nodeid>: int, [(<endpoint id>: int, Clusters.<cluster>.Attributes.<attribute>)])
读取属性值:
await devCtrl.ReadAttribute(1234, [(0, Clusters.BasicInformation.Attributes.VendorName)])WriteAttribute(<nodeid>: int, [(<endpoint id>: int, Clusters.<cluster>.Attributes.<attribute>(value=<attribute value>))])
写入属性值,支持各种数据类型:
await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.Int8u(value=1))]) await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.Boolean(value=True))]) await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.OctetString(value=b'123123\x00'))]) await devCtrl.WriteAttribute(1234, [(1, Clusters.UnitTesting.Attributes.CharString(value='233233'))])注意OctetString的 value 是bytes类型,CharString的 value 是str类型,其余数值型/布尔型按字面量传入即可。
ReadAttribute(..., reportInterval=(<min interval>: int, <max interval>: int))
配置 Matter 属性上报(订阅)设置,例如以 10~20 秒间隔订阅 OccupancySensing 集群的 Occupancy 属性:
await devCtrl.ReadAttribute(1234, [(1, Clusters.OccupancySensing.Attributes.Occupancy)], reportInterval=(10, 20))终止已有订阅使用返回订阅对象的Shutdown()方法:
sub = await devCtrl.ReadAttribute(1234, [(1, Clusters.OccupancySensing.Attributes.Occupancy)], reportInterval=(10, 20)) sub.Shutdown()使用 TAB 补全探索 Clusters、Attributes 与 Commands
在 Python REPL 中,Clusters 与 Attributes 都是类对象:Clusters模块包含所有集群定义。利用 IPython 的 TAB 补全可以非常高效地浏览 API 空间:
- 列出所有集群:键入
Clusters.后按 TAB,循环按 TAB 可在可用集群间切换,按回车选中; - 浏览属性:对选中集群键入
Clusters.(cluster name).Attributes.后按 TAB; - 浏览命令:同理,使用
Commands子类,键入Clusters.(cluster name).Commands.后按 TAB。
这套类结构的生成源头是 src/controller/python/templates 下的python-CHIPClusters-py.zapt与python-cluster-Objects-py.zapt模板,运行时由 matter/clusters 中的CHIPClusters.py、ClusterObjects.py等模块提供类定义,因此所有集群、属性、命令的对象名都与 Matter 规范保持一致,可直接作为参数传给上述控制命令。
进阶阅读
- 控制器高级用法(存储管理、多 Fabric、NFC 配网等)参见 Python CHIP Controller 高级用法;
- Python 控制器的自动化测试脚本位于 src/controller/python/tests/scripts(如 commissioning_test.py、commissioning_flow_test.py),可参考其组织真实配网流程;
- 构建环境与通用编译指引见 Building Matter。
【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考