更新时间:2023-10-10 10:22:06下载pdf
Matter 设备配网支持 Tuya Matter 设备和三方 Matter 设备配网,两者接入的 API 调用一致,但配网表现有不同。Matter 设备配网类型包含自发现、扫描二维码和手动输入编码配网三种方式。
基座初始化时,需要注册一下配网的类型,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
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈