I-设备功能

除了用户登录操作,SDK 中最重要的就是与设备通讯的任务了。一般情况下会包含以下几个任务:

任务名称 任务意义 任务作用
XLinkScanDeviceTask 扫描设备任务 扫描同一局域网内的设备以便后续添加订阅和连接
XLinkAddDeviceTask 添加订阅设备任务 添加设备,并将设备与用户关联绑定关系,实现任何情况下用户可同步并使用设备
XLinkSyncDeviceListTask 同步设备任务 同步与用户关联的设备列表信息
XLinkRemoveDeviceTask 移除设备任务 移除设备并取消用户与设备之前的关联关系
XLinkTMLProbeAttributeTask 获取设备物模型属性任务 获取设备物模型属性任务
XLinkTMLSetAttributeTask 设置设备物模型属性任务 设置设备物模型属性任务
XLinkTMLInvokeServiceTask 调用设备物模型服务 调用设备物模型服务

1. 设备管理

1.1. 扫描设备任务

对于一个全新的设备,需要通过扫描局域网内的设备发现设备,再进行后续的操作。这是设备操作的首要步骤。

//新建扫描设备任务
XLinkScanDeviceTask *scanTask = [XLinkScanDeviceTask scanDeviceTaskWithProductIdArray:@[@"123456789",@"987654321"]
                                                                              timeout:90
                                                           didDiscoveredDeviceHandler:^(XDevice *device) {
    //扫描到设备回调,同一设备仅会回调一次
}
                                                                    completionHandler:^(id result, NSError *error) {
    //无论搜不搜索到设备都会回调这个方法。返回的错误是任务超时
}];
[scanTask start];

XLinkScanDeviceTask 中,需要正确传入设备的ProductId(产品ID),对应的设备才会通过扫描回调。同时,支持传入包含多个ProductId 的数组。

注意:扫描设备时需要一些条件限制,请务必确认处于相应环境下才能正常扫描到设备

  • APP与扫描的设备必须在同一局域网中
  • 确认设备版本与APP支持的版本兼容

若扫描不到设备并无法确认原因,可查看附录FAQ相关问题解答

1.2. 添加订阅设备

添加设备是通过本地与设备通过后,再将校验信息提交到云端,通过云端的校验后将设备与用户形成绑定关系。成功订阅过的设备将在同步设备列表时可以同步到。

XLinkAddDeviceTask *addDeviceTask = [XLinkAddDeviceTask addDeviceTaskWithDevice:device
                                                                        pinCode:pingCode //pingCode需要硬件设备支持,一般情况下可以为nil
                                                                        timeout:60
                                                              completionHandler:^(id result, NSError *error) {
    if (!error) {
        //任务执行成功
    }else{
        //任务执行失败
    }
}];
[addDeviceTask start];

XLinkAddDeviceTask 中有个属性 needSubscription ,这个属性默认为 YES,已添加成功的设备,SDK会自动在云端建立当前用户账号与设备的订阅关系,并用于后续的数据更新和同步,具体请参考下文的“同步设备”。
如果设置为 NO,则SDK只会添加设备,而不会去订阅设备。关于添加与订阅的差异如下:

操作 说明 影响
添加设备 添加设备为SDK与设备之前建立起联系并从设备获取到部分设备信息(可用于校验工作) 添加是正常情况下使用设备的前提条件,但是添加操作与云端及用户无直接关联
订阅设备 通过云端提交设备信息,云端在校验成功后将设备与当前用户绑定关系 订阅是保存用户与设备之间关系的必要操作,只有订阅后的设备才能进行远程同步及控制

1.3. 同步设备任务

同步设备任务用于将将当前用户的设备设备从云端同步到本地。任务完成后默认自动发起本地连接和云端连接, 同步后的设备会自动添加到设备维护列表中进行维护,设备状态变更时也会有相应的状态回调。

XLinkSyncDeviceListTask *syncTask = [XLinkSyncDeviceListTask syncDeviceListTaskWithVersion:0 //目前只需要填入0即可
                                                                                   timeout:10
                                                                              connectLocal:YES //同步设备列表后是否需要和设备建立本地连接
                                                                         completionHandler:^(id result, NSError *error)  {
    if (!error) {
        //任务执行成功,设备列表会通过result返回
    }else{
        //任务执行失败
    }
}];
[syncTask start];

同步设备要求设备和当前用户之间有订阅关系,无订阅关系无法同步到设备。若设备与APP在同一局域网,一般建议 connectLocal-同步后是否进行本地连接设置为 YES 。完全不需要依赖本地通讯的,可以使用 NO,以减少部分资源的维护成本与性能消耗

1.4. 移除设备

移除设备成功时,SDK 会自动从云端解除当前用户与设备之间的订阅关系,并删除与该设备相关的共享和访问权限, 同时也会将该设备移除维护列表, 设备将不能再使用。

//新建删除设备任务
XLinkRemoveDeviceTask *removeDeviceTask = [XLinkRemoveDeviceTask removeDeviceTaskWithDevice:device
                                                                                    timeout:10
                                                                          completionHandler:^(id result, NSError *error) {
    if (!error) {
        //任务执行成功
    }else{
        //任务执行失败
    }
}];
[removeDeviceTask start];

1.5. 设备订阅关系管理

通过 XLinkAddDeviceTask 可在云端建立用户和设备之间的订阅关系。订阅关系建立后,可使用 XLinkSyncDeviceListTask 获取与当前用户有订阅关系的设备列表。通过XLinkRemoveDeviceTask可解除订阅关系。

订阅关系 操作途径
订阅关系的建立 1.添加设备 2.设备分享 3.其他建立云端订阅关系的途径(如通过二维码订阅)
订阅关系的解除 1.删除设备 2.设备重新激活(设备重置后再连上云端,设备会重新激活) 3.其他解除云端订阅关系的途径

1.5.1. 订阅关系变更回调

在订阅关系建立或解除时,以下两个回调会被触发:

1、设备信息变更

- (void)onDeviceChanged:(XDevice *)xDevice withEvent:(XDeviceEvent)event{
        switch (event) {
            case XDeviceEventSubscribe://与xDevice的订阅关系建立
                break;
            case XDeviceEventUnSubscribe://与xDevice的订阅关系解除
                break;
        }
}

2、云端事件推送

- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify {
     if (eventNotify.messageType == EventNotifyTypeSubscribeChanged) {
 
     }
}

尽管这两个回调都可用,强烈建议统一在 - (void)onDeviceChanged:(XDevice \*)xDevice withEvent:(XDeviceEvent)event 中进行所有设备订阅关系变化的处理,可以避免一些不必要的错误操作。因为实际上**- (void)onDeviceChanged:(XDevice *)xDevice withEvent:(XDeviceEvent)event的回调也是来源于- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify,当设备的订阅关系变更时,SDK 将接收到云端的消息推送,并且处理好对应设备的管理,在此过程中会再回调到- (void)onDeviceChanged:(XDevice *)xDevice withEvent:(XDeviceEvent)event**事件中。

当接收到订阅关系变化的通知时,SDK内部已断开和设备的连接,开发者应主动或提示用户刷新设备列表。

以上两个回调依赖云端连接,属于云端的推送消息。主要提供给APP开发者处理订阅关系被动建立或被动解除的情况(例如人为重置设备)

如果是用户主动添加或删除设备(XLinkAddDeviceTask 或 XLinkRemoveDeviceTask ),那么在执行成功的时候就要进行后续处理,例如刷新设备列表、更新ui等等,不应该等待云端通知再进行处理

1.6. 设备连接状态的刷新

开发 APP 的时候经常需要显示设备的连接状态,很多用例也依赖于设备的连接状态(例如控制设备的时候要求设备在线)。所以如何准确地在 APP 与设备之间同步连接状态是我们首先要解决的问题。

1.6.1. 获取设备连接状态

设备状态可以通过 xDevice.connectionState从设备实体中取出,代码如下:

XDevice *device =  [[XDeviceManager shareManager] getDeviceWithMacAddressData:xDevice.macAddress productId:xDevice.productID];
XDeviceConnectionState connectionState = device.connectionState;

1.6.2. 设备连接状态类型

对于连接状态,一个设备默认情况下允许获取到三种状态(连接状态是仅可读的,不允许进行修改,由内部设备维护管理对象维护)

连接状态 意义 使用场景
localConnectionState 获取当前设备的本地连接状态(内网) 当设备仅需要进行内网控制或者是允许进行内网控制时,或者关心设备的内网连接状态时,都可以从此状态获取最新的本地连接状态
cloudConnectionState 获取当前设备的云端连接状态(外网) 当设备仅需要进行外网控制或者是允许进行外网控制时,或者关心设备的外网连接状态时,都可以从此状态获取最新的云端连接状态
connectionState 获取当前设备的连接状态 只要内网或者外网任何一个连接中,该状态值都会返回连接中的状态,当全部断开连接时才会返回断开连接状态

大部分使用情况下,通过 connectionState关注设备的连接状态正常即可进行设备的控制。在对设备有特殊环境需求时则可以考虑其它的相关的状态值

对于设备返回的连接状态,主要有三种

状态值 意义
XDeviceConnectionStateDetached XDevice的状态未知
XDeviceConnectionStateOffline SDK设备与设备失去连接
XDeviceConnectionStateConnecting 设备正在尝试连接中
XDeviceConnectionStateOnline 设备连接成功,设备允许正常通讯

1.6.3. 订阅设备状态变化

开发者可以订阅设备的状态变化,通过SDK初始化配置设置状态监听,请参考基础功能使用说明-SDK基本配置。也可以通过设备管理对象对设备状态监听进行注册

//直接对设备管理对象注册设备状态监听事件
XDeviceStateObserver *stateObserver = [XDeviceStateObserver deviceStateChangedObserverWithDevice:_device deviceStateChangedBlock:^(XDevice * _Nonnull device, XDeviceConnectionState state) {
        //监听state的变化。
    }];
     
[[XDeviceManager shareManager] addDeviceStateObserver:stateObserver];

设备管理对象对所有注册的设备状态监听事件将会保持强引用,所以请务必记得取消订阅以免引起内存泄漏

//取消监听事件的注册
[[XDeviceManager shareManager] removeDeviceStateObserver:stateObserver];

当stop SDK 的时候,SDK内部会清除所有的设备状态监听事件。

简单地说,如果开发者不关心设备与SDK的连接方式,只需处理 connectionState 即可。当 connectionState`返回XDeviceConnectionStateOnline时,开发者可向设备发送或请求数据。

2. 设备控制

2.1. 设备物模型详解

物模型从属性、服务和事件三个维度,分别描述了其在物理空间中指代的实体是什么,能够做什么,能够对外提供哪些信息。从这三个维度定义好产品相应的物模型之后,也代表定义好了该产品的功能定义。在完成产品功能定义后,系统将自动生成该产品的物模型。

当设备的物模型发生变化,若设备已经连接到云端,那物模型的变化将会通过物联云平台提供的硬件 XAPP SDK,同步到云端上,以便厂商在云平台查看与收集设备的运行状态的变化。

物模型的固定格式

APP 开发者需要创建物模型,并传入SDK中,现在默认的都需要传入字典作为参数。字典中字段 “v” 和 “input” 均为必传字段。
其中 “v” 可以固定传 “2”。”input” 中的 key 是物模型属性定义的name, value 是设备物模型 所需要的值。例如设置物模型属性 “PowerSwitch” 为 YES,则需要设置的 input 为

@{
    @"PowerSwitch" : @(YES)
 }

以下是调用设置设备属性的服务的示例

NSDictionary *dataPayload = @{
    @"v" : @"2",
    @"input" : @{
        @"key1" : @"value1",
        @"key2" : @"value2"
    }
};
XLinkTMLSetAttributeTask *task = [XLinkTMLSetAttributeTask setAttributeTaskWithDevice:device dataPayload:dataPayload timeout:10 completionHandler:^(id  _Nullable result, NSError * _Nullable error) {
    if (error) {
        NSLog(@"服务调用失败了");
    } else {
        NSLog(@"服务调用成功了");
    }
}];
[task start];

2.2. 获取设备物模型属性

对设备的控制实际上就是对设备的物模型属性进行操作,从而达到设备状态或行为变化。其中获取设备物模型属性使用 XLinkTMLProbeAttributeTask

XLinkTMLProbeAttributeTask *task = [XLinkTMLProbeAttributeTask probeAttributeTaskWithDevice:device dataPayload:dataPayload timeout:10 completionHandler:^(id  _Nullable result, NSError * _Nullable error) {
    if (!error) {
        //任务执行成功,物模型属性列表会通过result返回
    }else{
        //任务执行失败
    }
}];

//执行查询物模型属性任务
[task start];

2.3. 设置设备物模型属性

对设备的控制实际上就是对设备的物模型属性进行操作,从而达到设备状态或行为变化。其中设置设备物模型属性使用 XLinkTMLSetAttributeTask

//修改物模型属性,控制设备
NSDictionary *dataPayload = @{
    @"v" : @"2",
    @"input" : @{
        @"PowerSwitch" : @(YES),
        @"key2" : @"value2"
    }
};
XLinkTMLSetAttributeTask *task = [XLinkTMLSetAttributeTask setAttributeTaskWithDevice:device dataPayload:dataPayload timeout:10 completionHandler:^(id  _Nullable result, NSError * _Nullable error) {
    if (error) {
        NSLog(@"服务调用失败了");
    } else {
        NSLog(@"服务调用成功了");
    }
}];
[task start];

2.4. 调用设备物模型服务

相比于属性,服务可通过一条指令实现更复杂的业务逻辑。其中调用设备物模型服务使用 XLinkTMLInvokeServiceTask。

//修改物模型属性,控制设备
NSDictionary *dataPayload = @{
    @"v" : @"2",
    @"input" : @{
        // 这里根据实际填入参数
    }
};
NSString *serviceName = @"name"; // 这里根据实际填入服务名
XLinkTMLInvokeServiceTask *invokeServiceTask = [XLinkTMLInvokeServiceTask invokeServiceTaskWithDevice:device serviceName:serviceName dataPayload:dataPayload timeout:10 completionHandler:^(id  _Nullable result, NSError * _Nullable error) {
    if (error) {
        NSLog(@"服务调用失败了");
    } else {
        NSLog(@"服务调用成功了");
    }     
}];
[invokeServiceTask start];

3. 设备分享管理

3.1 概述

设备的分享管理包括以下几部分:

  • 将设备分享给其它用户
  • 分享消息推送
  • 处理分享消息
  • 获取分享列表

3.2 分享设备

通过 XLinkShareDeviceTask 可以将设备权限分享给其他在平台里已经注册的同一企业下用户。

/** 创建一个分享设备task
@param device 设备
@param account 对方账号(邮箱或者手机号)
@param expired 分享有效期时间(单位秒)
@param shareDeviceMode 分享的方式
@param authority 对设备的控制权限,R可读,W可写,RW可读可写;默认为null相当于RW;
@param timeout task超时时间
@param shareCompleteBlock 完成后的回调
*/
XLinkShareDeviceTask *shareTask = [XLinkShareDeviceTask shareDeviceTaskWithDevice:device
                                                                     account:account
                                                                     expired:@"7200"
                                                                   shareMode:XLinkShareDeviceModeApp
                                                                   authority:@"RW"
                                                                     timeout:10
                                                           completionHandler:^(id result, NSError *error) {
    if (!error) {//分享成功
         
    }else{//分享失败
         
    }
}];
     
[shareTask start];
  • 分享的模式类型
类型 说明
XLinkShareDeviceModeApp 通过用户ID分享
XLinkShareDeviceModeQrcode 二维码方式分享
XLinkShareDeviceModeEmail 邮件方式分享
  • 设备操作权限
类型 说明
@”R” 只读
@”W” 只写
@”RW” 可读写

3.3 分享消息推送

当接受分享方在线时,对方的XLinkCloudDelegate中的 onReceiveEventNotify 会收到类型为 EventNotifyTypeDeviceShare 的通知:

/** * 当SDK连接上云端,并接收到云端推送时,会回调这个方法。 * * @param eventNotify 收到的云端推送信息 */
- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify {
    if (eventNotify.messageType == EventNotifyTypeDeviceShare) {
    //接收到的类型和设备分享相关
    }
}

注意:分享仅会有EventNotify的通知,设备订阅状态变更 - (void)onDeviceChanged:(XDevice *)xDevice withEvent:(XDeviceEvent)event 的回调。
由于分享的设备还不存在当前用户的维护列表中,是无法回调通知设备状态发送了变化的

开发者可通过 EventNotifyHelper 来获取分享的类型,如下所示:

- (void)onReceiveEventNotify:(XLinkEventNotify *)eventNotify {
    if (eventNotify.messageType == EventNotifyTypeDeviceShare) {
      //解析出设备分析事件
        XLinkDeviceShareNotify *shareNotify = [EventNotifyHelper parseDeviceShareNotifyWithData:eventNotify.notifyData];
        switch (shareNotify.shareState) {
            case DeviceShareStateShareRequest:
                //接收到分享请求
                break;
            case DeviceShareStateAcceptShare:
                //接受分享
                break;
            case DeviceShareStateDenyShare:
                //拒绝分享
                break;
            case DeviceShareStateShareCancel:
                //分享被取消
                break;
        }
    }
}

3.4 处理分享消息

开发者可以使用 XLinkHandleShareDeviceTask 对分享进行处理,如下所示:

XLinkHandleShareDeviceTask *handleTask = [XLinkHandleShareDeviceTask handleShareDeviceTaskWithInviteCode:invite_code
                                                                                       handleShareAction:XLinkHandleShareDeviceActionAccept
                                                                                                 timeout:20
                                                                                       completionHandler:^(id result, NSError *error) {
    if(!error){//处理成功
         
    }else{//处理失败
         
    }
}];
[handleTask start];

其中 Action 为分享处理的行为:

行为 操作对象 说明
XLinkHandleShareDeviceActionAccept 被分享者 接受该次分享
XLinkHandleShareDeviceActionAcceptQrCode 被分享者 接受该次二维码分享
XLinkHandleShareDeviceActionDeny 被分享者 拒绝这次分享
XLinkHandleShareDeviceActionCancel 发起分享者 取消已经分享出去的分享记录
XLinkHandleShareDeviceActionDeleteRecord 被分享者或发起分享者 删除该次分享记录

详情可参考 demo 中关于设备分享部分的代码及注释

3.5 获取分享列表

当APP不在线时,可能收不到设备分享的推送消息,这时候可以通过获取分享列表的接口拿到所以接收到分享的数据

获取的方法如下:

[XLinkRestKit getShareDeviceListWithCompletionHandler:^(id  _Nullable result, NSError * _Nullable err) {
     if(!err){//获取成功
         
    }else{//获取失败
         
    }
}];

成功获取的分享列表数据如下:

[
    {
        "invite_code" : 分享邀请码,
        "from_id" : 分享者ID,
        "from_user" : 分享者帐号,
        "to_id" : 被分享者ID,
        "to_user" : 被分享者帐号,
        "device_id" : 设备ID,
        "state" : 分享状态
        "create_date" : 分享产生时间,
        "expire_date" : 分享过期时间,
        "authority" : 分享权限
    },
]
字段 是否必须 描述
invite_code 分享ID
authority 对设备的控制权限,R可读,W可写,RW可读可写;默认为null相当于RW;同时用户可以扩展这个权限如RW+-等等,这个权限会在订阅时进入用户和设备的authority属性
from_id 分享者ID,一般都是设备管理员的ID。
from_user 分享者帐号,一般都是设备管理员的ID。
to_id 分享给谁
to_user 分享给谁的帐号
device_id 设备ID
state 分享状态
create_date 分享产生时间
expire_date 分享过期时间

分享状态

类型 说明
pending string 等待接收
accept string 已接收
deny string 拒绝
overtime string 超时
cancel string 已取消
invalid string 无效的请求
没找到需要的文档?
你可以提交工单反馈 或 阅读常见问题