尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Matter All-Devices 应用新增模拟设备完整指南:从规格研究到认证测试

Matter All-Devices 应用新增模拟设备完整指南:从规格研究到认证测试 Matter All-Devices 应用新增模拟设备完整指南从规格研究到认证测试【免费下载链接】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本指南面向希望在all-devices-app中实现并接入全新模拟 Matter 设备的开发者与 AI 编程代理。文章以MySensor--device my-sensor为贯穿案例完整覆盖规格研究、测试用例发现、设备类实现、DeviceFactory注册、GN/CMake 构建配置接入、构建目标与 golden 快照更新以及端到端与认证测试验证的全流程。读完本文你将掌握如何在保持编译期安全、跨平台可复用、可测试的前提下把一个新的 Matter 设备类型干净地集成进 all-devices-app并通过自动化 CI 校验与认证测试。all-devices-app是 Matter SDK 中一个一程序承载多种设备的模拟示例工程它把每一个 Matter 设备类型封装成独立的 C 设备类通过DeviceFactory在运行时按命令行参数如--device on-off-light实例化并注册到代码驱动的数据模型CodeDrivenDataModelProvider中。新增设备类型通常需要六个步骤规格研究 → 测试规划 → 实现设备类 → 注册工厂 → 接入构建配置 → 端到端验证与文档更新。Step 0研究规格要求在写任何代码之前先确定目标设备类型在 Matter 规范中的确切定义以 CSA Matter 规范为主Primary以最新版 CSA Matter 规范中对应章节作为权威依据确认 next-version 需求。本地 XML 为辅Secondary仓库中的data_model/{version}/device_types/{DeviceType}.xml是某一可认证规范版本的静态快照适合快速查表但可能缺少下一版本的新特性需要结合最新规范做增补。端点约束每个端点必须至少包含一个功能性、领域相关的 Server Cluster0-cluster 端点是明确不允许的。需要确认的关键需求Device Type ID十六进制标识例如 Temperature Sensor 为0x0302必选与可选 Cluster符合规范所需的所有 Server Cluster端点约束 / 组合规则端点树的组成规则父端点、组合模式、语义标签。AI Agent 辅助若使用 AI 编码代理可借助仓库中的 spec access skill 检索规范的相关章节。从仓库源码看设备类型 ID 最终会通过Spanconst DataModel::DeviceTypeEntry传入设备基类构造函数成为 Descriptor 集群 DeviceTypeList 属性的数据来源见 Interface.h 中DeviceInterface(Spanconst DataModel::DeviceTypeEntry deviceTypes)的保护构造。Step 0.5测试计划与测试发现定位测试计划Cluster 验证步骤可参考 CSA 成员可访问的私有chip-test-plans仓库。定位集成测试在 src/python_testing/ 中搜索TC_{CLUSTER}_*.py或在 src/app/tests/suites/ 中搜索对应的 YAML 测试套件。规划 CI 运行在 Python 测试脚本的 BEGIN CI TEST ARGUMENTS 块或 YAML 测试套件中新增运行配置并传入--device {your-device}即可让 CI 对新增设备跑对应的 cluster 测试。TC_DeviceBasicComposition.py等通用设备组成测试位于 src/python_testing/它们通过命令行指定--app与--app-args --device ...动态拉起被测设备是验证新设备能被正确组合与注册的第一道自动化关卡。架构最佳实践以下模式来自 all-devices-app 现有设备实现的沉淀目的是让设备代码编译期安全、跨平台可复用、易于测试。1. 抽象硬件交互核心设备类不要依赖具体 RTOS 或平台库像点亮 LED、播放声音这类硬件动作应抽象成纯虚委托接口delegate。这样其他平台的贡献者可以原样复用你的设备行为只需为各自目标板实现 delegate。2. 必选委托使用引用Delegate 对 Cluster 核心功能所必需的委托例如灯所需的OnOffDelegate、设备所需的IdentifyDelegate必须在构造函数中以 C 引用强制传入。好处是在编译期就保证传入了一个有效处理器彻底消除运行时空指针崩溃或设备静默忽略命令的风险。仅对按特性开关/配置可选的 Cluster才使用默认为nullptr的指针Delegate *。3. 公开 Cluster Getter始终提供公开的 C getter如IdentifyCluster()、OnOffCluster()把底层 cluster 实例暴露出去方便本地应用代码物理按键驱动、平台叶子类、shell 命令、Out-of-Band 访问器等以编程方式读写或修改设备状态。4. 对称的日志 Mockimpl/子文件夹为每个基础设备类在专用impl/子文件夹中实现一个默认打日志的 mock 子类如LoggingMySensor。采用self-delegate 模式mock 子类同时继承基础设备类与 delegate 接口实现回调并把日志打到控制台再把*this传给基类构造函数。这样 mock 完全自包含无需外部接线即可被DeviceFactory或单元测试直接实例化。5. 纯规格目录布局与能力抽取device/types/根目录应只放真正的、规范定义的 Matter 设备类型如dimmable-light、fan、air-purifier避免非规范继承例如让插排继承灯来复用代码若多个设备类型共享某能力如调光、空气循环把它抽取为device/capabilities/capability-name/下的抽象能力基类具体叶子设备再公开继承该能力基类。仓库中 device/capabilities/README.md 明确说明了这一设计规则能力是内部抽象如dimmable-load封装 Identify、OnOff、LevelControl、ScenesManagement、Groups 等 cluster 行为fan-load封装风扇控制on-off-load封装开关且只能依赖device/api/不得依赖具体设备类型。例如 OnOffLight.h 就是通过继承OnOffLoad能力基类构建的。6. 注册与销毁顺序注册顺序先调用RegisterDescriptor()构造 Descriptor cluster 并初始化端点元数据再通过provider.AddCluster()创建并添加所有领域/可选 cluster最后用provider.AddEndpoint(mEndpointRegistration)注册端点。一旦 provider 启动CodeDrivenDataModelProvider会拒绝向已注册端点继续添加 cluster返回CHIP_ERROR_INCORRECT_STATE。销毁顺序先调用UnregisterDescriptor(provider)内部通过provider.RemoveEndpoint()从 provider 移除端点之后才能移除/销毁领域与可选 cluster。provider 启动后禁止非原子端点修改若端点仍注册时调用provider.RemoveCluster()会返回CHIP_ERROR_INCORRECT_STATE。该顺序在 Interface.h 与 SingleEndpoint.h 的注释与接口文档中均有明确约束SingleEndpoint还通过mEndpointId默认kInvalidEndpointId标记设备是否已完成注册。此外Interface.h 提供了 RAII 事务守卫DeviceRegistrationTransaction在Register()开头实例化注册成功则调用Commit()若中途出错提前返回析构函数会自动调用Unregister()完成回滚避免半注册状态残留。Step 1实现设备类以MySensor为例目录结构新增设备位于all-devices-common/device/types/my-sensor/下包含头文件、源文件与impl/mock 子目录device/types/my-sensor/ ├── BUILD.gn ├── MySensor.h ├── MySensor.cpp └── impl/ ├── LoggingMySensor.h └── LoggingMySensor.cpp头文件MySensor.h从SingleEndpoint派生若管理复合/多端点设备则从DeviceInterface派生。必选委托以引用传入构造函数并声明公开 getter 暴露底层 cluster#pragma once #include app/clusters/identify-server/IdentifyCluster.h #include app/clusters/my-sensor-server/MySensorServerCluster.h // Example code-driven cluster #include data-model-providers/codedriven/CodeDrivenDataModelProvider.h #include device/api/SingleEndpoint.h #include lib/support/TimerDelegate.h namespace chip::app { class MySensor : public SingleEndpoint { public: MySensor(TimerDelegate timerDelegate, Clusters::IdentifyDelegate identifyDelegate); ~MySensor() override default; // DeviceInterface pure virtual lifecycle hooks CHIP_ERROR Register(chip::EndpointId endpoint, CodeDrivenDataModelProvider provider, EndpointComposition composition {}) override; void Unregister(CodeDrivenDataModelProvider provider) override; // Public cluster getters for programmatic control Clusters::IdentifyCluster IdentifyCluster() { return mIdentifyCluster.Cluster(); } Clusters::MySensorCluster MySensorCluster() { return mMySensorCluster.Cluster(); } private: TimerDelegate mTimerDelegate; Clusters::IdentifyDelegate mIdentifyDelegate; LazyRegisteredServerClusterClusters::IdentifyCluster mIdentifyCluster; LazyRegisteredServerClusterClusters::MySensorCluster mMySensorCluster; }; } // namespace chip::app要点LazyRegisteredServerClusterT是延迟创建的 cluster 包装器Create(...)时才真正构造构造函数的TimerDelegate与IdentifyDelegate引用为整个设备生命周期提供定时与识别回调能力。源文件MySensor.cpp在Register()中使用.WithDelegate()把必选委托接进 cluster 实例#include MySensor.h #include devices/Types.h #include lib/support/logging/CHIPLogging.h using namespace chip::app::Clusters; namespace chip::app { MySensor::MySensor(TimerDelegate timerDelegate, Clusters::IdentifyDelegate identifyDelegate) : SingleEndpoint(Spanconst DataModel::DeviceTypeEntry(Device::Type::kMySensor, 1)), mTimerDelegate(timerDelegate), mIdentifyDelegate(identifyDelegate) {} CHIP_ERROR MySensor::Register(chip::EndpointId endpoint, CodeDrivenDataModelProvider provider, EndpointComposition composition) { VerifyOrReturnError(mEndpointId kInvalidEndpointId, CHIP_ERROR_INCORRECT_STATE); DeviceRegistrationTransaction transaction(*this, provider); ReturnErrorOnFailure(RegisterDescriptor(endpoint, provider, composition)); // Wire up the mandatory identify delegate mIdentifyCluster.Create(IdentifyCluster::Config(endpoint, mTimerDelegate).WithDelegate(mIdentifyDelegate)); ReturnErrorOnFailure(provider.AddCluster(mIdentifyCluster.Registration())); mMySensorCluster.Create(endpoint); ReturnErrorOnFailure(provider.AddCluster(mMySensorCluster.Registration())); ReturnErrorOnFailure(provider.AddEndpoint(mEndpointRegistration)); transaction.Commit(); return CHIP_NO_ERROR; } void MySensor::Unregister(CodeDrivenDataModelProvider provider) { // UnregisterDescriptor MUST be called first to remove the endpoint from the provider. // Once started, calling provider.RemoveCluster while the endpoint is still registered returns CHIP_ERROR_INCORRECT_STATE. UnregisterDescriptor(provider); if (mMySensorCluster.IsConstructed()) { LogErrorOnFailure(provider.RemoveCluster(mMySensorCluster.Cluster())); mMySensorCluster.Destroy(); } if (mIdentifyCluster.IsConstructed()) { LogErrorOnFailure(provider.RemoveCluster(mIdentifyCluster.Cluster())); mIdentifyCluster.Destroy(); } } } // namespace chip::app这段实现完整体现了上文注册/销毁顺序与 RAII 事务模式mEndpointId校验防止重复注册DeviceRegistrationTransaction保证失败回滚UnregisterDescriptor()永远最先执行。对称日志 Mockimpl/LoggingMySensor.h与.cpp为DeviceFactory提供一个开箱即用、自带控制台日志的模拟变体采用 self-delegate 模式#pragma once #include device/types/my-sensor/MySensor.h #include lib/support/logging/CHIPLogging.h namespace chip::app { class LoggingMySensor : public MySensor, public Clusters::IdentifyDelegate { public: explicit LoggingMySensor(TimerDelegate timerDelegate) : MySensor(timerDelegate, *this) {} ~LoggingMySensor() override default; // IdentifyDelegate implementation void OnIdentifyStart(Clusters::IdentifyCluster cluster) override { ChipLogProgress(DeviceLayer, MySensor: OnIdentifyStart); } void OnIdentifyStop(Clusters::IdentifyCluster cluster) override { ChipLogProgress(DeviceLayer, MySensor: OnIdentifyStop); } void OnTriggerEffect(Clusters::IdentifyCluster cluster) override { ChipLogProgress(DeviceLayer, MySensor: OnTriggerEffect); } bool IsTriggerEffectEnabled() const override { return true; } }; } // namespace chip::appGN 构建BUILD.gn在all-devices-common/device/types/my-sensor/BUILD.gn定义独立 source set# Copyright (c) 2026 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the License); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an AS IS BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import(//build_overrides/chip.gni) source_set(my-sensor) { sources [ MySensor.cpp, MySensor.h, ] public_deps [ ${chip_root}/examples/all-devices-app/all-devices-common/device/api:single-endpoint-device, ${chip_root}/src/app/clusters/identify-server, # Add public_deps for your specific cluster servers here ${chip_root}/src/data-model-providers/codedriven, ${chip_root}/src/lib/core, ] }Step 2在DeviceFactory中注册设备类型要支持--device my-sensor运行时初始化把自包含的日志 mock注册进 DeviceFactory.h。包含日志 Mock 头文件保持 include 列表按字母序排列#include device/types/my-sensor/impl/LoggingMySensor.h在DeviceFactory构造函数中注册 Creatorif constexpr (ALL_DEVICES_ENABLE_MY_SENSOR) { RegisterCreator(my-sensor, [this]() { VerifyOrDie(mContext.has_value()); return MakeDeviceLoggingMySensor(mContext-timerDelegate); }); }注意工厂中实例化的是 Logging mock 版本因此它可以完全开箱即用、自带控制台日志平台 main 代码保持干净。从源码看DeviceFactory::RegisterCreator()会把注册键存入mRegistry并自动把第一个注册的设备设为默认设备mDefaultDeviceCreate()在找不到设备时打印INTERNAL ERROR: Invalid device type并提示用--help查看合法设备列表。MakeDeviceT()返回DeviceRegistrationEntry设备实例 注册后 hook 回调而Context集中承载timerDelegate、fabricTable、groupDataProvider、identifyDelegate等运行时依赖所有 creator lambda 都通过VerifyOrDie(mContext.has_value())确保已Init。可选注册 Out-of-Band 与 Named Pipe 支持如需模拟传感器触发或外部控制实现OOBAccessors.h/.cpp平台无关与NamedPipeTranslators.h/.cpp仅 POSIX在all-devices-common/oob-accessors/OOBAccessorHook.h中包含device/types/name/OOBAccessors.h在posix/named_pipe/Hook.h中包含device/types/name/NamedPipeTranslators.h让 SFINAE 探测钩子HasOOBAccessors、HasNamedPipeTranslators在编译期发现注册重载完整细节与示例见 Out-of-Band 控制架构文档。Step 3在构建配置中注册文件[!NOTE] 为保持项目列表整洁构建系统强制字母序排序。请把新设备条目按字母序插入否则 CI 的自动化格式检查会失败。1. 宏模板enabled_devices_config.h.in新增编译期 CMake 钩子该文件是模板最终会通过configure_file()生成app_config/enabled_devices.h#cmakedefine01 ALL_DEVICES_ENABLE_MY_SENSOR2. GN 配置enabled_devices.gni向_available_devices添加设备条目保持排序。该文件以[配置名, 宏后缀]二元组形式维护权威设备清单并通过enabled_devices_buildconfig_header模板为每个设备生成ALL_DEVICES_ENABLE_${NAME}1/0编译宏空设备列表默认表示全部启用_available_devices [ ... [ my-sensor, MY_SENSOR, ], ... ]3. CMake 配置enabled_devices.cmake把.cpp源文件加入ALL_DEVICES_DEVICE_SOURCES保持排序set(ALL_DEVICES_DEVICE_SOURCES # keep-sorted: start ... ${ALL_DEVICES_COMMON_DIR}/device/types/my-sensor/MySensor.cpp ... # keep-sorted: end )同时把设备 key 加入同文件中的激活循环保持排序。该循环会把 keymy-sensor派生为宏名ALL_DEVICES_ENABLE_MY_SENSOR-转_、小写转大写并根据ALL_DEVICES_ENABLED_DEVICES空 全量启用置位foreach(_key # keep-sorted: start ... my-sensor ... # keep-sorted: end )4. Device Factory 依赖BUILD.gn把新设备 target 加入device-factory的public_deps保持排序public_deps [ ... ${chip_root}/examples/all-devices-app/all-devices-common/device/types/my-sensor, ... ]5. 平台可执行文件依赖各BUILD.gn在构建 all-devices-app 的相关平台可执行 target如 examples/all-devices-app/posix/BUILD.gn以及 Silicon Labs、ESP32 等嵌入式平台构建中加入依赖${chip_root}/examples/all-devices-app/all-devices-common/device/types/my-sensor,Step 4扩展构建目标并更新快照为支持默认启用新设备的自动化构建变体扩展 Python 构建目标。1. targets.py打开scripts/build/build/targets.py把设备字符串追加进_ALL_DEVICES_APP_DEVICES保持排序_ALL_DEVICES_APP_DEVICES [ # keep-sorted: start ... my-sensor, ... ]2. 更新构建测试 golden 快照自动 PR 工作流会校验构建变体是否与 golden 快照一致。更新targets.py后scripts/build/test.py会暂时失败直到重新生成 golden 文件在激活的构建环境中运行构建脚本测试这次会失败但会生成实际输出文件scripts/run_in_build_env.sh python3 scripts/build/test.py用新生成的 actual 文件覆盖 golden 快照文件cp all_targets_linux_x64.txt.actual scripts/build/testdata/all_targets_linux_x64.txt rm all_targets_linux_x64.txt.actual重跑测试确认通过输出OKscripts/run_in_build_env.sh python3 scripts/build/test.pyStep 5端到端验证与认证测试1. 编译应用用标准 Python 构建脚本编译可执行文件source scripts/activate.sh ./scripts/build/build_examples.py --target linux-x64-all-devices-clang build2. 执行基本组合验证激活自动化测试虚拟环境并运行核心设备基本组合认证测试。该测试会指示二进制在子端点上动态生成你的新设备source out/venv/bin/activate ./scripts/tests/run_python_test.py \ --factory-reset \ --app ./out/linux-x64-all-devices-clang/all-devices-app \ --app-args --device my-sensor:2 --discriminator 1234 --KVS kvs1 \ --script src/python_testing/TC_DeviceBasicComposition.py \ --script-args --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021确认所有测试用例执行并通过。其中--device my-sensor:2表示把设备部署到端点 2--discriminator与--passcode用于 on-network 方式的配网commissioning。3. 使用chip-tool进行交互测试手动交互验证可编译并使用chip-tool详细的配网设置可参考chip-tool-testingskill从源码编译chip-toolsource scripts/activate.sh ./scripts/build/build_examples.py --target linux-x64-chip-tool-clang build启动配置了你的新设备的应用./out/linux-x64-all-devices-clang/all-devices-app --device my-sensor配网后对新设备端点执行 Interaction Model 的读写命令或自定义 cluster 命令验证数据模型操作符合预期。4. 运行专用 Cluster 认证套件在 src/python_testing/ 中找到与你实现的 cluster 匹配的 Python 集成测试或在 src/app/tests/suites/ 中找到对应 YAML 测试用例通过run_python_test.py执行这些专用测试脚本确保与 Matter 规范完全合规。Step 6更新实现状态文档实现并注册设备后手动更新跟踪文档这些文档维护着设备的认证状态supported_device_types.md 中列出了全部已实现设备及其 Ready / Minimally Ready / Blocked 状态supported_device_types.md把设备类型条目从Unimplemented表移到Implemented表并递增总数。文档中Discovery Updating Methodology一节明确说明DeviceFactory构造函数中的每个RegisterCreator(name, ...)调用都对应一个已实现设备部分平台专属设备如 Linux 上的 Commissioning By Proxy注册于平台覆盖文件 DeviceFactoryPlatformOverride.cpp。supported_clusters.md若设备引入了新 cluster 支持将其Used in All-Devices状态更新为Yes并在Notes/Devices列列出设备类型。README.md更新Supported Devices列表以及Running the Application章节下--deviceCLI 帮助选项示例块。总结在 all-devices-app 中新增一个模拟设备类型核心是规范驱动 架构纪律 全链路接入先用 Matter 规范与本地data_modelXML 确定设备类型 ID 与 cluster 组成再按SingleEndpoint/ 能力基类 / self-delegate logging mock 的既有模式实现设备类随后依次接入DeviceFactory、enabled_devices_config.h.in、enabled_devices.gni、enabled_devices.cmake与各平台BUILD.gn最后通过build_examples.py、TC_DeviceBasicComposition.py与chip-tool完成端到端验证并同步维护supported_device_types.md等跟踪文档。遵循文中强调的注册/销毁顺序与 RAII 事务模式可以确保你的设备在任何平台上都稳定、可测试且符合 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),仅供参考
返回列表