add various changes to superfrappy
not 100 % sure about the best state ...
This commit is contained in:
@@ -111,17 +111,17 @@ class SecNode:
|
||||
self.cfg = cfg
|
||||
self.description = cfg
|
||||
self.online = False
|
||||
self._status = 'created'
|
||||
self.status = 'created'
|
||||
self.trigger = True
|
||||
self.announce_pnp = True # None: do not announce, True: announce new, False: announce removal
|
||||
self.setup_was_loaded = False
|
||||
|
||||
def connect(self, complete_callback=None, log=None):
|
||||
self._status = 'connecting'
|
||||
self.status = 'connecting'
|
||||
self.log = log
|
||||
self.complete_callback = complete_callback
|
||||
if self.log:
|
||||
self.log.debug('spawn connect')
|
||||
self.log.info('spawn connect')
|
||||
self.client.spawn_connect(self.complete)
|
||||
|
||||
def get_setup(self):
|
||||
@@ -130,10 +130,10 @@ class SecNode:
|
||||
def complete(self):
|
||||
try:
|
||||
self.online = True
|
||||
self._status = 'completing'
|
||||
self.status = 'completing'
|
||||
self.nodename = self.client.nodename
|
||||
if self.log:
|
||||
self.log.debug('connected to %r', self.nodename)
|
||||
self.log.info('connected to %r', self.nodename)
|
||||
if self.complete_callback:
|
||||
if not self.cfg:
|
||||
if self.nodename == self.client.uri:
|
||||
@@ -147,19 +147,16 @@ class SecNode:
|
||||
self.complete_callback = None
|
||||
desc = self.client.properties.get('description') or self.nodename
|
||||
self.description = desc.split('\n')[0]
|
||||
self._status = 'connected'
|
||||
self.status = 'connected'
|
||||
except Exception as e:
|
||||
self.log.exception('connect failed')
|
||||
self._status = f'disconnected {e!r}'
|
||||
self.status = f'disconnected {e!r}'
|
||||
|
||||
def disconnect(self):
|
||||
self.online = False
|
||||
self._status = 'disconnecting'
|
||||
self.status = 'disconnecting'
|
||||
self.client.disconnect()
|
||||
self._status = 'disconnected'
|
||||
|
||||
def status(self):
|
||||
return self._status
|
||||
self.status = 'disconnected'
|
||||
|
||||
|
||||
def noop(*args):
|
||||
@@ -184,7 +181,6 @@ class NicosCache(Communicator):
|
||||
_sock = None
|
||||
|
||||
def doPoll(self):
|
||||
self.log.info('doPoll')
|
||||
if self._error:
|
||||
self.log.error('%r', self._error)
|
||||
self._error = None
|
||||
@@ -213,7 +209,6 @@ class NicosCache(Communicator):
|
||||
while True:
|
||||
try:
|
||||
self._connect(handler_lookup)
|
||||
self._error = 'connected'
|
||||
except Exception:
|
||||
self._error = formatExtendedTraceback()
|
||||
time.sleep(10)
|
||||
@@ -260,6 +255,7 @@ class SuperFrappy(HasIO, Readable):
|
||||
is_main_instrument = Property('this is the main instrument', BoolType(), default=True)
|
||||
value = Parameter('running servers', ArrayOf(secnodetype), default=())
|
||||
instance = Parameter('"this" or <instrument>', StringType())
|
||||
plugplay = Parameter('enable plug and play', BoolType(), readonly=False, default=False)
|
||||
nicos_setups = Parameter('active nicos se setups', ArrayOf(StringType()))
|
||||
_marche = None
|
||||
_secnodes = None # dict <host_post> of SecNode
|
||||
@@ -292,7 +288,7 @@ class SuperFrappy(HasIO, Readable):
|
||||
self.io.communicate(key + op + value)
|
||||
|
||||
def _handle_scripts(self, key, op, value):
|
||||
self.log.debug('scripts %r', value)
|
||||
self.log.info('scripts %r', value)
|
||||
if value:
|
||||
self._nicos_idle_since = None
|
||||
self.setFastPoll(False)
|
||||
@@ -303,19 +299,23 @@ class SuperFrappy(HasIO, Readable):
|
||||
|
||||
def _handle_setups(self, key, op, value):
|
||||
self._setups = set(value)
|
||||
self.log.debug('setups %r', value)
|
||||
self.log.info('setups %r', value)
|
||||
for secnode in self._secnodes.values():
|
||||
setup = secnode.get_setup()
|
||||
loaded = setup in self._setups
|
||||
pnp = self._current_plugplay.get(secnode.nodename)
|
||||
if loaded:
|
||||
if pnp is True:
|
||||
self._send_pnp_message(secnode.nodename, None, True)
|
||||
if self.plugplay:
|
||||
self._send_pnp_message(secnode.nodename, None, True)
|
||||
secnode.status = 'loaded'
|
||||
secnode.setup_was_loaded = True
|
||||
else:
|
||||
if pnp is False:
|
||||
self._send_pnp_message(secnode.nodename, None, False)
|
||||
if secnode.setup_was_loaded:
|
||||
if self.plugplay:
|
||||
self._send_pnp_message(secnode.nodename, None, False)
|
||||
if secnode.setup_was_loaded and secnode.host == 'localhost' or not secnode.client.online:
|
||||
secnode.status = 'to_close'
|
||||
self._to_close.add(secnode.host_port)
|
||||
|
||||
def _handle_plugplay(self, key, op, value):
|
||||
@@ -324,7 +324,7 @@ class SuperFrappy(HasIO, Readable):
|
||||
self._current_plugplay.pop(key, None)
|
||||
else:
|
||||
self._current_plugplay[key] = value
|
||||
self.log.debug('pnp %r', self._current_plugplay)
|
||||
self.log.info('pnp %r', self._current_plugplay)
|
||||
|
||||
def _write_setup_file(self, secnode):
|
||||
setup_file = Path(self.setupdir) / f'{secnode.get_setup()}.py'
|
||||
@@ -359,24 +359,26 @@ class SuperFrappy(HasIO, Readable):
|
||||
if secnode.announce_pnp is False:
|
||||
if self._nicos_idle_since:
|
||||
secnode.announce_pnp = None
|
||||
self._send_pnp_message(nodename, setup, False)
|
||||
if self.plugplay:
|
||||
self._send_pnp_message(nodename, setup, False)
|
||||
elif secnode.host_port not in self._to_close:
|
||||
secnode.announce_pnp = False
|
||||
else:
|
||||
if secnode.online:
|
||||
if not setup_file.is_file():
|
||||
self.log.debug('write_setup %r', secnode.cfg)
|
||||
self.log.info('write_setup %r', secnode.cfg)
|
||||
self._write_setup_file(secnode)
|
||||
if secnode.announce_pnp is True and self._nicos_idle_since:
|
||||
secnode.announce_pnp = None
|
||||
self._send_pnp_message(nodename, setup, True)
|
||||
if self.plugplay:
|
||||
self._send_pnp_message(nodename, setup, True)
|
||||
self._to_close.discard(secnode.host_port)
|
||||
for setup in self._setups:
|
||||
# do not delete active setups
|
||||
superfluous_setup_files.discard(Path(self.setupdir) / f'{setup}.py')
|
||||
reload_marche = bool(superfluous_cfg_files)
|
||||
for file in superfluous_setup_files | superfluous_cfg_files:
|
||||
self.log.debug('remove %s', file)
|
||||
self.log.info('remove %s', file)
|
||||
try:
|
||||
file.unlink()
|
||||
except FileNotFoundError:
|
||||
@@ -391,9 +393,9 @@ class SuperFrappy(HasIO, Readable):
|
||||
if msg:
|
||||
uri = msg['uri']
|
||||
if uri in self._secnodes:
|
||||
self.log.debug('%r is already known', msg)
|
||||
self.log.info('%r is already known', msg)
|
||||
else:
|
||||
self.log.debug('%r appeared', msg)
|
||||
self.log.info('%r appeared', msg)
|
||||
cfg = msg.get('device', '')
|
||||
if uri.startswith('localhost:') and cfg != 'superfrappy':
|
||||
self.connect(uri)
|
||||
@@ -411,7 +413,7 @@ class SuperFrappy(HasIO, Readable):
|
||||
def read_value(self):
|
||||
value = []
|
||||
for secnode in self._secnodes.values():
|
||||
info = {'cfg': secnode.cfg, 'uri': secnode.host_port, 'status': secnode.status()}
|
||||
info = {'cfg': secnode.cfg, 'uri': secnode.host_port, 'status': secnode.status}
|
||||
value.append(info)
|
||||
return value
|
||||
|
||||
@@ -442,9 +444,9 @@ class SuperFrappy(HasIO, Readable):
|
||||
host_port = normalizeuri(host_port, True)
|
||||
secnode = self._secnodes.get(host_port)
|
||||
if secnode:
|
||||
self.log.debug('already connected %r', host_port)
|
||||
self.log.info('already connected %r', host_port)
|
||||
else:
|
||||
self.log.debug('connect secnode %r', host_port)
|
||||
self.log.info('connect secnode %r', host_port)
|
||||
secnode = SecNode(host_port, self._marche.cfg_info.get(host_port, ''))
|
||||
self._secnodes[host_port] = secnode
|
||||
secnode.connect(log=self.log)
|
||||
@@ -474,13 +476,13 @@ class SuperFrappy(HasIO, Readable):
|
||||
:param service: 'stick', 'main', '' or a stringified port number
|
||||
:param cfg: config file or equipment id
|
||||
"""
|
||||
self.log.debug('add and start %r', cfg)
|
||||
self.log.info('add and start %r', cfg)
|
||||
port = self._marche.get_port(service)
|
||||
host_port = f'localhost:{port}'
|
||||
secnode = SecNode(host_port, cfg)
|
||||
self._secnodes[host_port] = secnode
|
||||
self._marche.add_frappy_service(service, secnode.cfg, secnode.port, self.log)
|
||||
self.log.debug('start %r at %r', secnode.cfg, host_port)
|
||||
self.log.info('start %r at %r', secnode.cfg, host_port)
|
||||
self._marche.start(secnode.cfg)
|
||||
secnode.connect(log=self.log)
|
||||
self.read_value()
|
||||
@@ -488,7 +490,7 @@ class SuperFrappy(HasIO, Readable):
|
||||
def _remove_secnode(self, secnode):
|
||||
secnode.announce = False
|
||||
secnode.disconnect()
|
||||
self.log.debug('secnode.host %r', secnode)
|
||||
self.log.info('secnode.host %r', secnode)
|
||||
if secnode.host == 'localhost':
|
||||
self._marche.stop(secnode.cfg)
|
||||
self._update()
|
||||
|
||||
@@ -27,7 +27,7 @@ import logging
|
||||
|
||||
|
||||
MARCHESRC = ['/home/software/marche']
|
||||
CFGDIRS = ['/home/linse/config', '/home/l_samenv/linse_config']
|
||||
# CFGDIRS = ['/home/linse/config', '/home/l_samenv/linse_config']
|
||||
|
||||
|
||||
def get_logger(previous=[]):
|
||||
@@ -144,8 +144,8 @@ class FrappyMarche(MarcheControl):
|
||||
def __init__(self, instance, host='localhost', port=None, user=None):
|
||||
parser = ConfigParser()
|
||||
parser.optionxform = str
|
||||
gencfg = f'~/.config/frappy/{instance}.cfg'
|
||||
parser.read([str(Path(gencfg).expanduser())])
|
||||
gencfg = '/sq_sw/linse/frappycfg/generalConfig.cfg'
|
||||
parser.read([gencfg])
|
||||
try:
|
||||
section = dict(parser['superfrappy'])
|
||||
except KeyError:
|
||||
@@ -208,6 +208,11 @@ class FrappyMarche(MarcheControl):
|
||||
return {sorted(v)[-1][-1]: k for k, v in result.items()}
|
||||
|
||||
def get_port(self, service):
|
||||
"""get a port number for service
|
||||
|
||||
return a predefined port number for 'main' and 'stick'
|
||||
or a free port number for 'addons'
|
||||
"""
|
||||
if service not in {'main', 'stick', 'addons', 'addon'}:
|
||||
raise ValueError('illegal service argument')
|
||||
ports = self.get_std_port(service)
|
||||
|
||||
Reference in New Issue
Block a user