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

Pymodbus TCP服务器读写问题:远程修改变量后如何在服务端获取处理?

嘿,我刚好之前折腾过Pymodbus的TCP服务器变量监听问题,给你两个实用的解决方案,应该能帮到你:

方案1:用回调函数实时捕获修改(最推荐)

Pymodbus的服务器支持注册回调函数,当远程客户端修改寄存器时会自动触发,这样你就能第一时间拿到修改后的值并处理。举个具体的代码例子:

首先定义一个处理写入请求的回调函数:

def handle_register_write(request, response):
    # 提取客户端修改的寄存器地址和新值
    start_address = request.address
    new_values = request.values
    
    print(f"收到远程修改:地址{start_address}开始的寄存器,新值为{new_values}")
    
    # 这里加入你的业务处理逻辑,比如更新本地监控变量、触发告警等
    update_monitored_vars(start_address, new_values)
    
    # 记得返回响应,告知客户端修改成功
    return response

然后在创建服务器时注册这个回调:

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

# 初始化保持寄存器存储(这里创建100个初始值为10的可写寄存器)
slave_store = ModbusSlaveContext(hr=[10]*100, di=None, co=None, ir=None)
server_context = ModbusServerContext(slaves=slave_store, single=True)

# 启动服务器并注册回调,监听保持寄存器的写入操作
server = StartTcpServer(context=server_context, address=("0.0.0.0", 502))
server.server.register_callback("write_registers", handle_register_write)

server.serve_forever()
方案2:定时轮询存储(适合简单场景)

如果回调的方式对你的场景有点复杂,也可以通过定时读取服务器的寄存器存储,对比历史值来检测变化:

import time
import threading
from pymodbus.server import StartTcpServer
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

# 初始化寄存器存储和服务器上下文
slave_store = ModbusSlaveContext(hr=[10]*100)
server_context = ModbusServerContext(slaves=slave_store, single=True)

# 保存上一次的寄存器状态(3代表保持寄存器的功能码)
last_register_values = slave_store.getValues(3, 0, count=100)

def check_for_changes():
    global last_register_values
    while True:
        current_values = slave_store.getValues(3, 0, count=100)
        if current_values != last_register_values:
            # 找出所有变化的寄存器位置和值
            changed_positions = [i for i, (old, new) in enumerate(zip(last_register_values, current_values)) if old != new]
            for pos in changed_positions:
                print(f"寄存器{pos}的值从{last_register_values[pos]}变为{current_values[pos]}")
                # 执行你的处理逻辑
                process_var_change(pos, current_values[pos])
            last_register_values = current_values.copy()
        time.sleep(1)  # 每秒轮询一次,可根据需求调整频率

# 启动轮询线程(设为守护线程,随服务器退出而终止)
poll_thread = threading.Thread(target=check_for_changes)
poll_thread.daemon = True
poll_thread.start()

# 启动TCP服务器
StartTcpServer(context=server_context, address=("0.0.0.0", 502))
几个注意点
  • 如果你用的是异步服务器(比如StartAsyncTcpServer),回调的注册方式会略有不同,需要适配异步逻辑。
  • 确保你的寄存器存储是可写的,初始化时不要使用只读数据块。
  • 处理共享变量时要注意线程安全,比如用threading.Lock()来保护临界区代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:29:32