设备模型 SDK
更新时间:2019-04-01 15:36:18
概述
设备模型 SDK 提供了 App 端的设备模型(属性,事件,服务),用来开发设备界面,实现手机对设备的查看和控制。
设备模型 SDK 中封装了云端请求通道以及本地通信通道,当 APP 端需要控制设备时,理论上可以从上述二通道中的任何一条通道将请求发至设备。此处提供解决方案在二条通道中选择最合适的通道控制设备,而开发者无需关心如何进行通道选择。
依赖 SDK | 概述 |
---|---|
日志 | 基础依赖SDK,提供客户端统一日志打印,日志等级控制,分模块日志隔离等能力 |
API 通道 SDK | API 通道 SDK,提供 IoT 业务协议封装的 https 请求能力,并通过整合安全组件来提升通道的安全性。 |
长连接通道 SDK | 长连接通道SDK,提供 IoT 业务协议封装的云端数据下行能力;为 app 提供订阅、发布消息的能力, 和支持请求响应模型。 |
初始化
此功能模块依赖 API 通道 SDK,以及长连接通道 SDK。使用前请先初始化这两个 SDK。请参见:
API 通道 - 初始化 长连接通道-初始化
在上述两个 SDK 初始化成功的基础上,再进行设备模型 SDK 的初始化,示例如下:
#import <IMSThingCapability/IMSThingCapability.h>
[kIMSThingManager startLocalAcceleration]; //初始化只需要添加此一行代码即可,此处会启动
// 本地通信加速能力.
// 当不再需要使用本地通信能力时,可调用下边接口停止
// [kIMSThingManager stopLocalAcceleration];
使用说明
获取本地发现且支持本地控制的设备列表
本地通信功能是设备模型 SDK 提供的一项基础能力,它提供了在外网断连的情况下,局域网内设备控制的 feature。
当外网断连的情况下,本地通信模块会去搜寻当前局域网内的设备,如果被发现的设备是之前用户控制过的设备,那么此时可以通过本地通信链路去控制设备。
在外网断连时,如向云端拉取用户账号下的设备列表会失败,此时可以使用以下接口获取当前可以本地通信控制的设备列表。由于本地发现设备是一个较长的过程,所以第一次调用此接口时有可能返回为空,此时需要允许用户刷新设备列表。
此 API 在 sdk 版本 1.2.3 中新增
#import <IMSThingCapability/IMSThingCapability.h>
(NSArray<NSDictionary *> *) devices = [kIMSThingManager getLocalAuthedDeviceDataList];
//其中 NSDictionary 保存了设备的详细信息。
创建设备
设备抽象类 IMSThing 封装了设备对外提供的所有接口:包括获取设备的模型、设备的操作方法、设备的基础信息等。
#import <IMSThingCapability/IMSThingCapability.h>
/**
APP端可以使用 API 通道 SDK,请求接口 '/uc/listByAccount',可以拿到当前账号下
所有绑定的设备列表,返回的设备信息中有设备的 iotId。
*/
_thingShell = [kIMSThingManager buildThing:_iotId];// _iotId为云端给设备颁发的唯一标识
// 当不再需要使用时,请记得销毁,如下所示:
// [kIMSThingManager destroyThing:_thingShell];
// 如果需要获取设备的 iotId
// NSString * iotId = [_thingShell iotId];
设备控制
APP 端需要控制设备时,SDK 会根据当前的实际情况来决定控制请求是通过本地还是通过云端发送至设备。
设备控制的接口协议为 IMSThingActions。
该协议定义了几个接口,用来对设备做控制,内部逻辑会实现通道选择。
设备控制是基于物的模型对设备定义的属性、事件、服务进行操作。关于属性、事件、服务的描述,请参见: 生成物的模型TSL
这些方法调用时的入参、出参,请参见: 物的核心模型服务 [获取物的属性] [触发物的服务][设置物的属性]等节。
获取设备状态
[[_thingShell getThingActions] getStatus:^(IMSThingActionsResponse * _Nullable response) {
NSDictionary * properties = [response.dataObject valueForKey:@"data"];
//格式如下:
/* {
"status":1 //
"time":1232341455
}
说明:status表示设备生命周期,目前有以下几个状态,
0:未激活;1:上线;3:离线;8:禁用;time表示当前状态的开始时间;
*/
}];
获取设备属性
[[_thingShell getThingActions] getPropertiesFull:^(IMSThingActionsResponse * _Nullable response) {
NSDictionary * properties = [response.dataObject valueForKey:@"data"];
//格式如下:
/* {
"_sys_device_mid": {
"time": 1516356290173,
"value": "example.demo.module-id"
},
"WorkMode": {
"time": 1516347450295,
"value": 0
},
"_sys_device_pid": {
"time": 1516356290173,
"value": "example.demo.partner-id"
}
}
*/
}];
设置设备属性
NSDictionary * items = @{@"power":@"on", @"temperature":25};
//items 为key-value对,具体的值请参考 物的模型 TSL-属性以及其 datatype
[[_thingShell getThingActions] setProperties:items
responseHandler:^(IMSThingActionsResponse * _Nullable response) {
if (response.success) {
dispatch_async(dispatch_get_main_queue(), ^{
[UiUtils showTip:[NSString stringWithFormat:@"设置属性 %@成功", [property name]]];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[UiUtils showTip:[NSString stringWithFormat:@"设置属性 %@失败", [property name]]];
});
}
}];
调用服务
// identifier 请参见 物的模型 TSL 中 Service 描述
// 调用服务时的入参 请参见 物的模型 TSL 中 Service 的 inputData
// 调用服务时的出参 请参见 物的模型 TSL 中 Service 的 outputData
[[ _thingShell getThingActions] invokeService:[service identifier]
params:valueDict
responseHandler:^(IMSThingActionsResponse * _Nullable response) {
if (response.success) {
dispatch_async(dispatch_get_main_queue(), ^{
[UiUtils showTip:[NSString stringWithFormat:@"调用服务 %@成功", [service name]]];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[UiUtils showTip:[NSString stringWithFormat:@"调用服务 %@失败", [service name]]];
});
} }];
订阅所有事件
[_thingShell registerThingObserver:self];//注册设备状态、属性变化、以及事件触发的观察者。
// 具体参见 `IMSThingObserver`。请注意对于注册的 Observer,
// SDK只会 Weak reference 其实例,请开发者自己保证 Observer 的生命周期。
// 在不需要监听时,请注销 [_thingShell unregisterThingObserver:self];
清理缓存
SDK 在使用过程中会保存本地通信加速的相关数据到手机沙盒目录,当手机账号登出时记得清理这些缓存。
[kIMSThingManager clearLocalCache];
更多功能
获取物的模型
物模型是对设备是什么、能做什么的描述,包括设备身份标识、连接状态、描述信息,以及设备的属性 (properties)、服务 (services)、事件 (events),后三者构成了设备的功能定义。阿里云 IoT 平台通过定义一种物的描述语言来描述物模型,称之为 TSL (即 Thing Specification Language)。
请参见: 物的模型TSL
当 IMSThingObserver didThingTslLoad 方法被回调时:可以拿到解析完成的物的模型。
IMSThingProfile * Profile = [thingShell getThingProfile];
//其中物的三要素 保存在 IMSThingProfile 中。
_thingProperties = [[_thingShell getThingProfile] allPropertiesOfModel];
_thingEvents = [[_thingShell getThingProfile] allEventsOfModel];
_thingServices = [[_thingShell getThingProfile] allServicesOfModel];
// 注意,此处拿到的 properties,events,services 是物的模型中的物的三要素。
// 具体请参见 IoT-TSL 规范
开发者也可以使用云端接口来获取原始的物的模型。
请参见 物的核心模型服务-获取物的模板 。
蓝牙功能API介绍
蓝牙设备受连接特性的约束,往往无法直接跟飞燕云端平台连接,因而需要借助一个网关设备来实现蓝牙设备与飞燕云端平台的连接通道。而手机在这一过程中也可以充当网关的角色。
此 SDK 额外提供以下几方面的能力:
1、提供发现蓝牙设备/连接蓝牙设备的能力
2、提供连云通道,可以供蓝牙设备数据上下云
3、提供蓝牙设备控制与数据获取的能力
接入蓝牙设备需要引入相关依赖:
依赖 SDK | 概述 |
---|---|
蓝牙 Breeze SDK | Breeze SDK 是按照规范实现的手机端蓝牙 SDK,方便合作厂商在手机端快速接入蓝牙功能。Breeze SDK 包含的主要功能有:设备发现连接,设备通信,加密传输,大数据传输等。 |
移动端设备网关 SDK | 移动端设备网关 SDK,运行于 APP 上的子设备网关,对于无法直连网络的子设备,如蓝牙设备,提供子设备的管理功能,如子设备添加拓扑,删除拓扑,上线,下线以及数据上下行等 |
初始化移动端设备网关 SDK
此功能模块依赖 移动端设备网关 SDK。使用前请先初始化这个 SDK。请参见:
移动端设备网关 SDK-初始化
蓝牙设备的发现
#import <IMSThingCapability/IMSThingCapability.h>
[[IMSThingDiscoveryRegistry sharedRegistry] startDiscoveryWithFilter:filterParams
didFoundBlock:^(NSArray * _Nullable result, NSError * _Nullable error) {
if ([result count]) {
[result enumerateObjectsUsingBlock:^(id<IMSLocalDevice> item, NSUInteger idx, BOOL * _Nonnull stop) {
NSString * productKey = item.productKey;
NSString * bleMac = item.deviceName;//对于Breeze 蓝牙设备,这里得到的是设备的MAC地址
}];
}
}];
蓝牙设备的添加绑定流程
蓝牙设备的绑定流程分为两个步骤
1、蓝牙设备通过 APP 去云端上线,可以使用SDK提供的API完成
#import <IMSThingCapability/IMSThingCapability.h>
NSMutableDictionary *devInfo = @{}.mutableCopy;
[devInfo setValue:@"EE:FF:DD:AA:BB:00" forKey:@"deviceName"]; //MAC地址为设备发现时取得的值-bleMac
[devInfo setValue:@"productKey---xxx" forKey:@"productKey"];//productKey为设备发现时取得的值
[IMSSubDeviceService subDeviceAuthenLogin:devInfo
resultBlock:^(NSDictionary * _Nullable object, NSError * _Nullable error)
{
NSString * productKey = [object valueForKey:@"productKey"];
NSString * deviceName = [object valueForKey:@"deviceName"];//
}
];
2、上线成功后,调用云端 API 去做绑定账号
#import <IMSApiClient/IMSApiClient.h>
#import <IMSApiClient/IMSIoTRequestBuilder.h>
#import <IMSThingCapability/IMSThingCapability.h>
NSDictionary * params = @{@"productKey" : productKey ?: @"", //productKey此处为蓝牙设备上线结果回调里获得的值
@"deviceName" : deviceName ?: @"", //deviceName此处为蓝牙设备上线结果回调里获得的值,切记不能传设备发现时的MAC地址
@"groupIds":@[]
};
IMSIoTRequestBuilder *builder = [[IMSIoTRequestBuilder alloc] initWithPath:@"/awss/time/window/user/bind"
apiVersion:@"1.0.3"
params:params];
[IMSRequestClient asyncSendRequest:builder.build responseHandler:^(NSError * _Nullable error, IMSResponse * _Nullable response) {
if (error) {
LKAELogError(@"auth received error response : %@", error);
} else {
NSString * iotId = [response.data valueForKey:@"iotID"];
NSMutableDictionary *devInfo = @{}.mutableCopy;
[devInfo setValue:bleMac forKey:@"deviceName"];//此处为设备发现时得到的MAC地址
[devInfo setValue:productKey forKey:@"productKey"]
[devInfo setValue:iotId forKey:@"iotId"];
[IMSSubDeviceService notifySubDeviceBinded:devInfo];
}
}];
蓝牙设备的本地连接/断开
1、启动蓝牙连接,需要在使用蓝牙设备前调用。
#import <IMSThingCapability/IMSThingCapability.h>
IMSThing * thing = [[IMSThingManager sharedManager] buildThing:iotId];
[thing startLocalConnect];
2、断开蓝牙连接,需要在不需要使用蓝牙设备时调用
#import <IMSThingCapability/IMSThingCapability.h>
IMSThing * thing = [[IMSThingManager sharedManager] buildThing:iotId];
[thing stopLocalConnect];
3、蓝牙连接状态变化
需要传入 Delegate
IMSThing * thing = [[IMSThingManager sharedManager] buildThing:iotId];
[thing registerThingObserver:self];//请参见IMSThingObserver
蓝牙设备的控制
蓝牙设备的控制以及信息获取跟 Wi-Fi 设备的 API 是一致的,可以参考本文档前述章节。