2. 系统架构设计:监控系统总体架构、数据流向、边缘计算节点部署、云平台架构
好,咱们进入第二章。这一章我打算把整个重力储能电站的监控系统骨架给你搭起来。说白了,就是搞清楚数据从哪来、经过哪、最后到哪去,以及每个环节该放什么东西。
我个人习惯,做任何系统设计之前,先画一张总图。脑子里没图,后面写代码全是乱的。来,先看这张我手绘的总体架构图。
2.1 监控系统总体架构:四层模型
这张图我画了四个层次。你仔细看,每一层都有明确的职责,层与层之间通过标准接口通信。我在实际项目中吃过亏——一开始图省事,把边缘计算和云平台的功能混在一起,结果后期维护成本翻了三倍。所以,分层一定要清晰。
这四层分别是:
- 现场设备层:所有传感器、执行器、PLC。这是数据的源头,也是控制指令的终点。
- 边缘计算节点层:部署在电站本地机房的工业网关或工控机。负责数据采集、协议转换、本地处理。
- 通信网络层:光纤为主,4G/5G为辅。必须冗余,我曾经见过光纤被施工挖断,全靠4G撑着没丢数据。
- 云平台层:远程数据中心。做数据存储、分析、展示、告警。
核心原则:边缘节点做「实时」和「本地」的事,云平台做「全局」和「历史」的事。千万别搞反。
2.2 数据流向:从传感器到云端的完整链路
数据怎么流?我举个例子你就明白了。假设一个重力块正在上升,我们需要监控它的位移和速度。
- 传感器采集:编码器每10ms产生一个脉冲信号,PLC读取后换算成位移值(单位mm)。
- 边缘节点接收:边缘网关通过Modbus TCP轮询PLC,每100ms读取一次数据。
- 边缘处理:网关对数据进行有效性检查——比如位移值不能突变超过50mm,否则标记为异常。同时计算瞬时速度。
- 数据上传:每1秒,边缘节点将聚合后的数据(平均值、最大值、最小值)打包成JSON,通过MQTT发布到云平台。
- 云平台存储:Kafka接收消息,InfluxDB写入时序数据。同时触发告警规则检查。
- 前端展示:WebSocket推送数据到浏览器,大屏实时刷新。
嗯,这里要注意一个细节:数据压缩。原始数据如果全量上传,带宽根本扛不住。我在一个项目中,单台边缘节点每秒产生2000条数据,压缩后只有原来的1/10。常用的方法有死区压缩和旋转门压缩。
我的经验:死区压缩适合缓慢变化的信号(如温度),旋转门压缩适合快速变化的信号(如振动)。别用反了。
2.3 边缘计算节点部署:选型与配置
边缘节点是整个系统的「腰部」。腰不好,上面再强的云平台也白搭。我一般按以下标准选型:
| 参数 | 推荐配置 | 说明 |
|---|---|---|
| CPU | ARM Cortex-A72 四核 或 x86 赛扬 | 满足协议转换和简单推理即可 |
| 内存 | 4GB ~ 8GB | 本地缓存1小时数据,防止断网丢失 |
| 存储 | 64GB eMMC + 128GB SSD | SSD用于时序数据库本地存储 |
| 网络 | 双网口(冗余)+ 4G模块 | 一个口接光纤环网,一个口接PLC |
| 系统 | Linux(Ubuntu Server / Debian) | 稳定,支持Docker部署 |
| 功耗 | < 30W | 无风扇设计,适应机房环境 |
部署位置呢?我建议放在电站的升压站机房或者控制室。距离现场设备不超过100米,用屏蔽双绞线连接。如果距离太远,考虑光纤转以太网。
避坑指南:我曾经把边缘节点放在户外机柜里,夏天温度一高,系统频繁重启。后来强制要求所有边缘节点必须放在空调机房,或者使用工业级宽温设备(-40℃~85℃)。
2.4 边缘计算的核心功能:不只是转发
很多人以为边缘节点就是个「数据二传手」,其实远不止。我总结了三项核心功能:
- 协议转换:现场设备协议五花八门——Modbus RTU、Modbus TCP、OPC UA、IEC 61850、西门子S7、三菱MC。边缘节点必须统一转换成MQTT/HTTP上报云端。
- 本地闭环控制:比如重力块超速时,边缘节点直接下发指令给PLC紧急制动,不需要等云端响应。延迟从秒级降到毫秒级。
- 断网续传:网络断了,数据先存在本地SQLite或TDengine里。网络恢复后,按时间戳补传。我遇到过断网12小时的情况,恢复后数据一条没丢。
这里给一段简单的边缘节点数据采集代码示例(Python伪代码):
import minimalmodbus
import paho.mqtt.client as mqtt
import json
import time
# 初始化Modbus从站(PLC)
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)
instrument.serial.baudrate = 115200
# MQTT客户端
client = mqtt.Client()
client.connect("cloud.energy-storage.com", 1883, 60)
while True:
try:
# 读取重力块位移(寄存器地址100,数据类型16位有符号)
displacement = instrument.read_register(100, 0, signed=True)
# 读取电机转速(寄存器地址101)
speed = instrument.read_register(101, 0, signed=True)
# 数据有效性检查
if displacement < 0 or displacement > 50000:
print("位移数据异常,丢弃")
continue
# 打包成JSON
payload = {
"timestamp": int(time.time() * 1000),
"device_id": "gravity_block_01",
"displacement_mm": displacement,
"speed_rpm": speed
}
# 发布到云平台
client.publish("gravity/data", json.dumps(payload), qos=1)
print(f"已发送: {payload}")
except Exception as e:
print(f"采集异常: {e}")
time.sleep(0.1) # 100ms采集周期
2.5 云平台架构:数据进来之后
数据到了云端,怎么组织?我习惯用微服务架构,每个组件各司其职。下图是云平台内部的数据流:
云平台的关键组件我列一下:
- MQTT Broker:推荐EMQX或VerneMQ。支持百万级并发连接,边缘节点直接接入。
- 消息队列:Kafka是标配。削峰填谷,防止数据库被瞬时流量打满。
- 时序数据库:InfluxDB适合中小规模,TDengine适合大规模(单机每秒写入百万点)。我个人偏爱TDengine,压缩比高,查询快。
- 告警服务:基于规则引擎。比如「重力块位移超过安全阈值持续5秒」触发告警,通过短信/邮件/钉钉通知运维人员。
- 可视化:Grafana + 自研大屏。Grafana做历史趋势图,自研大屏做3D电站全景展示。
关键设计决策:云平台必须支持水平扩展。当电站数量从1个增加到100个时,只需要加服务器节点,不需要改代码。Kafka和时序数据库天生支持集群,选型时优先考虑。
2.6 总结一下这一章的核心
系统架构设计,说白了就是「分而治之」。现场设备只管采集和执行,边缘节点管实时和本地,云平台管全局和历史。数据从下往上流,控制指令从上往下流。每一层做好自己的事,别越界。
嗯,这一章的内容就到这里。下一章我们开始动手搭环境,把边缘节点的软件栈跑起来。
公众号:蓝海资料掘金营,微信deep3321