示例代码工程源码(Java):点击下载
工程包括:
以下以protocol-adapter-sdk-example-gateway为例,示例模拟了一台连接风扇子设备的私有协议的网关使用泛协议接入SDK接入OneNET上传子设备数据和下发子设备命令的过程,使用IntelliJ IDEA 2020.1.3 (Ultimate Edition) ,示例中的配置仅供参考,运行时需要修改为您自己的泛协议接入服务的相关配置信息。
泛协议接入适配SDK提供AdapterApi进行网关设备相关操作及网关设备、子设备的批量数据和历史数据上传,提供SubAdapterApi进行子设备相关操作。
示例项目结构如下图所示:
|-- src
|-- main
|-- java
|-- com.github.cm.heclouds.adapter
|-- adapter
|-- SampleGatewayDeviceDownLinkHandler.java 网关设备平台下行数据处理
|-- SampleSubDeviceDownLinkHandler.java 子设备平台下行数据处理
|-- SampleUpLinkHandler.java 设备上行数据处理
|-- tlv
|-- Tlv.java 示例使用的私有协议格式
|-- TlvDecoder.java 私有协议解码
|-- TlvEncoder.java 私有协议编码
|-- ProtocolAdapterSDKDemo.java 程序入口类
|-- resources
|-- config
|-- adapter.conf SDK配置
|-- devices.conf 设备映射配置
|-- protocolhub-tcp.conf TCP协议站配置
|-- logback.xml 自定义日志配置
|-- pom.xml
本示例定义了一种简单的仅供测试使用的自定义协议格式,为便于测试,协议忽略了SDK对于设备上行数据的响应: 数据格式:TLV,大端模式编码
含义 | 数据长度 | 说明 | |
---|---|---|---|
Type | 操作类型 | 2字节(16bit) | 1-网关设备上线,9-网关设备下线,101-子设备上线,102-子设备上传数据,103-给子设备下发命令,109-子设备下线,111-子设备响应下发命令 |
Length | 数据长度 | 2字节(16bit) | 指定数据payload长度 |
Value | 数据 | 长度由Length指定 | 数据payload,JSON类型,详情如下: |
{
"device_name": "wangguan"
}
{}
{
"sub_device_name": "zishebei"
}
字段 | 含义 |
---|---|
sub_deivce_name | 子设备名称 |
{
"sub_device_name": "zishebei",
"data": {
"status": 1,
"gear": 2,
"duration": 10000
}
}
字段 | 含义 |
---|---|
status | 电风扇状态: 0-关,1-开 |
gear | 电风扇档位:1-低速,2-中速,3-高速 |
duration | 电风扇已开启持续时间: 单位ms |
{
"id": "1609916964",
"sub_device_name": "zishebei",
"data": {
"status": 1,
"gear": 1
}
}
{
"id": "1609916964",
"sub_device_name": "zishebei",
"code": 200,
"msg": "success"
}
字段 | 含义 |
---|---|
id | 命令id |
code | 响应状态:200-成功 |
msg | 响应信息 |
{
"sub_device_name": "zishebei"
}
1).新建并修改src/main/resources/config文件夹下的adapter.conf和device.conf文件:
可参考最佳实践-云云对接
2).新建并修改项目src/main/resources/config文件夹下的protocolhub-tcp.conf文件:
可参考最佳实践-代理直连设备
3).新建程序入口类ProtocolAdapterSdkDemo.java
网关设备登陆后,使用TCP工具发送00 65 00 1E 7B 22 73 75 62 5F 64 65 76 69 63 65 5F 6E 61 6D 65 22 3A 22 7A 69 73 68 65 62 65 69 22 7D,此报文为编码后的TLV数据,type=101,表示登录子设备,相应的处理代码为
subDeviceAdapterApi.subDeviceOnline(device, subDevice);
在Studio上可观察到子设备在线状态。
同时,在Studio上可观察到子设备最新上传的数据。
SubDeviceDownLinkRequestHandler中onSetSubDevicePropertyRequest(Device, String, String, String, JsonObject)方法提供了处理平台下发子设备属性设置业务的接口,SampleSubDeviceDownLinkHandler中实现了此接口。
1).实现监听接口:
private final DevicePropertySetListener listener = (device, id, version, params) -> {
logger.logDevInfo(ConfigUtils.getName(), PLATFORM_DOWN_LINK, device.getProductId(), device.getDeviceName(), "property set command received: " +
"id=" + id + ", version=" + version + ", value=" + params);
// 获取子设备原始id
String subDeviceName = params.get("deviceName").getAsString();
String subDevicePid = params.get("productId").getAsString();
String originalId = ConfigUtils.getDeviceConfig().getOriginalIdentity(subDevicePid, subDeviceName);
// 获取数据
JsonObject dataParams = params.get("params").getAsJsonObject();
JsonElement status = dataParams.get("status");
JsonElement gear = dataParams.get("gear");
// 构造给子设备下发的命令
// value格式为
//{
// "id": "1609916964",
// "sub_device_name": "subDevice",
// "data": {
// "status": 1,
// "gear": 1
// }
//}
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("id", id);
jsonObject.addProperty("sub_device_name", originalId);
JsonObject data = new JsonObject();
if (status != null) {
data.add("status", status);
}
if (gear != null) {
data.add("gear", gear);
}
jsonObject.add("data", data);
// type=111表示向子设备下发命令
Tlv tlv = new Tlv((short) 111, jsonObject);
// 推送给设备
deviceDownLinkApi.pushToDevice(device, tlv);
};
2).实现SubDeviceDownLinkRequestHandler,编写收到平台下发子设备属性设置的业务逻辑。
@Override
public void onSetSubDevicePropertyRequest(Device device, String id, String version, JsonObject params) {
listener.onCommandReceived(device, id, version, params);
}
3).调试设备
使用Studio设备调试工具设置子设备属性,填入合法属性值,点击发送。
SDK接收到平台下发的子设备属性设置请求,会按照代码编写的业务逻辑,将请求发送给网关设备,网关设备会收到如下图所示经TLV编码后的消息:
使用TCP工具模拟子设备响应命令下发,发送00 67 00 43 7B 22 69 64 22 3A 22 31 30 22 2C 22 73 75 62 5F 64 65 76 69 63 65 5F 6E 61 6D 65 22 3A 22 7A 69 73 68 65 62 65 69 22 2C 22 63 6F 64 65 22 3A 32 30 30 2C 22 6D 73 67 22 3A 22 73 75 63 63 65 73 73 22 7D报文,此报文为编码后的TLV数据,type=103,表示子设备响应回复:
{
"id": 10,
"code": 200,
"msg": "success"
}
您可使用SubDeviceAdapterApi提供的方法响应命令,如:
String id = tlvValue.get("id").getAsString();
int code = tlvValue.get("code").getAsInt();
String msg = tlvValue.get("msg").getAsString();
// 构造响应回复
Response response = new Response(id, code, msg);
// 注意device是网关设备,并不是子设备
subDeviceAdapterApi.replySubDevicePropertySetRequest(device, response);
此时,可在页面上看到平台已成功接收到子设备的命令响应。
网关设备发送00 6D 00 1E 7B 22 73 75 62 5F 64 65 76 69 63 65 5F 6E 61 6D 65 22 3A 22 7A 69 73 68 65 62 65 69 22 7D报文,此报文为编码后的TLV数据,type=109,表示子设备主动下线。调用子设备API通知平台接入机主动登出子设备:
subDeviceAdapterApi.deviceOffline(device, subDevice)
接入机返回登出成功响应。
此时在Studio页面中可观察到子设备已经离线: