上个月帮一个做注塑机车间改造的客户搭了一套本地部署的物联网平台,整个过程踩了不少坑,也攒了不少可以直接复用的经验。今天把思路、选型逻辑和能落地的细节整理出来,给正准备做本地部署物联网平台的朋友一个参考。
先说清楚一点,我这里说的“本地部署的物联网平台”,不是随便装个开源软件跑起来就完事,而是指设备数据采集、传输、存储、可视化、告警、甚至智能分析这一整套链路,全部跑在内网环境里,不依赖公有云。再加上今年本地部署大模型的热度这么高,Ollama、DeepSeek、Dify、RAGFlow这些关键词被反复提起,物联网平台本地部署之后,再把大模型能力接进去,让设备数据自己“开口说话”,其实是当前性价比极高的一个演进方向。这篇文章会从需求拆解讲到具体部署,代码和命令都会给全。
1. 项目思路拆解:本地部署物联网平台到底在解决什么问题
1.1 哪些场景必须放弃公有云,选择本地部署
很多人一听物联网平台,第一反应是阿里云IoT、AWS IoT Core这类托管服务。的确,公有云平台省事,按量付费,设备接入SDK也齐全。但实际项目里,有一批场景是打死都不能上公有云的。
我这次碰到的注塑机车间项目就非常典型。客户工厂里的注塑机本身通过PLC控制,设备数据涉及模具温度、射胶压力、锁模力、成型周期这些工艺参数。这些数据对企业来说是核心工艺资产,老板明确要求数据不能出内网。如果上公有云,哪怕只是把设备数据转发到云端做展示,客户心里那道坎也过不去。这不是技术问题,是信任问题和数据归属问题。
类似的场景还有不少:
- 工厂车间设备联网:设备数据是生产现场的核心资产,很多企业在数字化改造的招标文件里直接写明“数据本地存储,不得上传至公有云”,这种情况下只能做本地部署。
- 园区能耗监控:电表、水表、气表数据要接入统一的能源管理平台,但园区管理方希望数据完全可控,并且不希望每个月为设备接入量支付云平台费用。
- 教学实训环境:物联网仿真实训平台里,学生需要反复做设备接入、数据采集、规则引擎配置、可视化组态这些实验,如果依赖云端,网络一抖动实验就断了。本地部署的物联网平台可以无限创建实验环境,随便折腾,都不会有额外成本。
- 边缘机房、农业大棚、冷链仓库:很多这类环境根本没有稳定的公网连接,或者带宽非常有限。一个完全跑在本地的小型物联网平台,可以把网关、MQTT Broker、规则引擎、告警通知全部放在一台小主机上。
这里有个很现实的问题:公有云平台按设备数、消息数、数据存储量计费,一年下来一台设备的成本看着不高,但几百上千台设备,再加上长期存储和API调用,费用相当可观。本地部署是一次性投入,硬件到位后,后面新增设备基本没有边际成本。这也是很多中小型项目最终选择本地部署的核心原因。
1.2 本地部署的物联网平台整体架构怎么搭
明确了要本地部署,接下来就是架构设计。物联网平台虽然叫“平台”,但绝对不是一个大而全的软件,而是一组组件组合起来形成的整体能力。我习惯把整个链路拆成五层:
| 层级 | 职责 | 常用开源组件 | 部署方式 |
|---|---|---|---|
| 采集层 | 对接设备协议,采集传感器/PLC数据 | Node-RED、各种边缘网关 | Docker容器或物理网关 |
| 传输层 | 设备消息的接入与转发 | EMQX、Mosquitto、VerneMQ | Docker容器 |
| 存储层 | 时序数据、设备元数据、告警记录 | InfluxDB、TimescaleDB、MySQL | Docker容器 |
| 应用层 | 设备管理、可视化看板、告警通知 | ThingsBoard、Grafana、Node-RED | Docker容器 |
| AI增强层 | 设备数据智能分析、知识库问答 | Ollama、Dify、RAGFlow | Docker容器 |
这套架构的好处是每一层都可以单独替换。比如你不想用EMQX,传输层换成Mosquitto也能跑;你不想用Grafana做可视化,换ThingsBoard也行。每层之间通过标准协议通信——采集层到传输层走MQTT,传输层到存储层靠规则引擎写入时序数据库,应用层通过HTTP/API读取数据。这样哪怕以后某个组件不再维护,替换成本也很低。
选型的核心原则其实就几条:开源优先、社区活跃、本地部署方便、对硬件要求不能太苛刻。容器化是必须的,Docker Compose管理一组容器,比手工安装一堆依赖要省心太多。我见过有人非要在裸机上装EMQX、InfluxDB、Grafana,结果依赖冲突搞了一整天,最后老老实实回到Docker Compose。能用容器解决的问题,不要自己编译。
2. 核心组件选型:MQTT Broker、时序数据库与可视化工具的取舍
2.1 MQTT Broker首选EMQX的逻辑
物联网设备接入最常用的协议是MQTT,因为它基于发布/订阅模型,非常适合大量设备频繁上报小数据量的场景。而MQTT Broker就是整个平台的“消息中枢”,所有设备消息都要经过它转发,它的稳定性直接决定了平台的命脉。
我一开始考虑过Mosquitto,毕竟体积小、部署简单,一个几十MB的容器就能跑。但实际用下来发现,Mosquitto在功能上偏“裸”——它只提供最基础的MQTT消息转发,设备管理、规则引擎、数据集成这些能力全都没有。如果只是接几个传感器玩玩,够用;但要做一个正经的平台,后面还是要补一堆东西。
EMQX就完全是另一回事了。它本身是用Erlang写的,天生适合高并发连接,官方标称单节点可以支撑百万级连接。我们实际项目里几十台设备,对它来说就是洒洒水。更关键的是,EMQX内置了规则引擎,可以直接把MQTT消息通过SQL表达式处理后转发到InfluxDB、MySQL、Kafka等数据源,省掉了自己写桥接程序的麻烦。Dashboard也做得不错,设备连接数、消息量、订阅关系一眼就能看明白。
版本上我推荐直接用5.x。4.x虽然经典,但配置方式和插件机制跟5.x差异很大,网上搜到的很多教程都是老版本,照抄容易踩坑。5.x把认证、权限、规则引擎都整合到了Dashboard里操作,图形化配置对新手友好得多。
2.2 数据不能进MySQL:时序数据库的选型细节
设备数据第一特征是“时间戳密集”,而且几乎只追加、不修改。这种数据形态如果硬塞进MySQL,很快会遇到两个问题:一是写入性能,设备越多,每秒INSERT的并发越高,关系型数据库要处理索引、事务,很容易成为瓶颈;二是查询效率,你想看“最近一小时每台设备的平均温度”,SQL里要写一堆GROUP BY和日期函数,数据量大之后慢得让人抓狂。
时序数据库就是专门为这种场景设计的。它把时间戳作为主索引,按时间分区存储,数据压缩率极高,还自带按时间聚合查询的能力。
我这次用的是InfluxDB 2.x。选择它的原因是:
- 有官方Docker镜像,环境变量支持自动初始化,部署极其省事;
- 自带数据看板和告警规则,小项目甚至可以不开Grafana;
- Flux查询语言功能强大,窗口聚合、降采样、异常检测都能写;
- 2.x版本把权限、组织、桶(Bucket)的概念整合得很清晰,比1.x的数据库/保留策略模式简单不少。
如果数据量特别大,或者你对SQL生态更熟,可以考虑TimescaleDB。它是PostgreSQL的扩展,写的是标准SQL,迁移平滑,很多用过传统数据库的人上手很快。但TimescaleDB对硬件要求比InfluxDB高一点,而且规则引擎集成到InfluxDB更顺滑,所以我个人还是推荐先上InfluxDB。
顺便说个数据量估算的方法。我这次30台注塑机,每5秒上报一次数据,每台设备每天产生17280条记录,30台一天就是51.8万条。假设每条数据100字节,一天约50MB原始数据。InfluxDB压缩后大概能缩到原始数据的十分之一,30天存储量也就150MB左右。所以一般的车间项目,一台普通服务器或者高性能工控机完全够用,不需要上分布式集群。
2.3 可视化与流编排:Grafana、Node-RED、ThingsBoard的分工
可视化是物联网平台最容易出彩也是客户最关注的部分。很多人上来就问“用哪个可视化工具”,但我的经验是:先搞清楚你要展示什么、给谁看。
- 给操作工人看的产线大屏,讲究实时、简洁、大字号。这种情况我用Grafana,连接InfluxDB数据源,直接拖拽出实时曲线和统计面板。Grafana的图表类型丰富,告警状态、设备状态、能耗趋势都能画得漂亮,还支持自定义告警通知。
- 给设备工程师看的设备详情页,讲究历史曲线、参数对比、事件记录。这种情况可以用ThingsBoard,它自带设备资产模型、设备影子、告警管理,能跟EMQX通过MQTT对接,设备状态变化可以直接在平台里看到。
- 给IT/自动化工程师做的集成逻辑,比如设备数据清洗、格式转换、联动控制,我会用Node-RED。它是一个可视化流编排工具,把多个节点用线连起来就能实现一套逻辑。比如一条MQTT消息进来,先解析JSON,再判断数值是否超限,超限就发HTTP请求到企业微信机器人,同时写入MySQL。这种流在Node-RED里十来分钟就能搭好。
不过要提醒一句,ThingsBoard社区版虽然功能强大,但它默认的Docker Compose会拉起Kafka、Elasticsearch、PostgreSQL一堆服务,资源占用非常夸张。我第一次跑官方compose时,4GB内存的机器直接被卡死。如果你只是想快速看到设备数据、跑通流程,建议先用“EMQX + InfluxDB + Grafana + Node-RED”这套轻量组合。等确实需要设备管理、资产管理了,再把ThingsBoard加进来也不迟。
3. 实操过程:用Docker Compose一小时搭起本地物联网平台
3.1 环境准备与端口规划
开始部署之前,先把硬件和端口规划好,这一步省掉后面一大半的麻烦。
硬件方面,我们这次用的是客户淘汰的一台工作站,16GB内存、8核CPU、一块512GB SSD,跑这套轻量组合绰绰有余。如果你有NVIDIA GPU,后面打算接本地大模型,那建议至少32GB内存,GPU显存8GB起步。没有GPU也没关系,用小模型跑CPU推理也能用,只是响应速度慢一点。
操作系统我就用Ubuntu 22.04 LTS,安装完Docker Engine和Docker Compose插件后就可以开工。这里有个小坑:Ubuntu自带的docker.io包版本往往比较旧,一定要用官方源安装Docker Engine,否则后面拉镜像、用Compose插件都可能出问题。
端口规划上,我先把整个平台会用的端口列成了一张表,贴在工位上,避免后面服务启动时才发现端口冲突:
| 服务 | 端口 | 说明 |
|---|---|---|
| EMQX MQTT | 1883 | 设备接入端口,TCP |
| EMQX MQTT/SSL | 8883 | 加密接入,留作后续扩展 |
| EMQX Dashboard | 18083 | Web管理界面 |
| InfluxDB | 8086 | HTTP API端口 |
| Node-RED | 1880 | 流编排编辑器 |
| Grafana | 3000 | 可视化看板 |
| Ollama | 11434 | 本地大模型API |
有个很容易忽略的点:EMQX默认Dashboard端口是18083,InfluxDB是8086,Node-RED是1880,Grafana是3000。这些端口如果跟公司内网其他系统冲突,一定要在compose文件里提前改掉。我之前遇到过一台服务器上同时跑了Jenkins(8080)和另一个服务用了8083,结果EMQX的Web管理端口8083被占用,服务起来后Dashboard一直打不开,排查了半天才发现是端口冲突。
3.2 容器编排文件与启动验证
环境准备好之后,直接写docker-compose.yml。我先给出一份完整的、能直接用的编排文件:
version: '3.8' services: emqx: image: emqx/emqx:5.8.0 container_name: emqx ports: - "1883:1883" - "8883:8883" - "18083:18083" environment: - EMQX_NODE_NAME=emqx@127.0.0.1 restart: unless-stopped influxdb: image: influxdb:2.7 container_name: influxdb ports: - "8086:8086" environment: - DOCKER_INFLUXDB_INIT_MODE=setup - DOCKER_INFLUXDB_INIT_USERNAME=admin - DOCKER_INFLUXDB_INIT_PASSWORD=admin123456 - DOCKER_INFLUXDB_INIT_ORG=iotlab - DOCKER_INFLUXDB_INIT_BUCKET=iot_data - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-token-2024 volumes: - influxdb-data:/var/lib/influxdb2 restart: unless-stopped node-red: image: nodered/node-red:3.1.9 container_name: node-red ports: - "1880:1880" environment: - TZ=Asia/Shanghai volumes: - node-red-data:/data restart: unless-stopped grafana: image: grafana/grafana:11.1.0 container_name: grafana ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin123456 - TZ=Asia/Shanghai volumes: - grafana-data:/var/lib/grafana restart: unless-stopped volumes: influxdb-data: node-red-data: grafana-data:这个文件的几个细节值得说明一下:
InfluxDB的初始化环境变量是关键。第一次启动时,它会自动创建管理员账号、组织(org)、存储桶(bucket)以及访问令牌(token)。后续所有写入InfluxDB的请求都要用到这个token,所以那个my-super-secret-token-2024一定要记好,最好改成一个你自己的随机字符串,别照抄。
Grafana默认账号是admin,密码我通过环境变量直接改成了admin123456,第一次登录不用再改,也省得之后一遍遍输默认密码。
restart: unless-stopped这个策略非常推荐。服务器重启或者容器异常退出后,Docker会自动拉起容器,对无人值守的机房环境特别重要。我见过有人没写这个参数,半夜服务器重启了一下,第二天早上设备数据全断,因为MQTT Broker根本没起来。
文件写好之后,在对应目录下执行:
docker compose up -d然后等镜像拉取完成。拉镜像的时间取决于网络情况,EMQX的镜像大约100多MB,InfluxDB和Grafana也都不小。如果发现拉取超时,先检查一下Docker的registry-mirrors配置是否设置了一个可用的源,这个属于国内部署的基础操作。
启动完成后,逐个验证服务:
- 浏览器打开
http://服务器IP:18083,能出现EMQX Dashboard登录页,默认账号admin、密码public; - 浏览器打开
http://服务器IP:8086,能看到InfluxDB初始化界面; - 浏览器打开
http://服务器IP:1880,进入Node-RED编辑器; - 浏览器打开
http://服务器IP:3000,用admin/admin123456登录Grafana。
四个页面全部能打开,基础平台就算立住了。
3.3 设备接入实测:模拟数据从MQTT到InfluxDB再上大屏
平台跑起来之后,下一步就是设备接入。没有真实设备也没关系,我先用Python写一个模拟器,模拟30台注塑机的温度、压力数据,每5秒上报一次,走MQTT协议发到EMQX。
模拟器代码不长,核心逻辑就是循环连接EMQX,构造JSON消息,然后发布到固定主题:
import paho.mqtt.client as mqtt import time import json import random BROKER_HOST = "192.168.1.100" BROKER_PORT = 1883 USERNAME = "emqx_user" PASSWORD = "emqx_pass" TOPIC = "factory/injection/temperature" client = mqtt.Client(client_id="simulator_001") client.username_pw_set(USERNAME, PASSWORD) client.connect(BROKER_HOST, BROKER_PORT, 60) while True: for i in range(1, 31): payload = { "device_id": f"INJ-{i:03d}", "temperature": round(random.uniform(180, 220), 2), "pressure": round(random.uniform(10, 30), 2), "ts": int(time.time() * 1000) } client.publish(TOPIC, json.dumps(payload), qos=1) print(f"已发送一批数据,当前时间: {time.strftime('%Y-%m-%d %H:%M:%S')}") time.sleep(5)注意这里我调用了username_pw_set,也就是说EMQX上必须提前创建好这个认证用户。在EMQX Dashboard里找到“访问控制”→“认证”,添加一个用户名密码认证数据源,然后创建emqx_user/emqx_pass。MQTT Broker默认允许匿名连接,但生产环境必须关掉匿名认证,否则任何人都能往里发数据,也能订阅所有设备的实时数据,这是很容易被忽视的安全隐患。
模拟器跑起来之后,在EMQX Dashboard的“主题”页面能看到factory/injection/temperature主题有消息流动。接下来要把这些消息接入InfluxDB。
在EMQX Dashboard里创建一条规则,SQL大概是这样的:
SELECT clientid, payload.device_id as device_id, payload.temperature as temperature, payload.pressure as pressure, payload.ts as ts FROM "factory/injection/temperature"动作选择“数据转发到InfluxDB”,填上InfluxDB的地址、组织、bucket、token,并指定一个measurement名称。保存后,消息就会自动写入InfluxDB的iot_data桶中。
验证数据是否写入,可以在InfluxDB的Web界面里执行一个最简单的Flux查询:
from(bucket: "iot_data") |> range(start: -10m) |> limit(n: 20)能看到数据就说明整条链路已经通了。然后在Grafana里添加InfluxDB数据源,选Flux查询方式,建一个面板,查询最近一小时temperature的平均值,按device_id分组,展示成时间序列曲线。到这里,从设备模拟数据到可视化大屏的完整闭环就打通了。
4. 本地AI增强:把大模型接入物联网平台,让数据自己开口说话
4.1 Ollama本地部署与模型选型
平台跑通之后,如果只停留在“采集数据、展示曲线”这个层面,其实还没发挥出本地部署的全部潜力。最近本地部署大模型这个话题热度极高,Ollama、DeepSeek、RAGFlow这些工具的组合已经非常成熟,完全可以把大模型能力接到物联网平台上,做告警分析、维修辅助、数据问答。
先部署Ollama。Ollama是目前最省事的本地大模型运行环境,一行命令就能把模型跑起来,而且提供REST API,能被其他服务直接调用。
# 在有GPU的机器上,加上--gpus all参数,并把默认端口映射出来 docker run -d --gpus all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama:latest # 拉取一个7B参数的模型,日常分析够用 docker exec -it ollama ollama pull qwen2.5:7b模型选型上,我个人的建议是:机器内存16GB以内,先跑qwen2.5:7b;如果内存32GB以上或者有8GB以上显存,可以上qwen2.5:14b或者同类别的更大模型;如果只是做简单的分类、关键词提取,3B~4B的小模型也够,速度还快。7B模型在CPU上做简单推理,单条请求大约几秒到十几秒,作为异步分析完全够用;如果要实时响应,那就得靠GPU了。
部署好Ollama后,可以先做一个最简单的验证,用curl调用它的API:
curl http://localhost:11434/api/generate -d '{ "model": "qwen2.5:7b", "prompt": "一台注塑机连续5分钟温度超过210度,可能是什么原因?给出排查建议。", "stream": false }'能返回一段合理的文本回复,就说明本地大模型已经就位。
4.2 用Dify/RAGFlow构建设备知识库
大模型本身的问题是,它只懂通用知识,对你这套具体的设备、你的工厂历史维修记录一无所知。要让AI真正能帮上忙,得把企业的设备手册、历史维修记录、工艺参数文档喂给它,这就用到了知识库工具。当前最主流的两个选择是Dify和RAGFlow。
Dify的优势是应用编排能力很强。你可以创建一个“设备维修助手”应用,把设备告警JSON数据作为输入,先经过一个工作流节点,把告警信息、设备编号、最近历史数据拼装成Prompt,再调用Ollama里的模型生成分析结果,最后把结果返回给前端。整个过程不需要写太多代码,在网页上拖拽配置就行。
RAGFlow的优势在于文档解析。如果你手头有几十页的PDF设备手册,RAGFlow能把版面、表格、图片里的信息都解析出来存入向量库,检索准确率比普通切片方案要高不少。两者也支持一起用:RAGFlow负责把文档切成向量索引,Dify负责做对话流程编排。
这两套系统都属于“一个Docker Compose就能起”的类型,部署方式官方文档写得很清楚。它们对内存的要求稍高,建议至少8GB内存再跑。如果机器资源有限,也可以先只部署Dify,它本身自带知识库能力,只是文档解析精细度不如RAGFlow。
4.3 告警自动分析场景的实现示例
设备接入、数据入库、大模型部署都完成之后,我们来做一个完整的告警分析场景。
场景设定:注塑机INJ-003在连续5分钟内温度超过210度,平台要自动生成一条告警,并附带可能的故障原因、排查建议和历史上类似故障的处理记录。
实现思路是这样的:
- EMQX规则引擎实时监控温度数据,当某台设备连续多次超过阈值时,触发一条告警消息,发布到
alerts/injection主题; - Node-RED订阅这个主题,收到告警后,从InfluxDB查询该设备最近30分钟的历史数据,把温度、压力、趋势信息整理成文本;
- Node-RED把文本POST到Dify的“设备维修助手”应用API;
- Dify的工作流先从RAGFlow向量库检索相关历史维修记录,再将检索结果和告警信息一起组装成Prompt,调用Ollama的qwen2.5:7b模型;
- 模型生成的分析结果,再由Node-RED推送到企业微信机器人或者存入新的MQTT主题,供Web端展示。
这里面最核心的一段逻辑,是第三步调用Dify API的HTTP配置。Dify的API请求格式如下:
curl --location --request POST 'http://localhost/app/api/chat-messages' \ --header 'Authorization: Bearer app-xxxxx' \ --header 'Content-Type: application/json' \ --data-raw '{ "inputs": { "temperature": 212.5, "pressure": 18.6, "device_id": "INJ-003" }, "query": "这台注塑机温度偏高,请给出可能原因和排查建议", "response_mode": "blocking", "user": "edge-user-001" }'实际跑下来的效果,模型会综合设备当前数据和历史维修知识,生成类似这样的建议:“温度偏高且压力波动明显,优先检查模具冷却水路是否堵塞;其次检查热电偶安装位置是否偏移;历史记录显示INJ-003在2023年5月曾因冷却阀故障导致同类问题,当时更换电磁阀后恢复正常。”
这种输出对车间维修工来说,比干巴巴看一个温度曲线图有用得多。而且整个链路全部跑在内网,设备数据和维修知识都没有出过本地服务器。这正是本地部署物联网平台叠加本地大模型的最大价值。
5. 常见问题与避坑实录
5.1 高频问题速查表
部署这套平台的过程中,我整理了一份高频问题速查表,都是实际踩过的坑:
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| EMQX Dashboard打不开 | 端口18083未映射或防火墙没放行 | 检查docker compose端口映射,确认服务器防火墙放行18083 |
| MQTT客户端连不上 | EMQX开启了认证但用户没创建 | 在Dashboard的“访问控制-认证”中创建用户 |
| 设备数据写不进InfluxDB | token错误或bucket名不对 | 核对compose文件里的token,以及EMQX规则中填写的InfluxDB配置 |
| Grafana查不到数据 | 数据源选了InfluxQL但InfluxDB是2.x | Grafana数据源查询语言切为Flux,并写Flux查询语句 |
| 容器重启后服务没起来 | compose文件漏写restart策略 | 给每个服务加上restart: unless-stopped |
| Node-RED安装节点卡住 | npm默认源访问慢 | 在Node-RED容器中设置npm镜像源后重试 |
| 服务器时间不准导致数据时间错乱 | 容器时区未设置 | compose文件中统一配置TZ=Asia/Shanghai |
5.2 三个容易忽略的细节,直接影响项目成败
第一个细节是QoS级别。MQTT消息有三种QoS级别,0表示最多一次,1表示至少一次,2表示只有一次。很多人图省事用了QoS 0,结果网络一抖动,数据就丢了。物联网平台的数据是后续分析的基础,我建议平台内部所有消息至少用QoS 1。代价是消息确认会多一点网络开销,但对现在的网络环境来说完全不是问题。我实测过,30台设备每5秒上报,QoS 1对EMQX的影响几乎可以忽略,但数据完整性明显提升。
第二个细节是InfluxDB的时序数据时间戳单位。InfluxDB 2.x默认时间戳是纳秒级,而很多设备上报的时间戳是毫秒级。如果你在EMQX规则里直接把设备的毫秒时间戳写入InfluxDB而不做转换,查询出来的时间会偏离真实时间很多。我建议在写入时统一用now()或者让InfluxDB自动处理时间戳,数据到达时间跟设备时间差个几秒对大多数分析场景没有影响。
第三个细节是端口规划。平台本身组件不多,但加上Node-RED、Ollama、Dify之后,端口数量就上来了。我建议开工之前先画一张端口分配表,把每个服务的端口固定好,写进compose文件里的注释中,同时跟客户的IT部门确认这些端口没有被其他系统占用。否则上线当天发现1883端口被某个内部系统占了,临时改端口,客户端配置又要跟着改一遍,非常耽误事。
踩过几次坑之后,我个人的习惯是:先花半小时把数据模型、端口、存储周期想清楚,再开始写compose文件。部署这套本地物联网平台,真正花时间的不是敲命令,而是想清楚数据流、告警规则和AI分析逻辑。架构想透了,剩下的都是体力活。
这套方案后续还可以加边缘计算(比如用eKuiper在网关侧做实时过滤和聚合)、数字孪生可视化(把设备数据映射到3D模型上)、以及更细粒度的预测性维护模型。但不管怎么扩展,本地的数据底座和AI底座都不会变。先把基础打牢,后面做什么都有底气。