蓝牙设备配网

更新时间:2024-01-04 07:33:09下载pdf

蓝牙设备配网包含蓝牙设备搜索和配网,其中蓝牙设备包含蓝牙单点、蓝牙 Mesh、双模设备、beacon 等类型。

蓝牙类型 说明 设备应用示例
蓝牙单点 蓝牙设备与手机一对一连接单点设备(蓝牙或低功耗蓝牙) 体脂秤、手环、温控器、电动牙刷、门锁等
蓝牙 Mesh 蓝牙技术联盟发布的蓝牙拓扑通信 一路、二路、五路等灯泡、插座、传感器等子设备
双模设备 一些多协议设备也会使用到蓝牙技术,例如同时具备 Wi-Fi 能力和蓝牙能力的 双模设备 蓝牙 Mesh 网关、IPC 设备、新版多协议 Wi-Fi 设备等
Beacon Beacon 是建立在低功耗蓝牙协议基础上的一种广播协议 灯、风扇、遥控器、体脂秤等设备

蓝牙功能是可以裁剪的。如果不需要,则无需依赖以下组件:ThingBLEHomeManagerThingBLEInterfaceImplThingBLEMeshInterfaceImpl

配网流程

App业务拓展 SDK设备云端设备进入配网模式开始查找设备获取设备信息返回设备信息alt[查找设备]请求激活设备开始激活向云端激活设备激活成功返回激活的设备列表返回激活的设备列表alt[设备激活配网]App业务拓展 SDK设备云端蓝牙设备激活配网流程

注册配网类型

基座初始化时,需要注册一下配网的类型。

设备类型 配网类型 模型
蓝牙单点、双模 ThingSmartActivatorTypeBle ThingSmartActivatorTypeBleModel
蓝牙 Mesh ThingSmartActivatorTypeSigMesh ThingSmartActivatorTypeSigMeshModel
Beacon ThingSmartActivatorTypeBeacon ThingSmartActivatorTypeBeaconModel
/// Initialize network configuration types
/// @param typeList Network configuration types
- (void)registerWithActivatorList:(NSArray<ThingSmartActivatorTypeModel *>*)typeList;

参数说明

参数 说明
typeList 配网类型列表

查询 Token

使用涂鸦 SDK 获取配网 Token,然后进行设备配网。Token 的有效期为 10 分钟,且配置成功后就会失效。再次配网时,需要重新查询 Token。

接口说明

- (void)getTokenWithHomeId:(long long)homeId
                   success:(ThingSuccessString)success
                   failure:(ThingFailureError)failure;

参数说明

参数 说明
homeId 设备将要绑定到的家庭的 ID
success 成功回调,返回配网 Token
failure 失败回调,返回失败原因

开始搜索

开始搜索时,需要传入已注册的 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 搜索蓝牙设备时,未搜到设备以及搜索超时的情况下均不返回此模型

设备激活

接口说明

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

扫描 Wi-Fi 列表

双模设备配网失败出现以下错误码时,可以使用该方法扫描设备周围 Wi-Fi 列表,选择其中一个 Wi-Fi 信息,然后调用恢复配网方法,重新配网。

待配网设备的嵌入式固件基线版本必须大于等于 3.6.0,否则不支持扫描 Wi-Fi 列表功能。

错误码 说明
ThingSmartActivatorDiscoveryErrorResumeConfigInfoError 配网信息错误
ThingSmartActivatorDiscoveryErrorResumeRouterNotFound 路由器找不到
ThingSmartActivatorDiscoveryErrorResumeRouterConnectFailed 路由器连接失败
ThingSmartActivatorDiscoveryErrorResumeDHCPError DHCP 失败

接口说明

- (void)scanWifiList:(ThingSmartActivatorScanWifiParam *)param
       activatorType:(ThingSmartActivatorType)activatorType
             success:(void(^)(NSArray<ThingSmartActivatorScanWifiModel *> *list))success
             failure:(void(^)(NSError * _Nullable error))failure;

参数说明

参数 说明
param 扫描入参
activatorType 配网类型
success 扫描成功的 Wi-Fi 列表
failure 扫描失败回调,成功时返回 nil

恢复配网

双模设备配网报错出现以下错误码时,重新选择 Wi-Fi 后,可调用此方法重新配网。其中密码失败可以输入正确密码后恢复配网。

待配网设备的嵌入式固件基线版本必须大于等于 3.6.0,否则不支持恢复配网功能。

错误码 说明
ThingSmartActivatorDiscoveryErrorResumeConfigInfoError 配网信息错误
ThingSmartActivatorDiscoveryErrorResumeRouterNotFound 路由器找不到
ThingSmartActivatorDiscoveryErrorResumeRouterConnectFailed 路由器连接失败
ThingSmartActivatorDiscoveryErrorResumeDHCPError DHCP 失败
ThingSmartActivatorDiscoveryErrorResumeWrongPassword 密码失败

接口说明

/// Restore Wi-Fi network configuration
/// @param param Restore network configuration parameters
/// @param activatorType Network configuration type
/// @param success Success block
/// @param failure Failure block
- (void)resumeConfigWifi:(ThingSmartActivatorResumeConfigWiFiParam *)param
           activatorType:(ThingSmartActivatorType)activatorType
                 success:(void(^)(void))success
                 failure:(void(^)(ThingSmartActivatorErrorModel * _Nullable error))failure;

参数说明

参数 说明
param 恢复配网入参
activatorType 配网类型
success 接口调用成功回调
errorModel 失败回调

错误码说明

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

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

其中 error 对应的错误码,定义在 ThingSmartActivatorDiscoveryError 中。下表展示了常见错误与说明。

错误码 配网错误
ThingSmartActivatorDiscoveryErrorTimeout 配网超时。
ThingSmartActivatorDiscoveryErrorDeviceAlreadyBound 设备强绑定错误。该设备已经被用户绑定,无法被第二个用户绑定,需要第一个用户解绑才能完成配网操作。
ThingSmartActivatorDiscoveryErrorAPPUnsupportProduct 配网账号的 App 和产品没有绑定关系。
ThingSmartActivatorDiscoveryErrorTokenExpired Token 失效。
ThingSmartActivatorDiscoveryErrorGuestNotSupportStrongBind 游客模式无法对强绑定设备进行配网。
ThingSmartActivatorDiscoveryErrorBleScanExpired 设备扫描信息过期,即设备已不再处于配网状态。
ThingSmartActivatorDiscoveryErrorResumeConfigInfoError 配网信息错误。遇到该错误可调用扫描 Wi-Fi 设备列表方法,选择 Wi-Fi 信息之后重新配网。具体参考代码示例。
ThingSmartActivatorDiscoveryErrorResumeRouterNotFound 找不到路由器。遇到该错误可调用扫描 Wi-Fi 设备列表方法,选择 Wi-Fi 信息之后重新配网。具体参考代码示例。
ThingSmartActivatorDiscoveryErrorResumeWrongPassword 密码错误。遇到该错误可输入 Wi-Fi 密码重新配网。具体参考代码示例。
ThingSmartActivatorDiscoveryErrorResumeRouterConnectFailed 连不上路由器。遇到该错误可调用扫描 Wi-Fi 设备列表方法,选择 Wi-Fi 信息之后重新配网。具体参考代码示例。
ThingSmartActivatorDiscoveryErrorResumeDHCPError DHCP 解析错误。遇到该错误可调用扫描 Wi-Fi 设备列表方法,选择 Wi-Fi 信息之后重新配网。具体参考代码示例。

示例代码

蓝牙设备搜索

Swift

class BleScanModeTableViewController: UIViewController {

    var deviceList:[ThingSmartActivatorDeviceModel] = []

    private var typeModel: ThingSmartActivatorTypeBleModel = {
        let type = ThingSmartActivatorTypeBleModel()
        type.type = ThingSmartActivatorType.ble
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
        type.timeout = 120
        if let currentHome = Home.current {
            type.spaceId = currentHome.homeId
        } else {
            assert((Home.current != nil),"Home cannot be nil, need to create a Home")
        }
        return type
    }()

    private var sigModel: ThingSmartActivatorTypeSigMeshModel = {
        let type = ThingSmartActivatorTypeSigMeshModel()
        type.type = ThingSmartActivatorType.sigMesh
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.sigMesh)
        type.timeout = 120
        if let currentHome = Home.current {
            type.spaceId = currentHome.homeId
        } else {
            assert((Home.current != nil),"Home cannot be nil, need to create a Home")
        }
        return type
    }()

    private var beaconModel: ThingSmartActivatorTypeBeaconModel = {
        let type = ThingSmartActivatorTypeBeaconModel()
        type.type = ThingSmartActivatorType.beacon
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.beacon)
        type.timeout = 120
        return type
    }()

    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel,self.sigModel,self.beaconModel])
        discovery.setupDelegate(self)
        discovery.loadConfig()
        if let currentHome = Home.current {
            discovery.currentSpaceId(currentHome.homeId)
        } else {
            assert((Home.current != nil),"Home cannot be nil, need to create a Home")
        }
        return discovery
    }()

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        stopConfiguring()
    }

    @IBAction func searchTapped(_ sender: UIBarButtonItem) {
        discovery.startSearch([self.typeModel,self.sigModel,self.beaconModel])

        SVProgressHUD.show(withStatus: NSLocalizedString("Searching", comment: ""))

    }

    // MARK: - Private method
    private func stopConfiguring() {
        if !isSuccess {
            SVProgressHUD.dismiss()
        }

        discovery.stopSearch([self.typeModel,self.sigModel,self.beaconModel], clearCache: true)
        discovery.stopActive([self.typeModel,self.sigModel,self.beaconModel], clearCache: true)
        discovery.removeDelegate(self)
    }
}

// MARK: - ThingSmartActivatorSearchDelegate
extension BleScanModeTableViewController: ThingSmartActivatorSearchDelegate {
    func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {

        if var device = device {
            if device.deviceModelType == ThingSearchDeviceModelTypeBle {

            } else if device.deviceModelType == ThingSearchDeviceModelTypeSigMeshSubDevice {

            } else if device.deviceModelType == ThingSearchDeviceModelTypeBeacon {

            }
            deviceList.append(device)
        }
    }

}

Objective-C

- (void)scanBleDevice {
    ThingSmartActivatorTypeBleModel *bleModel  = [[ThingSmartActivatorTypeBleModel alloc] init];
    bleModel.type = ThingSmartActivatorTypeBle;
    bleModel.scanType = ThingBluetoothScanTypeNoraml;
    bleModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeBle);
    bleModel.spaceId = [ThingSmartActivatorLinkTool getSpaceId];
    bleModel.timeout = 120;

    ThingSmartActivatorTypeSigMeshModel *sigModel  = [[ThingSmartActivatorTypeSigMeshModel alloc] init];
    sigModel.type = ThingSmartActivatorTypeSigMesh;
    sigModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeSigMesh);
    sigModel.spaceId =[ThingSmartActivatorLinkTool getSpaceId];
    sigModel.timeout = 120;

    ThingSmartActivatorTypeBeaconModel *beaconModel = [[ThingSmartActivatorTypeBeaconModel alloc] init];
    beaconModel.type = ThingSmartActivatorTypeBeacon;
    beaconModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeBeacon);
    beaconModel.timeout = 120;

    [self.typeList addObject:bleModel];
    [self.typeList addObject:sigModel];
    [self.typeList addObject:beaconModel];

    [self.discovery registerWithActivatorList:self.typeList];
    [self.discovery setupDelegate:self];

    /// start search
    [self.discovery startSearch:self.typeList];

}

/// Device search callback, multiple times if multiple devices are searched for
- (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 {
    /// Device Type
    switch(deviceModel.deviceModelType){
      case ThingSearchDeviceModelTypeBle: {
         ThingSmartActivatorTypeBleModel *bleModel = (ThingSmartActivatorTypeBleModel *)[self.discovery activatorTypeModelWith:ThingSmartActivatorTypeBle];
         [self startActive:bleModel device:deviceModel];
      }
        break;
      case ThingSearchDeviceModelTypeBleWifi:{
         ThingSmartActivatorTypeBleModel *bleModel = (ThingSmartActivatorTypeBleModel *)[self.discovery activatorTypeModelWith:ThingSmartActivatorTypeBle];
         [self startActive:bleModel device:deviceModel];
      }
        break;
      case ThingSearchDeviceModelTypeBeacon:{
        ThingSmartActivatorTypeBeaconModel *beaconModel = (ThingSmartActivatorTypeBeaconModel *)[self.discovery activatorTypeModelWith:ThingSmartActivatorTypeBeaconModel];
         [self startActive:beaconModel device:deviceModel];
      }
        break;
      case ThingSearchDeviceModelTypeSigMeshSubDevice:{
        ThingSmartActivatorTypeSigMeshModel *sigModel = (ThingSmartActivatorTypeSigMeshModel *)[self.discovery activatorTypeModelWith:ThingSmartActivatorTypeSigMesh];
         [self startActive:sigModel device:deviceModel];
      }
        break;
    }
}

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

单点设备配网

单点设备只能串行进行添加。

Swift

func startConfiguring() {
        discovery.startActive(bleModel, deviceList: [deviceMode])
}

extension BleScanModeTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if (errorModel != nil) {
            SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate BLE Device", comment: ""))
            return
        }

        if (devices!.count > 0) {
            let device = devices?.first
            let name = device?.name ?? NSLocalizedString("Unknown Name", comment: "Unknown name device.")
            SVProgressHUD.showSuccess(withStatus: NSLocalizedString("Successfully Added \(name)", comment: "Successfully added one device."))
        }
    }
}

Objective-C

- (void)startActive:(ThingSmartActivatorTypeModel *)type device:(ThingSmartActivatorDeviceModel *)device {
     [self.discovery startActive:bleModel deviceList:@[device]];
}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel {
     if (devices && devices.count > 0) {
         // handle devices
     }
}

双模设备配网

双模设备只能串行进行添加。

设备基线大于 3.6.0 的设备,出现以下错误,可以重新输入 Wi-Fi 密码,恢复配网。

Swift

func startConfiguring() {
        typeModel.ssid = ssidTextField.text ?? ""
        typeModel.password = ssidTextField.text ?? ""
        discovery.startActive(typeModel, deviceList: [deviceMode])
}

extension BleScanModeTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if let errorModel = errorModel {
            let code = errorModel.error

            SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate BLE Device", comment: ""))
            return
        }

        if let devices = devices {
            let device = devices.first
            var successDevice: ThingSmartActivatorDeviceModel?

            self.searchDeviceList.forEach { obj in
                if device!.isEqual(toDevice: obj) {
                    successDevice = obj
                }
            }

            successDevice?.deviceStatus = ThingSearchDeviceStatusNetwork
            tableview.reloadData()
        }
}

Objective-C

- (void)startActive:(ThingSmartActivatorTypeModel *)type device:(ThingSmartActivatorDeviceModel *)device {
     ThingSmartActivatorTypeBleModel *bleModel = (ThingSmartActivatorTypeBleModel *)type;

     bleModel.ssid = selectSsid;
     bleModel.password = selectPassword;
     [self.discovery startActive:type deviceList:@[device]];
}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel {

     NSInteger code = errorModel.error.code;
    if (code == ThingSmartActivatorDiscoveryErrorResumeWrongPassword) {
        /// Prompts the user that the password is wrong, re-enter the password
        ThingSmartActivatorResumeConfigWiFiParam *wifiParam = [self getwifiInfo];

        // Resume activate
        [self.discovery resumeConfigWifi:wifiParam activatorType:self.typeModel.type success:^{

        } failure:^(ThingSmartActivatorErrorModel * _Nullable error) {
            ThingLogDebug(@"[LinkModeAP] ret:%ld", error.error.code);
        }];
        return;

    }
    else if (code == ThingSmartActivatorDiscoveryErrorResumeRouterNotFound || code == ThingSmartActivatorDiscoveryErrorResumeConfigInfoError || code == ThingSmartActivatorDiscoveryErrorResumeRouterConnectFailed || code == ThingSmartActivatorDiscoveryErrorResumeDHCPError) {
        /// Scan the list of surrounding WiFi and reactivate the network after selection
        [self.discovery scanWifiList:scanWifiParam
                       activatorType:ThingSmartActivatorTypeBle
                             success:^(NSArray<ThingSmartActivatorScanWifiModel *> * _Nonnull list) {
            if (list.count == 0) {
                return;
            }

        ThingSmartActivatorResumeConfigWiFiParam *wifiParam = [self getwifiInfo:list];
        [self.discovery resumeConfigWifi:wifiParam activatorType:self.typeModel.type success:^{

        } failure:^(ThingSmartActivatorErrorModel * _Nullable error) {
            ThingLogDebug(@"[LinkModeAP] ret:%ld", error.error.code);
        }];

        } failure:^(NSError * _Nullable error) {
        }];
        return;
    }

    if (devices && devices.count > 0) {
        /// handle devices
    }
}

蓝牙 Mesh 设备配网

蓝牙 Mesh 设备可以批量配网,搜索到多个蓝牙 Mesh,可以一起进行激活配网。

Swift

func startConfiguring() {
        discovery.startActive(typeModel, deviceList: [sigModel])
}

extension BleScanModeTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if let errorModel = errorModel {
            let code = errorModel.error

            SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate BLE Device", comment: ""))
            return
        }

        if let devices = devices {
            let device = devices.first
            var successDevice: ThingSmartActivatorDeviceModel?

            self.searchDeviceList.forEach { obj in
                if device!.isEqual(toDevice: obj) {
                    successDevice = obj
                }
            }

            successDevice?.deviceStatus = ThingSearchDeviceStatusNetwork
            tableview.reloadData()
        }
}

Objective-C

- (void)startActive:(ThingSmartActivatorTypeModel *)type device:(ThingSmartActivatorDeviceModel *)device {
     [self.discovery startActive:type deviceList:@[device]];
}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel {
     if (devices && devices.count > 0) {
        // handle devices
     }
}

Beacon 设备配网

Beacon 设备可以批量配网,搜索到多个 beacon,可以一起进行激活配网。

Swift

func startConfiguring() {
        discovery.startActive(typeModel, deviceList: [beaconModel])
}

extension BleScanModeTableViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if let errorModel = errorModel {
            let code = errorModel.error

            SVProgressHUD.showError(withStatus: NSLocalizedString("Failed to Activate BLE Device", comment: ""))
            return
        }

        if let devices = devices {
            let device = devices.first
            var successDevice: ThingSmartActivatorDeviceModel?

            self.searchDeviceList.forEach { obj in
                if device!.isEqual(toDevice: obj) {
                    successDevice = obj
                }
            }

            successDevice?.deviceStatus = ThingSearchDeviceStatusNetwork
            tableview.reloadData()
        }
}

Objective-C

- (void)startActive:(ThingSmartActivatorTypeModel *)type device:(ThingSmartActivatorDeviceModel *)device {
     [self.discovery startActive:type deviceList:@[device]];
}

- (void)activatorService:(id<ThingSmartActivatorActiveProtocol>)service
           activatorType:(ThingSmartActivatorTypeModel *)type
       didReceiveDevices:(nullable NSArray<ThingSmartActivatorDeviceModel *> *)devices
                   error:(nullable ThingSmartActivatorErrorModel *)errorModel {
     if (devices && devices.count > 0) {
        // handle deivces
     }
}