本文介绍云云对接SDK中进阶功能的使用,包括自定义配置文件路径、配置动态创建网桥设备、调用SDK中封装的接口进行物模型数据上报、设备属性和事件批量上报、属性设置和服务调用。
自定义配置管理
默认情况下,网桥的配置文件和设备证书的映射关系配置文件,都是从固定路径的固定文件(分别是application.conf和devices.conf)中读取的。
云云对接SDK提供自定义配置能力,您只需在调用bootstrap方法前,先调用ConfigFactory.init方法,自定义配置文件的路径,自定义实例实现对应的接口。
使用自定义配置管理,必须实现getDeviceIdentity
和getOriginalIdentity
方法。
代码示例:
private static DeviceConfigManager selfDefineDeviceConfigManager = new DeviceConfigManager() {
@Override
public DeviceIdentity getDeviceIdentity(String originalIdentity) {
// 根据originalIdentity返回设备信息
return devicesMap.get(originalIdentity);
}
@Override
public String getOriginalIdentity(String productKey, String deviceName) {
// 根据设备信息返回originalIdentity
return null;
}
};
BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
ConfigFactory.init(ConfigFactory.getBridgeConfigManager("application-self-define.conf"),selfDefineDeviceConfigManager);
bridgeBootstrap.bootstrap();
动态创建网桥设备
当在大量的服务器上部署网桥应用,如果为每一个网桥服务器指定不同的网桥设备,信息会比较繁琐。为解决此问题,您可配置网桥信息文件application.conf,动态创建网桥设备。
您需在配置文件中,传入参数productKey和popClientProfile,云云对接SDK将调用物联网平台开放的API,以服务器MAC地址作为设备名称,创建一个网桥设备。
动态创建网桥设备,仅需修改网桥配置文件,调用代码与基础用法一致。
popClientprofile的所有参数必须配置完整。如果当前MAC地址为已有设备名称,会直接使用该设备作为网桥设备。
参数deviceName和deviceSecret值必须为空,如果已指定网桥设备信息,不会再动态创建设备。
建议使用专用的调测设备调试程序,不要直接在本地机器上调试,以免影响正式的生产环境。
在多个本地PC上调试程序,每次都会将当前机器的MAC地址注册为网桥,并将devices.conf文件中的所有设备与该网桥关联。
表 1. 配置参数说明
参数 | 是否必需 | 说明 |
productKey | 是 | 网桥设备所属产品的ProductKey。 |
subDeviceConnectMode | 否 | 网桥挂载设备模式:
大型网桥、小型网桥的挂载设备下线策略不同,请参见设备下线。 |
http2Endpoint | 是 | HTTP2网关服务地址。网桥设备和物联网平台通过HTTP2协议建立长连接通道。 地址结构:
|
authEndpoint | 是 | 设备认证服务地址。 地址结构:
|
popClientProfile | 是 | 配置此参数,云云对接SDK将调用阿里云物联网平台开放接口自动创建一个网桥设备。 具体参数配置见下表popClientProfile。 |
表 2. popClientProfile
参数 | 是否必需 | 描述 |
accessKey | 是 | 您的阿里云账号的AccessKey ID。 在物联网平台控制台,鼠标移动到您的账号头像上,然后单击AccessKey管理,创建或查看AccessKey。 |
accessSecret | 是 | 您的阿里云账号的AccessKey Secret。 |
name | 是 | 将要创建网桥设备的所在地域ID。 地域的表达方法,请参见地域和可用区。 |
region | 是 | |
product | 是 | 产品名称,固定为Iot。 |
endpoint | 是 | 调用指定地域API的节点地址。结构为 变量${RegionId}需替换成您的服务所在地域代码。RegionId的表达方法,请参见地域和可用区。 例如:华东2(上海)地域的endpoint为 |
以企业版实例为例,动态创建小型网桥设备的配置代码如下:
// 服务地址
http2Endpoint = "https://${IotInstanceId}.http2.iothub.aliyuncs.com:443"
authEndpoint = "https://${IotInstanceId}.auth.iothub.aliyuncs.com/auth/bridge"
// 网桥设备信息
productKey = ${YourProductKey}
popClientProfile = {
accessKey = ${YourAliyunAccessKey}
accessSecret = ${YourAliyunAccessSecret}
name = cn-shanghai
region = cn-shanghai
product = Iot
endpoint = iot.cn-shanghai.aliyuncs.com
}
调用物模型数据上报接口
云云对接SDK中封装了部分数据上报接口,包括属性上报接口 reportProperty、事件上报接口fireEvent和更新设备标签接口updateDeviceTag。设备可通过以上接口向物联网平台上报相应消息。
调用示例:
TslUplinkHandler tslUplinkHandler = new TslUplinkHandler();
//上报属性。
//已定义testProp属性。
String requestId = String.valueOf(random.nextInt(1000));
//上报属性时,不携带时间戳。
tslUplinkHandler.reportProperty(requestId, originalIdentity, "testProp", random.nextInt(100));
//上报属性时,携带时间戳。
//tslUplinkHandler.reportProperty(requestId, originalIdentity, "testProp", random.nextInt(100), System.currentTimeMillis());
//上报事件。
//已定义testEvent事件。
requestId = String.valueOf(random.nextInt(1000));
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("testEventParam", 123);
//上报事件时,不携带时间戳。
tslUplinkHandler.fireEvent(originalIdentity, "testEvent", ThingEventTypes.INFO, params);
//上报事件时,携带时间戳
//tslUplinkHandler.fireEvent(originalIdentity, "testEvent", ThingEventTypes.INFO, params, System.currentTimeMillis());
//上报设备标签。
//已定义设备标签key为testDeviceTag。
requestId = String.valueOf(random.nextInt(1000));
tslUplinkHandler.updateDeviceTag(requestId, originalIdentity, "testDeviceTag", String.valueOf(random.nextInt(1000)));
以上示例中参数说明如下。
参数 | 说明 |
requestId | 请求消息ID。 |
originalIdentity | 设备的原始身份标识符。 |
testProp | 属性的identifier。本示例的产品已定义功能属性标识符为testProp。本示例上报了该属性的值。 |
random.nextInt(100) | 上报的属性值。定义属性时,可设置其取值范围。在本示例中,使用 |
testEvent | 事件的identifier。本示例的产品已定义功能事件标识符为testEvent。本示例上报了该事件。 |
ThingEventTypes.INFO | 事件类型。ThingEventTypes表示事件类型,INFO表示事件类型值为INFO(信息)。 本示例产品定义事件testEvent时,选择的事件类型为信息(INFO)。 如果事件类型定义为故障,则该参数为 |
params | 事件的输出参数。事件输出参数的identifier、数据类型、取值范围等已在定义事件时定义。本示例中,上报事件的出参identifier是testEventParam,参数值是123。 |
testDeviceTag | 设备标签键(key),String类型。本示例中为testDeviceTag。 实际使用时,请根据设备标签键规范和您的需求设置。更多信息,请参见设备标签。 |
String.valueOf(random.nextInt(1000)) | 设备标签值(value),String类型。本示例中,用 |
System.currentTimeMillis() | 获取当前系统时间的毫秒数。 |
调用设备属性、事件批量上报接口
云云对接SDK封装了数据批量上报接口,通过BatchPostEventPropertyMessage 对象实例,链式调用addProperty和addEvent方法,分别添加属性和事件数据后,再通过TslUplinkHandler调用对象实例BatchPostEventPropertyMessage ,实现设备数据批量上报。
调用示例:
TslUplinkHandler tslUplinkHandler = new TslUplinkHandler();
//批量上报属性和事件
String requestId = String.valueOf(random.nextInt(1000));
long startTime = System.currentTimeMillis() - 3000;
//构造批量上报的报文
BatchPostEventPropertyMessage batchPostEventPropertyMessage = new BatchPostEventPropertyMessage();
Map<String, Object> aiEventParams = new HashMap<>();
aiEventParams.put("EventContent", "hello world");
batchPostEventPropertyMessage
.addProperty("PowerConsumption", 1000, startTime)
.addProperty("PowerConsumption", 123, startTime + 1000)
.addProperty("LightAdjustLevel", 23, startTime)
.addProperty("LightAdjustLevel", 44, startTime + 1000)
.addProperty("LightAdjustLevel", 47, startTime + 2000)
.addEvent("AIEvent", aiEventParams, startTime);
batchPostEventPropertyMessage.setId(requestId);
//发起上报
tslUplinkHandler.batchPostEventPropertyMessage(originalIdentity, batchPostEventPropertyMessage);
以上示例中参数说明如下。
参数 | 说明 |
requestId | 请求消息ID。 |
startTime | 属性和事件上报时间戳。类型为UTC毫秒级时间。可根据实际业务自定义。 |
aiEventParams | 上报事件的具体信息。 |
PowerConsumption | 属性的identifier。本示例的产品已定义功能属性标识符为PowerConsumption、LightAdjustLevel。本示例上报了两属性不同时间点的值。 |
LightAdjustLevel | |
AIEvent | 事件的identifier。本示例的产品已定义功能事件标识符为AIEvent。本示例上报了该事件。 |
originalIdentity | 设备的原始身份标识符。 |
调用属性设置、服务调用接口
云云对接SDK中封装了属性设置接口PropertySetHandler和服务调用接口ServiceInvokeHandler。设备端可通过以上接口接收物联网平台下发的指令,实现数据更新。
调用示例:
BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
//属性设置
bridgeBootstrap.setPropertySetHandler(new PropertySetHandler() {
@Override
public void onPropertySet(PropertySetMessage msg) {
log.info("on property set, {}", msg.getParams());
//如果调用replySuccess,则SDK会向物联网平台发送/property/set_reply消息,code为200
msg.replySuccess();
//如果调用replyFail,则SDK会向物联网平台发送/property/set_reply消息,code为调用方指定的code
//msg.replyFail(400);
}
});
//服务调用
bridgeBootstrap.setServiceInvokeHandler(new ServiceInvokeHandler() {
@Override
public void onServiceInvoke(ServiceInvokeMessage message) {
log.info("on service invoke, {}", message.getParams());
//如果调用replySuccess,则SDK会向物联网平台发送/service/{service.identifier}_reply消息,code为200
message.replySuccess();
//如果调用replyFail,则SDK会向物联网平台发送/service/{service.identifier}_reply消息,code为调用方指定的code
//msg.replyFail(400);
}
});