基坑物联网
简介
使用硬件传感器设备,连接物联网网关,LORA网关或NB网关,由网关收集硬件设备的检测数据,发送到软件系统做展示,监控,告警等用途。并且可以通过软件控制是否接受某个硬件设备的数据
宏观架构

大致可将系统分为6层,从上往下分别介绍如下:
- 硬件设备是数据的源头,负责采集数据, 并由网关收集
- 硬件网关需要支持3种,IOT网关,LORA网关和NB网关
- IOT网关负责收集硬件设备采集到的数据,格式化数据并转发给软件网关层的MQTT服务器
- LORA网关通过Socket方式连接基坑网关层的Foundation-gateway应用,通过一发一收的方式获取网关数据
- 基坑网关层,有2个应用,一个是由JAVA语言编写的软件层网关, 主要作用有4点:
- 它是MQTT的客户端,将硬件网关层发送的mqtt消息收集
- 负责计算各个硬件设备的真实值,当然不是所有硬件设备的数据都需要计算,部分厂家的设备采集到的数据要使用到特定的公式求值
- 负责过滤掉软件应用层不需要采集的硬件设备
- 将数据整理,标准化格式为thingsboard规定的数据格式,并转发到thingsboard的MQTT服务端
- 基坑网关层另外一个应用是MQTTT服务端,用来衔接IOT硬件网关和Foundation-gateway应用之间的消息互通,搭建MQTT服务端的参考如下:
- Docker安装mosquitto
- 基础层Thingsboard, 内置MQTT服务端, 应用网关层的所有设备数据都会推送到Thingsboard的MQTT服务端,thingsboard将会对数据进行入库,告警等操作
- 基坑应用层,Foundation-Pit是Java编写的扩展thingsboard功能适应客户需求的一套程序。
- 显示层,分为后台管理和小程序,后台管理页面的接口来源于thingsboard和Foundation-Pit,通过应用服务器上的nginx做代理,/api开头的接口转发到thingsboard,/pit开头的接口转发到foundation-pit. thingsboard和fodundation-pit两个应用相辅相成,共同提供了后台admin页面所需要的全部后台接口和功能
- 显示层的小程序端的所有接口均来源与fodation-pit
应用解析
应用网关 foundation-gateway
```shell ├─src │ └─main │ ├─java │ │ └─com │ │ └─hn │ │ └─iot │ │ └─gateway │ │ ├─common │ │ ├─config │ │ │ └─properties │ │ ├─entity │ │ ├─mapper │ │ ├─mqtt │ │ ├─netty │ │ └─service │ │ └─impl │ └─resources
- mqtt包下对应的是mqtt客户端接受IOT网关发送过来的数据- netty包下对接2种通过tcp方式socket建立的通道连接1. 环境传感器:对接逻辑在com.hn.iot.gateway.netty.EnvMonitorRunner类下,有环境传感器厂商提供的外部包com.jnrsmcu.sdk,参考实现1. Lora网关:com.hn.iot.gateway.netty.LaraSocket实现对接lora网关的全部代码- Lora特性:需要手动发送一条请求指令给lora网关,lora网关通过指令返回相应收集到的数据。同一时间不可发送多条指令,比如3个设备,有三条指令,不可同时发送给lora网关,需要相隔3-5s发送一条- service包下是业务代码的实现- com.hn.iot.gateway.common.ComputeRuleEngine是计算公式统一处理类,采用了google的aviator公式引擎<a name="yBZBJ"></a>### 应用系统foundation-pit-api```shell├─deploy│ ├─chrome│ └─sql├─src│ └─main│ ├─java│ │ └─com│ │ └─hn│ │ └─iot│ │ ├─common│ │ │ ├─constant│ │ │ ├─exception│ │ │ ├─page│ │ │ ├─result│ │ │ └─util│ │ ├─config│ │ │ ├─interceptor│ │ │ └─properties│ │ ├─controller│ │ │ ├─applet│ │ │ └─backend│ │ │ ├─report│ │ │ │ └─vo│ │ │ └─screen│ │ ├─entity│ │ │ ├─dto│ │ │ └─vo│ │ ├─job│ │ ├─listener│ │ ├─mapper│ │ └─service│ │ └─impl│ └─resources│ ├─config│ └─mapper
- 数据库和thingsboard的数据库是相同的,数据为postgres
- 安装postgres方式:Ubuntu20.4安装postgres12 或者使用宝塔的PostgreSQL管理器 1.6,推荐宝塔的方式,简单直观比较无脑
- controller/backend下的接口是后台管理页面接口
- controller/backend/screen 是后台管理页面大屏的接口
- controller/backend/report 是报告模板生成器需要的所有接口
- 报告生成采用动态定时任务,开始,停止,新增,删除定时任务,目前报告模板的定时的时间固定了几个时间表达式,所以不需要在页面上填写
- 报告生成的需求是需要生成pdf和doc格式的文档,使用无头浏览器渲染页面,模拟浏览器ctrl+p的方式生成pdf,然后使用某js库将页面渲染成doc文档的文件流,最终保存在服务器上
- 为什么要用无头浏览器?答:vue.js开发的应用,大部门工作都在js里面,通过普通的爬虫只能取到几行js的引用,无头浏览器和用户普通的浏览器性质一样,它可以模拟用户打开浏览器到浏览器引擎通过js最终渲染成html的所有过程,所以可以很容易拿到页面最终的样子。
从头部署整个项目请查看foundation-pit-api 应用下 README.md文档
Nginx 配置参考
server {listen 80;server_name hengxin.xyduo.com;location /api {proxy_pass http://127.0.0.1:8080;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";}location /pit {proxy_pass http://127.0.0.1:9091;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;}location /rtp {proxy_pass http://127.0.0.1:8090/rtp;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;}location /applet {proxy_pass http://127.0.0.1:9091;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;}location /file {alias /java/foundation-pit/file;}location / {alias /java/foundation-pit/dist/;try_files $uri $uri/ /index.html;}}
设备接入
IOT网关接入流程
- 网关收集设备数据
- IOT网关的管理页面配置每个设备的寄存器地址
- 通过自定义管理页面可自定义python脚本,封装成软件网关层需要的格式
- 软件网关层作为MQTT的客户端,接收IOT网关指定topic推送的数据
- 软件网关层对每条上报过来的数据,做计算,公式计算或者保留2位小数
- 软件网关层将计算好的结果封装thingsboard指定格式并推送到thingsboard
LORA网关接入流程
- Lora网关由2个部分组成,分为硬件接入器和网关(内置SIM卡),硬件接入器负责对接硬件,网关负责读取接收器寄存器地址的值和上报给远端服务器,支持MQTT和Socket的方式。
- 目前对接基坑项目采用的是socket的方式。
- Lora的特性是透传,就是说,lora网关不会主动采集数据并定时上报给远端服务器,而需要远端服务器发送指令查询指定设备的值。比如说,lora接入器接入了一个硬件设备:应力计,寄存器地址位2,那么要采集到应力计这个设备的值,需要发送一条类似“020300000001”的指令给LORA网关,LORA网关收到指令后,会再请求LORA接收器对应寄存器的值,取到值之后异步返回给远端服务器。
- 一条指令只能请求一个设备的,不能请求多个,并且指令不能同一时间发送,每条指令发送间隔5-10s为宜,低于这个时间间隔发送,容易造成服务端读取线程超时.
- socket服务端,即软件网关层,使用一张表来维护LORA网关的设备与thingsboard之间的关系,字段如下:

- ID:主键,同时也是区分LORA上报数据返回寄存器的前缀,用于区分是哪个寄存器地址返回,也就是哪个设备
- device_name: 上报给thingsboard的MQTT消息的设备名称
- command: 发送给LORA网关查询设备采集数据的指令
- unit:上报给thingsboard的MQTT消息的设备单位
- type: 用于不同设备的计算公式
软件网关层接受到LORA的设备数据后,默认需要*0.1,有公式的再套公式,无公式的直接保留2位小数
环境传感器接入流程
环境传感器根据厂家的设定,采用socket的方式直接对接软件网关层,不走硬件网关
- 厂家提供了特定的jar包,用户方便用户对接,包放在foundation-pit-gateway/lib 下
- com.hn.iot.gateway.netty.EnvMonitorRunner 实现了环境传感器所有的逻辑
- 环境传感器的数据会主动定时上报,使用厂家提供的app配置
每次上报的数据分为10个节点,根据厂家预设指定的节点获取指定的指标,对照属性如下:
float PM2$5 = 0; // 节点1 温度float PM10 = 0; //节点1 湿度float noise = 0; //节点2 湿度float temperature = 0; //节点3 温度float humidity = 0; //节点3 湿度float windSpeed = 0; //节点4 湿度float windPower = 0; //节点4 温度float windDirection = 0; //节点5 湿度float windDegree = 0; //节点6 湿度float tsp = 0; //节点7 湿度
详情请阅读实现类EnvMonitorRunner
