Ejemplo n.º 1
0
def run_server():
    store = ModbusSlaveContext(
        di=ModbusSequentialDataBlock(0, [17] * 100),
        co=ModbusSequentialDataBlock(0, [17] * 100),
        hr=ModbusSequentialDataBlock(0, [17] * 100),
        ir=ModbusSequentialDataBlock(0, [17] * 100),
    )

    context = ModbusServerContext(slaves=store, single=True)

    identity = ModbusDeviceIdentification()
    identity.VendorName = "Pymodbus"
    identity.ProductCode = "PM"
    identity.VendorUrl = "http://github.com/riptideio/pymodbus/"
    identity.ProductName = "Pymodbus Server"
    identity.ModelName = "Pymodbus Server"
    identity.MajorMinorRevision = version.short()

    # socat -d -d PTY,link=/tmp/ptyp0,raw,echo=0,ispeed=9600 PTY,link=/tmp/ttyp0,raw,echo=0,ospeed=9600

    StartSerialServer(
        context,
        framer=ModbusRtuFramer,
        identity=identity,
        port="/tmp/ttyp0",
        timeout=0.005,
        baudrate=9600,
    )
Ejemplo n.º 2
0
def StartRTUServer():
    StartSerialServer(context,
                      framer=ModbusRtuFramer,
                      identity=identity,
                      port='COM6',
                      timeout=.005,
                      baudrate=9600)
Ejemplo n.º 3
0
def run_server(device, baud=9600):
    store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [17] * 100),
                               co=ModbusSequentialDataBlock(0, [17] * 100),
                               hr=ModbusSequentialDataBlock(0, [25185] * 1024),
                               ir=ModbusSequentialDataBlock(0, [25185] * 1024))
    slaves = {
        1: copy.deepcopy(store),
        2: copy.deepcopy(store),
        3: copy.deepcopy(store),
        4: copy.deepcopy(store),
        5: copy.deepcopy(store),
        6: copy.deepcopy(store),
        246: copy.deepcopy(store)
    }
    context = ModbusServerContext(
        slaves=slaves,
        single=False,
    )

    # RTU Server
    StartSerialServer(context,
                      identity=None,
                      port=device,
                      framer=ModbusRtuFramer,
                      stopbits=1,
                      bytesize=8,
                      parity=serial.PARITY_NONE,
                      baudrate=baud)
Ejemplo n.º 4
0
    def run_server(self, callback=None, debug=True):
        """Runs the modbus tcp or rtu server with given register information. if increment is true, the register values are dynamic and incrementing by one
        every interval provided in cycle_s argument"""
        if debug:
            logging.basicConfig()
            log = logging.getLogger()
            log.setLevel(logging.DEBUG)

        try:
            #Data callback function will be executed as a separate thread
            if callback != None:
                thread = Thread(target=callback,
                                args=(self.context, ),
                                daemon=True)
                thread.start()

            if self.xmlData.get('modbusType') == 'tcp/ip':
                print(
                    f"Running server on IP: {self.xmlData.get('ip')} and port {self.xmlData.get('port')}"
                )
                StartTcpServer(self.context,
                               identity=self.deviceIdentity,
                               address=(self.xmlData.get('ip'),
                                        self.xmlData.get('port')))

            elif self.xmlData.get('modbusType') == 'rtu':
                print(
                    f"Running server on COM: {self.xmlData.get('com')} and baudrate {self.xmlData.get('baud')}"
                )
                StartSerialServer(self.context,
                                  timeout=self.xmlData.get('timeout'),
                                  framer=ModbusRtuFramer,
                                  identity=self.deviceIdentity,
                                  port=self.xmlData.get('com'),
                                  stopbits=self.xmlData.get('stopbits'),
                                  bytesize=self.xmlData.get('bytesize'),
                                  parity=self.xmlData.get('parity'),
                                  baudrate=self.xmlData.get('baud'))

        except KeyboardInterrupt:
            print('Server stopped')
Ejemplo n.º 5
0
def run_updating_server():
    store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [0] * 0xff),
                               co=ModbusSequentialDataBlock(0, [0] * 0xff),
                               hr=ModbusSequentialDataBlock(0, [0] * 0xff),
                               ir=ModbusSequentialDataBlock(0, [0] * 0xff))
    context = ModbusServerContext(slaves=store, single=True)

    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 = '1.0'

    start_new_thread(updating_writer, (context, ))
    StartSerialServer(context,
                      framer=ModbusRtuFramer,
                      identity=identity,
                      port='/dev/ttyUSB0',
                      timeout=.005,
                      baudrate=9600)
Ejemplo n.º 6
0
def run_server():
    # ----------------------------------------------------------------------- #
    # initialize your data store
    # ----------------------------------------------------------------------- #
    # The datastores only respond to the addresses that they are initialized to
    # Therefore, if you initialize a DataBlock to addresses of 0x00 to 0xFF, a
    # request to 0x100 will respond with an invalid address exception. This is
    # because many devices exhibit this kind of behavior (but not all)::
    #
    #     block = ModbusSequentialDataBlock(0x00, [0]*0xff)
    #
    # Continuing, you can choose to use a sequential or a sparse DataBlock in
    # your data context.  The difference is that the sequential has no gaps in
    # the data while the sparse can. Once again, there are devices that exhibit
    # both forms of behavior::
    #
    #     block = ModbusSparseDataBlock({0x00: 0, 0x05: 1})
    #     block = ModbusSequentialDataBlock(0x00, [0]*5)
    #
    # Alternately, you can use the factory methods to initialize the DataBlocks
    # or simply do not pass them to have them initialized to 0x00 on the full
    # address range::
    #
    #     store = ModbusSlaveContext(di = ModbusSequentialDataBlock.create())
    #     store = ModbusSlaveContext()
    #
    # Finally, you are allowed to use the same DataBlock reference for every
    # table or you may use a separate DataBlock for each table.
    # This depends if you would like functions to be able to access and modify
    # the same data or not::
    #
    #     block = ModbusSequentialDataBlock(0x00, [0]*0xff)
    #     store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
    #
    # The server then makes use of a server context that allows the server to
    # respond with different slave contexts for different unit ids. By default
    # it will return the same context for every unit id supplied (broadcast
    # mode).
    # However, this can be overloaded by setting the single flag to False and
    # then supplying a dictionary of unit id to context mapping::
    #
    #     slaves  = {
    #         0x01: ModbusSlaveContext(...),
    #         0x02: ModbusSlaveContext(...),
    #         0x03: ModbusSlaveContext(...),
    #     }
    #     context = ModbusServerContext(slaves=slaves, single=False)
    #
    # The slave context can also be initialized in zero_mode which means that a
    # request to address(0-7) will map to the address (0-7). The default is
    # False which is based on section 4.4 of the specification, so address(0-7)
    # will map to (1-8)::
    #
    #     store = ModbusSlaveContext(..., zero_mode=True)
    # ----------------------------------------------------------------------- #
    store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [17] * 100),
                               co=ModbusSequentialDataBlock(0, [17] * 100),
                               hr=ModbusSequentialDataBlock(0, [17] * 100),
                               ir=ModbusSequentialDataBlock(0, [17] * 100))

    context = ModbusServerContext(slaves=store, single=True)

    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    # If you don't set this or any fields, they are defaulted to empty strings.
    # ----------------------------------------------------------------------- #
    identity = ModbusDeviceIdentification()
    identity.VendorName = 'Pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = '2.2.0'

    # ----------------------------------------------------------------------- #
    # run the server you want
    # ----------------------------------------------------------------------- #
    # Tcp:
    # StartTcpServer(context, identity=identity, address=("localhost", 5020))

    # TCP with different framer
    # StartTcpServer(context, identity=identity,
    #                framer=ModbusRtuFramer, address=("0.0.0.0", 5020))

    # Udp:
    # StartUdpServer(context, identity=identity, address=("0.0.0.0", 5020))

    # Ascii:
    # StartSerialServer(context, identity=identity,
    # port='/dev/ttyp0', timeout=1)

    # StartSerialServer(context, identity=identity,
    # port='/dev/ttyUSB0', timeout=1)

    # RTU:
    StartSerialServer(context,
                      framer=ModbusRtuFramer,
                      identity=identity,
                      port='/dev/ttyUSB0',
                      timeout=.005,
                      baudrate=9600)
Ejemplo n.º 7
0
 def testStartSerialServer(self):
     ''' Test the serial server starting factory '''
     with patch.object(ModbusSerialServer, 'serve_forever') as mock_server:
         StartSerialServer(port=SERIAL_PORT)
Ejemplo n.º 8
0
            logger.warning(f"No meters defined in {args.config}")

        identity = ModbusDeviceIdentification()
        server_ctx = ModbusServerContext(slaves=slaves, single=False)

        time.sleep(1)

        for t in threads:
            t.start()
            logger.info(f"Starting {t}")

        StartSerialServer(server_ctx,
                          framer=ModbusRtuFramer,
                          identity=identity,
                          port=confparser["server"].get(
                              "device",
                              fallback=default_config["server"]["device"]),
                          baudrate=confparser["server"].get(
                              "baud",
                              fallback=default_config["server"]["baud"]),
                          timeout=confparser["server"].get(
                              "timeout",
                              fallback=default_config["server"]["timeout"]))
    except KeyboardInterrupt:
        pass
    finally:
        for t_stop in thread_stops:
            t_stop.set()
        for t in threads:
            t.join()
    # 定义ir输入寄存器,存储起始地址为0,长度为10,内容为0~10递增数值列表
    ir_block = ModbusSequentialDataBlock(0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    # 定义hr保持寄存器,存储起始地址为0,长度为10,内容为0~10递增数值列表
    hr_block = ModbusSequentialDataBlock(0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

    # 创建从机,从机的di离散量、co线圈、hr保持寄存器、ir输入寄存器等由上面定义并传入
    slaves = ModbusSlaveContext(di=di_block,
                                co=co_block,
                                hr=hr_block,
                                ir=ir_block)
    # 创建单从机上下文,交由服务器调度
    context = ModbusServerContext(slaves=slaves, single=True)

    # 如果需要创建多个从机,参考如下:从机地址 + 从机配置
    # slaves = {
    # 1:ModbusSlaveContext(di=di_block, co=co_block, hr=hr_block, ir=ir_block),
    # 2:ModbusSlaveContext(di=di_block, co=co_block, hr=hr_block, ir=ir_block),
    # 3:ModbusSlaveContext(di=di_block, co=co_block, hr=hr_block, ir=ir_block)
    # }
    # context = ModbusServerContext(slaves=slaves, single=False)

    # 开启tcp服务器方法
    # StartTcpServer(context, address=('127.0.0.1', 5020))
    # 开启串行设备服务器方法
    # 参数:从机上下文、从机通行帧格式、监听设备'/dev/ttymxc1'、串口波特率、从机监听超时时间0为不阻塞立刻响应
    StartSerialServer(context,
                      framer=ModbusRtuFramer,
                      port="/dev/ttymxc1",
                      baudrate=115200,
                      timeout=0)
Ejemplo n.º 10
0
    BASE_ADDR_MODULE_A: store_a,
    BASE_ADDR_MODULE_B: store_b1,
    BASE_ADDR_MODULE_B + 1: store_b2,
    BASE_ADDR_MODULE_B + 5: store_b3,
}

context = ModbusServerContext(slaves=slaves, single=False)

#---------------------------------------------------------------------------#
# initialize the server information
#---------------------------------------------------------------------------#
# If you don't set this or any fields, they are defaulted to empty strings.
#---------------------------------------------------------------------------#
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 = '1.0'

#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------#
# Ascii:
#StartSerialServer(context, identity=identity, port='/dev/pts/36', timeout=1)

# RTU:
#StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='/dev/pts/36', timeout=.005)
StartSerialServer(context, identity=identity, port='/dev/pts/36', timeout=.005)
Ejemplo n.º 11
0
def run_server():
    # ----------------------------------------------------------------------- #
    # initialize your data store
    # ----------------------------------------------------------------------- #
    # The datastores only respond to the addresses that they are initialized to
    # Therefore, if you initialize a DataBlock to addresses of 0x00 to 0xFF, a
    # request to 0x100 will respond with an invalid address exception. This is
    # because many devices exhibit this kind of behavior (but not all)::
    #
    #     block = ModbusSequentialDataBlock(0x00, [0]*0xff)
    #
    # Continuing, you can choose to use a sequential or a sparse DataBlock in
    # your data context.  The difference is that the sequential has no gaps in
    # the data while the sparse can. Once again, there are devices that exhibit
    # both forms of behavior::
    #
    block = ModbusSparseDataBlock({
        # aux soc
        0x101: 0b01011111,
        # aux v
        0x102: 141, # 0.1V
        # aux a
        0x103: 3309, # 0.01A
        # controller temperature
        0x104: 0b0001010100001111, # H: ctrl temp, L: battery temp sensor
        # altenator voltage
        0x105: 146, # 0.1V
        # altenator amps
        0x106: 4000, #0.01A
        # altenator watts
        0x107: 496,
        # solar v
        0x108: 304,
        # solar a
        0x109: 20,
        # solar w
        0x10A: 6684,
        0x10B: 0,
        # lowest battery V in day
        0x10C: 108,     # 0.1
        # max battery V in day
        0x10D: 144,
        # max battery A in day
        0x10E: 5000, #0.01A

        0x10F: 0,
        0x110: 0,
        0x111: 0,
        0x112: 0,
        0x113: 0,
        0x114: 0,
        0x115: 0,

        # running day count
        0x116: 1,

        0x117: 0,
        # number of times battery is full in day
        0x118: 3,

        0x119: 0,
        0x11A: 0,
        0x11B: 0,
        0x11C: 0,
        0x11D: 0,
        0x11E: 0,
        0x11F: 0,
        0x120: 0,

        # charge state (L)
        0x121: 0b0000000010001010,

        0x122: 0,
        0x123: 0,
    })
    #     block = ModbusSequentialDataBlock(0x00, [0]*5)
    #
    # Alternately, you can use the factory methods to initialize the DataBlocks
    # or simply do not pass them to have them initialized to 0x00 on the full
    # address range::
    #
    #     store = ModbusSlaveContext(di = ModbusSequentialDataBlock.create())
    #     store = ModbusSlaveContext()
    #
    # Finally, you are allowed to use the same DataBlock reference for every
    # table or you may use a separate DataBlock for each table.
    # This depends if you would like functions to be able to access and modify
    # the same data or not::
    #
    #     block = ModbusSequentialDataBlock(0x00, [0]*0xff)
    #     store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
    #
    # The server then makes use of a server context that allows the server to
    # respond with different slave contexts for different unit ids. By default
    # it will return the same context for every unit id supplied (broadcast
    # mode).
    # However, this can be overloaded by setting the single flag to False and
    # then supplying a dictionary of unit id to context mapping::
    #
    store = ModbusSlaveContext(hr=block, ir=block)
    context = ModbusServerContext(slaves=store, single=True)

    # ----------------------------------------------------------------------- #
    # initialize the server information
    # ----------------------------------------------------------------------- #
    # If you don't set this or any fields, they are defaulted to empty strings.
    # ----------------------------------------------------------------------- #
    identity = ModbusDeviceIdentification()
    identity.VendorName = 'Pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = version.short()
    
    StartSerialServer(
        context, 
        framer=ModbusRtuFramer, 
        identity=identity,
        port='/dev/ttyUSB0', 
        timeout=.05, 
        baudrate=9600,
        stopbits=2,
        bytesize=8)
from pymodbus.transaction import ModbusRtuFramer
import logging

FORMAT = ('%(asctime)-15s %(threadName)-15s'
          ' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)



slave_context = ModbusSlaveContext(
        di = ModbusSequentialDataBlock(0, [11, 12, 13, 14, 15]),
        co = ModbusSequentialDataBlock(0, [21, 22, 23, 24, 25]),
        hr = ModbusSequentialDataBlock(0, [31, 32, 33, 34, 35]),
        ir = ModbusSequentialDataBlock(0, [41, 42, 43, 44, 45]),
        )


server_context = ModbusServerContext(slaves=slave_context, single=True)



StartSerialServer(server_context, framer=ModbusRtuFramer, port='/dev/ttyUSB0', baudrate=19200, stopbits=1, bytesize=8, parity="E")