def testSerialClientHandleResponse(self, mock_serial, mock_seriostream, mock_ioloop): """ Test the tornado serial client client handles responses """ client = AsyncModbusSerialClient(ioloop=schedulers.IO_LOOP, framer=ModbusRtuFramer( ClientDecoder()), port=SERIAL_PORT) client.connect() out = [] reply = ReadCoilsRequest(1, 1) reply.transaction_id = 0x00 # handle skipped cases client._handle_response(None) client._handle_response(reply) # handle existing cases d = client._build_response(0x00) d.add_done_callback(lambda v: out.append(v)) client._handle_response(reply) self.assertEqual(d.result(), reply)
def testSerialClientBuildResponse(self, mock_serial, mock_seriostream, mock_ioloop): """ Test the tornado serial client client builds responses """ client = AsyncModbusSerialClient(ioloop=schedulers.IO_LOOP, framer=ModbusRtuFramer( ClientDecoder()), port=SERIAL_PORT) self.assertEqual(0, len(list(client.transaction))) def handle_failure(failure): exc = failure.exception() self.assertTrue(isinstance(exc, ConnectionException)) d = client._build_response(0x00) d.add_done_callback(handle_failure) self.assertEqual(0, len(list(client.transaction))) client._connected = True d = client._build_response(0x00) self.assertEqual(1, len(list(client.transaction)))
def __init__(self, host='127.0.0.1', port=Defaults.Port, framer=ModbusSocketFramer, **kwargs): ''' Initialize a client instance :param host: The host to connect to (default 127.0.0.1) :param port: The modbus port to connect to (default 502) :param source_address: The source address tuple to bind to (default ('', 0)) :param timeout: The timeout to use for this socket (default Defaults.Timeout) :param framer: The modbus framer to use (default ModbusSocketFramer) .. note:: The host argument will accept ipv4 and ipv6 hosts ''' self.host = host self.port = port self.source_address = kwargs.get('source_address', ('', 0)) self.socket = None self.timeout = kwargs.get('timeout', Defaults.Timeout) BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
def start(self): AbstractHandler.start(self) framer = ModbusFramer(ClientDecoder()) pol_list = {} for t in self.config.keys(): if t in ["output", "input", "inputc"]: address_list = {} for x in self.config[t]: address = self.tagslist[x]["address"] address_list[address] = x pol_list[t] = self._generate_address_map(address_list) factory = SMHSFactory(framer, pol_list, self.logger, self.reader, self.writepool) SerialModbusClient(factory, "/dev/plc", reactor, baudrate=9600, parity=PARITY_EVEN, bytesize=SEVENBITS, stopbits=STOPBITS_TWO, timeout=0)
def __new__(cls, scheduler, host="127.0.0.1", port=Defaults.TLSPort, framer=None, sslctx=None, server_hostname=None, source_address=None, timeout=None, **kwargs): """ Scheduler to use: - async_io (asyncio) :param scheduler: Backend to use :param host: Host IP address :param port: Port :param framer: Modbus Framer to use :param sslctx: The SSLContext to use for TLS (default None and auto create) :param server_hostname: Target server's name matched for certificate :param source_address: source address specific to underlying backend :param timeout: Time out in seconds :param kwargs: Other extra args specific to Backend being used :return: """ if (not (IS_PYTHON3 and PYTHON_VERSION >= (3, 4)) and scheduler == ASYNC_IO): logger.critical("ASYNCIO is supported only on python3") import sys sys.exit(1) framer = framer or ModbusTlsFramer(ClientDecoder()) factory_class = get_factory(scheduler) yieldable = factory_class(host=host, port=port, sslctx=sslctx, server_hostname=server_hostname, framer=framer, source_address=source_address, timeout=timeout, **kwargs) return yieldable
def __init__(self, method='ascii', framer=None, **kwargs): '''Initialize a serial client instance. This is exceedingly gross, but we can't easily fix the ModbuSerialClient.__init__ (see BaseModubsClient in pymodbus/pymodbus/client/sync.py). Let it run, then fix the self.framer later... We know that self.transaction is OK, because framer isn't a ModbusSocketFramer. The methods to connect are:: - ascii - rtu - binary ''' # If a 'framer' is supplied, use it (and come up with a self.method name) super(modbus_client_rtu, self).__init__(method=method, **kwargs) if framer is not None: assert not isinstance(self.framer, ModbusSocketFramer) assert not isinstance(framer, ModbusSocketFramer) self.method = framer.__name__ self.framer = framer(ClientDecoder())
def test_framer_initialization(framer): decoder = ClientDecoder() framer = framer(decoder) assert framer.client == None assert framer._buffer == b'' assert framer.decoder == decoder if isinstance(framer, ModbusAsciiFramer): assert framer._header == {'lrc': '0000', 'len': 0, 'uid': 0x00} assert framer._hsize == 0x02 assert framer._start == b':' assert framer._end == b"\r\n" elif isinstance(framer, ModbusRtuFramer): assert framer._header == {'uid': 0x00, 'len': 0, 'crc': '0000'} assert framer._hsize == 0x01 assert framer._end == b'\x0d\x0a' assert framer._min_frame_size == 4 else: assert framer._header == {'crc': 0x0000, 'len': 0, 'uid': 0x00} assert framer._hsize == 0x01 assert framer._start == b'\x7b' assert framer._end == b'\x7d' assert framer._repeat == [b'}'[0], b'{'[0]]
def testUdpTornadoClient(self, mock_iostream, mock_ioloop): """ Test the udp tornado client client initialize """ protocol, future = AsyncModbusUDPClient(schedulers.IO_LOOP, framer=ModbusSocketFramer( ClientDecoder())) client = future.result() assert (isinstance(client, AsyncTornadoModbusUdoClient)) assert (0 == len(list(client.transaction))) assert (isinstance(client.framer, ModbusSocketFramer)) assert (client.port == 502) assert (client._connected) def handle_failure(failure): assert (isinstance(failure.exception(), ConnectionException)) d = client._build_response(0x00) d.add_done_callback(handle_failure) assert (client._connected) client.close() protocol.stop() assert (not client._connected)
def main(output='datastore.pickle', port=502, host='127.0.0.1', device=0x01, range='0:1000', debug=False): """ The main runner function """ if debug: try: log.setLevel(logging.DEBUG) logging.basicConfig() except Exception as ex: print("Logging is not supported on this system") # split the query into a starting and ending range query = [int(p) for p in range.split(':')] global SLAVE SLAVE = device try: log.debug("Initializing the client") framer = ModbusSocketFramer(ClientDecoder()) reader = LoggingContextReader(output) factory = ScraperFactory(framer, reader, query) # how to connect based on TCP vs Serial clients if isinstance(framer, ModbusSocketFramer): reactor.connectTCP(host, port, factory) else: SerialModbusClient(factory, options.port, reactor) log.debug("Starting the client") reactor.run() log.debug("Finished scraping the client") except Exception as ex: print(ex)
def __implementation(method): method = method.lower() if method == 'rtu': return AsyncModbusRtuFramer(ClientDecoder()) raise ParameterException("Unsupported framer method requested")
def binary_framer(): return ModbusBinaryFramer(ClientDecoder())
def ascii_framer(): return ModbusAsciiFramer(ClientDecoder())
def rtu_framer(): return ModbusRtuFramer(ClientDecoder())
def start_client(address, port=502): """Function that start a client address: the address to witch the client is going to connect port: the port of the server to witch the client is going to connect """ decoder = ClientDecoder() # Starting and connecting the client to the server client = ModbusTcpClient(address, port) client.connect() key_help() close = False while not close: try: if keyboard.is_pressed('q'): # Checking for the exit close = not close elif keyboard.is_pressed('s'): # Read the register by sector try: sector_in = int(input("Insert the sector index: ")) sector_ = read_register_by_sector(client, sector_in) key_help() print('\nSector '+str(sector_in)+': ') for i in range(len(sector_)): print('\tSensor '+ str(i) + ': ' + str(sector_[i])) print() except: key_help() print('Input not valid, please retry: ') elif keyboard.is_pressed('t'): # Read the register by type try: type_in = str(input("Insert the type of sensor letter: ")) type_ = read_register_by_type(client, type_in) key_help() print('\nType '+'"'+str(type_in)+'"'+': ') for i in range(len(type_)): print('\tSensor '+ str(i) + ': ' + str(type_[i])) print() except: key_help() print('Input not valid, please retry: ') elif keyboard.is_pressed('r'): # Read the register by his address try: address_in = int(input("Insert the register index: ")) count_in = input("Insert the number of registers you want to read (Press 'Enter' to read only one): ") # Cheking if the count is a number or not if count_in == "": address_ = read_register_by_address(client, address_in) key_help() print('\nAddress '+str(address_in)+': ') print('\tSensor: ' + str(address_[0])) print() else: address_ = read_register_by_address(client, address_in, int(count_in)) key_help() print('\nAddress '+str(address_in)+': ') for i in range(len(address_)): print('\tSensor '+ str(i) + ': ' + str(address_[i])) print() except: key_help() print('Input not valid, please retry: ') #elif keyboard.is_pressed('m'): #try: #except: except: pass client.close()
def __init__(self, factory, *args, **kwargs): protocol = factory.buildProtocol(None) self.decoder = ClientDecoder() serialport.SerialPort.__init__(self, protocol, *args, **kwargs)
''' The main runner function ''' options = get_options() if options.debug: try: log.setLevel(logging.DEBUG) logging.basicConfig() except Exception, ex: print "Logging is not supported on this system" # split the query into a starting and ending range query = [int(p) for p in options.query.split(':')] try: log.debug("Initializing the client") framer = ModbusSocketFramer(ClientDecoder()) reader = LoggingContextReader(options.output) factory = ScraperFactory(framer, reader, query) # how to connect based on TCP vs Serial clients if isinstance(framer, ModbusSocketFramer): reactor.connectTCP(options.host, options.port, factory) else: SerialModbusClient(factory, options.port, reactor) log.debug("Starting the client") reactor.run() log.debug("Finished scraping the client") except Exception, ex: print ex
def setUp(self): ''' Initializes the test environment ''' self.client = ClientDecoder() self.server = ServerDecoder() self.request = ( (0x01, '\x01\x00\x01\x00\x01'), # read coils (0x02, '\x02\x00\x01\x00\x01'), # read discrete inputs (0x03, '\x03\x00\x01\x00\x01'), # read holding registers (0x04, '\x04\x00\x01\x00\x01'), # read input registers (0x05, '\x05\x00\x01\x00\x01'), # write single coil (0x06, '\x06\x00\x01\x00\x01'), # write single register (0x07, '\x07'), # read exception status (0x08, '\x08\x00\x00\x00\x00'), # read diagnostic (0x0b, '\x0b'), # get comm event counters (0x0c, '\x0c'), # get comm event log (0x0f, '\x0f\x00\x01\x00\x08\x01\x00\xff'), # write multiple coils (0x10, '\x10\x00\x01\x00\x02\x04\0xff\xff'), # write multiple registers (0x11, '\x11'), # report slave id (0x14, '\x14\x0e\x06\x00\x04\x00\x01\x00\x02' \ '\x06\x00\x03\x00\x09\x00\x02'), # read file record (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \ '\x06\xaf\x04\xbe\x10\x0d'), # write file record (0x16, '\x16\x00\x01\x00\xff\xff\x00'), # mask write register (0x17, '\x17\x00\x01\x00\x01\x00\x01\x00\x01\x02\x12\x34'),# read/write multiple registers (0x18, '\x18\x00\x01'), # read fifo queue (0x2b, '\x2b\x0e\x01\x00'), # read device identification ) self.response = ( (0x01, '\x01\x01\x01'), # read coils (0x02, '\x02\x01\x01'), # read discrete inputs (0x03, '\x03\x02\x01\x01'), # read holding registers (0x04, '\x04\x02\x01\x01'), # read input registers (0x05, '\x05\x00\x01\x00\x01'), # write single coil (0x06, '\x06\x00\x01\x00\x01'), # write single register (0x07, '\x07\x00'), # read exception status (0x08, '\x08\x00\x00\x00\x00'), # read diagnostic (0x0b, '\x0b\x00\x00\x00\x00'), # get comm event counters (0x0c, '\x0c\x08\x00\x00\x01\x08\x01\x21\x20\x00'), # get comm event log (0x0f, '\x0f\x00\x01\x00\x08'), # write multiple coils (0x10, '\x10\x00\x01\x00\x02'), # write multiple registers (0x11, '\x11\x03\x05\x01\x54'), # report slave id (device specific) (0x14, '\x14\x0c\x05\x06\x0d\xfe\x00\x20\x05' \ '\x06\x33\xcd\x00\x40'), # read file record (0x15, '\x15\x0d\x06\x00\x04\x00\x07\x00\x03' \ '\x06\xaf\x04\xbe\x10\x0d'), # write file record (0x16, '\x16\x00\x01\x00\xff\xff\x00'), # mask write register (0x17, '\x17\x02\x12\x34'), # read/write multiple registers (0x18, '\x18\x00\x01\x00\x01\x00\x00'), # read fifo queue (0x2b, '\x2b\x0e\x01\x01\x00\x00\x01\x00\x01\x77'), # read device identification ) self.exception = ( (0x81, '\x81\x01\xd0\x50'), # illegal function exception (0x82, '\x82\x02\x90\xa1'), # illegal data address exception (0x83, '\x83\x03\x50\xf1'), # illegal data value exception (0x84, '\x84\x04\x13\x03'), # skave device failure exception (0x85, '\x85\x05\xd3\x53'), # acknowledge exception (0x86, '\x86\x06\x93\xa2'), # slave device busy exception (0x87, '\x87\x08\x53\xf2'), # memory parity exception (0x88, '\x88\x0a\x16\x06'), # gateway path unavailable exception (0x89, '\x89\x0b\xd6\x56'), # gateway target failed exception ) self.bad = ( (0x80, '\x80\x00\x00\x00'), # Unknown Function (0x81, '\x81\x00\x00\x00'), # error message )
def testSerialClientInit(self): """ Test the tornado serial client client initialize """ client = AsyncModbusSerialClient(ioloop=schedulers.IO_LOOP, framer=ModbusRtuFramer(ClientDecoder()), port=SERIAL_PORT) self.assertEqual(0, len(list(client.transaction))) self.assertTrue(isinstance(client.framer, ModbusRtuFramer)) framer = object() client = AsyncModbusSerialClient(framer=framer) self.assertTrue(framer is client.framer)
def make_protocol(): return ModbusClientProtocol(framer=ModbusRtuFramer(ClientDecoder()))
def testUdpTwistedClient(self): """ Test the udp twisted client client initialize """ with pytest.raises(NotImplementedError): AsyncModbusUDPClient(schedulers.REACTOR, framer=ModbusSocketFramer(ClientDecoder()))
def __init__(self, framer=None, **kwargs): framer = framer or ModbusRtuFramer(ClientDecoder()) super(ModbusSerClientProtocol, self).__init__(framer, **kwargs)