实验三 ThingsBoard MQTT API的使用
实验目的
使用Paho开发MQTT客户端,模拟设备网关采集设备数据并上传数据到MQTT平台。能够观察到MQTT平台上接收到数据。
实验内容
(1) 阅读Thingsboard MQTT API的使用指南。
(2) 安装任意Paho的具有图形化界面的客户端,通过输入参数观测数据变化。
(3) 使用Java开发Paho Java客户端,通过输入参数观测数据变化。
注:参考资料
https://thingsboard.io/docs/reference/mqtt-api/
http://www.ithingsboard.com/docs/reference/mqtt-api/
https://wiki.eclipse.org/Paho
https://mqtt.org/
https://www.w3school.com.cn/js/js_json_intro.asp
实验要求
(1) 能够通过Paho图形化界面测试使用MQTT与Thingsboard的通信。
(2) 掌握通过Paho Java Client测试使用MQTT与thingsboard的通信的编程方法。
实验步骤
Paho项目旨在为机器对机器(M2M)和物联网(IoT),现有的和新兴的应用程序提供可靠的开源和标准消息传递协议的开源实现。支持的最简单的数据格式是:{“key1”:”value1”,”key2”:”value2”}
3.1 Paho图形化界面测试MQTT通信
(1) 注册thingsboard账号,登录thingsboard平台
https://demo.thingsboard.io/devices
(2) 添加新设备Learn Mqtt,设备配置为default,点击添加
(3) 下载Paho图形化客户端(下载地址https://repo.eclipse.org/content/repositories/paho-releases/org/eclipse/paho/org.eclipse.paho.ui.app/1.1.1/org.eclipse.paho.ui.app-1.1.1-org.eclipse.paho.ui.app.executable.win32.win32.x86_64.zip)选择org.eclipse.paho.ui.app-1.1.1-org.eclipse.paho.ui.app.executable.win32.win32.x86_64.zip下载,按默认流程安装即可,打开Paho,将服务器地址设置为tcp://demo.thingsboard.io(如果是本地访问,将demo.thingsboard.io换成localhost:8080,使用localhost:8080的前提是租户管理员的账号可以正常登录),客户机标识为每个机器独有,不用管它
(4) 返回thingsboard/devices,点击刚才添加的设备Learn Mqtt,点击复制访问令牌
(5) 打开Paho,点击选项,打开开启登录,用户名一栏粘贴上一步复制的访问令牌,密码不用设置
(6) 点击连接,连接到在thingsboard中新建的设备
在线发布成功不显示数据,使用本地localhost:8080
(7) 在主题中输入v1/devices/me/attributes,消息中输入{“humidity”:70.0,“temperature”:36,“status”:false},模拟设备新建属性,点击发布,通过修改参数在thingsboard属性中观测变化
使用本地localhost8080
(8) 在主题中输入v1/devices/me/telemetry,消息中输入{“humidity”:70.0,“temperature”:36,“status”:false},模拟设备新建属性,点击发布,通过修改参数在thingsboard最新遥测数据中观测变化
(9) 在主题输入v1/devices/me/attributes/request/1,消息中输入{clientKeys":“humidity,temperature,status”},模拟从thingsboard管理的设备中接收数据,点击发布可以在Paho中观测到
3.2 paho的java客户端测试MQTT的通信
(1) 使用idea或者eclipse新建一个maven项目,命名为Paho-Client,pom配置如下
<groupId>org.example</groupId>
<artifactId>Paho-Client</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
(如果没有修改过maven的配置文件在此处下载依赖速度可能会非常的慢,大概需要半个小时左右,建议修改配置文件将阿里云镜像添加到maven的配置中,参考网址:https://blog.csdn.net/m0_62520968/article/details/124611730
(2) 新建一个class命名为Publishtest,模拟设备新建属性,点击运行,通过修改content中的参数在thingsboard属性中观测变化代码如下
import com.alibaba.fastjson.JSONObject;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class Publishtest {
public static void main(String[] args) {
String topic = "v1/devices/me/attributes";//主题
String content = "{\"humidity\":90.0,\"temperature\":38,\"status\":false}";//信息
int qos = 1;
String broker = "tcp://demo.thingsboard.io";//thingsboard的url
String userName = "htROeipSLXdoGeT7QXkA";//设备的访问令牌
String password = "";
String clientId = "Learn_Mqtt";
JSONObject object = new JSONObject();
//int
object.put("id",1);
//string
object.put("msg","");
// 内存存储
MemoryPersistence persistence = new MemoryPersistence();
try {
// 创建客户端
MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
// 创建链接参数
MqttConnectOptions connOpts = new MqttConnectOptions();
// 在重新启动和重新连接时记住状态
connOpts.setCleanSession(false);
// 设置连接的用户名
connOpts.setUserName(userName);
connOpts.setPassword(password.toCharArray());
// 建立连接
System.out.println("connecting to broker: " + broker);
sampleClient.connect(connOpts);
System.out.println("connected.");
// 创建消息
MqttMessage message = new MqttMessage(content.getBytes());
// 设置消息的服务质量
message.setQos(qos);
// 发布消息
MqttTopic mqttTopic = sampleClient.getTopic(topic);
if (mqttTopic == null) {
System.out.println("topic not exist");
}
MqttDeliveryToken token;
token = mqttTopic.publish(message);
token.waitForCompletion();
System.out.println("已经发送成功:"+token.isComplete());
System.out.println("publishing msg to " + topic + ":" + message);
//sampleClient.publish(topic, message);
// 断开连接
sampleClient.disconnect();
// 关闭客户端
sampleClient.close();
} catch (MqttException me) {
System.out.println("reason " + me.getReasonCode());
System.out.println("msg " + me.getMessage());
System.out.println("loc " + me.getLocalizedMessage());
System.out.println("cause " + me.getCause());
System.out.println("excep " + me);
me.printStackTrace();
}
}
}
运行结果在idea中可以看到信息发布成功
在thingsboard可以看到属性已经发生了变化
将String topic=”v1/devices/me/attributes”更改为”v1/devices/me/telemetry”将会在thingsboard管理的设备中的最新遥测数据中观测到数据变化
(3) 新建一个class命名为Publishtest,模拟通过MQTT接收数据,点击运行,观测结果
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
class Subcribetest {
public static void main(String[] args) {
String broker = "tcp://demo.thingsboard.io";
String TOPIC = "v1/devices/me/attributes/response/+";
int Qos = 1;
String clientid = "Learn Mqtt";
String userName = "htROeipSLXdoGeT7QXkA";
// String passWord = ;
String content="{clientKeys\":\"humidity,temperature,status\"}";
try {
// host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
MqttClient client = new MqttClient(broker, clientid, new MemoryPersistence());
// MQTT的连接设置
MqttConnectOptions options = new MqttConnectOptions();
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(true);
// 设置连接的用户名
options.setUserName(userName);
// 设置连接的密码
options.setPassword(passWord.toCharArray());
// 设置超时时间 单位为秒
options.setConnectionTimeout(10);
// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
options.setKeepAliveInterval(20);
// 设置回调函数
client.setCallback(new MqttCallback() {
public void connectionLost(Throwable cause) {
System.out.println("connectionLost");
}
public void messageArrived(String topic, MqttMessage message) {
System.out.println("======find the msg from [" + topic + "]======");
System.out.println("message content:"+new String(message.getPayload()));
}
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("deliveryComplete---------"+ token.isComplete());
}
});
// 建立连接
System.out.println("connect to broker: " + broker);
client.connect(options);
System.out.println("connection success.");
//订阅消息
int [] qos = {Qos};
String [] topics = {TOPIC}; //可订阅多个
MqttMessage message = new MqttMessage(content.getBytes());
client.subscribe(topics, qos);
client.publish("v1/devices/me/attributes/request/1",message);
System.out.println("listening to " + TOPIC);
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果在idea中可以观测到,成功通过MQTT接收到第二步为设备设置的数据