Thingsboard的MQTT设备协议

thingsboard官网: https://thingsboard.io/

thingsboard GitHub: https://github.com/thingsboard/thingsboard

thingsboard提供的体验地址: http://demo.thingsboard.io/

BY Thingsboard team

以下内容是在原文基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名(CC BY 2.5 AU)协议共享。

原文地址: ThingsBoard API参考:MQTT设备API


MQTT基础知识

MQTT是一种轻量级的发布 - 订阅消息传递协议,可能使其最适合各种物联网设备。您可以在此处找到有关MQTT的更多信息。

ThingsBoard服务器节点充当MQTT Broker,支持QoS级别0(最多一次)和1(至少一次)以及一组预定义主题。


客户端库设置

您可以在Web上找到大量MQTT客户端库。本文中的示例将基于Mosquitto,MQTT.jsPaho,要设置其中一个工具。

键值格式

默认情况下,ThingsBoard支持JSON中的键值内容。Key始终是一个字符串,而value可以是string,boolean,double或long。也可以使用自定义二进制格式或某些序列化框架。有关详细信息,请参阅物模型。例如:

 
{"stringKey":"value1", "booleanKey":true, "doubleKey":42.0, "longKey":}

遥测上传API

为了将遥测数据发布到ThingsBoard服务器节点,请将PUBLISH消息发送到以下主题:

 
v1/devices/me/telemetry

最简单的支持数据格式是:

 
{"key1":"value1", "key2":"value2"}

要么

 [{"key1":"value1"}, {"key2":"value2"}]

请注意,在这种情况下,服务器端时间戳将分配给上传的数据!

如果您的设备能够获取客户端时间戳,您可以使用以下格式:

 {"ts":, "values":{"key1":"value1", "key2":"value2"}}

在上面的示例中,我们假设“1451649600512”是具有毫秒精度的unix时间戳。例如,值'1451649600512'对应于'Fri,2016年1月1日12:00:00.512 GMT'

属性API

ThingsBoard属性API允许设备

  • 客户端设备属性上载到服务器。

将属性更新发布到服务器

要将客户端设备属性发布到ThingsBoard服务器节点,请将PUBLISH消息发送到以下主题:

 v1/devices/me/attributes

更多请看上文给出的连接。


Thingsboard的MQTT传输协议架构

因为Thingsboard最新release,是基于微服务架构,不利用单独理解代码。

Thingsboard源代码: https://github.com/thingsboard/thingsboard/tree/release-2.0/transport/mqtt

本文基于上面源代码后,剔除相关的安全验证和处理之后搭建简易的讲解项目:

https://github.com/sanshengshui/IOT-Technical-Guide/tree/master/IOT-Guide-MQTT


MQTT框架

因为Thingsboard是一个JVM技术栈的PaaS平台,所以使用的是基于Java通讯框架的Netty,如果有对Netty不太熟悉的同学,可以参考我之前搭建的Netty实践学习案例: https://github.com/sanshengshui/netty-learning-example

项目结构

 .
 ├── IOT-Guide-MQTT.iml
├── pom.xml
└── src
└── main
└── java
└── com
└── sanshengshui
└── mqtt
├── adapter
│ └── JsonMqttAdaptor.java // MQTT json转换器,在跟Thingsboard学习IOT-物模型有所讲解
├── IOTMqttServer.java // MQTT服务
├── MqttTopicMatcher.java
├── MqttTopics.java 
├── MqttTransportHandler.java //MQTT处理类
└── MqttTransportServerInitializer.java
 ​

项目代码讲解

IOTMqttServer

 
 private static final int PORT = 1884;
private static final String leakDetectorLevel = "DISABLED";
private static final Integer bossGroupThreadCount = 1;
private static final Integer workerGroupThreadCount = 12;
private static final Integer maxPayloadSize = 65536;

public static void main(String[] args) throws Exception {
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.valueOf(leakDetectorLevel.toUpperCase()));

EventLoopGroup bossGroup = new NioEventLoopGroup(bossGroupThreadCount);
EventLoopGroup workerGroup = new NioEventLoopGroup(workerGroupThreadCount);

try {

ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new MqttTransportServerInitializer(maxPayloadSize));
ChannelFuture f = b.bind(PORT);
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}

第8行,设置服务端Netty内存读写泄漏级别,缺省条件下为:DISABLED

第10行和第11行,设置boss线程组和work线程组的线程数量。默认情况下,boss线程组的线程数量为1,work线程组的数量为运行服务机器内核数量的2倍。

第15行,通过创建ServerBootstrap对象,在第16行设置使用EventLoopGroup

在17和19行,设置要被实例化的NioServerSockerChannel类,并设置最大的负载内容数量。

最后我们通过shutdowGracefully()函数优雅的关闭bossGroup和workGroup。


MqttTransportHandler#processMqttMsg()

 
 private void processMqttMsg(ChannelHandlerContext ctx, MqttMessage msg) {
address = (InetSocketAddress) ctx.channel().remoteAddress();
if (msg.fixedHeader() == null) {
processDisconnect(ctx);
return;
}

switch (msg.fixedHeader().messageType()) {
case CONNECT:
processConnect(ctx, (MqttConnectMessage) msg);
break;
case PUBLISH:
processPublish(ctx, (MqttPublishMessage) msg);
break;
case SUBSCRIBE:
processSubscribe(ctx, (MqttSubscribeMessage) msg);
break;
case UNSUBSCRIBE:
processUnsubscribe(ctx, (MqttUnsubscribeMessage) msg);
break;
case PINGREQ:
if (checkConnected(ctx)) {
ctx.writeAndFlush(new MqttMessage(new MqttFixedHeader(PINGRESP,false,AT_MOST_ONCE, false, 0)));
}
break;
case DISCONNECT:
if (checkConnected(ctx)) {
processDisconnect(ctx);
}
break;
default:
break;

}
}

第3行,通过判断消息的固定头部是否为空,如果空;则通过processDisconnect(ctx)将设备连接关闭。

processDisconnect(channelHandlerContext ctx)

 
private void processDisconnect(ChannelHandlerContext ctx) {
ctx.close(); // 关闭socket通道
}

第8行,通过判断固定头部的MQTT消息类型,针对不同消息做相应的处理。


MqttTransportHandler#PublishDevicePublish

以下是对发布消息进行相关的解读,更多消息类型的处理类,大家请参考我上面的IOT-Guide-MQTT进行阅读。

 
private void processDevicePublish(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, String topicName, int msgId) {
try {
if (topicName.equals(MqttTopics.DEVICE_TELEMETRY_TOPIC)) { //如果主题为v1/devices/me/attributes
JsonMqttAdaptor.convertToMsg(POST_TELEMETRY_REQUEST, mqttMsg);
} else if(topicName.equals(DEVICE_ATTRIBUTES_TOPIC)) {
JsonMqttAdaptor.convertToMsg(POST_ATTRIBUTES_REQUEST, mqttMsg);
} else if(topicName.equals(MqttTopics.DEVICE_ATTRIBUTES_REQUEST_TOPIC_PREFIX)) {
JsonMqttAdaptor.convertToMsg(GET_ATTRIBUTES_REQUEST, mqttMsg);
}
} catch (AdaptorException e) {

}

}

我上面的代码仅是对消息的主题进行判断,然后对主题内的内容进行物模型的解析,得到相关属性或者遥测数据的获得。


演示效果

我们通过Paho或者MQTT.js和服务进行连接,发布消息到以下主题:

 v1/devices/me/telemetry
 ​

简易的数据格式如下:

 {"key1":"value1", "key2":"value2"}

Paho图示:

服务器控制台打印数据:

 七月 24, 2019 1:37:18 下午 io.netty.handler.logging.LoggingHandler channelRegistered
信息: [id: 0xf2bfb3a8] REGISTERED
七月 24, 2019 1:37:18 下午 io.netty.handler.logging.LoggingHandler bind
信息: [id: 0xf2bfb3a8] BIND: 0.0.0.0/0.0.0.0:1884
七月 24, 2019 1:37:18 下午 io.netty.handler.logging.LoggingHandler channelActive
信息: [id: 0xf2bfb3a8, L:/0:0:0:0:0:0:0:0:1884] ACTIVE
七月 24, 2019 1:37:22 下午 io.netty.handler.logging.LoggingHandler channelRead
信息: [id: 0xf2bfb3a8, L:/0:0:0:0:0:0:0:0:1884] RECEIVED: [id: 0xe08abd12, L:/127.0.0.1:1884 - R:/127.0.0.1:48816]
key= 1563946708305
属性名=temperature 属性值=38
属性名=humidity 属性值=60

如上所示,希望大家对Thingsboard的IOT架构-MQTT设备协议这块有所了解!

物联网时代-跟着Thingsboard学IOT架构-MQTT设备协议的更多相关文章

  1. 物联网时代 跟着Thingsboard学IOT架构-CoAP设备协议

    thingsboard官网: https://thingsboard.io/ thingsboard GitHub: https://github.com/thingsboard/thingsboar ...

  2. 物联网时代-跟着Thingsboard学IOT架构-HTTP设备协议及API相关限制

    thingsboard官网: https://thingsboard.io/ thingsboard GitHub: https://github.com/thingsboard/thingsboar ...

  3. Thingsboard之MQTT设备协议简介

    MQTT基础知识 MQTT是一种轻量级的发布 - 订阅消息传递协议,可能使其最适合各种物联网设备.您可以在此处找到有关MQTT的更多信息.ThingsBoard服务器节点充当MQTT Broker,支 ...

  4. 物联网时代-新基建-ThingsBoard调试环境搭建

    前言 2020开年之际,科比不幸离世.疫情当道.经济受到了严重的损失.人们都不幸的感慨: 2020年真是太不真实的一年,可以重新来过就好了!国家和政府出台了拯救经济和加速建设的利好消息.3月份最热的词 ...

  5. 基于Azure IoT开发.NET物联网应用系列-全新的Azure IoT架构

    物联网技术已经火了很多年了,业界各大厂商都有各自成熟的解决方案.我们公司主要搞新能源汽车充电,充电桩就是物联网技术的最大应用,车联网.物联网.互联网三网合一.2017年的时候重点研究过Azure Io ...

  6. 开源的物联网技术平台(Thingsboard)

    1   总体说明 1.1   产品概述 1.1.1 Thingsboard作用 1.置备并控制设备. 2.采集设备数据并进行数据可视化. 3.分析设备数据,触发告警. 4.将数据传输到另一个系统. 5 ...

  7. [零基础学IoT Pwn] 环境搭建

    [零基础学IoT Pwn] 环境搭建 0x00 前言 这里指的零基础其实是我们在实战中遇到一些基础问题,再相应的去补充学习理论知识,这样起码不会枯燥. 本系列主要是利用网上已知的IoT设备(路由器)漏 ...

  8. 进阶高阶IoT架构-教你如何简单实现一个消息队列

    前言 消息队列是软件系统领域用来实现系统间通信最广泛的中间件.基于消息队列的方式是指由应用中的某个系统负责发送消息,由关心这条消息的相关系统负责接收消息,并在收到消息后进行各自系统内的业务处理.消息可 ...

  9. 【跟着stackoverflow学Pandas】 - Adding new column to existing DataFrame in Python pandas - Pandas 添加列

    最近做一个系列博客,跟着stackoverflow学Pandas. 以 pandas作为关键词,在stackoverflow中进行搜索,随后安照 votes 数目进行排序: https://stack ...

随机推荐

  1. 用了WS_EX_LAYERED 后所有Twincontrl的wm_paint消息会停止(官方Layered Windows文档很多内容)good

    fmx 和 vcl 不一样, fmx 的阴影可以通过2D显示出来. VCL 无标题栏窗口的阴影很麻烦 280425268 我也是用两个窗口做阴影,并重绘了非客户区,不过阴影是基础自TwinContro ...

  2. windows service 之访问权限(有NetworkService和LocalSystem的区分)

    最近写了一个关于从局域网的算机上下载文件的winodws service,最初认为应该没什么大的问题.通过本地的调试也没发现问题.但是当我把程序发布后发现服务报错“访问路径被拒绝”,我的第一感觉,肯定 ...

  3. Delphi各种从文件里读取内容的方法

    Hi I am having a problem running a function to read a text file the problem seems to be that my anti ...

  4. git初学【常用命令、上传项目到码云或从码云拉取、克隆项目】

    1.下载git.https://git-scm.com/   注册码云:https://gitee.com/2.安装git:  默认安装即可:  安装完成之后打开git bash进行最后一步配置  输 ...

  5. kubernetes实战篇之部署一个.net core微服务项目

    目录 继上一篇kubernetes理论知识完结.本篇主要讲解基于nexus搭建一个docker镜像仓库(当然大家实践过程是不必完全跟着做,也可以搭建harbor仓库或者直接把镜像推送到docker h ...

  6. Redis 学习笔记(篇二):字典

    字典 字典又称为符号表.关联数组或映射(map),是一种用于保存键值对(key-value)的数据结构. 那么 C 语言中有没有这样 key-value 型的内置数据结构呢? 答案:没有. 说起键值对 ...

  7. Spring Boot:整合Spring Security

    综合概述 Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication)和授权(Author ...

  8. JS的第一天,精彩内容

    1.JS 介绍 js的全称是JavaScript,它是一门前台语言 Java是一门后台语言 ,它们两个之间毫无关系 JavaScript的作者是布兰登,艾奇 前台语言:运行在客户端 后台语言:与数据库 ...

  9. Cisco packet tracer6.0下的网络工程实训

    期末的专业实训,在cisco6.0下配置一个简单的局域网.主要用到了下面几个技术:dhcp中继.vlan的划分.链路聚合.静态nat.ospf协议.访问控制列表.先看一下总的拓扑图,在分步实现功能. ...

  10. SPOJ STC02 - Antisymmetry(Manacher算法求回文串数)

    http://www.spoj.com/problems/STC02/en/ 题意:给出一个长度为n的字符串,问其中有多少个子串s可以使得s = s按位取反+翻转. 例如样例:11001011. 10 ...