快连 Plus 配网

更新时间:2025-04-01 06:36:38下载pdf

快连 Plus 配网,是双模配网的优化版本,旨在提升设备批量配网速度。

  • 支持批量添加设备。
  • 在配网失败时,系统能够快速定位问题,自动重试。
  • 提升设备对不同型号、不同设置路由器的兼容性。
  • 方法调用保持跟普通双模一致,快速接入。

接入配网扩展 SDK

Podfile 文件添加依赖,基座依赖 ThingSmartBusinessExtensionKit 和蓝牙实现依赖 ThingSmartBusinessExtensionKit,如下所示:

source 'https://github.com/tuya/tuya-pod-specs.git'
platform :ios, '11.0'

target 'Your_Project_Name' do
    # 从涂鸦开发者平台(https://platform.tuya.com)构建和获取 ThingSmartCryption
    # 购买正式版后,需重新在涂鸦开发者平台构建 SDK 并重新集成
    # ./ 代表将 ios_core_sdk.tar.gz 解压之后所在目录与 podfile 同级
    # 若自定义存放目录,可以修改 path 为自定义目录层级
    pod 'ThingSmartCryption', :path =>'./'
    pod 'ThingSmartHomeKit'
    pod 'ThingSmartBusinessExtensionKit'
    #蓝牙实现层
    pod 'ThingSmartBusinessExtensionKitBLEExtra'

end

接口说明

注册配网类型

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

设备类型 配网类型 模型
蓝牙单点、双模 ThingSmartActivatorTypeBle ThingSmartActivatorTypeBleModel

蓝牙配网模型

/// Ble
@interface ThingSmartActivatorTypeBleModel : ThingSmartActivatorTypeModel
/// Ble Scan Type
@property (nonatomic, assign) ThingActivatorBleScanType scanType;
/// Home ID
@property (nonatomic, assign) long long spaceId;
/// Pairing token (only used for Bluetooth fallback pairing)
@property (nonatomic, strong) NSString *token;
/// Wi-Fi name
@property (nonatomic, strong) NSString *ssid;
/// Wi-Fi password
@property (nonatomic, strong) NSString *password;
/// Gateway ID
@property (nonatomic, copy) NSString *gwDevId;
/// Active Type
@property (nonatomic, assign) ThingActivatorBleActiveType activeType;
@end

快连 Plus 配网,activeType 需要选择 ThingActivatorBleActiveTypeBatch

注册方法

/// 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 待激活设备列表,目前仅支持单个设备

设置批量激活

与单个双模配网不同,批量配网需要设置 ThingSmartActivatorTypeBleModelactiveType 属性为 batch,且需要设置入网 Token。

/// Special attention: Batch network configuration requires this setting, otherwise only the standard single device network configuration will proceed.
    typeModel.activeType = ThingActivatorBleActiveType.batch
    typeModel.token = token

停止激活

接口说明

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

示例代码

开始搜索

class BEDualModePlusViewController: UIViewController {
   
    // MARK: - Properties
    private var deviceList: [ThingSmartActivatorDeviceModel] = []
    private var cellModelList: [BEDeviceCellModel] = [] 
    private var isSuccess = false
    
    private lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        discovery.register(withActivatorList: [self.typeModel])
        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
    }()
    
    private lazy var typeModel: ThingSmartActivatorTypeBleModel = {
        let type = ThingSmartActivatorTypeBleModel()
        type.type = ThingSmartActivatorType.ble
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
        type.timeout = 120
        /// Special attention: Batch network configuration requires this setting, otherwise only the standard single device network configuration will proceed.
        type.activeType = ThingActivatorBleActiveType.batch
        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
    }()
    
 
    // MARK: - Actions
    @objc private func searchTapped() {
        deviceList.removeAll()
        tableView.reloadData()
        discovery.startSearch([self.typeModel])
        SVProgressHUD.show(withStatus: "Searching for devices...")
    }
    
    // MARK: - Private Methods
    private func stopConfiguring() {
        if !isSuccess {
            SVProgressHUD.dismiss()
        }
        
        discovery.stopSearch([self.typeModel], clearCache: true)
        discovery.stopActive([self.typeModel], clearCache: true)
        discovery.removeDelegate(self)
    }
    
}

设备搜索回调

// MARK: - ThingSmartActivatorSearchDelegate
extension BEDualModePlusViewController: ThingSmartActivatorSearchDelegate {
    func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didFindDevice device: ThingSmartActivatorDeviceModel?, error errorModel: ThingSmartActivatorErrorModel?) {
        if errorModel != nil {
            SVProgressHUD.showError(withStatus:"Faulty device")
            return
        }
        
        guard let device = device else { return }
        
        switch device.deviceModelType {
        case ThingSearchDeviceModelTypeBle:
            print("Please use Dual Mode to pair \(device.uniqueID)")
            SVProgressHUD.dismiss()
        case ThingSearchDeviceModelTypeBleWifi:
            if !deviceList.contains(where: { $0.uniqueID == device.uniqueID }) {
                deviceList.append(device)
                tableView.reloadData()
            }
            SVProgressHUD.dismiss()
        default:
            break
        }
    }
    
    func activatorService(_ service: ThingSmartActivatorSearchProtocol, activatorType type: ThingSmartActivatorTypeModel, didUpdateDevice device: ThingSmartActivatorDeviceModel) {
        let devicecellModel = cellModel(for: device)
        updateDeviceStatus(for: devicecellModel)
    }
}

开始配网

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        ssidTextField.resignFirstResponder()
        passwordTextField.resignFirstResponder()
        let deviceCellModel = cellModelList[indexPath.row]
        
        guard let ssid = ssidTextField.text, !ssid.isEmpty else {
            SVProgressHUD.showError(withStatus: "Please enter the WiFi name")
            return
        }
        
        guard let password = passwordTextField.text, !password.isEmpty else {
            SVProgressHUD.showError(withStatus: "Please enter the WiFi password")
            return
        }
        
        if typeModel.token.isEmpty {
            ThingSmartActivator.sharedInstance()?.getTokenWithHomeId(typeModel.spaceId, success: { [weak self] (token) in
                guard let self = self else { return }
                typeModel.token = token ?? ""
                self.startConfiguringNetwork(deviceCellModel: deviceCellModel, indexPath: indexPath)
            }, failure: { (error) in

            })
        } else {
            startConfiguringNetwork(deviceCellModel: deviceCellModel, indexPath: indexPath)
        }
    }

       private func startConfiguringNetwork(deviceCellModel: BEDeviceCellModel, indexPath: IndexPath) {
        deviceCellModel.deviceStatus = "Adding"
        typeModel.ssid = ssidTextField.text ?? ""
        typeModel.password = passwordTextField.text ?? ""
        updateDeviceStatus(for: deviceCellModel)
    
        // 开始配网
        discovery.startActive(typeModel, deviceList: [deviceCellModel.deviceModel])
//        discovery.startActive(typeModel, deviceList: deviceList)
    
        tableView.deselectRow(at: indexPath, animated: true)
    }

配网回调

// MARK: - ThingSmartActivatorActiveDelegate
extension BEDualModePlusViewController: ThingSmartActivatorActiveDelegate {
    func activatorService(_ service: ThingSmartActivatorActiveProtocol, activatorType type: ThingSmartActivatorTypeModel, didReceiveDevices devices: [ThingSmartActivatorDeviceModel]?, error errorModel: ThingSmartActivatorErrorModel?) {
        if let errorModel = errorModel {
            let cellModel = cellModel(for: errorModel.deviceModel!)
            cellModel.deviceStatus = "Failed"
            updateDeviceStatus(for: cellModel)            
            return
        }
        
        guard let device = devices?.first else { return }
        
        let cellModel = cellModel(for: device)
        cellModel.deviceStatus = "succeed"
        updateDeviceStatus(for: cellModel)
        isSuccess = true
    }
}