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, )
def StartRTUServer(): StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='COM6', timeout=.005, baudrate=9600)
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)
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')
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)
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)
def testStartSerialServer(self): ''' Test the serial server starting factory ''' with patch.object(ModbusSerialServer, 'serve_forever') as mock_server: StartSerialServer(port=SERIAL_PORT)
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)
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)
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")