2014-11-06 263 views
0

我使用pymodbus创建Modbus RTU服务器。Pymodbus 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) 

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

我现在想要做的是处理不同的请求。
例如:如果客户想要从保持寄存器中读取寄存器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 

如二,CO等我用MyData(...)代替ModbusSequentialDataBlock在ModbusSlaveContext

编辑

原来,这是在pymodbus的错误。使用异步服务器时,不能使用RTU成帧器。 我开了一个bug,它似乎是固定的: https://github.com/bashwork/pymodbus/issues/70#event-213935076

回答

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和所有其他寄存器由1每2递增前十个寄存器的秒数。

希望能帮到你。

不幸的是,当我尝试将值设置为负整数时,pymodbus抛出错误。这就是我难倒...

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

+0

感谢您的窍门。看我的编辑。这是使用RTU和异步服务器时的一个错误。 – 0xAffe 2015-02-04 07:32:02

相关问题