[英]Custom Datablock Example in pyModbus
I'm trying to develop custom datablock functionality using pyModbus and am following the example in their documentation: https://pymodbus.readthedocs.io/en/latest/source/example/custom_datablock.html我正在尝试使用 pyModbus 开发自定义数据块功能,并遵循其文档中的示例: https://pymodbus.readthedocs.io/en/latest/source/example/custom_datablock.html
The critical code is here, where they overload the ModbusSparseDataBlock with a custom block that has a modified setValues function.关键代码在这里,他们使用具有修改的 setValues function 的自定义块重载 ModbusSparseDataBlock。
class CustomDataBlock(ModbusSparseDataBlock):
""" A datablock that stores the new value in memory
and performs a custom action after it has been stored.
"""
def setValues(self, address, value):
""" Sets the requested values of the datastore
:param address: The starting address
:param values: The new values to be set
"""
super(ModbusSparseDataBlock, self).setValues(address, value)
# whatever you want to do with the written value is done here,
# however make sure not to do too much work here or it will
# block the server, espectially if the server is being written
# to very quickly
print("wrote {} to {}".format(value, address))
Unlike the example, I'm using the serial server (StartSerialServer) with RTU framer.与示例不同,我将串行服务器 (StartSerialServer) 与 RTU 成帧器一起使用。
StartSerialServer(context, framer=ModbusRtuFramer, identity=identity)
When I run the code, I get errors every time a message is received.当我运行代码时,每次收到消息时都会出错。 As far as I can tell, it's a failure of the response packet because the 'getValue' function is not specified.
据我所知,这是响应数据包的失败,因为未指定“getValue”function。
DEBUG:pymodbus.server.asynchronous:Datastore unable to fulfill request: Modbus Error: [Not Implemented] Datastore Value Retrieve
I'm not looking to do anything custom for the retrieval of the data, so I don't understand why it can't inherit the getValues() functionality from the ModbusSpareDataBlock class.我不想为检索数据做任何自定义,所以我不明白为什么它不能从 ModbusSpareDataBlock class 继承 getValues() 功能。 I tried adding an explicit overload for getValues() but that didn't resolve anything.
我尝试为 getValues() 添加显式重载,但这并没有解决任何问题。
I'm clearly missing something.我显然错过了一些东西。 Perhaps I don't quite understand how function overloads occur and the structure of the pyModbus stack.
也许我不太明白 function 过载是如何发生的以及 pyModbus 堆栈的结构。 Any suggestions would be much appreciated.
任何建议将不胜感激。
Here's the main part of the code:这是代码的主要部分:
from __future__ import print_function
from pymodbus.server.asynchronous import StartSerialServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSparseDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusRtuFramer
# --------------------------------------------------------------------------- #
# configure the service logging
# --------------------------------------------------------------------------- #
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
# serial stuff
import serial.tools.list_ports
serialports = [port.device for port in serial.tools.list_ports.comports()]
# --------------------------------------------------------------------------- #
# create your custom data block here
# --------------------------------------------------------------------------- #
class CustomDataBlock(ModbusSparseDataBlock):
""" A datablock that stores the new value in memory
and performs a custom action after it has been stored.
"""
def setValues(self, address, value):
""" Sets the requested values of the datastore
:param address: The starting address
:param values: The new values to be set
"""
super(ModbusSparseDataBlock, self).setValues(address, value)
# whatever you want to do with the written value is done here,
# however make sure not to do too much work here or it will
# block the server, espectially if the server is being written
# to very quickly
print("wrote {} to {}".format(value, address))
def getValues(self, address, values):
super(ModbusSparseDataBlock, self).getValues(address, values)
def run_custom_db_server():
# ----------------------------------------------------------------------- #
# initialize your data store
# ----------------------------------------------------------------------- #
block = CustomDataBlock({0x01: 0})
store = ModbusSlaveContext(hr=block)
context = ModbusServerContext(slaves=store, single=True)
# ----------------------------------------------------------------------- #
# initialize the server information
# ----------------------------------------------------------------------- #
identity = ModbusDeviceIdentification()
identity.VendorName = 'pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'pymodbus Server'
identity.ModelName = 'pymodbus Server'
identity.MajorMinorRevision = '2.3.0'
# ----------------------------------------------------------------------- #
# run the server you want
# ----------------------------------------------------------------------- #
# p = Process(target=device_writer, args=(queue,))
# p.start()
StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, #timeout=0,
port=serialports[0], baudrate=14400, parity='E')
if __name__ == "__main__":
run_custom_db_server()
try尝试
class CustomDataBlock(ModbusSparseDataBlock):
""" A datablock that stores the new value in memory
and performs a custom action after it has been stored.
"""
def setValues(self, address, value):
""" Sets the requested values of the datastore
:param address: The starting address
:param values: The new values to be set
"""
super().setValues(address, value)
# whatever you want to do with the written value is done here,
# however make sure not to do too much work here or it will
# block the server, espectially if the server is being written
# to very quickly
print("wrote {} to {}".format(value, address))
def getValues(self, address, values):
return super().getValues(address, values)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.