diff --git a/bin/frappy-cli b/bin/frappy-cli index a838067..5874326 100755 --- a/bin/frappy-cli +++ b/bin/frappy-cli @@ -30,7 +30,7 @@ from os import path # Add import path for inplace usage sys.path.insert(0, path.abspath(path.join(path.dirname(__file__), '..'))) -from frappy.client.interactive import Client, Console, clientenv, run +from frappy.client.interactive import init, run, clientenv, interact def parseArgv(argv): @@ -47,43 +47,9 @@ def parseArgv(argv): return parser.parse_args(argv) -USAGE = """ -Usage: -{client_assign} -# for all SECoP modules objects are created in the main namespace - - # list all parameters -. = # change parameter -() # set target and wait until not busy - # 'status' and 'value' changes are shown every 1 sec -{client_name}.mininterval = 0.2 # change minimal update interval to 0.2 s (default is 1 s) - -watch(T) # watch changes of T.status and T.value (stop with ctrl-C) -watch(T='status target') # watch status and target parameters -watch(io, T=True) # watch io and all parameters of T -{tail}""" - args = parseArgv(sys.argv[1:]) -if not args.node: - usage_args = { - 'client_assign': "\ncli = Client('localhost:5000')\n", - 'client_name': 'cli'} - success = True -else: - usage_args = { - 'client_assign': '', - 'client_name': '_c0'} - success = False -clientenv.init() - -for idx, node in enumerate(args.node): - client_name = '_c%d' % idx - try: - clientenv.namespace[client_name] = Client(node, name=client_name) - success = True - except Exception as e: - print(repr(e)) +success = init(args.node) run_error = '' file_success = False @@ -98,5 +64,4 @@ if success: if args.include and file_success and args.only_execute: print('skipping interactive mode') exit() - print(USAGE.format(tail=run_error, **usage_args)) - Console() + interact(run_error) diff --git a/frappy/client/interactive.py b/frappy/client/interactive.py index dcf67a1..c36a96b 100644 --- a/frappy/client/interactive.py +++ b/frappy/client/interactive.py @@ -19,28 +19,7 @@ # Markus Zolliker # # ***************************************************************************** -"""simple interactive python client - -Usage: - -from frappy.client.interactive import Client - -client = Client('localhost:5000') # start client. -# this connects and creates objects for all SECoP modules in the main namespace - - # list all parameters -. = # change parameter -() # set target and wait until not busy - # 'status' and 'value' changes are shown every 1 sec -client.mininterval = 0.2 # change minimal update interval to 0.2 s (default is 1 s) - -watch(T) # watch changes of T.status and T.value (stop with ctrl-C) -watch(T='status target') # watch status and target parameters -watch(io, T=True) # watch io and all parameters of T - -run('filename') # execute a script -/filename # execute a script -""" +"""simple interactive python client""" import sys import time @@ -59,6 +38,24 @@ try: except ImportError: readline = None + +USAGE = """ +Usage: +{client_assign} +# for all SECoP modules objects are created in the main namespace + + # list all parameters +. = # change parameter +() # set target and wait until not busy + # 'status' and 'value' changes are shown every 1 sec +{client_name}.mininterval = 0.2 # change minimal update interval to 0.2 s (default is 1 s) + +watch(T) # watch changes of T.status and T.value (stop with ctrl-C) +watch(T='status target') # watch status and target parameters +watch(io, T=True) # watch io and all parameters of T +{tail}""" + + LOG_LEVELS = {'debug', 'comlog', 'info', 'warning', 'error', 'off'} CLR = '\r\x1b[K' # code to move to the left and clear current line @@ -126,7 +123,7 @@ class Module: self._running = None self._status = None props = secnode.modules[name]['properties'] - self._title = f"# {props.get('implementation', '')} ({props.get('interface_classes', [''])[0]})" + self._title = f"# {props.get('implementation', '')} ({(props.get('interface_classes') or ['Module'])[0]})" def _one_line(self, pname, minwid=0): """return . = truncated to one line""" @@ -486,3 +483,25 @@ class Console(code.InteractiveConsole): def showtraceback(self): self.write(clientenv.short_traceback()) + + +def init(*nodes): + clientenv.init() + success = not nodes + for idx, node in enumerate(nodes): + client_name = '_c%d' % idx + try: + clientenv.namespace[client_name] = Client(node, name=client_name) + success = True + except Exception as e: + print(repr(e)) + return success + + +def interact(usage_tail=''): + empty = '_c0' not in clientenv.namespace + print(USAGE.format( + client_name='cli' if empty else '_c0', + client_assign="\ncli = Client('localhost:5000')\n" if empty else '', + tail=usage_tail)) + Console()