扫设备二维码配网

更新时间:2023-09-27 07:56:09下载pdf

扫码配网是一种通过扫描设备二维码来实现 单设备 快速配网的方式。目前支持的类型有直连设备和蓝牙设备。

配网流程

直连设备

直连设备特指 GPRS、LTE Cat.1 等直接连接的设备类型。

App业务拓展 SDK设备云端设备进入配网模式扫描设备二维码1解析二维码信息调用二维码解析接口2调用二维码解析接口3返回解析结果4返回解析结果5alt[扫描设备]开始激活设备6开始激活设备7返回激活设备列表8返回激活设备列表9alt[激活配网]App业务拓展 SDK设备云端直连设备扫描二维码配网流程

蓝牙扫码

蓝牙设备扫描二维码配网的流程如下:

App业务拓展 SDK设备云端设备进入配网模式扫描设备二维码1解析二维码信息调用二维码解析接口2调用二维码解析接口3返回解析结果4返回解析结果5对比和获取设备信息alt[扫描设备]开始激活设备6开始激活设备7返回激活设备列表8返回激活设备列表9alt[激活配网]App业务拓展 SDK设备云端蓝牙扫描二维码配网流程

二维码解析接口

扫描设备二维码,获取 URL,然后通过通用接口获取设备信息。根据接口返回的参数,确定该二维码是直连设备还是蓝牙扫码设备。

@protocol ThingSmartActivatorRequestProtocol <NSObject>

/// Provide QR code parsing capability
/// @param param Request Parameters
/// @param success Network success callback
/// @param failure Network Failure Callbacks
- (void)requestParseQRCodeWithParam:(ThingActivatorParseQRCodeRequestData *)param success:(void(^)(ThingSmartAScanCodeModel *result))success failure:(ThingActivatorCallbackError)failure;
@end

参数说明

参数 说明
param 请求参数
success 解析成功返回信息
failure 解析失败回调

返回结果说明:

@interface ThingSmartAScanCodeModel : NSObject
@property (nonatomic, strong) NSString * _Nullable actionName;
@property (nonatomic, assign) id _Nullable actionData;
@end

扫码类型如下,具体使用可参考示例代码。

  • 直连设备对应 actionName:“device_net_conn_multi_ver”
  • 蓝牙扫码对应 actionName:“device_net_conn_bind_blue”

注册配网类型

基座初始化时,需要注册一下配网的类型,直连设备对应为 ThingSmartActivatorTypeMQTTDirectlyModel,蓝牙扫码为 ThingSmartActivatorTypeBleModel

/// Initialize network configuration types
/// @param typeList Network configuration types
- (void)registerWithActivatorList:(NSArray<ThingSmartActivatorTypeModel *>*)typeList;

参数说明

参数 说明
typeList 配网类型列表

开始搜索

开始搜索时,需要传入已注册的 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 发现设备,返回此次配网的设备模型,失败时返回 nil
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 待激活设备列表,目前仅支持单个设备

停止激活

接口说明

/// 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 清空缓存设备信息

设备激活回调

接口说明

// 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

错误码说明

配网失败或者配网超时的情况下,会返回 ThingSmartActivatorErrorModel

@interface ThingSmartActivatorErrorModel : NSObject
@property (nonatomic, strong) ThingSmartActivatorDeviceModel *deviceModel;
@property (nonatomic) NSError *error;
@end

其中 error 对应的错误码,定义在 ThingSmartActivatorDiscoveryError 中。

示例代码

直连设备

Swift

class mqttDirectlyModeConfigurationVC: UITableViewController {

    private var token: String = ""
    private var typeModel:ThingSmartActivatorTypeMQTTDirectlyModel = {
        let type = ThingSmartActivatorTypeMQTTDirectlyModel()
        type.type = ThingSmartActivatorType.mqttDirectly
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.mqttDirectly)
        type.timeout = 120
        return type
    }()


    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel])
        discovery.setupDelegate(self)
        discovery.loadConfig()
        return discovery
    }()

    var request: ThingSmartActivatorDiscoveryRequest = {
        let request = ThingSmartActivatorDiscoveryRequest()
        return request
    }()

    private func startConfiguration(qrcode codeStr: String?) -> Void{
        SVProgressHUD.show()
        guard let homeID = Home.current?.homeId else { return }
        self.typeModel.spaceId = homeID

        let requestDate = ThingActivatorParseQRCodeRequestData()
        requestDate.code = codeStr ?? ""
        request.requestParseQRCode(withParam: requestDate) { codeModel in
            if codeModel.actionName == "device_net_conn_multi_ver" {
                self.typeModel.uuid = codeModel.actionData?.object(forKey: "uuid") as! String
                self.discovery.startActive(self.typeModel, deviceList: [])
            }
        } failure: { error in

        }
    }
}

extension mqttDirectlyModeConfigurationVC: 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
        SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
    }
}

Objective-C

- (void)qrParse:(NSString *)url {
   ThingActivatorParseQRCodeRequestData *param = [[ThingActivatorParseQRCodeRequestData alloc] init];
   param.code = url;
   [self.requestService requestParseQRCodeWithParam:param success:^(ThingSmartAScanCodeModel * _Nonnull model) {
       if ([model.actionName isEqualToString:@"device_net_conn_multi_ver"]){
        NSDictionary *dict = result.actionData;
        NSString *uuid = [dict objectForKey:@"uuid"];
        ThingSmartActivatorTypeMQTTDirectlyModel *type = [[ThingSmartActivatorTypeMQTTDirectlyModel alloc] init];
        type.type = ThingSmartActivatorTypeMQTTDirectly;
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeMQTTDirectly);
        type.timeout = 120;
        type.spaceId = [ThingSmartActivatorLinkTool getSpaceId];
        type.uuid = uuid;
        [self startConfigQRCode:type];
       }
   } failure:^(NSError *error) {

   }];
}

- (void)startConfigQRCode:(ThingSmartActivatorTypeMQTTDirectlyModel *)type {

  [self.discovery registerWithActivatorList:@[type]];
  [self.discovery setupDelegate:self];
  [self.discovery startActive:self.typeModel deviceList:@[]];

}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service 
           activatorType:(ThingSmartActivatorTypeModel *)type 
       didReceiveDevices:(NSArray<ThingSmartActivatorDeviceModel *> *)devices 
                   error:(ThingSmartActivatorErrorModel *)errorModel {
    if (errorModel) {
        [self _connectWifiError:errorModel];
        return;
    }

    if (device) {
        [self _handleDevice:device];
    }
}

- (void)_handleDevice:(ThingSmartActivatorDeviceModel *)deviceModel {
}

- (ThingSmartActivatorDiscovery *)discovery {
    if (!_discovery) {
        _discovery = [[ThingSmartActivatorDiscovery alloc] init];
    }
    return _discovery;
}

- (ThingSmartActivatorDiscoveryRequest *)requestService {
    if (!_requestService) {
        _requestService = [[ThingSmartActivatorDiscoveryRequest alloc] init];
    }
    return _requestService;
}

蓝牙扫码

Swift

class BleScanModeConfigurationVC: UITableViewController {

    private var uuid: String = ""
    private var mac: String = ""
    private var typeModel:ThingSmartActivatorTypeBleModel = {
        let type = ThingSmartActivatorTypeBleModel()
        type.type = ThingSmartActivatorType.ble
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
        type.timeout = 120
        type.spaceId = Home.current!.homeId
        return type
    }()


    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel])
        discovery.setupDelegate(self)
        discovery.loadConfig()
        return discovery
    }()

    var request: ThingSmartActivatorDiscoveryRequest = {
        let request = ThingSmartActivatorDiscoveryRequest()
        return request
    }()

    private func startConfiguration(qrcode codeStr: String?) -> Void{
        SVProgressHUD.show()
        let requestDate = ThingActivatorParseQRCodeRequestData()
        requestDate.code = codeStr ?? ""
        request.requestParseQRCode(withParam: requestDate) { codeModel in
            if codeModel.actionName == "device_net_conn_bind_blue" {
                self.uuid = codeModel.actionData?.object(forKey: "uuid") as! String
                self.mac = codeModel.actionData?.object(forKey: "mac") as! String
                self.discovery.startSearch([self.typeModel])
            }
        } failure: { error in

        }
    }
}

extension BleScanModeConfigurationVC: 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
        SVProgressHUD.show(withStatus: "Bind Success. \n devId: \(device?.uniqueID ?? "") \n name: \(device?.name ?? "")")
    }
}

extension BleScanModeConfigurationVC: ThingSmartActivatorSearchDelegate {

    func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
        if (errorModel != nil) {
            // Error
            SVProgressHUD.showError(withStatus: errorModel?.error.localizedDescription)
            return
        }

        if let device = device {
            if device.uniqueID.caseInsensitiveCompare(self.uuid) == .orderedSame ||  device.uniqueID.caseInsensitiveCompare(self.mac) == .orderedSame{
                discovery.currentSpaceId(Home.current!.homeId)
                discovery.startActive(typeModel, deviceList: [device])
            }
        }
    }

    func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didUpdateDevice device: ThingSmartActivatorDeviceModel) {

    }
}

Objective-C

- (void)qrParse:(NSString *)url {
   ThingActivatorParseQRCodeRequestData *param = [[ThingActivatorParseQRCodeRequestData alloc] init];
   param.code = url;

   [self.requestService requestParseQRCodeWithParam:param success:^(ThingSmartAScanCodeModel * _Nonnull model) {
       if ([model.actionName isEqualToString:@"device_net_conn_bind_blue"]){
        NSDictionary *dict = result.actionData;
        self.uuid = [dict objectForKey:@"uuid"];
        self.mac = [dict objectForKey:@"mac"];
        ThingSmartActivatorTypeBleModel *type = [[ThingSmartActivatorTypeBleModel alloc] init];
        type.type = ThingSmartActivatorTypeBle;
        type.scanType = ThingBluetoothScanTypeNoraml | ThingBluetoothScanTypeQRCode;
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeBle);
        type.timeout = self.timeout;

        [self startConfigQRCode:type];
       }
   } failure:^(NSError *error) {

   }];
}

- (void)startConfigQRCode:(ThingSmartActivatorTypeMQTTDirectlyModel *)type {

  [self.discovery registerWithActivatorList:@[type]];
  [self.discovery setupDelegate:self];
  [self.discovery startSearch:@[type]];

}

- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service activatorType:(ThingSmartActivatorTypeModel *)type didFindDevice:(ThingSmartActivatorDeviceModel *)device error:(ThingSmartActivatorErrorModel *)errorModel {
    if (errorModel) {
        [self _connectWifiError:errorModel];
        return;
    }

    if (device) {
        if ((NSOrderedSame == [device.uniqueID caseInsensitiveCompare:self.uuid])|| (NSOrderedSame == [device.uniqueID caseInsensitiveCompare:self.mac]))
        /// Bluetooth scanned the device is the QR code device
        [self _handleDevice:device];
    }
}

- (void)_handleDevice:(ThingSmartActivatorDeviceModel *)deviceModel {
     ThingSmartActivatorTypeBleModel *type = (ThingSmartActivatorTypeBleModel *)[activatorGateway activatorTypeModelWith:ThingSmartActivatorTypeBle];
    [self.discovery startActive:type deviceList:@[deviceModel]];
}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel {
                   if (errorModel) {
        [self _connectWifiError:errorModel];
        return;
    }

    if (device) {
        /// device activated successfully
    }
}

- (ThingSmartActivatorDiscovery *)discovery {
    if (!_discovery) {
        _discovery = [[ThingSmartActivatorDiscovery alloc] init];
    }
    return _discovery;
}

- (ThingSmartActivatorDiscoveryRequest *)requestService {
    if (!_requestService) {
        _requestService = [[ThingSmartActivatorDiscoveryRequest alloc] init];
    }
    return _requestService;
}