# MQTT直连接入

本文档以MQTTX为例,介绍使用第三方软件以MQTT协议接入物联网平台。

# 下载并安装MQTTX

前往官网下载 (opens new window)安装

# 系统配置

# 操作步骤

1.登录Jetlinks物联网平台,进入协议管理菜单,上传协议包。

获取协议包源码

2.进入网络组件菜单,配置MQTT服务类型的网络组件。

3.进入设备接入网关菜单,配置接入方式为MQTT直连的网关。
 (1)选择第2步创建的MQTT服务网络组件
 (2)选择第1步创建的协议包
 (3)填写设备接入网关名称

4.创建产品,并进入设备接入tab,选择所需的设备接入网关。

5.在设备接入tab页面中填写官方协议包认证信息;然后启用产品。

说明

不同协议包在设备接入界面所需要填写的方式不同。官方协议包,需要填写设备认证所需要的的账号密码

在设备接入tab页的MQTT认证配置项中填写 secureId为:admin secureKey为:admin。

6.创建设备,选择对应的所属产品,然后启用设备。

注意

需要先启用产品,才能基于产品创建设备

# 使用MQTTX模拟设备连接到平台

1.打开MQTTX软件,点击新建连接创建一个连接,设置连接参数

# 连接参数说明

参数 说明
Name 输入您的自定义名称。
Client ID 设备Id。必须与系统中设备的ID填写一致。
Host 连接域名。本地连接可直接填写 `127.0.0.1`,如为远程连接,请填写产品-设备接入页-连接信息显示的连接地址。
Port 请填写产品-设备接入页-连接信息显示的端口。
Username 填写接入账号
Password 填写接入密码

说明

使用JetLinks官方协议包接入设备,用户名和密码需要经过加密规则处理。
可使用账号密码自动生成器获取

注意

经过加密规则处理的账号密码超过5分钟后将不在可用,需重新生成

2.点击连接按钮,平台中设备状态变为在线

说明

如您在点击连接后遇到MQTTX提示异常信息或设备未上线等问题。可在设备详情-设备诊断页中,诊断设备未上线原因

# 设备数据上下行

设备连接上平台后,可进行一些基本的事件上报、属性读取等操作。

# 物模型创建

在产品详情-物模型tab页中分别创建属性、事件、功能三种物模型

创建属性 属性ID: temperature

创建功能 功能ID: playVoice

创建事件 事件ID: alarm_fire

# 读取设备属性

1.登录Jetlinks物联网平台,点击设备查看按钮,进入运行状态tab页。
2.点击设备运行状态中某个属性的获取属性值按钮。 MQTTX会收到平台下发指令消息

说明

复制好订阅该topic收到的消息中的messageId。此messageId将作为回复与平台设备属性的凭据之一。

3.回复平台设备读取消息
topic格式参考:JetLinks官方协议-读取设备属性
消息内容格式如下


{
  "deviceId": "设备Id",
  "messageId": "平台下发报文中的messageId",
  "properties":{
    "temperature": 35.6
  },
  "success": true
}

回复参数说明

参数 说明
messageId 平台下发报文中的messageId
deviceId 设备ID
success 成功标识
properties 设备属性值对象。例如: { "temperature":"50"}

点击消息发送按钮图标,向平台推送该消息。

4.平台收到MqttX推送的属性值后,将会实时展示到运行状态中。

注意

从在系统界面中点击刷新到MQTTX端回复消息,需在10秒内完成。否则平台会视为该次操作超时,导致读取属性值失败。

# 设备事件上报

MQTTX 推送设备事件消息到平台。

1.在MQTTX上,填写事件上报topic。topic格式参考JetLinks官方协议-设备事件上报
2.输入事件上报Topic和要发送的事件内容,点击"发送"按钮图标,向平台推送该事件消息。

设备事件上报数据

{
 "data":{
   "addr":"未来科技城 C2 栋",
  "time":"12-05-2012"
 }
}
参数 说明
data 对象类型的报文数据

上报成功后,在设备-运行状态tab页,可查看事件具体信息。

# 调用设备功能

1.在设备-设备功能tab页,选择设备功能模块,点击执行,向设备发送功能调用指令。 3.填写设备功能回复topic和报文。格式参考JetLinks官方协议-调用设备功能

设备功能回复报文

{
 "messageId":"平台下发报文中的messageId", 
 "output":true,
 "success":true
}
参数 说明
messageId 平台下发报文中的messageId
output 返回的对象类型执行结果
success 成功状态

设备功能调用成功后在设备-设备功能tab页显示调用回复结果。

# MQTT Broker接入

在某些场景,设备不是直接接入平台,而是通过第三方MQTT服务,如:emqx接入。 本文使用mqttx模拟设备端,通过emqx接入平台。

# 安装并启动EMQ

前往官网下载 (opens new window)安装

本文使用docker搭建

docker run -d --name emqx -p 18083:18083 -p 1883:1883 emqx/emqx:latest

# 访问EMQX Dashboard

在浏览器中输入 http://127.0.0.1:18083 ,默认账号密码为用户名:admin 密码:public。

# 系统配置

# 操作步骤

1.登录Jetlinks物联网平台,进入网络组件菜单,创建MQTT客户端网络组件。

如EMQX服务在本机电脑启用,MQTT客户端网络组件填写参数参考下图填写即可

网络组件填写参数说明

参数 说明
远程地址 emqx启动所在服务的IP地址,emq本机启动的可填写127.0.0.1
远程端口 emqx启动的服务端口
clientId 连接到emqx的客户端Id
用户名 连接到emqx时需要的用户名
密码 连接到emqx时需要的密码
最大消息长度 单次收发消息的最大长度,单位:字节;

2.进入协议管理菜单,上传协议包。

获取协议包源码

3.进入设备接入网关,创建MQTT Broker类型的接入网关。

网关创建完成后,可在emqx客户端中的“Subscriptions”菜单中看到订阅列表

4.创建产品,并选中接入方式为MQTT Broker类型的设备接入网关。

5 创建物模型

在产品详情-物模型tab页中创建温度属性物模型,属性ID:temperature

5.创建设备,选择第4步中创建的产品。

注意

需要先启用产品,才能基于产品创建设备

# 使用MQTTX模拟设备与平台进行交互

下载并安装MQTTX。 可前往官网下载 (opens new window)安装

1.打开MQTTX软件,点击新建连接创建一个连接

2.设置连接参数。连接到EMQX

如EMQX服务在本机电脑启用,连接参数参数参考下图填写即可

连接参数说明

参数 说明
Name 自定义名称
Client ID 注册到EMQX的客户端Id。可自定义填写任意字符串
Host 填写启动EMQX服务的IP地址
Port EMQX启动的服务端口

# 物模型属性上报

推送物模型属性消息到EMQX。实现平台设备上线与消息接收

推送设备上报属性topic格式和报文参考:JetLinks官方协议-读取设备属性

topic:/产品Id/设备Id/properties/report

{
    "properties":{"temperature":36.8}
}

进入平台设备详情界面,此时设备以变成在线状态,且收到了刚刚的温度属性消息

# 物模型属性读取回复

1.在MQTTX中点击订阅添加按钮

2.添加订阅设备读取属性topic:/+/+/properties/read。格式参考:JetLinks官方协议-读取设备属性

后续操作参考读取设备属性

# TCP 透传接入

通过官方设备模拟器模拟TCP设备接入平台

# 系统配置

1.登录Jetlinks物联网平台,进入网络组件菜单,创建TCP服务网络组件。

如服务在本机电脑启用,TCP服务网络组件填写参数参考下图填写即可

网络组件填写参数说明

参数 说明
本地地址 TCP绑定到服务器上的网卡地址,绑定到所有网卡:0.0.0.0
本地端口 监听指定端口的请求
远程地址 对外提供访问的地址,内网环境时填写服务器的内网IP地址
公网端口 对外提供访问端口
粘拆包规则 处理TCP粘拆包的方式
长度 从0开始,读取N个字节的数据值来标识TCP消息内容长度
偏移量 使用"长度"字段解析TCP消息内容长度时的偏移量
大小端 使用大端或小端来解析TCP消息内容长度

2.进入协议管理菜单,上传协议包。

获取协议包源码

3.进入设备接入网关,创建TCP透传类型的接入网关。

4.创建产品,并选中接入方式为TCP透传类型的设备接入网关。

5.设置TCP认证配置的secureKey值为admin

6.创建物模型

在产品详情-物模型tab页中创建温度属性物模型,属性ID:temperature

7.创建设备,选择第4步中创建的产品。

注意

需要先启用产品,才能基于产品创建设备

# 获取模拟器

前往获取JetLinks官方设备模拟器 (opens new window)

# 编写tcp设备模拟脚本

将如下脚本内容复制到模拟器项目的benchmark/tcp/benchmark.js中。覆盖原有脚本内容

注意

请修改下面脚本代码中deviceId为自己系统中刚刚创建的TCP设备ID


var protocol = require("benchmark/jetlinks-binary-protocol.js");


var $enableReport = "true" === args.getOrDefault("report", "true");
var $reportLimit = parseInt(args.getOrDefault("reportLimit", "1"));
var $reportInterval = parseInt(args.getOrDefault("interval", "1000"));

//绑定内置参数,否则匿名函数无法使用。
var $benchmark = benchmark;
//平台配置的密钥
var secureKey = args.getOrDefault("secureKey", "admin");

var deviceId = "1602199560887795712";


function beforeConnect(index, options) {
    options.setId(deviceId);
}


//平台下发读取属性指令时
protocol.doOnReadProperty(function (properties) {

    $benchmark.print("读取属性:" + properties);

    let data = newHashMap();

    properties.forEach(function (property) {
        data.put(property, randomFloat(20, 30))
    });

    return data;
});

//全部连接完成后执行
function onComplete() {
    if (!$enableReport) {
        return;
    }
    // 心跳
    $benchmark
        .interval(function () {
            return $benchmark.randomConnectionAsync(99999999, function (client) {
                return sendTo(client, protocol.createPing(client));
            });
        }, 1000)

    // 定时执行
    $benchmark
        .interval(function () {
            $benchmark.print("上报属性....");
            //随机获取100个连接然后上报属性数据
            return $benchmark.randomConnectionAsync($reportLimit, reportTcpProperty);
        }, $reportInterval)

}


function sendTo(client, buffer) {
    var len = buffer.writerIndex();
    // $benchmark.print(client.getId() + " 发送数据 0x" + client.toHex(buffer))
    client.send(
        newBuffer().writeInt(len).writeBytes(buffer)
    )

}

//协议发往设备
protocol.doOnSend(sendTo);


//单个连接创建成功时执行
function onConnected(client) {

    //上线
    sendTo(client, protocol.createOnline(client, secureKey));

    //订阅读取属性
    client
        .handlePayload(function (buf) {

            let buffer = buf.getByteBuf();

            //忽略长度字段
            buffer.readInt();

            protocol.handleFromServer(client, buffer);
        });

}

//随机上报数据
function reportTcpProperty(client) {
    var data = new java.util.HashMap();
    for (let i = 0; i < 1; i++) {
        data['temperature'] = randomFloat(10, 30);
    }
    sendTo(client, protocol.createReportProperty(client, data));
}


//重点! 绑定函数到benchmark
benchmark
    .beforeConnect(beforeConnect)
    .onConnected(onConnected)
    .onComplete(onComplete);

# 运行模拟器

1.在模拟器项目根目录执行如下命令

$ ./run-cli.sh

2.在运行成功的界面中执行如下命令。

 $ benchmark tcp --size=1 --name=tcp --host=127.0.0.1 --port=8803 --script=benchmark/tcp/benchmark.js
  1. 出现如下界面表示TCP设备连接成功,并正在上报数据

说明

如设备连接未成功,可以尝试更新最新版本的官方协议包后。重新连接

# HTTP接入

# 应用场景

说明

适用于HTTP设备接入平台。

# 指导介绍

1. 新增接入协议
2. 新增网络组件
3. 新增设备接入网关
4. 新增产品
5. 新增设备
6. 配置产品物模型
7. 设备接入

# 平台相关配置

# 新增接入协议

说明

设备与平台进行通信需要有协议包的支持,平台支持基于HTTP协议通过自定义协议包的方式,以解析不同厂家、不同设备上报的数据。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏运维管理>>>协议管理

协议管理页面

2、clone或者下载协议包,此示例使用的为JetLinks官方设备接入协议V3分支。将协议包下载或者clone到本地磁盘,如果clone过程中出现错误可以参考如何配置ssh-key

如何下载协议包

下载完成后的协议包目录如下。

clone或者下载完成解压后的protocol

3、在JetLinks平台协议管理内选择新增

通过Jar包的方式新增。

添加新协议

上传Jar包(需通过maven命令打包)。

上传Jar包

新增完成后平台显示新增的协议如下。

Jar包方式新增协议完成

# 新增网络组件

说明

网络组件是用于管理网络服务动态配置、启停,只负责接收、发送报文,不负责任何处理逻辑。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏运维管理>>>网络组件

2、填入配置参数,点击保存按钮

填写参数 说明
名称 必填项,该网络组件的名称。
类型 必选项,此处选择HTTP服务。
集群 必选项,共享配置:集群下所有节点共用同一配置。
独立配置:集群下不同节点使用不同配置。
本地地址 绑定到服务器上的网卡地址,此处固定为0.0.0.0,表示接收所有请求。
本地端口 必填项,监听指定端口的请求。
公网地址 必填项,对外提供访问的地址,内网环境时填写服务器的内网IPv4地址。仅用于展示,给运维人员做公网端口和本地地址绑定关系展示使用。
公网端口 必填项,对外提供访问的端口。
开启TLS 必选项,是否开启tls加密,如果选择开启则需要配置证书,配置详情可以参考证书配置
说明 选填项,该网络组件的备注说明。

说明

本地端口内可选择的端口号范围可在jetlinks-standalone模块内的application.yml配置文件中通过修改network.resources的值进行指定,完整路径为jetlinks-standalone/resources/application.yml

添加HTTP网络组件

# 新增设备接入网关

说明

负责平台侧统一的设备接入,使用网络组件处理对应的请求以及报文,使用配置的协议解析为平台统一的设备消息(DeviceMessage),然后推送到事件总线。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏运维管理>>>设备接入网关

2、点击新增>>>HTTP推送接入,选择配置的HTTP网络组件JetLinks官方协议,命名后点击保存

网络组件添加配置

网关配置

网关配置

# 新增产品

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏设备管理>>>产品

2、点击新增,填写产品名称,选择设备类型,之后点击确定

新增HTTP产品

3、点击创建好的产品进入产品详情页,选择设备接入,点击选择并在弹出的设备接入配置中选择上一步配置的HTTP接入网关,点击确定。

产品配置网关

4、填写HTTP认证配置,填入Token值,然后启用产品。

说明

Token是设备连接到平台时的身份验证,每次发送数据包都会在Header中携带,可以在协议包中进行配置一型一密或者一机一密。

产品信息配置完成

# 新增设备

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏设备管理>>>设备

2、点击新增,填写设备名称,选择上一步配置的产品,此处选择之后点击确定,并在此页面启用设备。

新增设备

启用设备

# 配置产品物模型

说明

物模型是对某一类产品自身功能的一种抽象,在平台可表述为属性、功能、事件和标签。当在产品中配置物模型后,该类型下的设备都会继承该产品的物模型。但如果在设备中单独进行配置,即使未对继承的物模型进行更改,该设备的物模型也会脱离产品,需要独自进行维护。

1、 进入物联网>>>设备管理>>>产品页面,点击上文创建的产品,进入该产品的产品详情页,选择物模型

产品配置物模型

2、在物模型>>>属性定义内点击右侧新增来新增属性定义

填写标识actual_voltage,名称实际电压,数据类型float,来源选择设备,读写类型选择读 写 上报

配置产品物模型属性

3、选择事件定义>>>右侧新增,填入参数后右上角选择保存

填写标识abnormal_current,名称电流异常,级别警告,输出参数选择object(结构体)

产品添加事件

填写标识actual_current,名称实际电流,数据类型long

产品添加事件配置参数

4、配置完成后可以选择设备并找到对应产品下的设备,点击查看设备详情,选择运行状态,可以直观的看到配置完成的属性和事件。

设备运行状态页面

设备事件

# Postman模拟设备接入

# 设备接入

说明

本示例将使用Postman模拟设备进行连接平台以及属性和事件上报。

# 设备上线

1、 下载Postman,安装完成后打开。

添加新请求

2、填写连接参数

配置连接参数。

参数 说明
POST 本次请求为POST
连接地址 http://{产品详情页里设备接入页面中的连接信息ip:端口号}/{指定的topic},具体的Topic信息,可以查看官方协议Topic列表。此处为设备上线消息/{产品id}/{设备id}/online

添加配置参数配置Headers参数。

参数Key 参数Value 说明
Authorization Bearer My_Token Key固定填写Authorization,Bearer为固定值,注意中间有一个空格My_Token为在产品的设备接入页面配置的Token

postman添加headers

配置Body参数。

参数 说明
raw 可以上传任意格式的文本,可以上传text、json、xml、html等,此处选择JSON
JSON 选择上传JSON格式的文本
消息体 想要上传的文本内容,此处由于为设备上线,所以消息体可以不写,但必须填写{}

postman配置Body

配置完成后点击Send按钮,发送本次请求,可以看到下方收到的消息"success": true,表示设备上线成功,可以在平台看到设备为在线状态。

设备上线

# 设备上报属性

上报属性的Topic为/{产品id}/{设备id}/properties/report

//上报的消息体
{
	"deviceId": "1621406622872461312",//设备Id
	"properties": {
		"actual_voltage": 12.4 //上报数据
	}
}

Postman设备属性上报

配置完成后点击Send按钮,发送本次请求,收到的消息"success": true,表示此次属性上报成功,可以在平台看到设备运行状态内有上报的属性值。

设备上报的属性

# 设备事件上报

上报事件的Topic为/{产品id}/{设备id}/event/{事件id}

//上报的消息体
{
	"timestamp": 1675417805717, //毫秒时间戳
	"messageId": "1621330658213723941", //随机消息Id
	"data": {
		"actual_current": 23 //上报数据,类型与物模型事件中定义的类型一致
	}
}

事件上报

配置完成后点击Send按钮,发送本次请求,收到的消息"success": true,表示此次事件上报成功,可以在平台看到设备运行状态内有事件上报的值。

事件上报成功

# 使用设备模拟器

1、获取设备模拟器

获取JetLinks官方设备模拟器 (opens new window)

2、启动设备模拟器

启动设备模拟器

设备模拟器启动成功

3、修改项目目录下的benchmark/http/benchmark.js内容

/**
 * JetLinks http 官方协议模拟器
 *  benchmark http --url http://127.0.0.1:8801 report=true reportLimit=100 interval=1000
 */

//绑定内置参数,否则匿名函数无法使用。
var $benchmark = benchmark;

//在jetlinks平台的产品ID
var productId = args.getOrDefault("productId", "1621404717110747136");
//在jetlinks平台的设备ID
var deviceIdPrefix = args.getOrDefault("deviceIdPrefix", "1621406622872461312");
//配置的Token信息
var secureKey = "My_Token";

var $enableReport = "true" === args.getOrDefault("report", "true");
//上报次数
var $reportLimit = parseInt(args.getOrDefault("reportLimit", "100"));
//上报间隔 毫秒
var $reportInterval = parseInt(args.getOrDefault("interval", "1000"));


//创建连接之前动态生成用户名密码
function beforeConnect(index, options) {
    var clientId = deviceIdPrefix;
    options.setId(clientId);
    $benchmark.print(toJson(clientId));
}

//全部连接完成后执行
function onComplete() {
    if (!$enableReport) {
        return
    }
    //定时执行1s
    $benchmark
        .interval(function () {
            $benchmark.print("批量上报属性..");
            return $benchmark
                .randomConnectionAsync($reportLimit, reportProperties);
        }, $reportInterval)

}

function reportProperties(client) {
    //创建随机数据
    var data = {};
    // $benchmark.print("上报[" + client.getId() + "]属性");
        //jetlinks平台内属性上报配置的属性值
        data["actual_voltage"] = randomFloat(10, 30);
    var msg = {
        "properties": data
    }
    $benchmark.print(toJson(msg));
    //请求
    return client.requestAsync({
        method: "POST",
        headers: {
            "Authorization": "Bearer " + secureKey
        },
        path: createTopic(client, "/properties/report"),
        contentType: "application/json",
        body: toJson(msg)
    });

}

//根据jetlinks官方协议topic规则创建topic
function createTopic(client, topic) {
    return "/" + productId + "/" + client.getId() + topic;
}


//重点! 绑定函数到benchmark
benchmark
    .beforeConnect(beforeConnect)
    // .onConnected(onConnected)
    .onComplete(onComplete);

4、执行命令开始属性上报

运行指令

//需要修改连接地址
benchmark http --url http://192.168.66.203:8810 report=true reportLimit=1000 --size=1  --script=benchmark/http/benchmark.js

属性上报成功

# UDP接入

# 应用场景

说明

适用于UDP设备接入平台。

# 指导介绍

1. 新增协议
2. 新增网络组件
3. 新增设备接入网关
4. 新增产品
5. 新增设备
6. 配置产品物模型
7. 设备接入

# 平台配置相关

# 新增协议

说明

设备与平台进行通信需要有协议包的支持,平台支持基于UDP协议通过自定义协议包的方式,以解析不同厂家、不同设备上报的数据。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏运维管理>>>协议管理

协议管理页面

2、clone或者下载协议包,此示例使用的为JetLinks官方设备接入协议V3分支。将协议包下载或者clone到本地磁盘,如果clone过程中出现错误可以参考如何配置ssh-key

如何下载协议包

下载完成后的协议包目录如下。

clone或者下载完成解压后的protocol

3、在JetLinks平台协议管理内选择新增

通过Jar包的方式新增。

添加新协议

上传Jar包(需通过maven命令打包)。

上传Jar包

新增完成后平台显示新增的协议如下。

Jar包方式新增协议完成

# 新增udp网络组件

说明

网络组件是用于管理网络服务动态配置、启停,只负责接收、发送报文,不负责任何处理逻辑。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏运维管理>>>网络组件

2、填入配置参数,点击保存按钮

填写参数 说明
名称 必填项,该网络组件的名称。
类型 必选项,此处选择UDP。
集群 必选项,共享配置:集群下所有节点共用同一配置。
独立配置:集群下不同节点使用不同配置。
本地地址 绑定到服务器上的网卡地址,此处固定为0.0.0.0,表示接收所有请求。
本地端口 必填项,监听指定端口的请求。
公网地址 必填项,对外提供访问的地址,内网环境时填写服务器的内网IPv4地址。仅用于展示,给运维人员做公网端口和本地地址绑定关系展示使用。
公网端口 必填项,对外提供访问的端口。
开启DTLS 必选项,是否开启DTLS加密,如果选择开启则需要配置证书,配置详情可以参考证书配置
说明 选填项,该网络组件的备注说明。

说明

本地端口内可选择的端口号范围可以在代码jetlinks-standalone模块内的application.yml配置文件中通过修改network.resources的值进行指定,完整路径为jetlinks-standalone/resources/application.yml

添加UDP网络组件

# 新增udp设备接入网关

说明

负责平台侧统一的设备接入,使用网络组件处理对应的请求以及报文,使用配置的协议解析为平台统一的设备消息(DeviceMessage),然后推送到事件总线。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏运维管理>>>设备接入网关

2、点击新增>>>UDP接入,选择配置好的UDP网络组件JetLinks官方协议,命名后点击保存

网络组件添加配置

UDP网关配置

UDP网关配置

# 新增udp产品

说明

对某一型设备的分类,通常是已经存在的某一个设备型号。

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏设备管理>>>产品

2、点击新增,填写产品名称,选择设备类型,点击确定

新增UDP产品

3、点击创建的产品并进入产品详情页,选择设备接入,点击选择并选择上一步配置的UDP设备接入网关,点击确定。

UDP产品配置网关

4、继续在此页面的底端找到UDP认证配置,填入secureKey的值,此处配置为admin,然后点击启用产品。

说明

secureKey是设备连接到平台时的身份验证,每次发送数据包都会携带,可以在协议包中进行配置一型一密还是一机一密。

UDP产品信息配置完成

# 新增udp设备

1、 登录JetLinks平台,选择顶部导航栏物联网>>>左侧菜单栏设备管理>>>设备

2、点击新增,填写设备名称,选择所属产品,此处选择之后点击确定,并在此页面启用设备。

说明

此处设置ID为ele_dev_a_1_13是方便后续设备上线、属性上报等操作上报的报文一致。

新增UDP设备

启用UDP设备

# 配置udp产品物模型

说明

物模型是对某一类产品自身功能的一种抽象,在平台可表述为属性、功能、事件和标签。当在产品中配置物模型后,该类型下的设备都会继承该产品的物模型。但如果在设备中单独进行配置,即使未对继承的物模型进行更改,该设备的物模型也会脱离产品,需要独自进行维护。

1、 进入物联网>>>设备管理>>>产品页面,点击上文创建的产品,进入该产品的产品详情页,选择物模型

UDP产品配置物模型

2、在物模型>>>属性定义内点击右侧的新增来新增属性定义

配置UDP产品物模型属性

3、选择功能定义>>>右侧新增,注意此处配置的为输出参数,参数配置完成后选择保存

输出参数选择为结构体。

功能选择结构体

新增参数,标识location,名称电表位置,数据类型选择text

配置UDP产品功能

新增参数,标识timestamp,名称时间戳,数据类型选择long

配置UDP产品功能

新增参数,标识consumption,名称用电量,数据类型选择double

配置UDP产品功能

4、选择事件定义>>>右侧新增,填入参数后右上角选择保存

新增参数,标识location,名称位置,数据类型选择text

UDP产品添加事件

新增参数,标识timestamp,名称时间戳,数据类型选择long

UDP产品添加事件

新增参数,标识state_code,名称状态码,数据类型选择text

UDP产品添加事件

4、配置完成后可以选择设备并找到对应产品下的设备,点击查看设备详情,选择运行状态,可以直观的看到配置完成的属性和事件,选择设备功能可以看到已经配置好的产品功能。

设备运行状态页面

设备功能页面

# 使用SocketTool接入

# udp设备接入

说明

本示例将使用SocketTool模拟设备进行连接平台以及属性、事件上报和功能调用回复。

# 设备上线

1、 下载SocketTool,下载完成后打开。

socket-tool

2、配置连接参数连接平台。

配置连接参数

连接成功

3、填写报文00000561646d696e01000001862606b03e0077000e656c655f6465765f615f315f3133000561646d696e报文是如何计算的?),之后点击发送数据,进行设备上线。

socket工具发送数据

收到平台消息

4、设备成功上线。

udp设备上线

# 设备上报属性

填写报文00000561646D696E03000001862666B12B0088000E656C655F6465765F615F315F31330001000B636F6E73756D7074696F6E0A40888A8F5C28F5C3报文是如何计算的?),之后点击发送数据,可以在设备运行状态页面查看上报的属性。

udp设备上报属性

查看属性上报

# 设备事件上报

填写报文(注意去除每一段之间的换行符)00000561646D696E0a000001862666B12B0088000E656C655F6465765F615F315F3133000d73746174655f7761726e696e6700
0300086c6f636174696f6e0B000c6a696e6b655f615f315f3133000974696d657374616d700500000186281cb583000a7374617
4655f636f64650B000e696c6c656167616c5f7374617465
报文是如何计算的? ),之后点击发送数据,可以在设备运行状态页面查看上报的事件。

设备事件上报

事件上报成功

# 设备功能调用回复

说明

功能调用回复需要在10秒内回复,否则会出现超时的提示。

在调试时,可以通过修改配置将功能调用回复的超时时间设置的比较长。

设置超时时间

将超时时间设置为120秒,配置完成后需要重启后台服务。

设置超时时间

Jetlinks平台选择对应的设备,点击设备功能,点击执行

设备执行功能

选择日志管理查看最新一条的功能调用日志的内容,复制其中的messageId的值。如果提示设备已离线,则需要先发送上线报文00000561646d696e01000001862606b03e0077000e656c655f6465765f615f315f3133000561646d696e进行设备上线。

获取messageId

JetLinks官方协议的代码中找到testFunction方法,路径为org.jetlinks.protocol.official.binary.BinaryMessageTypeTest。复制示例代码,并将messageId的值修改为上一步复制的messageId后运行。

找到对应的Test类

    @Test
    public void testFunction() {
        FunctionInvokeMessageReply reply = new FunctionInvokeMessageReply();
        reply.setDeviceId("ele_dev_a_1_13");
        reply.setMessageId("1622906517320265729");//修改为复制的messageId值
        Map<String, Object> output = new LinkedHashMap<>();
        output.put("location", "location");
        output.put("timestamp", "1675764401261");
        output.put("consumption", new Random().nextDouble());
        reply.setOutput(output);
        doTest(reply);
    }

复制报文段

在生成的报文段前加上00000561646d696e后通过工具发送,然后可以在平台日志查看调用功能回复的内容。

添加报文段

功能调用回复成功

# 获取报文

1、找到官方协议中的BinaryMessageTypeTest类,完整路径为org.jetlinks.protocol.official.binary.BinaryMessageTypeTest

找到测试类

2、选择需要生成报文类型的方法

选择测试方法

3、设置所需参数,运行后可以得到消息体报文

获得报文

4、拼接固定报文

例如拼接的报文为00000561646d696e,其中00为固定值,0005表示平台配置的secureKey长度,使用十六进制表示。61646d696e表示平台配置的十六进制secureKey值,此处为字符串的admin

5、获取完整报文

00000561646d696e05000001862bd8d7be0002000474657374010001000474656d700a404070a3d70a3d71,使用工具发送即可,此处生成的报文表示读取属性回复。

# 使用设备模拟器

1、获取设备模拟器

获取JetLinks官方设备模拟器 (opens new window)

2、启动设备模拟器

启动设备模拟器

3、修改项目目录下的benchmark/udp/benchmark.js内容

/**
 * JetLinks tcp 官方协议模拟器
 *
 *    benchmark tcp --host=127.0.0.1 --port=8801 --script=demo/tcp/benchmark.js report=true reportLimit=100 interval=1000
 */

var protocol = require("benchmark/jetlinks-binary-protocol.js");


var $enableReport = "true" === args.getOrDefault("report", "true");
//上报次数
var $reportLimit = parseInt(args.getOrDefault("reportLimit", "100"));
//发送时间间隔 单位毫秒
var $reportInterval = parseInt(args.getOrDefault("interval", "1000"));

//绑定内置参数,否则匿名函数无法使用。
var $benchmark = benchmark;
//平台配置的密钥
var secureKey = args.getOrDefault("secureKey", "admin");


//平台下发读取属性指令时
protocol.doOnReadProperty(function (properties) {

    $benchmark.print("读取属性:" + properties);

    let data = new java.util.HashMap();

    properties.forEach(function (property) {
        data.put(property, randomFloat(20, 30))
    });

    return data;
});

//全部连接完成后执行
function onComplete() {
    if (!$enableReport) {
        return;
    }
    // 定时执行1s
    $benchmark
        .interval(function () {
            $benchmark.print("上报属性....");
            //随机获取100个连接然后上报属性数据
            return $benchmark.randomConnectionAsync($reportLimit, reportTcpProperty);
        }, $reportInterval)

}

function sendTo(client, buffer) {
    var token = secureKey;

    var newBuf = newBuffer();
    //认证类型
    newBuf.writeByte(0);
    //token
    protocol.types.StringType.encode(token, newBuf);

    //指令
    newBuf.writeBytes(buffer);

    client.send(newBuf)

}

//协议发往设备
protocol.doOnSend(sendTo);


//单个连接创建成功时执行
function onConnected(client) {

    //订阅读取属性
    client
        .handlePayload(function (buf) {

            var buffer = buf.getByteBuf();

            //todo 不同认证类型处理
            var authType = buffer.readByte();

            var token = protocol.types.StringType.decode(buffer);

            var type = buffer.getByte(buffer.readerIndex());


            if (token !== secureKey && type !== parseInt(2)) {
                $benchmark.print("平台下发指令token错误:" + token);

            }
            //交给协议处理
            protocol.handleFromServer(client, buffer);
        });

}

//随机上报数据
function reportTcpProperty(client) {
    var data = new java.util.HashMap();

    //在jetlinks平台对应产品内配置的物模型属性
    data['consumption'] = randomFloat(1, 300);

    sendTo(client, protocol.createReportProperty(client, data));
}

//重点! 绑定函数到benchmark
benchmark
    //.beforeConnect(beforeConnect)
    .onConnected(onConnected)
    .onComplete(onComplete);

4、执行命令开始属性上报

运行指令

//需要修改host以及port,--id为设备id
benchmark udp --host=192.168.66.203 --port=8806 report=true reportLimit=100 interval=1000 --script=benchmark/udp/benchmark.js --id=ele_dev_a_1_13

属性上报成功