def __init__(self, threadID, name, config, modbusRs2modbusTcp, modbusTcp2modbusRs): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.config = config self.log = logging.getLogger(name) self.modbusRs2modbusTcp = modbusRs2modbusTcp # kolejka do odbierania danych z modbusRs self.modbusTcp2modbusRs = modbusTcp2modbusRs # kolejka do wysylania danych do modbusRS self.tick = 0.01 self.interval = 0.1 self.exitFlag = False self.store = ModbusSlaveContext( # Tworzymy rejestr. Inicjalizujemy wszystko zerami. di=ModbusSequentialDataBlock(0, [00] * 1), co=ModbusSequentialDataBlock(0, [00] * 1), hr=ModbusSequentialDataBlock(0, [00] * 100000), ir=ModbusSequentialDataBlock(0, [00] * 1)) # Multipleksacja na podstawie adresów rejestrów HR a nie na poziomie Unit Id. self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'pymodbus' self.identity.ProductCode = 'PM' self.identity.VendorUrl = 'itcloud' self.identity.ProductName = 'pymodbus Server' self.identity.ModelName = 'pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.framer = ModbusSocketFramer self.server = ModbusTcpServer(self.context, self.framer, self.identity, (self.config["modbusTcp"]["bindIp"], self.config["modbusTcp"]["bindPort"]))
def run(self): store = ModbusSlaveContext( di=ModbusSequentialDataBlock(0, [i for i in range(100)],), co=ModbusSequentialDataBlock(0, [i for i in range(100)]), hr=ModbusSequentialDataBlock(0, [i for i in range(100)]), ir=ModbusSequentialDataBlock(0, [i for i in range(100)]), zero_mode=True ) for key, value in store.store.items(): log.debug('number of coils/registers in {}: {}'.format(key, len(value.values))) 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 = '1.5' self.server = ModbusTcpServer(context, identity=identity, address=("localhost", 5020)) log.info("starting modbus tcp server [localhost:5020]: {}".format(self.server)) self.server.serve_forever()
def ServerThread(e): global server # Configure the service logging #import logging #logging.basicConfig() #log = logging.getLogger() #log.setLevel(logging.DEBUG) # Initialize your data store 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 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 # StartTcpServer(context, identity=identity, address=(args.ip, 502)) server = ModbusTcpServer(context, identity=identity, address=(ip, 502)) print 'Server started' server.serve_forever(0.1) print 'Server stopped'
def __init__(self,port=1234,sub_topic="modbus_server/write_to_registers",pub_topic="modbus_server/read_from_registers"): """ Creates a Modbus TCP Server object .. note:: The default port for modbus is 502. This modbus server uses port 1234 by default, otherwise superuser rights are required. .. note:: Use "startServer" to start the listener. :param port: Port for the modbus TCP server :type port: int :param sub_topic: ROS topic name for the subscriber that updates the modbus registers :type sub_topic: string :param pub_topic: ROS topic name for the publisher that publishes a message, once there is something written to the writeable modbus registers :type pub_topic: string """ chr = CustomHoldingRegister(ADDRESS_WRITE_START, [17]*100,sub_topic,pub_topic) self.store = ModbusSlaveContext( di = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [17]*100), co = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [17]*100), hr = chr, ir = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [17]*100)) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'Pymodbus' self.identity.ProductCode = 'PM' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'Pymodbus Server' self.identity.ModelName = 'Pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.store.setValues(2,0,[0]*1) self.post = Post(self) framer = ModbusSocketFramer self.server = ModbusTcpServer(self.context, framer, self.identity, address=("0.0.0.0", port))
def testTcpServerProcess(self): ''' test that the synchronous TCP server processes requests ''' with patch('pymodbus.compat.socketserver.ThreadingTCPServer' ) as mock_server: server = ModbusTcpServer(None) server.process_request('request', 'client') self.assertTrue(mock_server.process_request.called)
def __init__(self, ip, port, unit, data, parent): super(MBTCPServer, self).__init__(parent) self.slave = MBSlave(ModbusSequentialDataBlock(1, data[0]), ModbusSequentialDataBlock(1, data[1]), ModbusSequentialDataBlock(1, data[2]), ModbusSequentialDataBlock(1, data[3])) self.ctx = ModbusServerContext(slaves={unit: self.slave}, single=False) self.server = ModbusTcpServer(self.ctx, framer=MSF, address=(ip, port))
def __init__(self, address, port): self.holding_register_block = HoldingRegisterDataBlock.create() self.coil_block = ModbusSparseDataBlock.create() self.store = ModbusSlaveContext(hr=self.holding_register_block, co=self.coil_block) self.context = ModbusServerContext(slaves=self.store, single=True) self.server = ModbusTcpServer(self.context, address=(address, port)) self.thread = Thread(target=self.__run_thread__, args=())
def testTcpServerClose(self): ''' test that the synchronous TCP server closes correctly ''' with patch.object(socket.socket, 'bind') as mock_socket: identity = ModbusDeviceIdentification(info={0x00: 'VendorName'}) server = ModbusTcpServer(context=None, identity=identity) server.threads.append(Mock(**{'running': True})) server.server_close() self.assertEqual(server.control.Identity.VendorName, 'VendorName') self.assertFalse(server.threads[0].running)
def __init__(self, context, framer=None, identity=None, address=None, handler=None, **kwargs): self.allow_reuse_address = True ModbusTcpServer.__init__(self, context, framer, identity, address, handler, **kwargs)
def testTcpServerClose(self): ''' test that the synchronous TCP server closes correctly ''' identity = ModbusDeviceIdentification(info={0x00: 'VendorName'}) server = ModbusTcpServer(context=None, identity=identity, bind_and_activate=False) server.threads.append(Mock(**{'running': True})) server.server_close() self.assertEqual(server.control.Identity.VendorName, 'VendorName') self.assertFalse(server.threads[0].running)
def __init__(self, address, port): self.holding_register_block = HoldingRegisterDataBlock.create() self.coil_block = CoilsDataBlock.create() self.store = ModbusSlaveContext(hr=self.holding_register_block, co=self.coil_block, zero_mode=True) self.context = ModbusServerContext(slaves=self.store, single=True) self.server = ModbusTcpServer(self.context, address=(address, port)) self.thread = Thread(target=self.__run_thread__, args=()) self.holding_register_block.setValues(t_o_address, 277) self.holding_register_block.setValues(t_zco_address, 400)
def __init__( self, *args, **kwds ): if kwds.get( 'ignore_missing_slaves' ): assert list( map( int, pymodbus_version.split( '.' ))) >= [1,3,0], \ "The pymodbus version %s installed lacks ignore_missing_slaves keyword; requires 1.3.0 or better" % ( pymodbus_version ) if kwds.get( 'handler' ): assert list( map( int, pymodbus_version.split( '.' ))) >= [1,3,0], \ "The pymodbus version %s installed lacks request handler keyword; requires 1.3.0 or better" % ( pymodbus_version ) # NOT a new-style class (due to SocketServer.ThreadingTCPServer); no super(...) ModbusTcpServer.__init__( self, *args, **kwds )
def __init__(self, *args, **kwds): if kwds.get('ignore_missing_slaves'): assert list( map( int, pymodbus_version.split( '.' ))) >= [1,3,0], \ "The pymodbus version %s installed lacks ignore_missing_slaves keyword; requires 1.3.0 or better" % ( pymodbus_version ) if kwds.get('handler'): assert list( map( int, pymodbus_version.split( '.' ))) >= [1,3,0], \ "The pymodbus version %s installed lacks request handler keyword; requires 1.3.0 or better" % ( pymodbus_version ) # NOT a new-style class (due to SocketServer.ThreadingTCPServer); no super(...) ModbusTcpServer.__init__(self, *args, **kwds)
def run_server(): global mtcp_server store = ModbusSlaveContext(di=d_inputs, co=d_outputs, ir=a_inputs, hr=a_outputs, zero_mode=True) context = ModbusServerContext(slaves=store, single=True) #run server mtcp_server = ModbusTcpServer(context, address=("localhost", 2605)) mtcp_server.serve_forever()
def __init__(self, address, blocks): Thread.__init__(self) store = ModbusSlaveContext( di=blocks.get('di', ModbusSequentialDataBlock(0, [0])), co=blocks.get('co', ModbusSequentialDataBlock(0, [0])), hr=blocks.get('hr', ModbusSequentialDataBlock(0, [0])), ir=blocks.get('ir', ModbusSequentialDataBlock(0, [0]))) self.context = ModbusServerContext(slaves=store, single=True) self.server = ModbusTcpServer(context=self.context, framer=None, identity=None, address=address)
def StartTcpServerLogging( context=None, identity=None, framer=ModbusSocketFramer, address=None ): ''' A factory to start and run a tcp modbus server :param context: The ModbusServerContext datastore :param identity: An optional identify structure :param address: An optional (interface, port) to bind to. ''' server = ModbusTcpServer(context, framer, identity, address) # Print the address successfully bound; this is useful, if attempts are made # to bind over a range of ports. print( "Success; Started Modbus/TCP Simulator; PID = %d; address = %s:%s" % ( os.getpid(), address[0] if address else "", address[1] if address else Defaults.Port )) sys.stdout.flush() server.serve_forever()
def run(self): print("Starting ModBus Server: {}:{}".format(self.node.ipaddr, self.node.port)) framer = ModbusSocketFramer #TODO-REMOVE ALLOW_ADDRESS_REUSE IN FINAL CODE. socketserver.TCPServer.allow_reuse_address = True self.server = ModbusTcpServer(self.context, framer, self.identity, address=(self.node.ipaddr, self.node.port)) for name in self.node.name: t = threading.Thread(target=ping_outstation, args=(self, name)) t.start() self.server.serve_forever()
class serverthreads(threading.Thread): ipalloc = [] # class list of ipaddresses in use def __init__(self, vnic, ipaddr, port): threading.Thread.__init__(self) self.ipaddr = ipaddr # ip address self.port = port # port address self.vnic = vnic # virtual nic self.mode = "" # server or client self.state = "" # up or down self.serverstop = threading.Event() self.server = "" self.framer = "" def run(self): self.serverint() def serverint(self): # instantiate server stuff #print "Server mode" # StartTcpServer(context, identity=identity, address=(self.ipaddr, self.port)) self.framer = ModbusSocketFramer self.server = ModbusTcpServer(context, self.framer, identiy=identity, address=(self.ipaddr, self.port)) self.server.timeout = 1 while(not self.serverstop.is_set()): self.server.handle_request() # The original function overrides socketserver->serve_forever() # self.server.serve_forever() # self.server.shutdown() def alloc(self): # Allocate ip address if(self.ipaddr in self.ipalloc): print "Address in-use" return 0 else: self.ipalloc.append(self.ipaddr) cmdargs = [self.vnic, self.ipaddr] subprocess.call(["ifconfig"] + cmdargs) self.state = "up" return 1 def dealloc(self): # De-allocate ip address self.ipalloc.remove(self.ipaddr) cmdargs = [self.vnic] subprocess.call(["ifconfig"] + cmdargs + ["down"]) def stop(self): self.serverstop.set() return
def run_server(): block1 = ModbusSequentialDataBlock(0x00, [0] * 0xFF) block2 = ModbusSequentialDataBlock(0x10, [0] * 0xFF) block3 = ModbusSequentialDataBlock(0x00, [0] * 0xFF) block4 = ModbusSequentialDataBlock(0x00, [0] * 0xFF) store1 = ModbusSlaveContext(co=block3, di=block4, hr=block1, ir=block2) store2 = ModbusSlaveContext(co=block3, di=block4, hr=block1, ir=block2) slaves = {0xFF: store1} context = ModbusServerContext(slaves=slaves, single=False) 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 = '1.0' interval = 1 server = ModbusTcpServer(context, identity=identity, address=('0.0.0.0', 502)) t = threading.Thread(target=server.serve_forever, daemon=True) t.start() loop = LoopingCall(f=updatevalues, a=server) loop.start(interval, now=True) reactor.run()
def __init__(self,port=1234): """ Creates a Modbus TCP Server object .. note:: The default port for modbus is 502. This modbus server uses port 1234 by default, otherwise superuser rights are required. .. note:: Use "startServer" to start the listener. :param port: Port for the modbus TCP server :type port: int """ # chr = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) # cdi = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) self.onShutdown=False; self.state_changed = Signal() cco = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) self.store = ModbusSlaveContext( di = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100), co = cco, hr = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100), ir = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100)) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'Pymodbus' self.identity.ProductCode = 'PM' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'Pymodbus Server' self.identity.ModelName = 'Pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.store.setValues(2,0,[0]*1) self.post = Post(self) framer = ModbusSocketFramer self.server = ModbusTcpServer(self.context, framer, self.identity, address=("0.0.0.0", port))
def __init__(self, system_settings): """ Modified StartTcpServer from pymodbus.server.sync .. warning:: DO NOT CHANGE START TCP SERVER SECTION! VERY SENSITIVE! """ identity = ModbusDeviceIdentification() identity.VendorName = system_settings['company'] identity.ProductCode = system_settings['product'] identity.VendorUrl = system_settings['url'] identity.ProductName = system_settings['product'] identity.ModelName = system_settings['version'] identity.MajorMinorRevision = system_settings['version'] framer = ModbusSocketFramer if MODBUS_FILL_EMPTY_DATA: slave = ModbusSlaveContext() else: # TODO: Complete this feature! Does not work properly at the moment! empty_block = ModbusSparseDataBlock({0x00: 0x00}) slave = ModbusSlaveContext(di=empty_block, co=empty_block, hr=empty_block, ir=empty_block) # LOGGER.debug("slave.store = " + str(slave.store)) context = ModbusServerContext(slaves=slave, single=True) self.server = ModbusTcpServer(context, framer) self.server.RequestHandlerClass = CustomModbusHandler super(ModbusProcess, self).__init__(target=self.server.serve_forever)
def __init__(self, server="tcp", *args, **kwargs): # initialize server information self.identity = ModbusDeviceIdentification() self._add_device_info() self._server_type = server self._port = kwargs.get('port', None) self.context = ModbusServerContext(single=False) self.simulate = kwargs.get('simulate', False) byte_order = kwargs.pop("byte_order", "big") word_order = kwargs.pop("word_order", "big") self.byte_order = Endian.Big if byte_order == "big" else Endian.Little self.word_order = Endian.Big if word_order == "big" else Endian.Little self.dirty = False if server == "tcp": self._port = int(self._port) self._address = kwargs.get("address", "localhost") self.server = ModbusTcpServer(self.context, identity=self.identity, address=(self._address, self._port)) else: self.server = MbusSerialServer(self.context, framer=ModbusRtuFramer, identity=self.identity, **kwargs) self.server_thread = ThreadedModbusServer(self.server)
def serverint(self): # instantiate server stuff #print "Server mode" # StartTcpServer(context, identity=identity, address=(self.ipaddr, self.port)) self.framer = ModbusSocketFramer self.server = ModbusTcpServer(context, self.framer, identiy=identity, address=(self.ipaddr, self.port)) self.server.timeout = 1 while(not self.serverstop.is_set()): self.server.handle_request() # The original function overrides socketserver->serve_forever()
def __configureServer(self): if self.cfg["method"] == "tcp": self.servTCP = ModbusTcpServer(self.context, identity=self.identity, address=(self.__getIPAddress(), self.cfg["tcpPort"])) elif self.cfg["method"] == "rtu": self.servRTU = ModbusSerialServer(self.context, framer=ModbusRtuFramer, identity=self.identity, port=self.cfg["rtuPort"], stopbits=self.cfg["stopbits"], bytesize=self.cfg["bytesize"], parity=self.cfg["parity"], baudrate=self.cfg["baudrate"], timeout=self.cfg["timeout"]) else: raise ReferenceError("Invalid server type")
def __init__(self, address, port): self.coil = CoilDataBlock() self.discrete_input = DiscreteInputDataBlock() self.input_register = InputRegisterDataBlock() self.holding_register = HoldingRegisterDataBlock() self.store = ModbusSlaveContext(di=self.discrete_input, co=self.coil, hr=self.holding_register, ir=self.input_register) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'pymodbus' self.identity.VendorName = 'pymodbus' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'pymodbus Server' self.identity.ModelName = 'pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.server = ModbusTcpServer(context=self.context, framer=None, identity=self.identity, address=(address, port))
class Server: def __init__(self, address, port): self.holding_register_block = HoldingRegisterDataBlock.create() self.coil_block = ModbusSparseDataBlock.create() self.input_register_block = ModbusSparseDataBlock.create() self.store = ModbusSlaveContext(co=self.coil_block, hr=self.holding_register_block) self.context = ModbusServerContext(slaves=self.store, single=True) self.server = ModbusTcpServer(self.context, address=(address, port)) self.thread = threading.Thread(target=self.__run_thread__, args=()) def __run_thread__(self): self.server.serve_forever() def run(self): self.thread.start() def stop(self): self.server.server_close() self.server.shutdown() self.thread.join() def set_time_callback(self, function): self.holding_register_block.set_time_callback(function) def set_ready_flag(self): self.coil_block.setValues(ready_flag_address, True) def get_time(self): return self.holding_register_block.get_time()
class FakeModbusAgent(threading.Thread): def __init__(self, port=5020, endian="big"): threading.Thread.__init__(self) self.setDaemon(True) self.port = port self._stop = threading.Event() if endian.lower() == "big": self.endian = Endian.Big else: self.endian = Endian.Little self.snmpEngine = None def run(self) -> None: builder = BinaryPayloadBuilder(byteorder=self.endian, wordorder=self.endian) builder.add_32bit_uint(42) builder.add_16bit_uint(12) builder.add_32bit_int(64) builder.add_16bit_int(128) builder.add_32bit_float(256) store = ModbusSlaveContext( di=ModbusSequentialDataBlock(18476, builder.to_registers()), co=ModbusSequentialDataBlock(18476, builder.to_registers()), hr=ModbusSequentialDataBlock(18476, builder.to_registers()), ir=ModbusSequentialDataBlock(18476, builder.to_registers()), zero_mode=True ) slaves = { 0x01: store, 0x02: store, 0x03: store, 0x04: store, } # context = ModbusServerContext(slaves=store, single=True) context = ModbusServerContext(slaves=slaves, single=False) 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.3.0' framer = ModbusSocketFramer self.server = ModbusTcpServer(context, framer, identity, address=("127.0.0.1", self.port)) self.server.serve_forever() # function using _stop function def stop(self): self.server.shutdown() self.server.server_close()
def run(self) -> None: builder = BinaryPayloadBuilder(byteorder=self.endian, wordorder=self.endian) builder.add_32bit_uint(42) builder.add_16bit_uint(12) builder.add_32bit_int(64) builder.add_16bit_int(128) builder.add_32bit_float(256) store = ModbusSlaveContext( di=ModbusSequentialDataBlock(18476, builder.to_registers()), co=ModbusSequentialDataBlock(18476, builder.to_registers()), hr=ModbusSequentialDataBlock(18476, builder.to_registers()), ir=ModbusSequentialDataBlock(18476, builder.to_registers()), zero_mode=True ) slaves = { 0x01: store, 0x02: store, 0x03: store, 0x04: store, } # context = ModbusServerContext(slaves=store, single=True) context = ModbusServerContext(slaves=slaves, single=False) 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.3.0' framer = ModbusSocketFramer self.server = ModbusTcpServer(context, framer, identity, address=("127.0.0.1", self.port)) self.server.serve_forever()
class Server: def __init__(self, address, port): self.holding_register_block = HoldingRegisterDataBlock.create() self.coil_block = ModbusSparseDataBlock.create() self.store = ModbusSlaveContext(hr=self.holding_register_block, co=self.coil_block) self.context = ModbusServerContext(slaves=self.store, single=True) self.server = ModbusTcpServer(self.context, address=(address, port)) self.thread = Thread(target=self.__run_thread__, args=()) def __run_thread__(self): self.server.serve_forever() def run(self): self.thread.start() def stop(self): self.server.server_close() self.server.shutdown() self.thread.join() def set_time_callback(self, function): self.holding_register_block.set_time_callback(function) def set_value_callback(self, function): self.holding_register_block.set_value_callback(function) def set_ready_flag(self): self.coil_block.setValues(ready_flag_address, True) def get_time(self): return self.holding_register_block.get_time() def read_values(self): values = [] # reading incremented addresses because registers' addressing is fu..d up :/ values.append(self.holding_register_block.getValues(303)[0]) # T_pco values.append(self.holding_register_block.getValues(301)[0]) # F_zm values.append(self.holding_register_block.getValues(103)[0]) # T_zm values.append(self.holding_register_block.getValues(101)[0]) # T_o ts = HoldingRegisterDataBlock.__calculate_timestamp__([ self.holding_register_block.getValues(1)[0], self.holding_register_block.getValues(2)[0] ]) values.append(ts) # time # if min(values) == 0: # print('Some value is 0!') # values.append(self.holding_register_block.getValues(302)) # T_pco # values.append(self.holding_register_block.getValues(300)) # F_zm # values.append(self.holding_register_block.getValues(102)) # T_zm # values.append(self.holding_register_block.getValues(100)) # T_o return values
def get_request( self ): """Configure each accepted Client socket with TCP_NODELAY and SO_KEEPALIVE, to maximize thruput and ensure detection of zombie TCP/IP connections where the final FIN or RST was dropped. """ conn,addr = ModbusTcpServer.get_request( self ) try: conn.setsockopt( socket.IPPROTO_TCP, socket.TCP_NODELAY, 1 ) except Exception as exc: logging.warning( "Couldn't set TCP_NODELAY on socket to Modbust/TCP client at %s:%s: %s", addr[0], addr[1], exc ) try: conn.setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1 ) except Exception as exc: logging.warning( "Couldn't set SO_KEEPALIVE on socket to Modbus/TCP client at %s:%s: %s", addr[0], addr[1], exc ) logging.info( "Set TCP_NODELAY and SO_KEEPALIVE on socket to Modbus/TCP client at %s:%s", addr[0], addr[1] ) return conn,addr
class MBTCPServer(QThread): def __init__(self, ip, port, unit, data, parent): super(MBTCPServer, self).__init__(parent) self.slave = MBSlave(ModbusSequentialDataBlock(1, data[0]), ModbusSequentialDataBlock(1, data[1]), ModbusSequentialDataBlock(1, data[2]), ModbusSequentialDataBlock(1, data[3])) self.ctx = ModbusServerContext(slaves={unit: self.slave}, single=False) self.server = ModbusTcpServer(self.ctx, framer=MSF, address=(ip, port)) def run(self): self.server.serve_forever() def quit(self): self.server.server_close() self.server.shutdown() super(MBTCPServer, self).quit()
class Server: def __init__(self, address, port): self.holding_register_block = HoldingRegisterDataBlock.create() self.coil_block = CoilsDataBlock.create() self.store = ModbusSlaveContext(hr=self.holding_register_block, co=self.coil_block, zero_mode=True) self.context = ModbusServerContext(slaves=self.store, single=True) self.server = ModbusTcpServer(self.context, address=(address, port)) self.thread = Thread(target=self.__run_thread__, args=()) self.holding_register_block.setValues(t_o_address, 277) self.holding_register_block.setValues(t_zco_address, 400) def __run_thread__(self): self.server.serve_forever() def run(self): self.thread.start() def stop(self): self.server.server_close() self.server.shutdown() self.thread.join() def get_holding_register(self, index): return self.holding_register_block.getValues(index, 1) def set_time_flag_callback(self, function): self.coil_block.set_time_flag_callback(function) def set_ready_flag(self): self.coil_block.setValues(ready_flag_address, True) def get_ready_flag(self): return self.coil_block.getValues(ready_flag_address, 1) def get_time(self): return self.holding_register_block.get_time() def get_t_o_from_registers(self): return self.holding_register_block.getValues(t_o_address, 1) def get_t_zco_from_registers(self): return self.holding_register_block.getValues(t_zco_address, 1)
class ModbusServer: def __init__(self, address, port): self.coil = CoilDataBlock() self.discrete_input = DiscreteInputDataBlock() self.input_register = InputRegisterDataBlock() self.holding_register = HoldingRegisterDataBlock() self.store = ModbusSlaveContext(di=self.discrete_input, co=self.coil, hr=self.holding_register, ir=self.input_register) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'pymodbus' self.identity.VendorName = 'pymodbus' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'pymodbus Server' self.identity.ModelName = 'pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.server = ModbusTcpServer(context=self.context, framer=None, identity=self.identity, address=(address, port)) def start(self): rospy.loginfo("Start Modbus Server") t = Thread(target=self.__start_server) t.start() def __start_server(self): self.discrete_input.start_ros_subscribers() self.input_register.start_ros_subscribers() self.server.serve_forever() def stop(self): rospy.loginfo("Stop Modbus Server") self.discrete_input.stop_ros_subscribers() self.input_register.stop_ros_subscribers() rospy.sleep(0.1) self.server.server_close() self.server.shutdown()
class ModbusServerThread(Thread): def __init__(self, address, blocks): Thread.__init__(self) store = ModbusSlaveContext( di=blocks.get('di', ModbusSequentialDataBlock(0, [0])), co=blocks.get('co', ModbusSequentialDataBlock(0, [0])), hr=blocks.get('hr', ModbusSequentialDataBlock(0, [0])), ir=blocks.get('ir', ModbusSequentialDataBlock(0, [0]))) self.context = ModbusServerContext(slaves=store, single=True) self.server = ModbusTcpServer(context=self.context, framer=None, identity=None, address=address) def run(self): self.server.serve_forever() def stop(self): self.server.server_close() self.server.shutdown()
def run_tcp(args, server_context): server = ModbusTcpServer( context=server_context, framer=ModbusSocketFramer, address=(args.host, int(args.port))) server.serve_forever()
class ModbusWrapperServer(): def __init__(self,port=1234): """ Creates a Modbus TCP Server object .. note:: The default port for modbus is 502. This modbus server uses port 1234 by default, otherwise superuser rights are required. .. note:: Use "startServer" to start the listener. :param port: Port for the modbus TCP server :type port: int """ # chr = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) # cdi = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) self.onShutdown=False; self.state_changed = Signal() cco = CustomHoldingRegister(ADDRESS_WRITE_START, [16]*100) self.store = ModbusSlaveContext( di = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100), co = cco, hr = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100), ir = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [16]*100)) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'Pymodbus' self.identity.ProductCode = 'PM' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'Pymodbus Server' self.identity.ModelName = 'Pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.store.setValues(2,0,[0]*1) self.post = Post(self) framer = ModbusSocketFramer self.server = ModbusTcpServer(self.context, framer, self.identity, address=("0.0.0.0", port)) def startServer(self): """ Non blocking call to start the server """ self.post._startServer() def _startServer(self): print "Modbus server started" self.server.serve_forever() def stopServer(self): """ Closes the server """ self.onShutdown = True self.server.server_close() self.server.shutdown() def waitForCoilOutput(self,address,timeout=2): now = time.time() while not self.onShutdown: values = self.store.getValues(1,address, 1) if values[0] is True: return True else: if timeout > 0 and now + timeout > time.time(): time.sleep(1/50) else: return False def stateChangeListener(self,address): self.post.__stateChangeListener(address) def __stateChangeListener(self,address): old_state = 0; while not self.onShutdown: value = self.store.getValues(1,address, 1)[0] if old_state != value: old_state = value self.state_changed(address,value) #print "state has changed" time.sleep(1/50) def setDigitalInput(self,address,values): if not values is list: values = [values] self.store.setValues(2,address,values) def triggerInput(self,address,timeout=0.5): self.setDigitalInput(address, True) self.post.resetInput(address, timeout) def resetInput(self,address,timeout): time.sleep(timeout) self.setDigitalInput(address, False)
class ModbusWrapperServer(): def __init__(self,port=1234,sub_topic="modbus_server/write_to_registers",pub_topic="modbus_server/read_from_registers"): """ Creates a Modbus TCP Server object .. note:: The default port for modbus is 502. This modbus server uses port 1234 by default, otherwise superuser rights are required. .. note:: Use "startServer" to start the listener. :param port: Port for the modbus TCP server :type port: int :param sub_topic: ROS topic name for the subscriber that updates the modbus registers :type sub_topic: string :param pub_topic: ROS topic name for the publisher that publishes a message, once there is something written to the writeable modbus registers :type pub_topic: string """ chr = CustomHoldingRegister(ADDRESS_WRITE_START, [17]*100,sub_topic,pub_topic) self.store = ModbusSlaveContext( di = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [17]*100), co = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [17]*100), hr = chr, ir = ModbusSequentialDataBlock(ADDRESS_WRITE_START, [17]*100)) self.context = ModbusServerContext(slaves=self.store, single=True) self.identity = ModbusDeviceIdentification() self.identity.VendorName = 'Pymodbus' self.identity.ProductCode = 'PM' self.identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' self.identity.ProductName = 'Pymodbus Server' self.identity.ModelName = 'Pymodbus Server' self.identity.MajorMinorRevision = '1.0' self.store.setValues(2,0,[0]*1) self.post = Post(self) framer = ModbusSocketFramer self.server = ModbusTcpServer(self.context, framer, self.identity, address=("0.0.0.0", port)) def startServer(self): """ Non blocking call to start the server """ self.post.__startServer() rospy.loginfo("Modbus server started") def __startServer(self): self.server.serve_forever() def stopServer(self): """ Closes the server """ self.server.server_close() self.server.shutdown() def waitForCoilOutput(self,address,timeout=2): """ Blocks for the timeout in seconds (or forever) until the specified address becomes true. Adapt this to your needs :param address: Address of the register that wanted to be read. :type address: int :param timeout: The time in seconds until the function should return latest. :type: float/int """ now = time.time() while True: values = self.store.getValues(1,address, 1) if values[0] is True: return True else: if timeout <=0 or now + timeout > time.time(): time.sleep(1/50) else: return False def setDigitalInput(self,address,values): """ Writes to the digital input of the modbus server :param address: Starting address of the values to write :type: int :param values: List of values to write :type list/boolean/int """ if not values is list: values = [values] self.store.setValues(2,address,values)
class modbusServer(): def __init__(self): self.__logging() self.cfg = yamlImport.importYAML("./cfg/modbusSettings.yaml") self.builder = BinaryPayloadBuilder(endian=Endian.Little) self.__setupContext() self.__serverInfo() self.__configureServer() def __logging(self): import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) def __setupContext(self): #Setup Coils co = ModbusSequentialDataBlock(1, [0]*1) di = ModbusSequentialDataBlock(1, [0]*6) #Setup Registers (Inc floats) for i in range(0,3): self.builder.add_32bit_float(0.0) ir = ModbusSequentialDataBlock(1, self.builder.to_registers()) for i in range(0,3): self.builder.add_32bit_float(0.0) hr = ModbusSequentialDataBlock(1, self.builder.to_registers()) #Setup datastore store = ModbusSlaveContext(co=co,di=di,hr=hr,ir=ir) self.context = ModbusServerContext(slaves=store, single=True) def __serverInfo(self): self.identity = ModbusDeviceIdentification() self.identity.VendorName = self.cfg["VendorName"] self.identity.VendorUrl = self.cfg["VendorUrl"] self.identity.ProductName = self.cfg["ProductName"] self.identity.ModelName = self.cfg["ModelName"] self.identity.MajorMinorRevision = self.cfg["Revision"] def __getIPAddress(self): if self.cfg["manualIP"] == "N": return socket.gethostbyname(socket.gethostname()) return self.cfg["ip"] def __configureServer(self): if self.cfg["method"] == "tcp": self.servTCP = ModbusTcpServer(self.context, identity=self.identity, address=(self.__getIPAddress(), self.cfg["tcpPort"])) elif self.cfg["method"] == "rtu": self.servRTU = ModbusSerialServer(self.context, framer=ModbusRtuFramer, identity=self.identity, port=self.cfg["rtuPort"], stopbits=self.cfg["stopbits"], bytesize=self.cfg["bytesize"], parity=self.cfg["parity"], baudrate=self.cfg["baudrate"], timeout=self.cfg["timeout"]) else: raise ReferenceError("Invalid server type") def runServer(self): if self.cfg["method"] == "tcp": self.servTCP.serve_forever() elif self.cfg["method"] == "rtu": self.servRTU.serve_forever() else: raise ReferenceError("Invalid server type") def stopServer(self): if self.cfg["method"] == "tcp": self.servTCP.server_close() self.servTCP.shutdown() elif self.cfg["method"] == "rtu": self.servRTU.server_close() else: raise ReferenceError("Invalid server type") def encodeData(self,data): self.builder.reset() try: for i in range(0,len(data)): self.builder.add_32bit_float(data[i]) except TypeError: self.builder.add_32bit_float(data) return self.builder.to_registers() def decodeData(self,data): returnData = [0]*(len(data)/2) decoder = BinaryPayloadDecoder.fromRegisters(data, endian=Endian.Little) for i in range(0,len(data)/2): returnData[i] = round(decoder.decode_32bit_float(),2) return returnData
def testTcpServerProcess(self): ''' test that the synchronous TCP server processes requests ''' with patch('SocketServer.ThreadingTCPServer') as mock_server: server = ModbusTcpServer(None) server.process_request('request', 'client') self.assertTrue(mock_server.process_request.called)