def start_powerflex_simulator( *options, **kwds ): """Start a simple EtherNet/IP CIP simulator (execute this file as __main__), optionally with Tag=<type>[<size>] (or other) positional arguments appended to the command-line. Return the command-line used, and the detected (host,port) address bound. Looks for something like: 11-11 11:46:16.301 7fff7a619000 network NORMAL server_mai enip_srv server PID [ 7573] running on ('', 44818) containing a repr of the (<host>,<port>) tuple. Recover this address using the safe ast.literal_eval. Use the -A to provide this on stdout, or just -v if stderr is redirected to stdout (the default, w/o a stderr parameter to nonblocking_command) At least one positional parameter containing a Tag=<type>[<size>] must be provided. Note that the output of this file's interpreter is not *unbuffered* (above), so we can receive and parse the 'running on ...'! We assume that server/network.py flushes stdout when printing the bindings. We could use #!/usr/bin/env -S python3 -u instead to have all output unbuffered. """ command = nonblocking_command( [ sys.executable, os.path.abspath( __file__ ), '-a', ':0', '-A', '-p', '-v', '--no-udp', ] + list( options ), stderr=None, bufsize=0, blocking=None ) # For python 2/3 compatibility (can't mix positional wildcard, keyword parameters in Python 2) CMD_WAIT = kwds.pop( 'CMD_WAIT', 10.0 ) CMD_LATENCY = kwds.pop( 'CMD_LATENCY', 0.1 ) assert not kwds, "Unrecognized keyword parameter: %s" % ( ", ".join( kwds )) begun = timer() address = None data = '' while address is None and timer() - begun < CMD_WAIT: # On Python2, socket will raise IOError/EAGAIN; on Python3 may return None 'til command started. raw = None try: raw = command.stdout.read() logging.debug( "Socket received: %r", raw) if raw: data += raw.decode( 'utf-8', 'backslashreplace' ) except IOError as exc: logging.debug( "Socket blocking...: {exc}".format( exc=exc )) assert exc.errno == errno.EAGAIN, "Expected only Non-blocking IOError" except Exception as exc: logging.warning("Socket read return Exception: %s", exc) if not raw: # got nothing; wait a bit time.sleep( CMD_LATENCY ) while data.find( '\n' ) >= 0: line,data = data.split( '\n', 1 ) logging.info( "%s", line ) m = re.search( r"running on (\([^)]*\))", line ) if m: address = ast.literal_eval( m.group(1).strip() ) logging.normal( "EtherNet/IP CIP Simulator started after %7.3fs on %s:%d", timer() - begun, address[0], address[1] ) break return command,address
def start_powerflex_simulator(*options, **kwds): """Start a simple EtherNet/IP CIP simulator (execute this file as __main__), optionally with Tag=<type>[<size>] (or other) positional arguments appended to the command-line. Return the command-line used, and the detected (host,port) address bound. Looks for something like: 11-11 11:46:16.301 7fff7a619000 network NORMAL server_mai enip_srv server PID [ 7573] running on ('', 44818) containing a repr of the (<host>,<port>) tuple. Recover this address using the safe ast.literal_eval. At least one positional parameter containing a Tag=<type>[<size>] must be provided. """ command = nonblocking_command([ 'python', os.path.abspath(__file__), '-v', ] + list(options)) # For python 2/3 compatibility (can't mix positional wildcard, keyword parameters in Python 2) CMD_WAIT = kwds.pop('CMD_WAIT', 10.0) CMD_LATENCY = kwds.pop('CMD_LATENCY', 0.1) assert not kwds, "Unrecognized keyword parameter: %s" % (", ".join(kwds)) begun = timer() address = None data = '' while address is None and timer() - begun < CMD_WAIT: # On Python2, socket will raise IOError/EAGAIN; on Python3 may return None 'til command started. try: raw = command.stdout.read() logging.debug("Socket received: %r", raw) if raw: data += raw.decode('utf-8') except IOError as exc: logging.debug("Socket blocking...") assert exc.errno == errno.EAGAIN, "Expected only Non-blocking IOError" except Exception as exc: logging.warning("Socket read return Exception: %s", exc) if not data: time.sleep(CMD_LATENCY) while data.find('\n') >= 0: line, data = data.split('\n', 1) logging.info("%s", line) m = re.search(r"running on (\([^)]*\))", line) if m: address = ast.literal_eval(m.group(1).strip()) logging.normal( "EtherNet/IP CIP Simulator started after %7.3fs on %s:%d", timer() - begun, address[0], address[1]) break return command, address
def start_powerflex_simulator( *options, **kwds ): """Start a simple EtherNet/IP CIP simulator (execute this file as __main__), optionally with Tag=<type>[<size>] (or other) positional arguments appended to the command-line. Return the command-line used, and the detected (host,port) address bound. Looks for something like: 11-11 11:46:16.301 7fff7a619000 network NORMAL server_mai enip_srv server PID [ 7573] running on ('', 44818) containing a repr of the (<host>,<port>) tuple. Recover this address using the safe ast.literal_eval. At least one positional parameter containing a Tag=<type>[<size>] must be provided. """ command = nonblocking_command( [ 'python', os.path.abspath( __file__ ), '-v', ] + list( options )) # For python 2/3 compatibility (can't mix positional wildcard, keyword parameters in Python 2) CMD_WAIT = kwds.pop( 'CMD_WAIT', 10.0 ) CMD_LATENCY = kwds.pop( 'CMD_LATENCY', 0.1 ) assert not kwds, "Unrecognized keyword parameter: %s" % ( ", ".join( kwds )) begun = timer() address = None data = '' while address is None and timer() - begun < CMD_WAIT: # On Python2, socket will raise IOError/EAGAIN; on Python3 may return None 'til command started. try: raw = command.stdout.read() logging.debug( "Socket received: %r", raw) if raw: data += raw.decode( 'utf-8' ) except IOError as exc: logging.debug( "Socket blocking...") assert exc.errno == errno.EAGAIN, "Expected only Non-blocking IOError" except Exception as exc: logging.warning("Socket read return Exception: %s", exc) if not data: time.sleep( CMD_LATENCY ) while data.find( '\n' ) >= 0: line,data = data.split( '\n', 1 ) logging.info( "%s", line ) m = re.search( "running on (\([^)]*\))", line ) if m: address = ast.literal_eval( m.group(1).strip() ) logging.normal( "EtherNet/IP CIP Simulator started after %7.3fs on %s:%d", timer() - begun, address[0], address[1] ) break return command,address