inform user about possible device change
taking into account cfg retrieved from frappy and sea service manager
This commit is contained in:
206
commands.py
206
commands.py
@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# *****************************************************************************
|
# *****************************************************************************
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
@ -20,124 +19,15 @@
|
|||||||
#
|
#
|
||||||
# *****************************************************************************
|
# *****************************************************************************
|
||||||
|
|
||||||
import sys
|
|
||||||
from os.path import expanduser, basename, join
|
|
||||||
from configparser import ConfigParser
|
|
||||||
|
|
||||||
from nicos import session, config
|
from nicos import session, config
|
||||||
from nicos.core import status
|
|
||||||
from nicos.utils import printTable
|
from nicos.utils import printTable
|
||||||
from nicos.commands import helparglist, usercommand
|
from nicos.commands import helparglist, usercommand
|
||||||
from nicos.commands.basic import AddSetup, CreateAllDevices, CreateDevice
|
|
||||||
from nicos.devices.secop.devices import get_attaching_devices
|
|
||||||
from nicos_sinq.frappy_sinq.devices import applyAliasConfig, FrappyNode
|
|
||||||
|
|
||||||
|
|
||||||
home = expanduser('~')
|
|
||||||
if home not in sys.path:
|
|
||||||
# the first Frappy installations have /home/nicos in the PYTHONPATH in nicos.conf
|
|
||||||
# for newer Frappy installations this should be home (= /home/<instrument>)
|
|
||||||
# the following line fixes this in case nicos.conf is not yet updated
|
|
||||||
sys.path.append(home)
|
|
||||||
from servicemanager import FrappyManager
|
from servicemanager import FrappyManager
|
||||||
|
|
||||||
|
|
||||||
def cleanup_defunct():
|
|
||||||
for devname, setupname in list(session.dynamic_devices.items()):
|
|
||||||
dev = session.devices.get(devname)
|
|
||||||
if dev and dev._defunct:
|
|
||||||
devnames = [d.name for d, _ in get_attaching_devices(dev)]
|
|
||||||
if devnames:
|
|
||||||
session.log.warning('can not remove device %r due to dependencies on %s'
|
|
||||||
% (devname, ', '.join(devnames)))
|
|
||||||
else:
|
|
||||||
session.destroyDevice(devname)
|
|
||||||
session.dynamic_devices.pop(devname, None)
|
|
||||||
|
|
||||||
|
|
||||||
SERVICES = FrappyManager.services
|
SERVICES = FrappyManager.services
|
||||||
|
|
||||||
|
|
||||||
def all_info(all_cfg):
|
|
||||||
info = []
|
|
||||||
addkwd = False
|
|
||||||
for srv in SERVICES:
|
|
||||||
cfginfo = all_cfg.get(srv)
|
|
||||||
if cfginfo is None:
|
|
||||||
addkwd = True
|
|
||||||
elif addkwd:
|
|
||||||
info.append('%s=%r' % (srv, cfginfo))
|
|
||||||
else:
|
|
||||||
info.append(repr(cfginfo))
|
|
||||||
result = 'frappy(%s)' % ', '.join(info)
|
|
||||||
if '?' in result:
|
|
||||||
result += ' (?: device from sea has no frappy cfg file)'
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def frappy_start(**services):
|
|
||||||
"""start/stop frappy servers
|
|
||||||
|
|
||||||
for example: frappy_start(main='xy', stick='')
|
|
||||||
- restart main server with cfg='xy'
|
|
||||||
- stop stick server
|
|
||||||
- do not touch addons server
|
|
||||||
|
|
||||||
in addition, if a newly given cfg is already used on a running server,
|
|
||||||
this cfg is removed from the server (remark: cfg might be a comma separated list)
|
|
||||||
"""
|
|
||||||
frappy_config = session.devices.get('frappy_config')
|
|
||||||
for service in SERVICES:
|
|
||||||
if services.get(service) == '':
|
|
||||||
seaconn = session.devices.get(f'se_sea_{service}')
|
|
||||||
if seaconn and seaconn._attached_secnode:
|
|
||||||
seaconn.communicate('frappy_remove %s' % service)
|
|
||||||
used_cfg = {}
|
|
||||||
all_cfg = {}
|
|
||||||
new_cfg = []
|
|
||||||
remove_cfg = []
|
|
||||||
for service in reversed(SERVICES):
|
|
||||||
secnode = session.devices.get('se_' + service)
|
|
||||||
cfginfo = services.get(service)
|
|
||||||
if cfginfo is not None:
|
|
||||||
if cfginfo:
|
|
||||||
new_cfg.append((service, secnode, cfginfo))
|
|
||||||
else:
|
|
||||||
remove_cfg.append(secnode)
|
|
||||||
if secnode:
|
|
||||||
secnode('')
|
|
||||||
if secnode:
|
|
||||||
all_cfg[service] = secnode.get_info()
|
|
||||||
|
|
||||||
# check cfg is not used twice
|
|
||||||
for cfg in (cfginfo or '').split(','):
|
|
||||||
cfg = cfg.strip()
|
|
||||||
if cfg:
|
|
||||||
prev = used_cfg.get(cfg)
|
|
||||||
if prev:
|
|
||||||
raise ValueError('%r can not be used in both %s and %s' % (cfg, prev, service))
|
|
||||||
used_cfg[cfg] = service
|
|
||||||
|
|
||||||
if new_cfg:
|
|
||||||
for service, secnode, cfginfo in new_cfg:
|
|
||||||
nodename = 'se_' + service
|
|
||||||
if not secnode:
|
|
||||||
AddSetup('frappy_' + service)
|
|
||||||
secnode = session.devices[nodename]
|
|
||||||
secnode(cfginfo)
|
|
||||||
all_cfg[service] = secnode.get_info()
|
|
||||||
CreateDevice(nodename)
|
|
||||||
cleanup_defunct()
|
|
||||||
CreateAllDevices()
|
|
||||||
if frappy_config:
|
|
||||||
frappy_config.set_envlist()
|
|
||||||
else:
|
|
||||||
applyAliasConfig()
|
|
||||||
for secnode in remove_cfg:
|
|
||||||
secnode.disable()
|
|
||||||
return all_cfg
|
|
||||||
|
|
||||||
|
|
||||||
@usercommand
|
@usercommand
|
||||||
def set_se_list():
|
def set_se_list():
|
||||||
frappy_config = session.devices['frappy_config']
|
frappy_config = session.devices['frappy_config']
|
||||||
@ -146,34 +36,37 @@ def set_se_list():
|
|||||||
|
|
||||||
@usercommand
|
@usercommand
|
||||||
@helparglist('main [, stick [, addons]]')
|
@helparglist('main [, stick [, addons]]')
|
||||||
def frappy(*args, main=None, stick=None, addons=None):
|
def frappy(*args, main=None, stick=None, addons=None, force=False):
|
||||||
"""(re)start frappy server(s) with given configs and load setup if needed
|
"""(re)start frappy server(s) with given configs and load setup if needed
|
||||||
|
|
||||||
- without argument: list running frappy servers, restart failed frappy servers
|
- without argument: list running frappy servers, restart failed frappy servers
|
||||||
- frappy('<cfg>'): if available, the standard stick is added too
|
- frappy('<cfg>'): if available, the standard stick is added too
|
||||||
- frappy(''): the stick is removed too
|
- frappy(''): the stick is removed too
|
||||||
- addons are not changed when not given
|
- addons are not changed when not given
|
||||||
- frappy(main='<cfg>') # main cfg is changed, but stick is kept
|
- frappy(main='<cfg>') # main cfg is changed, but stick is kept
|
||||||
|
- frappy('restart') # restart all frappy servers
|
||||||
|
- frappy(stick='restart') # restart stick frappy server
|
||||||
"""
|
"""
|
||||||
seacfg = FrappyManager().cfg_from_sea(config.instrument)
|
confirmed = FrappyManager().cfg_from_sea(config.instrument).get('confirmed')
|
||||||
if args:
|
if args:
|
||||||
if main is not None:
|
if main is not None:
|
||||||
raise TypeError('got multiple values for main')
|
raise TypeError('got multiple values for main')
|
||||||
main = args[0]
|
main = args[0]
|
||||||
if len(args) == 1: # special case: main given as single argument
|
if len(args) == 1: # special case: main given as single argument
|
||||||
if stick is None: # auto stick
|
if main == 'restart':
|
||||||
|
stick = 'restart'
|
||||||
|
addons = 'restart'
|
||||||
|
elif stick is None: # auto stick
|
||||||
if main == '':
|
if main == '':
|
||||||
stick = '' # remove stick with main
|
stick = '' # remove stick with main
|
||||||
else:
|
else:
|
||||||
allsticks = FrappyManager().all_cfg(config.instrument, 'stick')
|
allsticks = FrappyManager().all_cfg(config.instrument, 'stick')
|
||||||
if seacfg.get('main') != main:
|
stickcfg = main + 'stick'
|
||||||
# main sea device has changed
|
if stickcfg in allsticks:
|
||||||
stickcfg = main + 'stick'
|
# if a default stick is available, start this also
|
||||||
if stickcfg in allsticks:
|
stick = stickcfg
|
||||||
# if a default stick is available, start this also
|
else:
|
||||||
stick = stickcfg
|
stick = '' # remove stick when main has changed
|
||||||
else:
|
|
||||||
stick = '' # remove stick when main has changed
|
|
||||||
else:
|
else:
|
||||||
if stick is not None:
|
if stick is not None:
|
||||||
raise TypeError('got multiple values for stick')
|
raise TypeError('got multiple values for stick')
|
||||||
@ -182,63 +75,12 @@ def frappy(*args, main=None, stick=None, addons=None):
|
|||||||
if addons is not None:
|
if addons is not None:
|
||||||
raise TypeError('got multiple values for addons')
|
raise TypeError('got multiple values for addons')
|
||||||
addons = ','.join(alist)
|
addons = ','.join(alist)
|
||||||
allcfg = frappy_start(main=main, stick=stick, addons=addons)
|
if confirmed and confirmed != main and not force:
|
||||||
session.log.info('currently configured %s', all_info(allcfg))
|
session.log.warning('%r is plugged to the cryostat control rack', confirmed)
|
||||||
else:
|
session.log.warning('if you are sure, use frappy(..., force=True)', confirmed)
|
||||||
allcfg = frappy_start(main=main, stick=stick, addons=addons)
|
raise TypeError('refuse to override plugged device')
|
||||||
session.log.info('currently configured %s', all_info(allcfg))
|
frappy_config = session.devices['frappy_config']
|
||||||
guess1 = {}
|
frappy_config.show_config(*frappy_config.check_or_start(main, stick, addons))
|
||||||
guess2 = {}
|
|
||||||
for s in SERVICES:
|
|
||||||
info = allcfg.get(s, '')
|
|
||||||
prev = info.split(' ', 1)[0]
|
|
||||||
if prev != info:
|
|
||||||
guess1[s] = prev
|
|
||||||
guess2[s] = prev
|
|
||||||
fromsea = seacfg.get(s)
|
|
||||||
if fromsea and fromsea != prev:
|
|
||||||
guess2[s] = fromsea
|
|
||||||
if guess1 and guess2:
|
|
||||||
session.log.info('please consider to call one of:')
|
|
||||||
elif guess1 or guess2:
|
|
||||||
session.log.info('please consider to call:')
|
|
||||||
if guess1:
|
|
||||||
session.log.info('from frappy / cache: %s', all_info(guess1))
|
|
||||||
if guess2:
|
|
||||||
session.log.info('including info from sea: %s', all_info(guess2))
|
|
||||||
|
|
||||||
|
|
||||||
@usercommand
|
|
||||||
@helparglist('cfg')
|
|
||||||
def frappy_main(cfg=None):
|
|
||||||
"""(re)start frappy_main server with given cfg and load setup if needed
|
|
||||||
|
|
||||||
- without argument: list running frappy servers
|
|
||||||
- cfg = "": stop frappy_main server
|
|
||||||
"""
|
|
||||||
session.log.info('currently configured %s', all_info(frappy_start(main=cfg)))
|
|
||||||
|
|
||||||
|
|
||||||
@usercommand
|
|
||||||
@helparglist('cfg')
|
|
||||||
def frappy_stick(cfg=None):
|
|
||||||
"""(re)start frappy_stick server with given cfg and load setup if needed
|
|
||||||
|
|
||||||
- without argument: list running frappy servers
|
|
||||||
- cfg = "": stop frappy_stick server
|
|
||||||
"""
|
|
||||||
session.log.info('currently configured %s', all_info(frappy_start(stick=cfg)))
|
|
||||||
|
|
||||||
|
|
||||||
@usercommand
|
|
||||||
@helparglist('cfg,...')
|
|
||||||
def frappy_addons(cfg=None):
|
|
||||||
"""(re)start frappy_addons server with given cfg and load setup if needed
|
|
||||||
|
|
||||||
- without argument: list running frappy servers
|
|
||||||
- cfg = "": stop frappy_addons server
|
|
||||||
"""
|
|
||||||
session.log.info('currently configured %s', all_info(frappy_start(addons=cfg)))
|
|
||||||
|
|
||||||
|
|
||||||
@usercommand
|
@usercommand
|
||||||
@ -250,8 +92,6 @@ def frappy_list(service=None):
|
|||||||
def prt(line):
|
def prt(line):
|
||||||
content.append(line)
|
content.append(line)
|
||||||
|
|
||||||
# TODO: remove next line
|
|
||||||
bases = list(dict.fromkeys(expanduser(p) for p in FrappyNode.config_dirs(config.instrument, service or 'main')))
|
|
||||||
if service is None:
|
if service is None:
|
||||||
prt('Available configuration files')
|
prt('Available configuration files')
|
||||||
prt('')
|
prt('')
|
||||||
@ -265,3 +105,7 @@ def frappy_list(service=None):
|
|||||||
FrappyManager().do_listcfg(config.instrument, service or 'main', prt)
|
FrappyManager().do_listcfg(config.instrument, service or 'main', prt)
|
||||||
session.log.info('\n%s', '\n'.join(content))
|
session.log.info('\n%s', '\n'.join(content))
|
||||||
|
|
||||||
|
|
||||||
|
@usercommand
|
||||||
|
def frappy_changed():
|
||||||
|
session.devices['frappy_config'].changed()
|
||||||
|
221
devices.py
221
devices.py
@ -27,16 +27,21 @@ SEC Node with added functionality for starting and stopping frappy servers
|
|||||||
connected to a SEC node
|
connected to a SEC node
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import time
|
||||||
from os.path import expanduser
|
import threading
|
||||||
|
|
||||||
from nicos import config, session
|
from nicos import config, session
|
||||||
from nicos.core import Override, Param, Moveable, status, POLLER, SIMULATION, DeviceAlias
|
from nicos.core import Override, Param, Moveable, status, POLLER, SIMULATION, DeviceAlias, \
|
||||||
|
Device, anytype, listof
|
||||||
from nicos.devices.secop.devices import SecNodeDevice
|
from nicos.devices.secop.devices import SecNodeDevice
|
||||||
from nicos.core import Device, anytype, listof
|
from nicos.core.utils import USER, User, createThread
|
||||||
|
from nicos.services.daemon.script import RequestError, ScriptRequest
|
||||||
from nicos.utils.comparestrings import compare
|
from nicos.utils.comparestrings import compare
|
||||||
|
from nicos.devices.secop.devices import get_attaching_devices
|
||||||
|
from nicos.commands.basic import AddSetup, CreateAllDevices, CreateDevice
|
||||||
from servicemanager import FrappyManager
|
from servicemanager import FrappyManager
|
||||||
|
|
||||||
|
SERVICES = FrappyManager.services
|
||||||
|
|
||||||
|
|
||||||
def suggest(poi, allowed_keys):
|
def suggest(poi, allowed_keys):
|
||||||
comp = {}
|
comp = {}
|
||||||
@ -67,6 +72,48 @@ def applyAliasConfig():
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_defunct():
|
||||||
|
for devname, setupname in list(session.dynamic_devices.items()):
|
||||||
|
dev = session.devices.get(devname)
|
||||||
|
if dev and dev._defunct:
|
||||||
|
devnames = [d.name for d, _ in get_attaching_devices(dev)]
|
||||||
|
if devnames:
|
||||||
|
session.log.warning('can not remove device %r due to dependencies on %s'
|
||||||
|
% (devname, ', '.join(devnames)))
|
||||||
|
else:
|
||||||
|
session.destroyDevice(devname)
|
||||||
|
session.dynamic_devices.pop(devname, None)
|
||||||
|
|
||||||
|
|
||||||
|
def all_info(all_cfg, prefix='currently configured: '):
|
||||||
|
info = []
|
||||||
|
addkwd = False
|
||||||
|
for srv in SERVICES:
|
||||||
|
cfginfo = all_cfg.get(srv)
|
||||||
|
if cfginfo is None:
|
||||||
|
addkwd = True
|
||||||
|
elif addkwd:
|
||||||
|
info.append('%s=%r' % (srv, cfginfo))
|
||||||
|
else:
|
||||||
|
info.append(repr(cfginfo))
|
||||||
|
return f"{prefix}frappy({', '.join(info)})"
|
||||||
|
|
||||||
|
|
||||||
|
def get_guess(allcfg):
|
||||||
|
guess = {}
|
||||||
|
seacfg = FrappyManager().cfg_from_sea(config.instrument)
|
||||||
|
guess.pop('confirmed', '')
|
||||||
|
for s in ('main', 'stick', 'addons'):
|
||||||
|
info = allcfg.get(s, '')
|
||||||
|
prev = info.split(' ', 1)[0]
|
||||||
|
if prev != info:
|
||||||
|
guess[s] = prev
|
||||||
|
fromsea = seacfg.get(s)
|
||||||
|
if fromsea and fromsea != prev:
|
||||||
|
guess[s] = fromsea
|
||||||
|
return guess
|
||||||
|
|
||||||
|
|
||||||
class FrappyConfig(Device):
|
class FrappyConfig(Device):
|
||||||
# respect the order: e.g. temperature_regulation must be after temperature
|
# respect the order: e.g. temperature_regulation must be after temperature
|
||||||
# because it will not be added to envlist when temperature is the same device
|
# because it will not be added to envlist when temperature is the same device
|
||||||
@ -92,6 +139,121 @@ class FrappyConfig(Device):
|
|||||||
|
|
||||||
meanings = list(parameters)
|
meanings = list(parameters)
|
||||||
meanings.remove('nodes')
|
meanings.remove('nodes')
|
||||||
|
_trigger_change = None
|
||||||
|
_previous_shown = None
|
||||||
|
|
||||||
|
def doInit(self, mode):
|
||||||
|
if mode != SIMULATION and session.sessiontype != POLLER:
|
||||||
|
self._trigger_change = threading.Event()
|
||||||
|
createThread('frappy change notification', self.handle_notifications)
|
||||||
|
|
||||||
|
def handle_notifications(self):
|
||||||
|
try:
|
||||||
|
controller = session.daemon_device._controller
|
||||||
|
while True:
|
||||||
|
self._trigger_change.wait()
|
||||||
|
self._trigger_change.clear()
|
||||||
|
time.sleep(2)
|
||||||
|
if self._trigger_change.is_set():
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
current = self.check_or_start()
|
||||||
|
if current != self._previous_shown:
|
||||||
|
cmd = 'frappy_changed()'
|
||||||
|
controller.new_request(ScriptRequest(cmd, None, User('guest', USER)))
|
||||||
|
except RequestError as e:
|
||||||
|
session.log.error(f'can not queue request {e!r}')
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
def check_or_start(self, main=None, stick=None, addons=None):
|
||||||
|
"""start/stop frappy servers
|
||||||
|
|
||||||
|
for example: check_or_start(main='xy', stick='')
|
||||||
|
- restart main server with cfg='xy'
|
||||||
|
- stop stick server
|
||||||
|
- do not touch addons server
|
||||||
|
|
||||||
|
in addition, if a newly given cfg is already used on a running server,
|
||||||
|
this cfg is removed from the server (remark: cfg might be a comma separated list)
|
||||||
|
"""
|
||||||
|
services = {'main': main, 'stick': stick, 'addons': addons}
|
||||||
|
for service, cfg in services.items():
|
||||||
|
if cfg == '':
|
||||||
|
seaconn = session.devices.get(f'se_sea_{service}')
|
||||||
|
if seaconn and seaconn._attached_secnode:
|
||||||
|
seaconn.communicate('frappy_remove %s' % service)
|
||||||
|
used_cfg = {}
|
||||||
|
all_cfg = {}
|
||||||
|
new_cfg = {}
|
||||||
|
secnodes = {}
|
||||||
|
remove_cfg = []
|
||||||
|
for service, cfginfo in services.items():
|
||||||
|
secnodes[service] = secnode = session.devices.get('se_' + service)
|
||||||
|
chkinfo = ''
|
||||||
|
if secnode:
|
||||||
|
all_cfg[service] = chkinfo = secnode.get_info()
|
||||||
|
if cfginfo is not None:
|
||||||
|
new_cfg[service] = chkinfo = cfginfo
|
||||||
|
|
||||||
|
# check cfg is not used twice
|
||||||
|
for cfg in chkinfo.split(','):
|
||||||
|
cfg = cfg.strip()
|
||||||
|
if cfg and cfg != 'restart':
|
||||||
|
prev = used_cfg.get(cfg)
|
||||||
|
if prev:
|
||||||
|
raise ValueError('%r can not be used in both %s and %s' % (cfg, prev, service))
|
||||||
|
used_cfg[cfg] = service
|
||||||
|
|
||||||
|
for service, cfginfo in reversed(list(new_cfg.items())):
|
||||||
|
if cfginfo != all_cfg.get(service, ''):
|
||||||
|
secnode = secnodes[service]
|
||||||
|
if secnode:
|
||||||
|
secnode('') # stop previous frappy server
|
||||||
|
|
||||||
|
if new_cfg:
|
||||||
|
for service, cfginfo in new_cfg.items():
|
||||||
|
nodename = 'se_' + service
|
||||||
|
secnode = secnodes[service]
|
||||||
|
prev = all_cfg.get(service)
|
||||||
|
if cfginfo != prev:
|
||||||
|
if cfginfo == 'restart':
|
||||||
|
cfginfo = prev
|
||||||
|
if not cfginfo:
|
||||||
|
continue
|
||||||
|
if not secnode:
|
||||||
|
if not cfginfo:
|
||||||
|
continue
|
||||||
|
AddSetup('frappy_' + service)
|
||||||
|
secnode = session.devices[nodename]
|
||||||
|
secnode(cfginfo)
|
||||||
|
all_cfg[service] = secnode.get_info()
|
||||||
|
CreateDevice(nodename)
|
||||||
|
cleanup_defunct()
|
||||||
|
CreateAllDevices()
|
||||||
|
self.set_envlist()
|
||||||
|
for secnode in remove_cfg:
|
||||||
|
secnode.disable()
|
||||||
|
return all_cfg, get_guess(all_cfg)
|
||||||
|
|
||||||
|
def show_config(self, allcfg, guess):
|
||||||
|
# remove 'frappy_changed()' commands in script queue
|
||||||
|
controller = session.daemon_device._controller
|
||||||
|
controller.block_requests(r['reqid'] for r in controller.get_queue() if r['script'] == 'frappy_changed()')
|
||||||
|
self._previous_shown = allcfg, guess
|
||||||
|
session.log.info(all_info(allcfg))
|
||||||
|
if guess:
|
||||||
|
info = all_info(guess, '')
|
||||||
|
session.log.warning('please consider to call:')
|
||||||
|
session.log.info(info)
|
||||||
|
if '?' in info:
|
||||||
|
session.log.warning("but create cfg files first for items marked with '?'")
|
||||||
|
|
||||||
|
def changed(self):
|
||||||
|
current = self.check_or_start()
|
||||||
|
#if current == self._previous_shown:
|
||||||
|
# return
|
||||||
|
self.show_config(*current)
|
||||||
|
|
||||||
def remove_aliases(self):
|
def remove_aliases(self):
|
||||||
for meaning in self.meanings:
|
for meaning in self.meanings:
|
||||||
@ -135,7 +297,10 @@ class FrappyConfig(Device):
|
|||||||
continue
|
continue
|
||||||
for devname, (_, desc) in nodedev.setup_info.items():
|
for devname, (_, desc) in nodedev.setup_info.items():
|
||||||
secop_module = desc['secop_module']
|
secop_module = desc['secop_module']
|
||||||
meaning = secnode.modules[secop_module]['properties'].get('meaning')
|
try:
|
||||||
|
meaning = secnode.modules[secop_module]['properties'].get('meaning')
|
||||||
|
except KeyError:
|
||||||
|
meaning = None
|
||||||
if meaning:
|
if meaning:
|
||||||
meaning_name, importance = meaning
|
meaning_name, importance = meaning
|
||||||
sample_devices.setdefault(meaning_name, []).append((importance, devname))
|
sample_devices.setdefault(meaning_name, []).append((importance, devname))
|
||||||
@ -230,6 +395,7 @@ class FrappyNode(SecNodeDevice, Moveable):
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cfgvalue = None
|
_cfgvalue = None
|
||||||
|
_lastcfg = None
|
||||||
|
|
||||||
def doStart(self, value):
|
def doStart(self, value):
|
||||||
if value == 'None':
|
if value == 'None':
|
||||||
@ -241,17 +407,18 @@ class FrappyNode(SecNodeDevice, Moveable):
|
|||||||
|
|
||||||
def doInit(self, mode):
|
def doInit(self, mode):
|
||||||
if mode != SIMULATION and session.sessiontype != POLLER:
|
if mode != SIMULATION and session.sessiontype != POLLER:
|
||||||
cfg = self.doRead()
|
self._lastcfg = self.doRead()
|
||||||
self.restart(cfg, False) # do not restart when not changed
|
self.restart(self._lastcfg, False) # do not restart when not changed
|
||||||
super().doInit(mode)
|
super().doInit(mode)
|
||||||
|
|
||||||
def doRead(self, maxage=0):
|
def doRead(self, maxage=0):
|
||||||
try:
|
try:
|
||||||
return self.secnode.descriptive_data['_frappy_config']
|
if self._secnode.online:
|
||||||
|
return self._secnode.descriptive_data['_frappy_config']
|
||||||
except (KeyError, AttributeError):
|
except (KeyError, AttributeError):
|
||||||
pass
|
pass
|
||||||
if self._cfgvalue is None:
|
if self._cfgvalue is None:
|
||||||
sea_cfg = FrappyManager().cfg_from_sea(config.instrument).get(self.service)
|
sea_cfg = FrappyManager().cfg_from_sea(config.instrument).get(self.service)
|
||||||
if sea_cfg:
|
if sea_cfg:
|
||||||
return sea_cfg
|
return sea_cfg
|
||||||
if self._cache:
|
if self._cache:
|
||||||
@ -259,7 +426,10 @@ class FrappyNode(SecNodeDevice, Moveable):
|
|||||||
return self._cfgvalue
|
return self._cfgvalue
|
||||||
|
|
||||||
def createDevices(self):
|
def createDevices(self):
|
||||||
|
cfg = self.read()
|
||||||
super().createDevices()
|
super().createDevices()
|
||||||
|
if cfg != self._lastcfg:
|
||||||
|
session.devices.get('frappy_config')._trigger_change.set()
|
||||||
if self.param_category:
|
if self.param_category:
|
||||||
for devname, (_, devcfg) in self.setup_info.items():
|
for devname, (_, devcfg) in self.setup_info.items():
|
||||||
params_cfg = devcfg['params_cfg']
|
params_cfg = devcfg['params_cfg']
|
||||||
@ -269,23 +439,14 @@ class FrappyNode(SecNodeDevice, Moveable):
|
|||||||
if not pinfo.category:
|
if not pinfo.category:
|
||||||
pinfo.category = self.param_category
|
pinfo.category = self.param_category
|
||||||
|
|
||||||
@classmethod
|
def nodeStateChange(self, online, state):
|
||||||
def config_dirs(cls, ins, service):
|
super().nodeStateChange(online, state)
|
||||||
# TODO: no more needed after allowing ~cfg in FrappyManager.do_start
|
if not online:
|
||||||
return FrappyManager().config_dirs(ins, service)
|
self._cfgvalue = None
|
||||||
|
cfg = self.read()
|
||||||
@classmethod
|
if self._lastcfg != cfg:
|
||||||
def available_cfg(cls, service):
|
self._lastcfg = cfg
|
||||||
# TODO: no more needed after allowing ~cfg in FrappyManager.do_start
|
session.devices.get('frappy_config')._trigger_change.set()
|
||||||
ins = config.instrument
|
|
||||||
available_cfg = set()
|
|
||||||
for d in cls.config_dirs(ins, service):
|
|
||||||
try:
|
|
||||||
# available_cfg |= set(c[:-4] for c in os.listdir(expanduser(d)) if c.endswith('.cfg'))
|
|
||||||
available_cfg |= set(c[:-7] for c in os.listdir(expanduser(d)) if c.endswith('_cfg.py'))
|
|
||||||
except FileNotFoundError: # ignore missing directories
|
|
||||||
pass
|
|
||||||
return available_cfg
|
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
seaconn = session.devices.get('sea_%s' % self.service)
|
seaconn = session.devices.get('sea_%s' % self.service)
|
||||||
@ -315,12 +476,12 @@ class FrappyNode(SecNodeDevice, Moveable):
|
|||||||
fm.get_procs(cfginfo=cfginfo)
|
fm.get_procs(cfginfo=cfginfo)
|
||||||
running_cfg = cfginfo.get((ins, self.service), '')
|
running_cfg = cfginfo.get((ins, self.service), '')
|
||||||
if not forced:
|
if not forced:
|
||||||
sea_cfg = fm.cfg_from_sea(ins).get(self.service)
|
sea_cfg = fm.cfg_from_sea(ins).get(self.service, '')
|
||||||
if '?' in sea_cfg:
|
if '?' in sea_cfg:
|
||||||
if sea_cfg == '?':
|
if sea_cfg == '?':
|
||||||
self.log.warning('undefined sea device')
|
self.log.warning('undefined sea device')
|
||||||
else:
|
else:
|
||||||
self.log.warning(f"missing frappy cfg file for {sea_cfg.replace('?', ''))}")
|
self.log.warning(f"missing frappy cfg file for {sea_cfg.replace('?', '')}")
|
||||||
cfg = '' # stop server
|
cfg = '' # stop server
|
||||||
elif sea_cfg:
|
elif sea_cfg:
|
||||||
cfg = sea_cfg
|
cfg = sea_cfg
|
||||||
@ -335,7 +496,7 @@ class FrappyNode(SecNodeDevice, Moveable):
|
|||||||
fm.do_stop(ins, self.service)
|
fm.do_stop(ins, self.service)
|
||||||
is_cfg = cfg and ':' not in cfg
|
is_cfg = cfg and ':' not in cfg
|
||||||
if is_cfg:
|
if is_cfg:
|
||||||
available_cfg = self.available_cfg(self.service)
|
available_cfg = FrappyManager().all_cfg(config.instrument, self.service)
|
||||||
failed = False
|
failed = False
|
||||||
for cfgitem in cfg.split(','):
|
for cfgitem in cfg.split(','):
|
||||||
if cfgitem not in available_cfg:
|
if cfgitem not in available_cfg:
|
||||||
|
Reference in New Issue
Block a user