基于PLC的工业数据采集方案:通过OPC UA对接边缘计算网关
在工业4.0架构中,PLC位于控制层,MES/ERP位于管理层,中间的数据桥梁就是边缘计算网关。OPC UA(统一架构)作为跨平台、安全加密、信息模型丰富的通信标准,正在取代传统OPC DA和私有协议,成为PLC数据上行的首选。本文以西门子S7-1200对接基于Linux的边缘网关为例,演示从PLC端配置到网关Python客户端的完整数据采集链路。
为什么选择OPC UA
相比Modbus TCP和S7协议,OPC UA有三个核心优势:一是原生加密和认证,无需担心数据泄露;二是信息模型支持,PLC可以暴露结构化数据(如设备名称、单位、报警状态),而非裸寄存器地址;三是跨平台,从Windows到ARM Linux均可部署。S7-1200从固件v2.0起内置OPC UA服务器,无需额外硬件。
第一步:PLC端OPC UA服务器配置
在TIA Portal中启用OPC UA并授权访问:
设备组态 → 选中CPU → 属性 → OPC UA → 服务器 → 勾选“激活OPC UA服务器”
通信 → 安全 → 选择“基本128位RSA加密”(安全模式建议选SignAndEncrypt,生产环境不应使用None)
在“OPC UA → 用户认证”中创建用户名/密码(如admin/admin123)
将需要暴露的DB块添加到OPC UA命名空间:右击DB块 → 属性 → OPC UA → 勾选“发布到OPC UA服务器”
配置完成后下载到PLC,重启后OPC UA服务自动运行在端口4840。
第二步:边缘网关Python客户端
网关使用Python的opcua-asyncio库(推荐异步版本,性能优于同步库):
pip install opcua-asyncio
连接PLC并读取温度值:
import asyncio
from opcua import Client
async def read_plc():
client = Client("opc.tcp://192.168.0.1:4840")
try:
await client.connect()
# 设置安全模式(可选)
client.set_security_string("Basic128Rsa15,SignAndEncrypt,./cert.der,./key.pem")
# 获取根节点
root = client.get_root_node()
# 浏览命名空间找到温度变量(路径根据实际配置调整)
temp_node = root.get_child(["Objects", "PLC", "DB1", "Temperature"])
temp = await temp_node.read_value()
print(f"当前温度: {temp} °C")
finally:
await client.disconnect()
asyncio.run(read_plc())
如果不需要加密,可以省略set_security_string,但生产环境强烈建议启用。
第三步:批量轮询与边缘处理
实际项目中需要周期性采集多个变量,并在网关侧做滤波、聚合和缓存。以下是一个完整的采集循环:
import asyncio, json, time
from opcua import Client, ua
class PLCCollector:
def __init__(self, url, username, password):
self.url = url
self.username = username
self.password = password
self.client = Client(url)
self.nodes = {}
async def connect(self):
await self.client.connect()
self.client.set_user(self.username)
self.client.set_password(self.password)
# 预获取节点句柄,避免每次遍历
root = self.client.get_root_node()
self.nodes['temp'] = root.get_child(["Objects", "PLC", "DB1", "Temperature"])
self.nodes['pressure'] = root.get_child(["Objects", "PLC", "DB1", "Pressure"])
self.nodes['flow'] = root.get_child(["Objects", "PLC", "DB1", "FlowRate"])
async def poll_once(self):
data = {}
for name, node in self.nodes.items():
try:
value = await node.read_value()
data[name] = value
except ua.UaStatusCodeError as e:
print(f"读取 {name} 失败: {e}")
return data
async def run(self, interval=1.0):
await self.connect()
while True:
data = await self.poll_once()
data['timestamp'] = time.time()
# 本地缓存(写入SQLite或InfluxDB)
self.store_locally(data)
# 判断是否需要报警
if data.get('temp', 0) > 80:
print("⚠️ 温度超限")
await asyncio.sleep(interval)
def store_locally(self, data):
# 简化为打印,实际写入时序数据库
print(json.dumps(data))
async def main():
collector = PLCCollector("opc.tcp://192.168.0.1:4840", "admin", "admin123")
await collector.run()
asyncio.run(main())
第四步:数据上云
边缘网关采集的数据通常需要上传到云端平台(如ThingsBoard、Azure IoT)。使用MQTT转发:
import paho.mqtt.client as mqtt
mqtt_client = mqtt.Client()
mqtt_client.connect("cloud.thingsboard.cloud", 1883)
# 在poll_once之后
payload = json.dumps(data)
mqtt_client.publish("v1/gateway/telemetry", payload)
性能与安全建议
订阅模式:如果PLC支持OPC UA订阅(MonitoredItem),可以替代轮询,减少网络流量和CPU占用
安全加固:生产环境务必启用SignAndEncrypt,使用CA签发的证书,避免明文传输
断线重连:网关程序必须实现自动重连机制,OPC UA客户端库通常内置此功能
数据压缩:上传云端前对JSON做gzip压缩,节省带宽
写在最后
OPC UA+边缘网关的组合,为PLC数据采集提供了一个标准化、安全、可扩展的架构。PLC端只需勾选几个配置项,边缘网关用几十行Python代码就能完成数据读取、本地处理和云端转发。相比传统的Modbus轮询,OPC UA的信息模型让数据自带语义,减少了上位机侧的解析工作量。当你的产线需要从“能采集”升级到“可管理、可分析”时,OPC UA是那条最宽阔的桥梁。





