更新时间:2024-08-22 02:39:40下载pdf
Matter 设备配网支持 Tuya Matter 设备和三方 Matter 设备配网,两者接入的 API 调用一致,但配网表现有不同。Matter 设备配网类型包含自发现、扫描二维码和手动输入编码配网三种方式。
ThingSmartBusinessExtensionKitMatterExtra
组件提供了比 ThingSmartMatterActivator
更多的功能。如果您仍直接在使用 ThingSmartMatterActivator
,请参考 此链接。
在开始接入 Matter 设备之前,您需要对项目工程进行配置。在涂鸦,Matter 设备被分为 涂鸦 Matter 设备 和 其他第三方 Matter 设备。对于第三方 Matter 设备,您需对 Xcode 工程进行额外的 Extension Target 配置。
打开项目设置。
选中 主工程 Target > Signing & Capabilities,单击 + Capability
,如下图所示:
添加 Matter Allow Setup Payload
权限,用于处理 Matter 二维码解析。
添加 App Groups
权限,用于与 Matter Extension Target
共享数据,注意勾选的 App Group Id
需要与 Matter Extension Target
中配置的一致。
添加 Background Modes
权限,勾选 Uses Bluetooth LE accessories
权限,用于保证蓝牙通讯稳定性
配置后最终如图所示:
打开 Xcode 项目设置。
选中 主工程 Target > Info > Custom iOS Target Properties,如下图所示:
蓝牙隐私权限
添加 NSBluetoothPeripheralUsageDescription
权限,用于蓝牙使用隐私声明。
Bonjour 服务权限
Matter 强依赖局域网通信,因此需要在主工程的 Info.plist 文件中配置 Bonjour 服务,代码如下:
<key>NSBonjourServices</key>
<array>
<string>_meshcop._udp</string>
<string>_matter._tcp</string>
<string>_matterc._udp</string>
<string>_matterd._udp</string>
</array>
CocoaPods 建议更新至最新版本。
在 Podfile
文件中添加以下内容:
platform :ios, '9.0'
target 'Your_Project_Name' do
pod "ThingSmartMatterKit"
end
在项目根目录下执行 pod update
命令进行集成。
CocoaPods 的使用请参考 CocoaPods 官方文档。
根据 快速集成 章节指引,在初始化 SDK 完成之后,完成 Matter 模块初始化:
// 初始化 SDK
[[TuyaSmartSDK sharedInstance] startWithAppKey:<#your_app_key#> secretKey:<#your_secret_key#>];
// 初始化 Matter 模块
[ThingSmartMatterActivatorConfig setMatterConfigKey:<#YOUR_APP_GROUP_ID#>];
接口说明
+ (void)setMatterConfigKey:(NSString *)configKey;
参数说明
参数 | 说明 |
---|---|
configKey | 工程 App Group ID |
示例代码
Objective C:
[ThingSmartMatterActivatorConfig setMatterConfigKey:<#YOUR_APP_GROUP_ID#>];
Swift:
ThingSmartMatterActivatorConfig.setMatterKey("YOUR_APP_GROUP_ID")
Matter Extension Target
,使用默认生成的代码文件即可,然后 请跟随本文配置修改代码文件。Matter Extension Target
仅支持 Swift 项目。+ Capability
。App Groups
权限,用于与 主工程 Target
共享数据,注意勾选的 App Group Id
需要与 主工程 Target
中配置的一致。CocoaPods 建议更新至最新版本。
在 Podfile
文件中添加以下内容:
platform :ios, '9.0'
target 'Your_Matter_Extension_Target_Name' do
pod "ThingSmartMatterExtensionKit"
end
在项目根目录下执行 pod update
命令进行集成。
CocoaPods 的使用请参考 CocoaPods 官方文档。
打开 ExtensionTarget
工程中的 RequestHandler.swift
文件,重写 init
方法。
override init()
接口说明
+ (void)setMatterConfigKey:(NSString *)configKey;
参数说明
参数 | 说明 |
---|---|
configKey | 工程 App Group ID |
示例代码
Swift:
override init() {
super.init()
ThingMatterExtensionSupport.shared.setMatterConfigKey(configKey: <#YOUR_APP_GROUP_ID#>)
}
按文档生成 Matter Extension Target 工程后,会在 Extension 工程中看到RequestHandler.swift
文件,API 方法由系统提供,按如下代码调用 ThingSmartMatterExtensionKit
接口。
将 ThingSmartMatterExtensionKit
引入库。
import ThingSmartMatterExtensionKit
按照以下示例代码,在官方自动生成的方法中调用 API。
RequestHandler.swift
中的回调方法均由系统自动生成,不可更改。
override func validateDeviceCredential(_ deviceCredential: MatterAddDeviceExtensionRequestHandler.DeviceCredential) async throws {
ThingMatterExtensionSupport.shared.validateDeviceCredential(deviceCredential)
}
override func selectWi-FiNetwork(from wifiScanResults: [MatterAddDeviceExtensionRequestHandler.Wi-FiScanResult]) async throws -> MatterAddDeviceExtensionRequestHandler.Wi-FiNetworkAssociation {
// Use this function to select a Wi-Fi network for the device if your ecosystem has special requirements.
// Or, return `.defaultSystemNetwork` to use the iOS device's current network.
return ThingMatterExtensionSupport.shared.selectWi-FiNetwork(from: wifiScanResults)
}
override func selectThreadNetwork(from threadScanResults: [MatterAddDeviceExtensionRequestHandler.ThreadScanResult]) async throws -> MatterAddDeviceExtensionRequestHandler.ThreadNetworkAssociation {
// Use this function to select a Thread network for the device if your ecosystem has special requirements.
// Or, return `.defaultSystemNetwork` to use the default Thread network.
return ThingMatterExtensionSupport.shared.selectThreadNetwork(from: threadScanResults)
}
override func commissionDevice(in home: MatterAddDeviceRequest.Home?, onboardingPayload: String, commissioningID: UUID) async throws {
// Use this function to commission the device with your Matter stack.
ThingMatterExtensionSupport.shared.commissionDevice(in: home, onboardingPayload: onboardingPayload, commissioningID: commissioningID)
}
override func rooms(in home: MatterAddDeviceRequest.Home?) async -> [MatterAddDeviceRequest.Room] {
// Use this function to return the rooms your ecosystem manages.
// If your ecosystem manages multiple homes, ensure you are returning rooms that belong to the provided home.
return ThingMatterExtensionSupport.shared.rooms(in: home)
}
override func configureDevice(named name: String, in room: MatterAddDeviceRequest.Room?) async {
// Use this function to configure the (now) commissioned device with the given name and room.
ThingMatterExtensionSupport.shared.configureDevice(named: name, in: room)
}
由于 Matter 设备的特性,其一切能力都建立在 Matter Fabric 网络之上。在使用 Matter 设备配网和控制管理等功能前,您需要调用相关接口进行 Matter 基础信息配置。该配置操作需要在进行 Matter 相关业务处理前完成。
Fabric 是 Matter 定义的同一安全域下节点(即设备)的集合,在该安全域下节点能够彼此认证建立安全通信。一个 Fabric 共享同一证书机构(Certificate Authority,CA)的根证书(Root of Trust),同时约定一个 Fabric ID。
Matter 相关的信息与家庭相关联,因此需在 家庭切换完成 或 家庭首次加载完成 时,调用 - loadFabricWithSpaceId
查询该家庭对应的 Fabric 信息。
接口说明
@interface ThingSmartMatterManager : NSObject
+ (instancetype)sharedInstance;
- (void)loadFabricWithSpaceId:(long long)spaceId
success:(ThingSuccessHandler)success
failure:(ThingFailureError)failure;
@end
参数说明
参数 | 说明 |
---|---|
spaceId | 当前家庭 HomeID |
success | 成功回调 |
failure | 失败回调 |
示例代码
Objective C:
- (void)loadMatterCurrentHomeFabric:(long long)homeId {
// 在完成切换家庭/首次加载家庭完成后调用
[[ThingSmartMatterManager sharedInstance] loadFabricWithSpaceId:homeId success:^{
NSLog(@"load fabric success");
} failure:^(NSError *error) {
NSLog(@"load fabric fail");
}];
}
Swift:
func loadMatterCurrentHomeFabric(homeId: Int64) {
// 在完成切换家庭/首次加载家庭完成后调用
ThingSmartMatterManager.sharedInstance().loadFabric(withSpaceId: homeId) {
print("load fabric success")
} failure: { error in
print("load fabric fail")
}
}
相较于其他涂鸦设备,有部分 Matter 设备信息需要提前处理,必须在 家庭设备 和 Fabric 信息准备 两者加载完成后,调用 - getDevicesFabricNodesWithdevIds:callback:
处理家庭中的 Matter 设备。
接口说明
@interface ThingSmartMatterShareManager : NSObject
+ (instancetype)sharedInstance;
- (void)getDevicesFabricNodesWithdevIds:(NSArray <NSString *>*)devIds callback:(void(^)(NSArray <ThingSmartMatterDeviceNodeModel *>*result))callback;
@end
参数说明
参数 | 说明 |
---|---|
devIds | 设备 ID 列表 |
示例代码
Objective C:
- (void)loadMatterDeviceInfo {
// 在 `- loadFabric` 和 家庭设备加载完成 之后调用
[[ThingSmartMatterShareManager sharedInstance] getDevicesFabricNodesWithdevIds:deviceIdList callback:^(NSArray<ThingSmartMatterDeviceNodeModel *> *result) {
NSLog(@"load matter device node succes");
}];
}
Swift:
func loadMatterDeviceInfo(){
// 在 `- loadFabric` 和 家庭设备加载完成 之后调用
ThingSmartMatterShareManager.sharedInstance().getDevicesFabricNodesWithdevIds(deviceIdList) { modelList in
print("load matter device info success")
}
}
基座初始化时,需要注册一下配网的类型,Matter 配网对应为 ThingSmartActivatorTypeMatterModel
。
接口说明
/// Initialize network configuration types
/// @param typeList Network configuration types
- (void)registerWithActivatorList:(NSArray<ThingSmartActivatorTypeModel *>*)typeList;
参数说明
参数 | 说明 |
---|---|
typeList | 配网类型列表 |
使用涂鸦 SDK 获取配网 Token,然后进行配网。Token 的有效期为 10 分钟,且配置成功后就会失效。再次配网时,需要重新查询 Token。
接口说明
- (void)getTokenWithHomeId:(long long)homeId
success:(ThingSuccessString)success
failure:(ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
homeId | 设备将要绑定到的家庭的 ID |
success | 成功回调,返回配网 Token |
failure | 失败回调,返回失败原因 |
二维码和手动码解析接口,若二维码和手动码错误,则不会返回设备模型。
/// Check the matter code is legal or not. Returns nil if it is invalid.
/// @param qrString The matter QRCode string or Manual Code string.
- (ThingSmartActivatorDeviceModel *)parseSetupCode:(NSString *)qrString;
参数说明
参数 | 说明 |
---|---|
qrString | 二维码或者手动设备码信息 |
开始搜索时,需要传入已注册的 typeList
。
接口说明
/// Start searching
/// @param typeList Network configuration types
- (void)startSearch:(NSArray <ThingSmartActivatorTypeModel *>*)typeList;
参数说明
参数 | 说明 |
---|---|
typeList | 配网类型列表 |
接口说明
/// Stop searching
/// @param typeList Network configuration types
/// @param clearCache Whether to clear the cache
- (void)stopSearch:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;
参数说明
参数 | 说明 |
---|---|
typeList | 配网类型列表 |
clearCache | 是否清空当前搜索设备缓存 |
搜到设备之后,会通过搜索回调返回设备信息。如果失败,则会返回对应的失败信息。
接口说明
/// Device search callback
/// @param service Search instance
/// @param type Network configuration type
/// @param device Discovered device
/// @param errorModel Error callback
- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service
activatorType:(ThingSmartActivatorTypeModel *)type
didFindDevice:(nullable ThingSmartActivatorDeviceModel *)device
error:(nullable ThingSmartActivatorErrorModel *)errorModel;
参数说明
参数 | 说明 |
---|---|
service | 配网服务。 |
type | 配网类型。 |
device | 发现设备,返回此次配网的设备模型。 |
errorModel | 如果配网失败或者超时,返回此模型,成功时返回 nil 。 |
接口说明
/// Activate devices with a single network configuration type
/// @param type Network configuration type
/// @param deviceList Devices to be activated
- (void)startActive:(ThingSmartActivatorTypeModel *)type deviceList:(NSArray<ThingSmartActivatorDeviceModel *>*)deviceList;
参数说明
参数 | 说明 |
---|---|
type | 配网类型 |
deviceList | 待激活设备列表,目前仅支持单个设备 |
SDK 会根据设备广播包自动选择最合适的配网链路,并回调给业务层进行相应的页面显示。共有三种类型,涂鸦链路、分享配网链路以及 MatterSupport 链路。
如您需要支持 MatterSupport 链路配网,请参考 Matter设备接入准备。只有配置完成后,才可以进行 MatterSupport 配网。
/// Discoveryed Matter Device.
/// @param typeModel device type model
- (void)matterDeviceDiscoveryed:(ThingMatterDeviceDiscoveriedType *)typeModel;
参数说明
参数 | 说明 |
---|---|
typeModel | 具体配网链路 |
Matter 设备连接后建立完成密码认证会话建立(Password Authenticated Session Establishment,PASE)会话,将触发 PASE 会话成功回调。
/// Matter commission establish complete, model's type will be known.
/// @param deviceModel Device model.
- (void)matterCommissioningSessionEstablishmentComplete:(ThingSmartActivatorDeviceModel *)deviceModel;
参数说明
参数 | 说明 |
---|---|
deviceModel | PASE 会话阶段的 Matter 设备模型,可用于部分数据提取 |
完成 PASE 会话后,部分关键信息如设备类型等已经可以拿到,如您确认需要激活设备上云,且完成了证书认证会话建立(Certificate Authenticated Session Establishment,CASE)会话的必要参数组装,则需要继续调用该接口完成 CASE 会话建立。
/// @param deviceModel the matter devicemodel.
/// @param typeModel Network configuration type.
- (void)continueCommissionDevice:(ThingSmartActivatorDeviceModel *)deviceModel typeModel:(ThingSmartActivatorTypeMatterModel *)typeModel;
参数说明
参数 | 说明 |
---|---|
deviceModel | PASE 会话阶段完成后回调的 Matter 设备模型,从 matterCommissioningSessionEstablishmentComplete 回调中获取。 |
typeModel | 组装的 CASE 会话参数模型,双模设备需要 ssid 、password ,thread 设备需要 gwDevId 。 |
如果您配对的是一个未经过官方认证的 Matter 设备,那么会触发认证回调。如果触发了该回调,在您选择继续或放弃前,配网流程将会暂停。
// Matter device attestation fails, use `-continueCommissioningDevice:ignoreAttestationFailure:error:` to continue OR interrupt.
///
/// **Notice**
/// Usually app will display an alert view to the user, allowing the user to judge whether to ignore the attestation failure.
///
/// @param device the failure device.
/// @param error the failure error info.
- (void)matterDeviceAttestation:(void *)device error:(NSError * _Nonnull)error;
参数说明
参数 | 说明 |
---|---|
device | 配网链路中的设备对象地址指针 |
error | 未通过认证的错误信息 |
如您认为该设备证书可以被信任,可以调用该接口继续配网。
/// Continue the pairing or NOT.
///
/// **Notice:** Can only be used after the `-matterDeviceAttestation:error:` delegate callback.
///
/// @param device It MUST BE the device object through the `-matterDeviceAttestation:error:` delegate callback.
/// @param ignoreAttestationFailure Ignore the attestation fail or NOT. `YES` - continue pairing, `NO` - interrupt pairing.
/// @param error the error info.
- (void)continueCommissioningDevice:(void *)device
ignoreAttestationFailure:(BOOL)ignoreAttestationFailure
error:(NSError * __autoreleasing *)error;
参数说明
参数 | 说明 |
---|---|
device | Attestation 回调方法中的设备对象地址指针,必须透传回调上来的参数,不可进行其他操作 |
ignoreAttestationFailure | 是否忽略未认证信息 |
error | 该操作执行后可能的错误信息 |
// Device network configuration result callback
/// @param service Device network configuration implementation object
/// @param type Network configuration type
/// @param devices Devices being configured
/// @param errorModel Error encountered during network configuration
- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
activatorType:(ThingSmartActivatorTypeModel *)type
didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
error:(nullable ThingSmartActivatorErrorModel *)errorModel;
参数说明
参数 | 说明 |
---|---|
service | 配网服务 |
type | 配网类型 |
devices | 激活成功设备 |
errorModel | 如果配网失败或者超时,返回此模型,成功时返回 nil |
接口说明
/// Stop activating devices
/// @param typeList Array of network configuration types
/// @param clearCache Whether to clear the cache
- (void)stopActive:(NSArray <ThingSmartActivatorTypeModel *>*)typeList clearCache:(BOOL)clearCache;
参数说明
参数 | 说明 |
---|---|
typeList | 配网类型 |
clearCache | 清空缓存设备信息 |
配网失败或者配网超时的情况下,会返回 ThingSmartActivatorErrorModel
。
@interface ThingSmartActivatorErrorModel : NSObject
@property (nonatomic, strong) ThingSmartActivatorDeviceModel *deviceModel;
@property (nonatomic) NSError *error;
@end
其中 error 对应的错误码,定义在 ThingSmartActivatorDiscoveryError 中。
Swift
class BEMatterTableViewController: UITableViewController {
private var typeModel: ThingSmartActivatorTypeMatterModel = {
let type = ThingSmartActivatorTypeMatterModel()
type.type = ThingSmartActivatorType.matter
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.matter)
type.timeout = 180
return type
}()
lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.typeModel])
discovery.setupDelegate(self)
discovery.loadConfig()
return discovery
}()
func bindMatter(qrcode codeStr: String?) -> Void {
let homeId = (Home.current?.homeId)!
let payload = self.discovery.parseSetupCode(codeStr ?? "")
let activator = ThingSmartActivator()
activator.getTokenWithHomeId(homeId, success: { [weak self] (token) in
guard let self = self else { return }
self.typeModel.token = token ?? ""
self.typeModel.spaceId = homeId
self.discovery.startActive(self.typeModel, deviceList:[payload])
SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
}, failure: { (error) in
let errorMessage = error?.localizedDescription ?? ""
SVProgressHUD.showError(withStatus: errorMessage)
})
}
private func stopConfigWifi() {
SVProgressHUD.dismiss()
discovery.stopActive([typeModel], clearCache: true)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
discovery.startSearch([self.typeModel])
}
}
extension BEMatterTableViewController: ThingSmartActivatorSearchDelegate {
func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
if let device = device {
if device.deviceModelType == ThingSearchDeviceModelTypeMatterWifi {
self.typeModel.ssid = ssid.text ?? ""
self.typeModel.password = password.text ?? ""
print("Please use Dual Mode to pair: %@", device.uniqueID)
}
if device.deviceModelType == ThingSearchDeviceModelTypeMatterThread {
self.typeModel.gwDevId = "gateway deivce id"
}
let homeId = (Home.current?.homeId)!
let payload = self.discovery.parseSetupCode(codeStr ?? "")
let activator = ThingSmartActivator()
activator.getTokenWithHomeId(homeId, success: { [weak self] (token) in
guard let self = self else { return }
self.typeModel.token = token ?? ""
self.typeModel.spaceId = homeId
self.discovery.startActive(self.typeModel, deviceList:[payload])
SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
}, failure: { (error) in
let errorMessage = error?.localizedDescription ?? ""
SVProgressHUD.showError(withStatus: errorMessage)
})
}
if let errorModel = errorModel {
// Error
SVProgressHUD.showError(withStatus: errorModel.error.localizedDescription)
}
}
}
extension BEMatterTableViewController: ThingSmartActivatorActiveDelegate {
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if errorModel != nil {
SVProgressHUD.showError(withStatus: "Bind Failure. (\(errorModel?.error.localizedDescription ?? ""))")
return
}
let device = devices?.first
isSuccess = true
SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
}
}
extension BEMatterTableViewController: ThingSmartActivatorDeviceExpandDelegate {
func matterDeviceDiscoveryed(_ typeModel: ThingMatterDeviceDiscoveriedType) {
deviceTypeModel = typeModel
}
func matterCommissioningSessionEstablishmentComplete(_ deviceModel: ThingSmartActivatorDeviceModel) {
if deviceTypeModel?.deviceType == .wifi {
self.typeModel.ssid = ssid.text ?? ""
self.typeModel.password = password.text ?? ""
self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
}
///
if deviceTypeModel?.deviceType == .thread {
self.typeModel.gwDevId = "your gateway id"
self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
}
}
func matterDeviceAttestation(_ device: UnsafeMutableRawPointer, error: Error) {
let alertControl = UIAlertController(title: "Attestation", message: "Should Continue?", preferredStyle: .alert)
let alertAction = UIAlertAction(title: "Continue", style: .default) { _ in
self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: true, error: nil)
}
let canAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: false, error: nil)
}
alertControl.addAction(alertAction)
alertControl.addAction(canAction)
self.present(alertControl, animated: true)
}
}
Objective-C
- (void)getToken {
ThingSmartActivator *wiredActivator = [[ThingSmartActivator alloc] init];
[wiredActivator getTokenWithHomeId:homeId success:^(NSString *token) {
NSLog(@"getToken success: %@", token);
[self startConfigWiFi:token];
} failure:^(NSError *error) {
NSLog(@"getToken failure: %@", error.localizedDescription);
}];
}
- (void)startConfigWiFi:(NSString *)token {
ThingSmartActivatorTypeMatterModel *matterType = [[ThingSmartActivatorTypeMatterModel alloc] init];
matterType.type = ThingSmartActivatorTypeMatter;
matterType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeMatter);
matterType.timeout = 120;
matterType.spaceId = homeId;
matterType.token = token;
[self.discovery registerWithActivatorList:@[matterType]];
[self.discovery setupDelegate:self];
[self.discovery startSearch:@[matterType]];
}
- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service activatorType:(ThingSmartActivatorTypeModel *)type didFindDevice:(ThingSmartActivatorDeviceModel *)device error:(ThingSmartActivatorErrorModel *)errorModel {
if (errorModel) {
[self _connectWifiError:errorModel];
return;
}
if (device) {
[self _handleDevice:device];
}
}
- (void)_handleDevice:(ThingSmartActivatorDeviceModel *)deviceModel {
ThingSmartActivatorTypeMatterModel *matterType = (ThingSmartActivatorTypeMatterModel *)[self.discovery activatorTypeModelWith:ThingSmartActivatorTypeMatter];
[self.discovery startActive:matterType deviceList:@[deviceModel]];
}
- (void)matterRoutingComplete:(ThingSmartMatterRoutingType)routingType {
self.routingType = routingType;
if (routingType == ThingSmartMatterRoutingTypeSupport) {
}
}
-(void)matterCommissioningSessionEstablishmentComplete:(ThingSmartActivatorDeviceModel *)deviceModel {
if (self.routingType == ThingSmartMatterRoutingTypeThing && deviceModel.deviceModelType == ThingSearchDeviceModelTypeMatterThread) {
self.matterType..gwDevId = gatewayID;
[self.discovery continueCommissionDevice:deviceModel typeModel:self.matterType];
}
if (self.routingType == ThingSmartMatterRoutingTypeThing && deviceModel.deviceModelType == ThingSearchDeviceModelTypeMatterWifi) {
self.matterType.ssid = factoryConfig.ssid;
self.matterType.password = factoryConfig.password;
[self.discovery continueCommissionDevice:deviceModel typeModel:self.matterType];
}
}
- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
activatorType:(ThingSmartActivatorTypeModel *)type
didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
error:(nullable ThingSmartActivatorErrorModel *)errorModel {
if (devices && devices.count > 0) {
}
}
- (ThingSmartActivatorDiscovery *)discovery {
if (!_discovery) {
_discovery = [[ThingSmartActivatorDiscovery alloc] init];
}
return _discovery;
}
Swift
class BEMatterTableViewController: UITableViewController {
/// UI 部分
private var typeModel: ThingSmartActivatorTypeMatterModel = {
let type = ThingSmartActivatorTypeMatterModel()
type.type = ThingSmartActivatorType.matter
type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.matter)
type.timeout = 180
return type
}()
lazy var discovery: ThingSmartActivatorDiscovery = {
let discovery = ThingSmartActivatorDiscovery()
discovery.register(withActivatorList: [self.typeModel])
discovery.setupDelegate(self)
discovery.loadConfig()
return discovery
}()
func bindMatter(qrcode codeStr: String?) -> Void {
let homeId = (Home.current?.homeId)!
let payload = self.discovery.parseSetupCode(codeStr ?? "")
let activator = ThingSmartActivator()
activator.getTokenWithHomeId(homeId, success: { [weak self] (token) in
guard let self = self else { return }
self.typeModel.token = token ?? ""
self.typeModel.spaceId = homeId
self.discovery.startActive(self.typeModel, deviceList:[payload])
SVProgressHUD.show(withStatus: NSLocalizedString("Configuring", comment: ""))
}, failure: { (error) in
let errorMessage = error?.localizedDescription ?? ""
SVProgressHUD.showError(withStatus: errorMessage)
})
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = QRCodeScanerViewController()
vc.scanCallback = { [weak self] codeStr in
self?.bindMatter(qrcode: codeStr)
}
navigationController?.pushViewController(vc, animated: true)
}
}
extension BEMatterTableViewController: ThingSmartActivatorActiveDelegate {
func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
if errorModel != nil {
SVProgressHUD.showError(withStatus: "Bind Failure. (\(errorModel?.error.localizedDescription ?? ""))")
return
}
let device = devices?.first
isSuccess = true
SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
}
}
extension BEMatterTableViewController: ThingSmartActivatorDeviceExpandDelegate {
func matterDeviceDiscoveryed(_ typeModel: ThingMatterDeviceDiscoveriedType) {
deviceTypeModel = typeModel
}
func matterCommissioningSessionEstablishmentComplete(_ deviceModel: ThingSmartActivatorDeviceModel) {
if deviceTypeModel?.deviceType == .wifi {
self.typeModel.ssid = ssid.text ?? ""
self.typeModel.password = password.text ?? ""
self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
}
///
if deviceTypeModel?.deviceType == .thread {
self.typeModel.gwDevId = "your gateway id"
self.discovery.continueCommissionDevice(deviceModel, typeModel: self.typeModel)
}
}
func matterDeviceAttestation(_ device: UnsafeMutableRawPointer, error: Error) {
let alertControl = UIAlertController(title: "Attestation", message: "Should Continue?", preferredStyle: .alert)
let alertAction = UIAlertAction(title: "Continue", style: .default) { _ in
self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: true, error: nil)
}
let canAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
self.discovery.continueCommissioningDevice(device, ignoreAttestationFailure: false, error: nil)
}
alertControl.addAction(alertAction)
alertControl.addAction(canAction)
self.present(alertControl, animated: true)
}
}
Objective-C
- (void)getToken {
ThingSmartActivator *wiredActivator = [[ThingSmartActivator alloc] init];
[wiredActivator getTokenWithHomeId:homeId success:^(NSString *token) {
NSLog(@"getToken success: %@", token);
[self startConfigWiFi:token];
} failure:^(NSError *error) {
NSLog(@"getToken failure: %@", error.localizedDescription);
}];
}
- (void)startConfigWiFi:(NSString *)token {
ThingSmartActivatorTypeMatterModel *matterType = [[ThingSmartActivatorTypeMatterModel alloc] init];
matterType.type = ThingSmartActivatorTypeMatter;
matterType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeMatter);
matterType.timeout = 120;
matterType.spaceId = homeId;
matterType.token = token;
[self.discovery registerWithActivatorList:@[matterType]];
[self.discovery setupDelegate:self];
ThingSmartActivatorDeviceModel *deviceModel = [self.discovery parseSetupCode:code];
if (deviceModel) {
[self.discovery startActive:matterType deviceList:@[deviceModel]];
} else {
}
}
//Follow-up processing logic is consistent with search activate
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈