复合扫描设备功能

更新时间:2024-08-19 07:41:43下载pdf

复合扫描目前支持 Wi-Fi 快连(EZ)、闪电、有线设备、子设备、网关路由器、蓝牙、Matter 七种配网设备扫描方式,方便您直接使用一个或多个复合扫描能力。

  • 多个扫描功能合并成一个扫描,减少多个不同扫描回调繁琐的数据处理。
  • 减少用户对扫描到设备的唯一标识的理解,可以直接使用提供的统一扫描数据类的唯一标识。

当前支持的扫描类型

以下仅列举出可以进行扫描的配网类型枚举,其他类型暂不支持。

typedef NS_OPTIONS(NSInteger, ThingSmartActivatorType) {
    ThingSmartActivatorTypeWired =       1 << 0, // Wired
    ThingSmartActivatorTypeBle =         1 << 1, // 蓝牙 LE
    ThingSmartActivatorTypeSigMesh =     1 << 3, // 蓝牙 mesh
    ThingSmartActivatorTypeSubDevice =   1 << 4, // Sub-device
    ThingSmartActivatorTypeEZSearch =    1 << 5, // EZ
    ThingSmartActivatorTypeHomeKit =     1 << 7, // HomeKit
    ThingSmartActivatorTypeRouter =      1 << 8, // Router
    ThingSmartActivatorTypePegasus =     1 << 9, // Pegasus
    ThingSmartActivatorTypeMatter =      1 << 13, // Matter
    ThingSmartActivatorTypeBeacon =      1 << 20, // Beacon
};

注册配网类型

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

接口说明

/// 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 如果配网失败或者超时,返回此模型,成功时返回 nil

设备信息更新回调

接口说明

/// Device information update or device rediscovered on a different channel
/// @param service Search instance
/// @param type Network configuration type
/// @param device Device model
- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service
            activatorType:(ThingSmartActivatorTypeModel *)type
           didUpdateDevice:(ThingSmartActivatorDeviceModel *)device;

参数说明

参数 说明
service 配网服务
type 配网类型
device 返回变化的设备信息

前置条件说明

EZ、免密、网关路由器、子设备扫描过程及激活过程,如果有包含上述设备在内的多种设备并行搜索展示的功能需求,可以将其与蓝牙等具有搜索流程的设备进行合并设计。每种配网类型所需前置信息不同,通过继承 ThingSmartActivatorTypeModel,扩展每个类型的参数。

通用参数

必传参数 说明
timeout 超时时长(ms)
type 配网类型
typeName 配网类型名称
action 配网扩展行为
extensions 扩展参数

蓝牙单点扫描

所需权限:系统蓝牙和 App 蓝牙权限。
搜索对应模型 ThingSmartActivatorTypeBleModel,搜索时其中字段可不处理。

EZ 扫描

所需权限:本地网络权限,且证书需要配置 com.apple.developer.networking.multicast 权限。

必传参数 说明
ssid Wi-Fi 名称
password Wi-Fi 密码
token 鉴权标识
action 配网扩展行为
spaceId homeID

有线网关扫描

搜索设备需要与手机在同一个网络下,无需参数。

网关路由器扫描

必传参数 说明
routerActiveDeviceList 支持网关路由器设备 ID 列表
token 鉴权标识

闪电扫描

必传参数 说明
pegasusServerDevIDs 支持闪电设备 ID 列表

Matter 扫描

所需权限:系统蓝牙和 App 蓝牙权限。

子设备扫描

必传参数 说明
gwDevId 网关 ID

示例代码

开启扫描

Swift

class searchModeConfigurationVC: UITableViewController {

    var typeList:[ThingSmartActivatorTypeModel] = []

    private var sigModel: ThingSmartActivatorTypeSigMeshModel = {
        let type = ThingSmartActivatorTypeSigMeshModel()
        type.type = ThingSmartActivatorType.sigMesh
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.sigMesh)
        type.timeout = 120
        return type
    }()

    private var bleModel: ThingSmartActivatorTypeBleModel = {
        let type = ThingSmartActivatorTypeBleModel()
        type.type = ThingSmartActivatorType.ble
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ble)
        type.timeout = 120
        return type
    }()

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

    private var subDeviceModel: ThingSmartActivatorTypeSubDeviceModel = {
        let type = ThingSmartActivatorTypeSubDeviceModel()
        type.type = ThingSmartActivatorType.subDevice
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.subDevice)
        type.timeout = 120
        type.gwDevId = selectedGateway.deviceId
        return type
    }()

    private var pegasusModel: ThingSmartActivatorTypePegasusModel = {
        let type = ThingSmartActivatorTypePegasusModel()
        type.type = ThingSmartActivatorType.pegasus
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.pegasus)
        type.timeout = 120
        return type
    }()

    private var routerModel: ThingSmartActivatorTypeRouterModel = {
        let type = ThingSmartActivatorTypeRouterModel()
        type.type = ThingSmartActivatorType.router
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.router)
        type.timeout = 120
        return type
    }()

    private var wiredModel: ThingSmartActivatorTypeWiredModel = {
        let type = ThingSmartActivatorTypeWiredModel()
        type.type = ThingSmartActivatorType.wired
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.wired)
        type.timeout = 120
        return type
    }()

    private var EZModel: ThingSmartActivatorTypeEZModel = {
        let type = ThingSmartActivatorTypeEZModel()
        type.type = ThingSmartActivatorType.ezSearch
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.ezSearch)
        type.timeout = 120
        return type
    }()


    private var matterModel: ThingSmartActivatorTypeMatterModel = {
        let type = ThingSmartActivatorTypeMatterModel()
        type.type = ThingSmartActivatorType.matter
        type.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorType.matter)
        type.timeout = 120
        return type
    }()

    lazy var discovery: ThingSmartActivatorDiscovery = {
        let discovery = ThingSmartActivatorDiscovery()
        self.typeList = [self.matterModel,self.EZModel,self.wiredModel,self.pegasusModel,self.bleModel,self.sigModel,self.beaconModel,self.subDeviceModel,self.routerModel]
        discovery.register(withActivatorList: self.typeList)
        discovery.setupDelegate(self)
        discovery.loadConfig()
        return discovery
    }()

    private func startSearch() {
        guard let homeID = Home.current?.homeId else { return }
        let deviceArray = ThingSmartPegasusActivator.pegasusDeviceList(withHomeID: homeID)
        var devIds: [String] = []

        deviceArray.forEach { (obj) in
            devIds.append(obj.devId)
        }

        pegasusModel.pegasusServerDevIDs = devIds

        EZModel.spaceId = homeID;
        EZModel.token = token
        EZModel.ssid =  ssid
        EZModel.password = password

        routerModel.token = token
        sigModel.spaceId = homeID
        matterModel.spaceId = homeID
        wiredModel.spaceId = homeID
        bleModel.spaceId = homeID


        let routerActivator = ThingSmartRouterActivator()
        routerModel.routerActiveDeviceList = routerActivator.autoActiveRouterDeviceList(withHomeId: homeID)

        discovery.startSearch(typeList)
    }


}

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

        if let device = device {
            /// discovery Device
        }
    }

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

    }

}

Objective-C

- (void)startSearch {
    self.typedic = [NSMutableDictionary dictionary];

    ThingSmartActivatorTypeSubDeviceModel *subType = [[ThingSmartActivatorTypeSubDeviceModel alloc] init];
    subType.type = ThingSmartActivatorTypeSubDevice;
    subType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeSubDevice);
    subType.gwDevId = gwDevId;
    [self.typedic setObject:subType forKey:subType.typeName];

    ThingSmartActivatorTypeBleModel *bleModel  = [[ThingSmartActivatorTypeBleModel alloc] init];
    bleModel.type = ThingSmartActivatorTypeBle;
    bleModel.scanType = ThingBluetoothScanTypeNoraml;
    bleModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeBle);

    ThingSmartActivatorTypeSigMeshModel *sigModel  = [[ThingSmartActivatorTypeSigMeshModel alloc] init];
    sigModel.type = ThingSmartActivatorTypeSigMesh;
    sigModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeSigMesh);
    sigModel.spaceId = homeId;

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

    [self.typedic setObject:bleModel forKey:bleModel.typeName];
    [self.typedic setObject:sigModel forKey:sigModel.typeName];
    [self.typedic setObject:beaconModel forKey:beaconModel.typeName];


    ThingSmartActivatorTypeRouterModel *routerType = [[ThingSmartActivatorTypeRouterModel alloc] init];
    routerType.type = ThingSmartActivatorTypeRouter;
    routerType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeRouter);
    routerType.routerActiveDeviceList = [[[ThingSmartRouterActivator alloc]init] autoActiveRouterDeviceListWithHomeId:homeId];
    routerType.token = token;
    [self.typedic setObject:routerType forKey:routerType.typeName];


    ThingSmartActivatorTypeWiredModel *wiredType = [[ThingSmartActivatorTypeWiredModel alloc] init];
    wiredType.type = ThingSmartActivatorTypeWired;
    wiredType.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeWired);
    wiredType.spaceId = homeId;
    [self.typedic setObject:wiredType forKey:wiredType.typeName];

    ThingSmartActivatorTypePegasusModel *typeModel = [[ThingSmartActivatorTypePegasusModel alloc] init];
    typeModel.type = ThingSmartActivatorTypePegasus;
    typeModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypePegasus);

    NSArray *array = [ThingSmartPegasusActivator pegasusDeviceListWithHomeID:homeId];
    NSMutableArray *devIds = [NSMutableArray array];
    [array enumerateObjectsUsingBlock:^(ThingSmartDeviceModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [devIds addObject:obj.devId];
    }];
    typeModel.pegasusServerDevIDs = devIds;
    typeModel.spaceId = homeId;
    [self.typedic setObject:typeModel forKey:typeModel.typeName];

    ThingSmartActivatorTypeEZModel *ezModel  = [[ThingSmartActivatorTypeEZModel alloc] init];
    ezModel.type = ThingSmartActivatorTypeEZSearch;
    ezModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeEZSearch);
    ezModel.spaceId = homeId;
    ezModel.token = token;
    ezModel.ssid = ssid;
    ezModel.password = password;
    [self.typedic setObject:ezModel forKey:ezModel.typeName];

    ThingSmartActivatorTypeMatterModel *matterModel = [[ThingSmartActivatorTypeMatterModel alloc] init];
    matterModel.type = ThingSmartActivatorTypeMatter;
    matterModel.typeName = NSStringFromThingSmartActivatorType(ThingSmartActivatorTypeMatter);
    matterModel.spaceId = homeId;
    [self.typedic setObject:matterModel forKey:matterModel.typeName];

    [self.discovery registerWithActivatorList:self.typedic.allValues];
    [self.discovery setupDelegate:self];
    [self.discovery startSearch:self.typedic.allValues];
}

- (void)activatorService:(id<ThingSmartActivatorSearchProtocol>)service activatorType:(ThingSmartActivatorTypeModel *)type didFindDevice:(ThingSmartActivatorDeviceModel *)device error:(ThingSmartActivatorErrorModel *)errorModel {

    if (errorModel) {
        [self _connectWifiError:errorModel];
        return;
    }

    if (self.typeModel.type == device.activatorType) {
        [self _handleDevice:device];
    }
}

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

停止扫描

Swift

discovery.stopSearch(typeList, clearCache: true)

Objective-C

[self.discovery stopSearch:self.typedic.allValues clearCache:YES];