我正在使用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)
我的客户端连接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
as di,co等我在MyData(...)
中使用了ModbusSlaveContext
而不是ModbusSequentialDataBlock。
修改
原来,这是pymodbus中的一个错误。使用asynchronus服务器时,您无法使用RTU成帧器。 我打开了一个bug,它似乎已修复: https://github.com/bashwork/pymodbus/issues/70#event-213935076
答案 0 :(得分: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,并且前10个寄存器每2秒递增1个其他寄存器。
希望对你有所帮助。
不幸的是,当我尝试将值设置为负整数时,pymodbus会抛出错误。这就是我难以接受的......