You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于pymodbus读取离散输入值并触发自动化任务的技术问询

代码问题修正与优化建议

一、修复代码中的语法与基础错误

你的代码存在语法、依赖及逻辑问题,先修正这些基础问题:

from pymodbus.client.sync import ModbusTcpClient
import os
import time  # 补充缺失的time模块

host = '100.100.110.104'   
port = 502
client = ModbusTcpClient(host, port)

# 初始化状态变量,避免重复触发
last_state = 0

while True:
    # 优化连接逻辑:仅在断开时重连
    if not client.is_socket_open():
        if not client.connect():
            print("无法连接到PLC,等待重试...")
            time.sleep(5)
            continue
    
    try:
        # 读取起始地址1000的1个离散输入点
        rr = client.read_discrete_inputs(1000, 1, unit=1)
        
        # 检查读取是否成功
        if rr.isError():
            print(f"读取失败: {rr}")
            time.sleep(5)
            continue
        
        current_state = rr.bits[0]    
        # 仅在状态从0变为1时触发脚本
        if current_state == 1 and last_state == 0:
            print("触发工单录入脚本")
            os.system('python AUTOMATED.pyw')
        
        # 更新状态记录
        last_state = current_state
        
    except Exception as e:
        print(f"运行异常: {e}")
        client.close()  # 异常后断开连接,下次循环重连
    
    time.sleep(5)

二、无PLC测试的解决方案

可以用pymodbus搭建本地Modbus TCP模拟器,模拟PLC的离散输入状态:

模拟服务器代码(单独运行)

from pymodbus.server.sync import StartTcpServer
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

# 模拟1000个离散输入点,初始值全为0
store = ModbusSlaveContext(di=[0]*1000)
context = ModbusServerContext(slaves=store, single=True)

# 启动本地模拟服务器,端口502
StartTcpServer(context, address=("localhost", 502))

测试配置

把主代码里的host改为'localhost',运行模拟服务器后,你可以手动修改模拟数据的离散输入值(比如将di[999]设为1,对应起始地址1000),即可测试触发逻辑。

三、关键优化点说明

  • 语法修正:if判断用==而非=,补充语句末尾的冒号,导入缺失的time模块
  • 连接优化:避免循环内重复连接,仅在断开时尝试重连
  • 去重触发:通过状态变量记录上一次状态,仅在开关从断开变闭合时执行脚本,避免重复触发
  • 异常处理:捕获读取和连接异常,避免程序直接崩溃

内容的提问来源于stack exchange,提问作者Peddlur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:22:36