1 代码结构
后端基于 Java(Spring Boot)、前端基于 Angular。
目录结构
thingsboard/
├── application/ # 应用启动器(单体或微服务)
├── common/ # 公共代码(POJO、枚举、常量、异常等)
├── dao/ # 数据访问层(JPA / Cassandra / SQL)
├── transport/ # 各种协议支持(MQTT/CoAP/HTTP)
│ ├── mqtt/
│ ├── coap/
│ └── http/
├── rule-engine/ # 规则引擎核心和节点定义
├── ui/ # Angular Web UI 前端(仪表盘、管理界面)
├── tools/ # 开发/部署工具(如数据迁移)
├── extensions/ # 插件系统(集成其他系统)
├── microservices/ # 微服务架构支持(Kubernetes/Redis/gRPC 等)
└── target/ # 编译生成目录
核心模块
模块名 | 描述 |
---|---|
common | 实体类(Device、Telemetry)、DTO、常量、工具类 |
dao | 抽象数据库访问层,支持 SQL 和 Cassandra |
application | 启动入口,包含 ThingsboardServerApplication.java |
transport | 每个协议的接入模块,如 mqtt-transport 、coap-transport |
rule-engine | 规则链的执行器、规则节点定义,如报警、数据转发等 |
ui | Angular 项目,用户界面,支持仪表盘、设备配置等 |
extensions | 第三方集成(如 Apache Kafka、Azure IoT Hub) |
microservices | 对微服务模式的支持,拆分 transport、core、rule-engine 等服务 |
数据流程
设备(MQTT/CoAP) → Transport 模块 → Rule Engine → 存储(PostgreSQL) → Web UI
↓
Extensions(Kafka、Email、报警)
是的,ThingsBoard 的前端和后端是相互独立的模块,它们之间主要通过 HTTP REST API 和 WebSocket 进行通信。这种架构使得二次开发和集成第三方系统变得灵活和高效。
✅ 架构总览
🌐 前端(UI)
使用 Angular(TypeScript) 编写
是一个 单页应用(SPA)
项目目录:
ui-ngx/
与后端通信主要通过:
REST API(JSON)
WebSocket(实时数据推送)
🖥️ 后端(服务端)
使用 Java + Spring Boot 实现
提供:
REST API(设备、资产、告警、用户、规则链等操作)
WebSocket API(用于 telemetry 实时推送、RPC 控制等)
MQTT/CoAP/HTTP 协议网关
项目目录:
application/
和相关模块
🔗 前后端交互方式
通信方式 用途 说明 REST API 页面加载时获取资源数据(设备列表等) 通过 /api/**
路径请求WebSocket 实时推送遥测数据、RPC 响应等 使用 /api/ws/**
路径连接JWT Token 登录认证机制 登录成功后存储 token,之后通过 Authorization: Bearer <token>
访问所有 API文件上传接口 上传图标、脚本、数据导入等 多数通过 REST Multipart 上传实现
📁 前端开发者角度(Angular)
配置 API 服务入口:
src/app/api/
使用 HttpClient 与后端交互
可通过浏览器控制台查看实际 REST API 请求结构,方便对接或二次开发
🛠️ 二次开发建议
🎯 前端定制
修改仪表盘样式、组件
新增可视化组件(例如你的桥梁 3D 模型组件)
自定义 widget,通过 Angular + 自定义 SVG/WebGL(如 Three.js)
🎯 后端扩展
增加新的 REST 接口
添加规则链组件(自定义 Node)
集成外部 AI/数据库/平台
🧪 示例交互流程
假设你打开一个仪表盘显示设备数据:
前端通过 REST 请求获取设备列表:
GET /api/customer/devices?pageSize=10
然后发起 WebSocket 请求订阅实时遥测数据:
POST /api/ws/telemetry
后端通过 WebSocket 实时推送数据,前端渲染更新。
📌 总结
特性 描述 前后端完全分离 可独立部署,方便对接第三方系统或替换 UI 通信方式 REST API + WebSocket,支持高并发与实时性 易于二次开发 可自定义仪表盘组件、后台业务逻辑、集成机器学习模型、接入外部系统等 接口开放文档 Swagger 接口文档,方便调试:Swagger UI
如果你希望:
自定义前端组件(桥梁 3D 模型 + 传感器位置展示)
开发自己的 API 或规则链节点
将 ML 模型分析接入 ThingsBoard 决策流程
我可以为你提供具体的操作示例或开发指南。是否继续?
3 增加小功能
常见二次开发
方向 | 修改位置 |
---|---|
添加新的协议(如 Zigbee) | transport/zigbee 模块,继承 TransportService |
修改设备模型或属性 | common/data 添加实体字段;同步修改 dao , web , ui |
定制 UI(如仪表盘样式) | ui-ngx/src/app 下的 Angular 组件 |
添加新的规则引擎节点 | rule-engine 添加新节点 Java 类,注册元数据 |
接入 Kafka/Redis 等系统 | 扩展 extensions 模块或在 rule-engine 创建转发节点 |
多租户逻辑增强 | common/data/tenant 模块和 dao/tenant |
定制 REST API | 修改 application/src/main/java/org/thingsboard/server/controller 下控制器 |
3.1 3D显示
为了在 ThingsBoard 中实现一个 3D 桥梁显示组件,并在其上根据设备的属性显示传感器的位置,我们需要结合 前端(Angular) 和 ThingsBoard 数据 来构建这个功能。整体的开发步骤分为前后端,后端用于提供设备属性,前端负责展示 3D 桥梁及传感器位置。
🏗️ 1. 后端(ThingsBoard Server)开发
1.1. 定义设备及属性
假设我们需要显示一个包含传感器的桥梁,首先要确保设备模型中有 设备的属性和传感器位置 信息。你可以在 ThingsBoard 中为每个设备设置一个自定义属性(如传感器坐标)。
例如:
bridge_position_x
,bridge_position_y
,bridge_position_z
表示传感器的位置。
sensor_type
表示传感器类型(温度、湿度、应力等)。这些属性可以在设备的 属性 或 遥测数据 中定义。
1.2. 定义一个 API 端点(可选)
如果需要从后端向前端提供传感器的位置信息,可以考虑添加一个自定义的 REST API 端点,用于获取设备的属性数据。
创建一个新的 REST Controller,用于返回设备的传感器位置数据:
@RestController @RequestMapping("/api/bridge") public class BridgeController { @Autowired private DeviceService deviceService; @GetMapping("/{deviceId}/sensorPositions") public ResponseEntity<List<SensorPosition>> getSensorPositions(@PathVariable String deviceId) { List<SensorPosition> sensorPositions = deviceService.getSensorPositions(deviceId); return ResponseEntity.ok(sensorPositions); } // 需要在 DeviceService 中实现获取设备属性的逻辑 }
1.3. 存储设备属性
确保传感器的位置信息被保存在设备的属性中,你可以通过 ThingsBoard 的设备配置界面或者通过 REST API 来设置属性:
{ "sensor_position_x": 10.5, "sensor_position_y": 3.2, "sensor_position_z": 1.0 }
🌐 2. 前端开发(Angular)
2.1. 在前端创建一个 3D 显示桥梁组件
前端开发部分需要使用 Three.js 库来创建 3D 场景并显示桥梁和传感器位置。Three.js 是一个用于创建 3D 图形的 JavaScript 库,能够在浏览器中渲染 3D 对象。
首先,安装 Three.js:
npm install three
2.2. 创建 3D 桥梁组件
在
ui-ngx
项目中,创建一个新的 BridgeComponent 组件,用于显示 3D 桥梁和传感器。import { Component, OnInit } from '@angular/core'; import * as THREE from 'three'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-bridge', templateUrl: './bridge.component.html', styleUrls: ['./bridge.component.css'] }) export class BridgeComponent implements OnInit { private scene: THREE.Scene; private camera: THREE.PerspectiveCamera; private renderer: THREE.WebGLRenderer; private bridgeGeometry: THREE.BoxGeometry; private bridgeMaterial: THREE.MeshBasicMaterial; private bridge: THREE.Mesh; private sensorMarkers: THREE.Mesh[] = []; constructor(private http: HttpClient) { } ngOnInit(): void { this.init3DScene(); this.loadBridge(); this.loadSensors(); } init3DScene() { this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(this.renderer.domElement); } loadBridge() { this.bridgeGeometry = new THREE.BoxGeometry(50, 1, 10); // Example bridge size this.bridgeMaterial = new THREE.MeshBasicMaterial({ color: 0x7777ff }); this.bridge = new THREE.Mesh(this.bridgeGeometry, this.bridgeMaterial); this.scene.add(this.bridge); this.camera.position.z = 100; } loadSensors() { // 从 ThingsBoard 后端 API 获取传感器数据 this.http.get<any[]>('/api/bridge/{deviceId}/sensorPositions').subscribe(sensorPositions => { sensorPositions.forEach(position => { const sensor = this.createSensor(position); this.sensorMarkers.push(sensor); this.scene.add(sensor); }); }); } createSensor(position: any): THREE.Mesh { const geometry = new THREE.SphereGeometry(0.5, 32, 32); // 传感器的形状为小球 const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); const sensor = new THREE.Mesh(geometry, material); sensor.position.set(position.x, position.y, position.z); return sensor; } animate() { requestAnimationFrame(() => this.animate()); this.renderer.render(this.scene, this.camera); } }
2.3. 显示桥梁并加载传感器
使用 Three.js 创建桥梁的几何形状,这里使用了 BoxGeometry。
通过 HTTP 请求获取传感器的位置,并将其显示为小球(SphereGeometry)放置在桥梁上的特定位置。
你可以在
loadSensors
方法中根据传感器的位置调整小球的坐标。2.4. 修改 HTML 模板
在
bridge.component.html
中,添加用于渲染 3D 内容的容器:<div id="3d-container"></div>
2.5. 样式调整
你可以在
bridge.component.css
中添加一些基本的样式,使 3D 场景适应窗口大小:#3d-container { width: 100%; height: 100vh; background-color: #f0f0f0; }
🔌 3. 集成与测试
确保后端返回正确的数据: 确保设备的传感器位置数据正确地保存在数据库中,并通过 API 返回给前端。
前端 API 调用: 在前端的
BridgeComponent
中确保正确地调用后端接口获取数据并在 3D 场景中显示。调试与优化: 通过浏览器调试工具检查 3D 显示效果,确保传感器位置正确,桥梁显示正常。
📈 未来拓展
动态更新: 使用 WebSocket 或 Server-Sent Events (SSE) 来实时更新传感器数据,这样桥梁和传感器位置可以动态变化。
传感器数据可视化: 可以通过颜色、大小等属性显示不同传感器的状态(如温度过高时显示为红色)。
用户交互: 可以添加用户交互功能,比如点击传感器显示详细信息。
这个方案提供了一个基础框架,可以根据你实际的需求进一步定制或扩展。如果有任何具体问题或需要进一步细化某部分功能,随时可以告诉我!
3.2 增加推理
在 ThingsBoard 系统中接收数据后,如果你希望使用 机器学习模型分析数据并决定后续处理动作(如告警、控制或通知),可以将 ThingsBoard 与外部 ML 模型或平台集成。以下是一个完整的实现方案,分为 数据接入、模型集成、决策反馈 三个阶段。
🧭 总体流程图
┌────────────┐ 数据流 ┌──────────────┐ 调用接口 ┌─────────────┐ │ 设备/传感器 │ ───────────► │ ThingsBoard │ ───────────────► │ ML 推理服务 │ └────────────┘ └──────────────┘ └────┬────────┘ 推理结果│ ▼ ┌────────────┐ │ 告警/决策引擎 │ └────────────┘
🚀 1. 数据接入(ThingsBoard)
ThingsBoard 接收到传感器上报的数据后,可以通过 Rule Engine 转发给 ML 服务:
✅ 示例数据格式
{ "temperature": 72.5, "humidity": 55, "stress_level": 120.3 }
🧠 2. ML 模型服务部署与接入
你可以将机器学习模型封装为一个 独立的推理服务(推荐使用 Python FastAPI/Flask + ONNX/TorchServe 等):
🛠️ 示例模型服务 (FastAPI)
from fastapi import FastAPI, Request import joblib # 或 torch/onnx etc. app = FastAPI() model = joblib.load("bridge_model.pkl") @app.post("/predict") async def predict(data: dict): features = [data["temperature"], data["humidity"], data["stress_level"]] prediction = model.predict([features])[0] return {"decision": prediction}
🔗 对外暴露 API,例如:
POST http://ml-server.local:8000/predict Body: { "temperature": 72.5, "humidity": 55, "stress_level": 120.3 } Response: { "decision": "high_risk" }
🔁 3. 在 ThingsBoard Rule Engine 中集成 ML 推理
💡 创建 Rule Chain 的几个关键节点:
Originator Telemetry – 接收设备数据。
Script Transformation(可选)– 格式化数据发送格式。
REST API Call Node – 调用你部署的 ML 模型服务。
Switch Node / Script Node – 根据 ML 推理结果判断采取什么行动。
告警节点 / RPC Call / Email – 发起告警或控制指令。
示例 JSON 脚本节点(判断结果)
// 输入:ML 推理返回 {"decision": "high_risk"} var decision = msg.decision; if (decision == "high_risk") { return {msg: msg, metadata: metadata, msgType: "ALARM"}; } else if (decision == "medium_risk") { return {msg: msg, metadata: metadata, msgType: "NOTIFY"}; } else { return {msg: msg, metadata: metadata, msgType: "SUCCESS"}; }
📬 4. 后续处理动作(可选)
如果模型预测为高风险:
生成告警(Alarm Node)
发送邮件/短信
执行设备 RPC 指令(如关闭通道、启动风扇)
通过 Kafka/MQTT 转发到其他系统
🧪 5. 模型训练建议
你可以离线使用历史传感器数据训练模型:
特征:温度、湿度、应力等
标签:是否存在危险、是否报警
使用常见算法:XGBoost、Random Forest、SVM、神经网络等。
模型训练平台可选:
Jupyter + scikit-learn
PyTorch / TensorFlow
或 MLOps 平台如 MLFlow、Kubeflow
🗺️ 总结:集成路线图
阶段 技术建议 模型训练 Python + pandas + scikit-learn / PyTorch 推理服务 FastAPI / Flask + joblib/ONNX ThingsBoard 调用 Rule Engine REST API Call Node 决策处理 Switch Node + 告警/通知/RPC 控制 持续更新模型 可使用 cron 定时训练,或引入 MLOps 流程
如果你愿意,我可以为你生成一个:
✅ FastAPI 推理服务样例代码
✅ ThingsBoard Rule Chain JSON 模板
✅ 模型训练示例(Jupyter Notebook)
需要哪部分我可以立刻帮你做。是否继续?
学习 ThingsBoard 的代码,建议结合它的架构、模块功能、具体项目目标,采用“从宏观到微观、从用法到源码”的策略。下面是一套系统学习方法,适合初学者到进阶开发者:
✅ 第一步:理解整体架构(花 1~2 天)
📌 推荐做法:
-
阅读官方架构图
官网链接:ThingsBoard Community Edition | ThingsBoard Community Edition-
包括:微服务架构图、各服务职责、技术栈图(Spring Boot + Akka + Kafka + PostgreSQL + Cassandra)
-
-
了解关键模块职责:
模块 作用 transport
各类协议接入(MQTT, CoAP, HTTP) core
业务逻辑处理,如规则链、遥测等 dao
数据访问层(PostgreSQL / Cassandra) web-ui
Angular 前端 msa
微服务拆分模块 common
通用 Java 工具与定义(DTO、消息等) -
理清核心流程:
例如:设备 → MQTT 接入 → 传输模块 → Core 处理 → Rule Chain → DB 存储 / 告警处理
✅ 第二步:本地部署并观察运行(花 1~3 天)
你只有看过系统跑起来,调试体验过流程,源码才更容易理解。
✔ 推荐部署方式:
-
使用 Docker Compose 部署(最快)
👉thingsboard/docker
目录或官网文档 -
或者 源码编译部署(参考你之前遇到的问题)
🧪 建议动手做的实验:
-
创建一个设备 → 上报温湿度数据
-
配置一个 Rule Chain → 打印日志 / 触发告警
-
用 MQTT.fx 或 Python client 向设备发数据
✅ 第三步:定位感兴趣的模块深入阅读(从用法到源码)
📌 建议阅读顺序(从外到内):
-
设备接入模块(transport/)
-
transport/mqtt
是最常用的起点 -
看点:Netty 处理、DeviceSessionCtx、消息分发
-
-
Core 模块(处理消息流)
-
application
启动入口:ThingsboardServerApplication.java
-
重点关注:
-
RuleEngineActor
-
RuleChainActor
→ 每个设备规则链运行逻辑 -
TelemetryService
→ 处理遥测数据
-
-
-
消息结构(common/)
-
类如
TelemetryUploadRequestMsg
、RuleNodeMsg
、TbMsg
-
建议先画出消息流动过程图
-
-
DAO 层
-
数据存储与设备/遥测历史数据的保存
-
结合 PostgreSQL 表查看效果(如
ts_kv_latest
,device
)
-
-
Web UI(Angular)
-
在
web-ui/
下,src/app/pages/...
是主要页面 -
可观察设备列表、规则链编辑器如何实现
-
✅ 第四步:配合调试 / 实践项目带动阅读
🧪 项目实践建议(按难度):
项目 | 涉及模块 | 推荐目标 |
---|---|---|
添加一个新的设备属性字段 | Core + DAO | 理解设备模型存取流程 |
自定义一个 Rule Node(比如温度超过某值发邮件) | Rule Engine + Plugin | 学习扩展机制 |
新增一种协议接入(如 Modbus) | Transport 模块 | 理解传输结构 |
写个前端仪表盘 | web-ui | 熟悉 Angular 结构 |
二次开发成一个视觉物联网平台 | 全栈 | 集成摄像头或 AI 模块 |
✅ 第五步:结合社区、官方文档、源码跳转工具
📘 学习资源:
-
官方文档:ThingsBoard Community Edition | ThingsBoard Community Edition
-
GitHub 源码仓库:https://github.com/thingsboard/thingsboard
-
社区教程(推荐搜索博客关键词:“ThingsBoard 二次开发”、“ThingsBoard 规则链开发”)
-
视频课程(B站上也有入门讲解)
🛠 工具辅助:
-
使用 IDE 的结构图(如 IntelliJ 的类层次、调用图)
-
熟练掌握调试工具断点追踪流程
-
Elasticsearch 方式索引代码(如使用 SourceGraph)
✅ 总结学习路径图:
ThingsBoard 学习路径:
1. 架构图 & 文档熟悉
↓
2. 本地部署运行 + 实验设备数据上报
↓
3. 从 transport → core → dao 模块按流程读代码
↓
4. 调试关键数据流(如遥测、RuleChain 消息)
↓
5. 开始做二次开发(自定义规则/接入/前端仪表盘)
↓
6. 阅读更多社区源码 & 模块扩展
如果你愿意告诉我你打算如何使用 ThingsBoard(比如做视觉监控、智能设备上报、AI 分析等),我可以为你制定一个更针对的阅读与开发计划,比如“如何加摄像头数据流进 ThingsBoard 并触发 AI 识别”等。是否希望我帮你制定这部分?