简体   繁体   English

pyModbus 中的自定义数据块示例

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM