【问题标题】:Pymodbus RTU Server - Handle requestsPymodbus RTU 服务器 - 处理请求
【发布时间】:2015-01-02 22:29:52
【问题描述】:

我正在使用 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

【问题讨论】:

    标签: python modbus


    【解决方案1】:

    我做的事情有点不同...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,前十个寄存器每隔 2 秒递增 1。

    希望对你有所帮助。

    不幸的是,当我尝试将值设置为负整数时,pymodbus 会引发错误。这就是我难过的地方......

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

    【讨论】:

    • 感谢您的提示。请参阅我的编辑。这是使用 RTU 和异步服务器时的错误。
    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多