python - Pymodbus RTU 服务器 - 处理请求

标签 python modbus

我正在使用 pymodbus 创建 Modbus RTU 服务器。

我根据文档中的示例以非常基本的方式创建了服务器。

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [0x0]*10000),
    co = ModbusSequentialDataBlock(0, [0x0]*10000),
    hr = ModbusSequentialDataBlock(0, [0x0]*10000),
    ir = ModbusSequentialDataBlock(0, [0x0]*10000))
context = ModbusServerContext(slaves=store, single=True)

StartSerialServer(context, port='/dev/ttyUSB0', framer=ModbusRtuFramer)

我的客户端连接正确。服务器打印出请求的十六进制值。

我现在想做的是处理不同的请求。
例如:如果客户端想要从保存寄存器读取寄存器 4128,我想发送一个值作为响应。

我在文档中找不到任何有用的示例(或者也许我只是不理解它?)
我已经尝试对 ModbusSequentialDataBlock 进行子类化并重写 get/setValue 方法,但没有成功。

这是我的数据存储区的代码。它非常简单,我希望在我的 get/setValues 方法中看到打印结果。但我什么也没看到。

class MyData(ModbusSequentialDataBlock):
    def __init__(self, address, values):
        self.address = address
        self.values = values

    def validate(self, address, count=1):
        print "validate"

    def getValues(self, address, count=1):
        print "getValues"
        print address

    def setValues(self, address, count=1):
        print "setValues"
        print address

作为 di、co 等,我在 ModbusSlaveContext 中使用 MyData(...) 而不是 ModbusSequentialDataBlock。

编辑

事实证明,这是 pymodbus 中的一个错误。使用异步服务器时,您无法使用 RTU 成帧器。 我打开了一个错误,它似乎已修复: https://github.com/bashwork/pymodbus/issues/70#event-213935076

最佳答案

我做的事情有点不同......ModbusTCP而不是ModbusRTU......但是我已经弄清楚如何让它返回不同的值,我认为这就是你正在寻找的(getValues/setValues)。给你...

from pymodbus.server.async import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
import sys
import logging
from twisted.internet.task import LoopingCall

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)


def getModbusSlaveContext():
    hr_block = ModbusSequentialDataBlock(0, [9999 for x in range(10000)])
    return ModbusSlaveContext(hr=hr_block)

def incdecvalues(valuelist):
    lengthOfList = len(valuelist)
    for counter in range(lengthOfList):
        if counter % 2:
            valuelist[counter]+=1
        #else:
        #    valuelist[counter]+=-1

def updatevalues(a):
    context = a[0]
    register = 3
    slave_id = 0x01
    address = 0x00
    values = context[slave_id].getValues(register, address, count=10)
    incdecvalues(values)
    context[slave_id].setValues(register, address, values)

slaves = {
    0x01 : getModbusSlaveContext()
    }

context = ModbusServerContext(slaves=slaves, single=False)

time = 2
loop = LoopingCall(f=updatevalues, a=(context,))
loop.start(time, now=True)
StartTcpServer(context, identity=None, address=('localhost', 9091))

所有保持寄存器(从 3001 开始,共有 10000 个)初始值设置为 9999。从机 ID 为 1,前 10 个寄存器每 2 秒递增 1。

希望对您有帮助。

不幸的是,当我尝试将 Values 设置为负整数时,pymodbus 会抛出错误。这就是我所困惑的......

https://stackoverflow.com/questions/28244730/pymodbus-setvalues-how-to-resolve-error-integer-out-of-range-for-h-format-co

关于python - Pymodbus RTU 服务器 - 处理请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26779095/

相关文章:

Python 3 套接字 - 在停止和重新运行程序时可以保持套接字打开吗?

python - 没有名为 spinup.run 的模块

c++ - C++ 抽象 Endian 是中性的吗?

java - 需要 modbus Java 库

python - Python3.3需要watcher

python - 单独使用 python 在 localhost 托管本地 html 文件

python - 字符串转 float 错误

visual-studio-2010 - MFC 中的 libmodbus

python - 使用 Python 读取 MODBUS 寄存器时遇到问题