Matter 设备管理

更新时间:2024-06-12 10:23:44下载pdf

Matter 协议是 CSA 联盟 与 Google、Amazon、Apple 共同推进的物联网标准连接方案,旨在实现所有 IoT 设备的兼容性,实现一套协议控制所有设备。本文介绍 Matter 设备接入后的相关管理和控制功能。

准备工作

在使用 Matter 设备前,您需要完成 开发项目工程配置 以及 实现 Matter 设备配网,详情请参考 Matter 设备配网 系列文档。

完成上述流程后,即可添加 Matter 设备到 App 中进行使用。

判断 Matter 设备

接口说明

- (BOOL)isSupportMatter;

代码示例

Objective-C:

- (void)judgeSupportMatter {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];
    BOOL isSupport = [self.device.deiceModel isSupportMatter];
    NSLog(@"judgeSupportMatter: %ld", isSupport);
}

Swift:

func judgeSupportMatter() {
    let isSupport = device?.deviceModel?.isSupportMatter()
}

控制 Matter 设备

与普通设备一样,使用 ThingSmartDevice-publishDps:success:failure: 进行下发即可。

Matter 设备目前支持的通道情况如下:

设备类型 支持通道 备注
涂鸦 Matter 基于 Wi-Fi
  • Matter 局域网通道
  • MQTT 通道
涂鸦局域网通道待后续硬件固件支持
涂鸦 Matter 网关
  • Matter 局域网通道
  • 涂鸦局域网通道
  • MQTT 通道
-
涂鸦 Matter Thread 设备
  • Matter 局域网通道
  • 涂鸦局域网通道
  • MQTT 通道
-
三方 Matter 设备 Matter 局域网通道 -

判断 Matter 设备在线状态

与其他设备一样,可以使用 ThingSmartDeviceModelisOnline 字段综合判断设备的在离线状态。

跨 Fabric

跨 Fabric(Multiple Fabrics) 是 Matter 设备的特色功能,让设备基于 Matter 支持跨不同厂商生态使用的特性,可以同时在多个支持 Matter 生态的 App 上激活使用。您的 Matter 设备不仅可以在涂鸦相关的 App(例如 智能生活)中使用,同时也可以苹果 Home、谷歌 Home、亚马逊 Alexa 等等中使用。

Fabric 是 Matter 定义的同一安全域下节点(即设备)的集合,在该安全域下节点能够彼此认证建立安全通信。一个 Fabric 共享同一证书机构(Certificate Authority,CA)的根证书(Root of Trust),同时约定一个唯一 64 位标识符的 Fabric ID。

跨 Fabric 包含 Fabrics 分享Fabrics 管理 两个模块。

通道可用性检查

在使用 Fabrics 分享Fabrics 管理 API 之前,可以使用本方法来判断 App 是否可以和设备进行通讯。

  1. 从智能生活 App SDK 5.2.0 版本开始,SDK 支持了多种通道进行 Fabrics 分享Fabrics 管理,提供了新的前置通道可用性检查方式。
  2. 多通道通讯方式需要设备侧对应的固件支持,新接口内部同样兼容之前的设备,推荐配套迁移到新的方式使用。

大于等于 5.2.0 版本 SDK

接口说明

- (BOOL)checkPipelineAvailable;

代码示例

Objective-C:

- (void)preCheck {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    BOOL available = [self.fabricShare checkPipelineAvailable];
    NSLog(@"fabric pipeline available: %d", available);
}

Swift:

func preCheck() {
    let available = fabricShare.checkPipelineAvailable
    print("fabric pipeline available: \(available)")
}

低于 5.2.0 版本 SDK

接口说明

- (void)getConnectedStatusSuccess:(ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)checkConnectStatus {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare getConnectedStatusSuccess:^{
        NSLog(@"matter device is connected");
    } failure:^(NSError *error) {
        NSLog(@"matter device not connect: %@", error);
    }];
}

Swift:

func checkConnectStatus() {
    fabricShare.getConnectedStatusSuccess {
        print("matter device is connected")
    } failure: { error in
        print("matter device not connect: \(error)")
    }
}

从智能生活 App SDK 5.2.0 版本开始,大幅简化了生成 Multiple Fabric 分享配网码的 API 使用方式,并且支持了多种通道通讯方式以提高成功率。

大于等于 5.2.0 版本 SDK

在使用 API 前建议,配合 大于等于 5.2.0 版本 SDK 通道可用性检查接口 使用。

打开分享配网窗口

内部包含了 读取最大支持 Fabric 数量读取当前已使用 Fabric 数量获取设备连接 SSID 名称关闭配网窗口打开分享配网窗口 这一系列流程阶段,无需像 5.2.0 版本 SDK 一样逐步调用接口,仅需一个接口即可完成上述流程。

接口说明

- (void)sendEnhancedCommissioning:(BOOL)forceRefresh
                         ssidInfo:(nullable void(^)(NSString * __nullable ssid))ssidInfo
                          success:(void(^)(NSString *qrCodeStr, NSString *setupCode))success
                          failure:(nullable ThingFailureError)failure

代码示例

Objective-C:

- (void)openECM {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare sendEnhancedCommissioning:YES ssidInfo:^(NSString * __nullable ssid){
        NSLog(@"device ssid: %@", ssid)
    } success:^(NSString * _Nonnull qrCodeStr, NSString * _Nonnull setupCode) {
        NSLog(@"open ecm success: %@, %@", qrCodeStr, setupCode);
    } failure:^(NSError *error) {
        NSLog(@"open ecm fail: %@", error);
    }];
}

Swift:

func openECM() {
    fabricShare.sendEnhancedCommissioning(true) { ssid in
        print("device ssid: \(ssid)")
    } success: { qrcode, setupCode in
        print("open ecm success: \(qrcode) \(setupCode)")
    } failure: { error in
        print("open ecm fail: \(error)")
    }
}

低于 5.2.0 版本 SDK

需按照业务流程图的说明实现对应流程的 API 调用,在使用 API 前建议配合 低于 5.2.0 版本 SDK 通道可用性检查接口 使用。

读取最大支持 Fabric 数量

通常 Matter 设备根据自身性能的差异,对于最大支持 Fabric 的定义是不同的。

接口说明

- (void)readSupportedFabricsSuccess:(ThingSuccessInt)success
                                                      failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)readMaxSupportFabricsNumber {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare readSupportedFabricsSuccess:^(int maxNum) {
        NSLog(@"max support fabrics number: %i", maxNum);
    } failure:^(NSError *error) {
        NSLog(@"read max support fabrics number fail: %@", error);
    }];
}

Swift:

func readMaxSupportFabricsNumber() {
    fabricShare.readSupportedFabricsSuccess { maxNum in
        print("max support fabrics number: \(maxNum)")
    } failure: { error in
        print("read max support fabrics number fail: \(error)")
    }
}

读取当前已使用 Fabric 数量

接口说明

- (void)readCommissionedFabricsSuccess:(ThingSuccessInt)success failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)readUsedFabricsNumber {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare readCommissionedFabricsSuccess:^(int usedNum) {
        NSLog(@"used fabrics number: %i", usedNum);
    } failure:^(NSError *error) {
        NSLog(@"read used fabrics number fail: %@", error);
    }];
}

Swift:

func readUsedFabricsNumber() {
    fabricShare.readCommissionedFabricsSuccess { usedNum in
        print("used fabrics number: \(usedNum)")
    } failure: { error in
        print("read used fabrics number fail: \(error)")
    }
}

获取设备连接 SSID 名称

Matter Wi-Fi 设备可以获取到设备当前连接的 SSID 名称,对于有线网关和 Thread 设备无法获取到。

接口说明

- (void)getWifiDeviceSsid:(ThingSuccessString)success failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)fetchDeviceConnectWifi {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare getWifiDeviceSsid:^(NSString *result) {
        NSLog(@"now the device connect ssid: %@", result);
    } failure:^(NSError *error) {
        NSLog(@"get the device connect ssid fail: %@", error);
    }];
}

Swift:

func fetchDeviceConnectWifi() {
    fabricShare.getWifiDeviceSsid { ssid in
        print("now the device connect ssid: \(ssid)")
    } failure: { error in
        print("get the device connect ssid fail: \(error)")
    }
}

打开分享配网窗口

先获取 ThingSmartMatterMultipleFabricPasscodeModel 模型对象。

接口说明

// 获取 PasscodeModel 对象
- (void)getMultipleFabricPasscodeCompletion:(void(^)(ThingSmartMatterMultipleFabricPasscodeModel *result, NSError *error))completionBlock;

// 强制刷新获取 PasscodeModel 对象
- (void)getMultipleFabricPasscodeForceRefreshCompletion:(void(^)(ThingSmartMatterMultipleFabricPasscodeModel *result, NSError *error))completionBlock;

代码示例

Objective-C:

- (void)getPassscodeModel {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare getMultipleFabricPasscodeCompletion:^(ThingSmartMatterMultipleFabricPasscodeModel * _Nonnull passcodeModel, NSError * _Nonnull error) {
        if (error) {
            NSLog(@"get passcode model fail: %@", error);
            return;
        }
        NSLog(@"get the passcode model: %@", passcodeModel);
    }];
}

- (void)getRefreshPasscodeModel {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare getMultipleFabricPasscodeForceRefreshCompletion:^(ThingSmartMatterMultipleFabricPasscodeModel * _Nonnull passcodeModel, NSError * _Nonnull error) {
        if (error) {
            NSLog(@"get refresh passcode model fail: %@", error);
            return;
        }
        NSLog(@"get refresh the passcode model: %@", passcodeModel);
    }];
}

Swift:

func getPassscodeModel() {
    fabricShare.getMultipleFabricPasscodeCompletion { passcodeModel, error in
        if error != nil {
            print("get passcode model fail: \(error)")
            return;
        }
        print("get the passcode model: \(passcodeModel)")
    }
}

func getRefreshPasscodeModel() {
    fabricShare.getMultipleFabricPasscodeForceRefreshCompletion { passcodeModel, error in
        if error != nil {
            print("get refresh passcode model fail: \(error)")
            return;
        }
        print("get refresh passcode model: \(passcodeModel)")
    }
}

使用上一步获取到的 passcodeModel 进行打开设备分享配网窗口。

接口说明

- (void)sendEnhancedCommissioningCommandWithFabricPasscodeModel:(ThingSmartMatterMultipleFabricPasscodeModel *)passcodeModel
                                                        success:(void(^)(NSString *qrCodeStr, NSString *setupCode))success
                                                        failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)openECM {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare sendEnhancedCommissioningCommandWithFabricPasscodeModel:passcodeModel success:^(NSString * _Nonnull qrCodeStr, NSString * _Nonnull setupCode) {
        NSLog(@"open ecm success: %@, %@", qrCodeStr, setupCode);
    } failure:^(NSError *error) {
        NSLog(@"open ecm fail: %@", error);
    }];
}

Swift:

func openECM() {
    fabricShare.sendEnhancedCommissioningCommand(with: passcodeModel) { qrCode, setupCode in
        print("open ecm success: \(qrCode) \(setupCode)")
    } failure: { error in
        print("open ecm fail: \(error)")
    }
}

关闭分享配网窗口

由于分享配网窗口不能在已经打开的状态下再次进行打开,所以需要先关闭分享配网窗口,再进行打开配网窗口。

接口说明

- (void)revokeCommissioningCommandSuccess:(ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)revokeCommissioning {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare revokeCommissioningCommandSuccess:^{
        NSLog(@"revoke commission success");
    } failure:^(NSError *error) {
        NSLog(@"revoke commission fail: %@", error);
    }];
}

Swift:

func revokeCommissioning() {
    fabricShare.revokeCommissioningCommandSuccess {
        print("revoke commission success")
    } failure: { error in
        print("revoke commission fail: \(error)")
    }
}

Fabrics 管理

由于 Matter 支持跨生态 App 分享使用,在管理上目前主要提供 获取当前 Fabrics 列表 以及 移除指定 Fabric 这两种类型的 API。

从智能生活 App SDK 5.2.0 版本开始,支持了多种通道通讯方式以提高成功率,Fabric 管理对外 API 使用方式无变化。

获取 Fabric 列表

通过此 API 可以获取到所有能够控制该设备的 Fabric 列表,为执行 移除指定 Fabric 时作为参数数据参考。

接口说明

- (void)readFabricsWithSuccess:(void(^)(NSArray<ThingSmartMatterMultipleFabricInfoModel *> *fabrics))success
                       failure:(nullable ThingFailureError)failure;

数据模型

ThingSmartMatterMultipleFabricInfoModel 模型字段含义说明:

属性 类型 说明
vendorId NSNumber 厂商 ID
nodeId long long 配网时此 Fabric 提供的 nodeId
fabricId long long 配网时此 Fabric 提供的 fabricId
fabricIndex NSInteger 配网时此 Fabric 的 index
label NSString 配网时此 Fabric 提供的 nodeLabel
isCurrent BOOL 是否是当前 App

代码示例

Objective-C:

- (void)fetchFabricList {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare readFabricsWithSuccess:^(NSArray<ThingSmartMatterMultipleFabricInfoModel *> * _Nonnull fabrics) {
        NSLog(@"read fabrics success");
    } failure:^(NSError *error) {
        NSLog(@"read fabrics fail: %@", error);
    }];
}

Swift:

func fetchFabricList() {
    fabricShare.readFabrics { fabricInfoModels in
        print("read fabrics success: \(fabricInfoModels)")
    } failure: { error in
        print("read fabrics fail: \(error)")
    }
}

移除指定的 Fabric

移除某一个 Fabric 后,该 Fabric 将失去控制设备的权利。

移除的 fabricIndex 不能是当前 App 使用的,可以通过 ThingSmartMatterMultipleFabricInfoModelisCurrent 字段判断是否是当前 App。

接口说明

- (void)removeFabricIndex:(NSInteger)fabricIndex
                  success:(ThingSuccessHandler)success
                  failure:(nullable ThingFailureError)failure;

代码示例

Objective-C:

- (void)removeFabricIndex:(NSInteger)fabricIndex {
    // self.fabricShare = [[ThingSmartMatterMultipleFabricShare alloc] initWithDeviceModel:deviceModel];
    [self.fabricShare removeFabricIndex:fabricIndex success:^{
        NSLog(@"remove success");
    } failure:^(NSError *error) {
        NSLog(@"remove fail: %@", error);
    }];
}

Swift:

func remove(fabricIndex: Int) {
    fabricShare.removeFabricIndex(fabricIndex) {
        print("remove success")
    } failure: { error in
        print("remove fail: %@", error)
    }
}

错误码

更多错误码声明可见 ThingSmartMatterKitErrors.h 中。

错误码 说明
3027 设备所有通道均不在线
3051 打开分享配网窗口失败
3037 读取设备属性失败,例如:
  • 获取设备支持分享次数失败
  • 获取设备已使用次数失败
  • 读取设备配网窗口状态失败
  • 获取 fabricList 失败
  • 获取设备基础信息失败
3055 移除设备 fabricIndex 失败
3057 请求云端 API 接口失败,例如,获取云端 Fabric passcode 接口失败
3058 关闭设备配网窗口失败
3059 计算可用 Fabric 次数为零