add playground
+ fix SR_7270 communicator Change-Id: If9604f9a6fe59ca3de3bbdbecf1b5053fce0573e
This commit is contained in:
parent
ab1fdbae16
commit
1171245704
39
bin/frappy-play
Executable file
39
bin/frappy-play
Executable file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# *****************************************************************************
|
||||
# Copyright (c) 2015-2016 by the authors, see LICENSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Module authors:
|
||||
# Markus Zolliker <markus.zolliker@psi.ch>
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
import sys
|
||||
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 Console
|
||||
from frappy.playground import play, USAGE
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
play(sys.argv[1])
|
||||
else:
|
||||
print(USAGE)
|
||||
|
||||
Console(sys.modules['__main__'].__dict__, 'play')
|
@ -409,12 +409,12 @@ class Client(SecopClient):
|
||||
|
||||
|
||||
class Console(code.InteractiveConsole):
|
||||
def __init__(self, local):
|
||||
def __init__(self, local, name='cli'):
|
||||
super().__init__(local)
|
||||
history = None
|
||||
if readline:
|
||||
try:
|
||||
history = expanduser('~/.frappy-cli-history')
|
||||
history = expanduser(f'~/.frappy-{name}-history')
|
||||
readline.read_history_file(history)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
137
frappy/playground.py
Normal file
137
frappy/playground.py
Normal file
@ -0,0 +1,137 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# *****************************************************************************
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Module authors:
|
||||
# Markus Zolliker <markus.zolliker@psi.ch>
|
||||
#
|
||||
# *****************************************************************************
|
||||
"""playground dummy server
|
||||
|
||||
a dummy server for testing drivers interactively
|
||||
|
||||
Remarks:
|
||||
- the poller is not started
|
||||
"""
|
||||
|
||||
import sys
|
||||
from logging import DEBUG, INFO, addLevelName
|
||||
import mlzlog
|
||||
from frappy.errors import NoSuchModuleError
|
||||
from frappy.server import Server
|
||||
from frappy.config import load_config, Mod as ConfigMod
|
||||
from frappy.lib import generalConfig
|
||||
|
||||
|
||||
USAGE = """create config on the fly:
|
||||
|
||||
Mod('io', ...)
|
||||
Mod('mf', ...)
|
||||
play()
|
||||
|
||||
or use a config file:
|
||||
|
||||
play('<configfile(s)>')
|
||||
|
||||
|
||||
and then call methods for trying:
|
||||
|
||||
io.communicate('...')
|
||||
mf.read_value()
|
||||
mf.write_target(...)
|
||||
"""
|
||||
|
||||
OFF = 99
|
||||
COMLOG = 15
|
||||
addLevelName(COMLOG, 'COMLOG')
|
||||
assert DEBUG < COMLOG < INFO
|
||||
LOG_LEVELS = dict(mlzlog.LOGLEVELS, off=OFF, comlog=COMLOG)
|
||||
LEVEL_NAMES = {v: k for k, v in LOG_LEVELS.items()}
|
||||
|
||||
|
||||
main = sys.modules['__main__']
|
||||
|
||||
|
||||
class MainLogger:
|
||||
def __init__(self):
|
||||
self.log = None
|
||||
self.console_handler = None
|
||||
mlzlog.setLoggerClass(mlzlog.MLZLogger)
|
||||
assert self.log is None
|
||||
self.log = mlzlog.log = mlzlog.MLZLogger('')
|
||||
self.log.setLevel(mlzlog.DEBUG)
|
||||
self.log.addHandler(mlzlog.ColoredConsoleHandler())
|
||||
self.log.handlers[0].setLevel(LOG_LEVELS['comlog'])
|
||||
|
||||
|
||||
class Dispatcher:
|
||||
def __init__(self, name, log, opts, srv):
|
||||
self.log = log
|
||||
self._modules = {}
|
||||
|
||||
def announce_update(self, modulename, pname, pobj):
|
||||
if pobj.readerror:
|
||||
value = repr(pobj.readerror)
|
||||
else:
|
||||
value = pobj.value
|
||||
self.log.info('%s:%s %r', modulename, pname, value)
|
||||
|
||||
def register_module(self, moduleobj, modulename, export=True):
|
||||
setattr(main, modulename, moduleobj)
|
||||
self._modules[modulename] = moduleobj
|
||||
|
||||
def get_module(self, modulename):
|
||||
if modulename in self._modules:
|
||||
return self._modules[modulename]
|
||||
raise NoSuchModuleError(f'Module {modulename!r} does not exist on this SEC-Node!')
|
||||
|
||||
|
||||
logger = MainLogger()
|
||||
|
||||
|
||||
class Playground(Server):
|
||||
def __init__(self, **kwds): # pylint: disable=super-init-not-called
|
||||
for modname, cfg in kwds.items():
|
||||
cfg.setdefault('description', modname)
|
||||
self.log = logger.log
|
||||
self.node_cfg = {'cls': 'frappy.playground.Dispatcher', 'name': 'playground'}
|
||||
self._testonly = True # stops before calling startModule
|
||||
self._cfgfiles = 'main'
|
||||
self.module_cfg = {}
|
||||
|
||||
def __call__(self, cfgfiles=None):
|
||||
if cfgfiles:
|
||||
if not generalConfig.initialized:
|
||||
generalConfig.init()
|
||||
merged_cfg = load_config(cfgfiles, self.log)
|
||||
merged_cfg.pop('node', None)
|
||||
self.module_cfg = merged_cfg
|
||||
self._processCfg()
|
||||
|
||||
|
||||
play = Playground()
|
||||
|
||||
|
||||
def Mod(name, cls, description=None, **kwds):
|
||||
"""like Mod() in config files, but description may be omitted"""
|
||||
description = description or name # be lazy: fix missing description
|
||||
mod = ConfigMod(name, cls, description, **kwds)
|
||||
play.module_cfg[mod.pop('name')] = mod
|
||||
|
||||
|
||||
def loglevel(level):
|
||||
"""set log level (COMLOG by default)"""
|
||||
logger.log.handlers[0].setLevel(LOG_LEVELS.get(level, level))
|
@ -28,7 +28,7 @@ class SR7270(StringIO):
|
||||
end_of_line = b'\x00'
|
||||
|
||||
def communicate(self, command): # remove dash from terminator
|
||||
reply = StringIO.communicate(self, command)
|
||||
reply = super().communicate(command)
|
||||
status = self._conn.readbytes(2, 0.1) # get the 2 status bytes
|
||||
return reply + ';%d;%d' % tuple(status)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user