摘要 :对于IIoT应用开发者而言,如何优雅地处理底层异构的PLC协议,是一个常见的挑战。本文将提供一个具体的、可复现的实战项目:在一个开放的工业边缘计算网关(以鲁邦通EG系列为例)上,利用Python和Docker,创建一个统一的数据服务,实现对西门子S7和三菱MC协议PLC的并发、异步读写,并将结果通过统一的MQTT主题发布。
导语 :作为开发者,我们理想中的数据采集应该是:调用一个简单的API,如read_tag("Motor_Speed"),而无需关心这个标签是来自西门子的DB块,还是三菱的D寄存器。本文将向你展示,如何利用工业边缘计算网关的开放性和计算能力,结合强大的开源社区,构建出这样一个与底层协议细节解耦的、优雅的南向数据服务。
项目架构设计
我们将构建一个运行在Docker容器内的Python应用。该应用包含三个核心模块:
-
S7 Client Module: 使用
python-snap7库,负责与西门子PLC通信。 -
MC Client Module: 使用
pymcprotocol库,负责与三菱PLC通信。 -
Main Service Module: 负责调度上述两个客户端,并发地、周期性地轮询点位,并将读取到的数据,以统一的JSON格式,发布到MQTT Broker。
1. 准备Dockerfile
我们需要一个包含Python环境和所需库的ARM64 Docker镜像。
Dockerfile:
Dockerfile
# Use an ARM64 compatible Python base image from a trusted source
FROM arm64v8/python:3.9-slim-bullseye
# Install snap7 library dependencies
RUN apt-get update && apt-get install -y libsnap7-1 libsnap7-dev && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
# Install Python libraries
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]
requirements.txt:
python-snap7
pymcprotocol
paho-mqtt
2. 核心代码实现 (main.py)
为了实现并发轮询,我们为每台PLC创建一个独立的线程。
Python
import snap7
import pymcprotocol
import paho.mqtt.client as mqtt
import threading
import time
import json
# --- Config ---
SIEMENS_IP = '192.168.1.10'
MITSUBISHI_IP = '192.168.1.11'
MQTT_BROKER = 'localhost' # Use the gateway's own MQTT broker
MQTT_TOPIC_PREFIX = 'factory/plc'
# --- Siemens Polling Thread ---
def siemens_poller():
client = snap7.client.Client()
try:
client.connect(SIEMENS_IP, 0, 1) # Rack 0, Slot 1
except Exception as e:
print(f"Siemens connection error: {e}")
return
while True:
try:
# Read DB1, starting at byte 0, for 4 bytes (a REAL value)
data = client.db_read(1, 0, 4)
speed = snap7.util.get_real(data, 0)
payload = {"tag": "Motor_Speed", "value": speed, "ts": time.time()}
mqtt_client.publish(f"{MQTT_TOPIC_PREFIX}/siemens", json.dumps(payload))
print(f"Published Siemens data: {payload}")
except Exception as e:
print(f"Siemens read error: {e}")
time.sleep(1)
client.disconnect()
# --- Mitsubishi Polling Thread ---
def mitsubishi_poller():
client = pymcprotocol.Type3E()
try:
client.connect(MITSUBISHI_IP, 5002) # Port for MC Protocol
except Exception as e:
print(f"Mitsubishi connection error: {e}")
return
while True:
try:
# Read D100 and D101 (a 32-bit integer)
value = client.batchread_wordunits(headdevice="D100", readsize=2)
# Assuming D100 is low word, D101 is high word for a DINT
dint_value = (value[1] << 16) + value[0]
payload = {"tag": "Total_Count", "value": dint_value, "ts": time.time()}
mqtt_client.publish(f"{MQTT_TOPIC_PREFIX}/mitsubishi", json.dumps(payload))
print(f"Published Mitsubishi data: {payload}")
except Exception as e:
print(f"Mitsubishi read error: {e}")
time.sleep(2)
client.close()
# --- Main ---
if __name__ == '__main__':
# Setup MQTT Client
mqtt_client = mqtt.Client()
mqtt_client.connect(MQTT_BROKER, 1883, 60)
mqtt_client.loop_start()
# Create and start threads
s7_thread = threading.Thread(target=siemens_poller)
mc_thread = threading.Thread(target=mitsubishi_poller)
s7_thread.start()
mc_thread.start()
s7_thread.join()
mc_thread.join()
3. 部署到边缘计算网关
-
构建镜像: 在开发机上,使用
docker buildx build --platform linux/arm64 -t my-plc-collector . --load命令构建好多架构镜像。 -
推送镜像: 将镜像推送到Docker Hub或私有仓库。
-
在网关上运行: 通过SSH登录到鲁邦通边缘计算网关,执行:
Bashdocker run -d --name plc_collector --restart always --network host your-repo/my-plc-collector:latest我们使用
--network host是为了让容器能直接访问到局域网内的PLC和网关上可能运行的本地MQTT Broker。
4. 验证
你可以使用一个MQTT客户端(如MQTTX),订阅factory/plc/#主题,就能看到来自西门子和三菱PLC的数据,被统一格式化后,源源不断地发布出来。
常见问题解答 (FAQ)
-
问题1:为什么不使用厂商自带的中间件(如E2C Pro)而是自己开发?
-
答:厂商中间件能解决80%的通用需求,非常高效。但当遇到非标协议、需要进行复杂的数据预处理或需要与特定系统进行深度集成时,自定义开发就提供了无限的灵活性。一个好的工业边缘计算网关应该同时提供这两种选择。
-
-
问题2:这种并发轮询方式,在PLC数量很多时,性能如何保证?
-
答:当PLC数量增加时,基于线程的模型会遇到性能瓶颈。更优的架构是采用基于
asyncio的异步I/O模型,使用一个单线程的事件循环来处理所有PLC的通信,可以轻松支持数十上百台PLC的并发连接。
-
-
问题3:开源的PLC通信库可靠吗?
-
答:像
python-snap7和pymcprotocol都是在社区经过了大量验证的、相对成熟的库。但在生产环境中大规模使用前,仍需进行详尽的压力和异常测试。对于追求极致稳定性的项目,使用厂商(如鲁邦通)经过商业验证和加固的协议驱动,是更稳妥的选择。
-
总结:鲁邦通工业边缘计算网关的开放性,为开发者提供了巨大的舞台。通过结合强大的开源社区和现代化的Docker部署技术,我们能够以一种高效、统一且可扩展的方式,攻克工业现场最棘手的异构协议集成难题。本文的实战项目,仅仅是一个开始。基于这个架构,你可以轻松地扩展支持更多品牌的PLC,或在数据发布前,增加更复杂的本地分析和处理逻辑,从而构建出真正强大的边缘智能应用。
Python+Docker统一读写PLC

被折叠的 条评论
为什么被折叠?



