59 Commits
linse ... tmp

Author SHA1 Message Date
89d9e184bc unify Frappy.show and Frappy.show_state
+ fix indentation
2024-12-03 14:56:50 +01:00
423366a5c5 improve meaning handling
- Moveables with meaning 'temperature' are added to
  the 'temperature_regulation' target list
- Devices with meaning 'temperature_regulation' are added
  to 'temperature' target list, but with much lower priority
  (should be considered only when no sample quantity is detected)
2024-12-03 11:47:22 +01:00
d06b552526 FrappyConfig.__call__: fix bug when main is None 2024-12-03 11:47:22 +01:00
dmc
4f1834105b fix meaning bug 2024-12-03 11:47:22 +01:00
84f70f8204 improve mechanism to determine aliases
- meanings from name guessing has sligthly lower importance then
  given meanings
- then temperature meaning is missing, take temperature_regulation
2024-12-03 11:47:22 +01:00
771e0fdce7 improve config guess 2024-12-03 11:47:22 +01:00
dmc
2189323983 try to avoid 'None' as target
use '-' instead
2024-12-03 11:47:21 +01:00
cbb857f439 try to treat FrappyNode.target == 'None' properly 2024-12-03 11:47:21 +01:00
d30bb11bc1 do not show fm.error
as it will flood log output

- how to handle this properly?
2024-12-03 11:47:21 +01:00
0869f8b5d9 no warning 'does not match target' while restarting 2024-12-03 11:47:21 +01:00
173ef914d7 fix 2 issues with starting stopping
- secnode devices were not disconnected before stopping
  leading to error messages
- target of secnodes not properly updated
2024-12-03 11:47:21 +01:00
l_samenv
cb99a73935 FrappyNode.doInit must super call SecNodeDevice.doInit 2024-12-03 11:47:21 +01:00
666cefb6a6 fix error with predef_aliases 2024-12-03 11:47:21 +01:00
4e260decb4 FrappyNode.target must be set after stop but before restart 2024-12-03 11:47:21 +01:00
163e0194b1 FrappyNode.target must be set before restarting servers 2024-12-03 11:47:21 +01:00
81dd4aad23 fix envlist calculation
+ fix pathed loggers mechanism
2024-12-03 11:47:21 +01:00
62da0bd55e add timestamp and ppms setups 2024-12-03 11:47:21 +01:00
a5f6047b75 frappy.show: do not show nicos column if equal to frappy 2024-12-03 11:47:21 +01:00
3cec0ea357 frappy.show_state: do not show partial status 2024-12-03 11:47:21 +01:00
3c41e7cf0c nicer output of server state
- more outstanding output of frappy server state
- frappy() does now alse an update if needed
- frappy.show() to show state only
2024-12-03 11:47:21 +01:00
2dcf8f0cc3 improve detect_changes
check also if envlist and aliases have to be rebuilt
2024-12-03 11:47:21 +01:00
24d76e4d2d [wip] auto sample environment change, basic version 2024-12-03 11:47:21 +01:00
5bd6eeff98 frappy.has_changed() should not be triggered repeatedly
fix bug
2024-12-03 11:47:21 +01:00
57e6a73599 rework frappy to be a device instead of a command
+ improve proposed config mechanism
2024-12-03 11:47:21 +01:00
5d2e4aeedd fix bad prefix in frappy_main setup 2024-12-03 11:47:21 +01:00
0e9216629b se_ prefix may be override by SE_PREFIX env var. 2024-12-03 11:45:14 +01:00
b978489695 improve frappy() command
- only informational effect without arguments
- consider also cfg from sea
- on nicos restart, frappy nodes look also for sea device
2024-12-03 11:45:14 +01:00
0642ab7d09 remove disconnected from state 2023-10-17 14:38:48 +02:00
7b08743a3f add proposed into state 2023-10-17 14:37:19 +02:00
062341ab8a better text 2023-10-17 14:23:48 +02:00
2c01121ccc catch error when shutting frappy (sea remove) 2023-10-17 14:18:34 +02:00
03359d5b15 add disconnected services to proposed 2023-10-17 14:07:59 +02:00
9b56a6fb95 fix clearing target on secnode 2023-10-17 14:00:28 +02:00
15cefee221 set secnode target to '' on disconnect 2023-10-17 13:59:16 +02:00
9e489d8cfd [WIP] fix disconencted info 2023-10-17 13:55:52 +02:00
b97eff8afb [WIP] add <disconnected> info 2023-10-17 13:54:36 +02:00
aa40e0255b [WIP} add frappy.update() 2023-10-17 13:39:55 +02:00
15a839bf6c add frappy.has_changed() to startup 2023-10-17 13:07:57 +02:00
91dde94e24 [WIP] remove givencfgs from result 2023-10-17 13:07:40 +02:00
ee56a23d0b [WIP] bug fix 2023-10-17 12:54:54 +02:00
f5ac31f25f [WIP] add 'server' to title line 2023-10-17 11:29:13 +02:00
a54a4054d9 [WIP] do not show given column 2023-10-17 11:21:36 +02:00
da56f6da6d [WIP] fix call to to_consider in handle_notifcations 2023-10-17 11:17:58 +02:00
04b5c1921b [WIP] remove 'strict' arg 2023-10-17 11:04:33 +02:00
45fd71077c [WIP] use get_server_state instead of propose_cfgs 2023-10-17 11:02:27 +02:00
0edda9f5c8 [WIP] show server state at startup only when initial guess failed 2023-10-17 08:40:11 +02:00
0f39271ff1 [WIP] fix 'auto' type 2023-10-17 08:28:34 +02:00
093b27804c [WIP] show_server_state arg for frappy.has_changed() 2023-10-16 16:03:47 +02:00
b945dd94ec [WIP] do not show table at setup 2023-10-16 16:00:23 +02:00
6195bfb6e5 [WIP] rename to frappy.has_changed() 2023-10-16 15:57:14 +02:00
d4e2b12016 [WIP] _previous_shown is service state 2023-10-16 11:54:45 +02:00
0e059c644c [WIP] frappy_changed() -> frappy.changed() 2023-10-16 11:50:59 +02:00
03d4ffb0bc [WIP] show_config: line by line 2023-10-16 11:40:54 +02:00
ed983d36ae [WIP] frappy(): show all servers config 2023-10-16 11:39:19 +02:00
c2473d9e51 [WIP] rename frappy_config to frappy in setup 2023-10-16 11:30:49 +02:00
fedfe3a278 [WIP] fix old .guess_cfg method 2023-10-16 11:29:35 +02:00
0f1538c156 [WIP] frappy() is now a device 2023-10-16 11:16:18 +02:00
c73390195d [WIP] change frappy_config to frappy
work to be done:
- frappy() is now called as e device

work done:
- handle_notifications is not only waiting for triggers,
  but rechecks servers all 60 seconds
2023-09-25 17:26:46 +02:00
56fec16247 improve frappy server management
- do connect in background when the frappy server is not running
  on startup
2023-09-20 17:25:07 +02:00
5 changed files with 54 additions and 1692 deletions

View File

@@ -27,12 +27,10 @@ connected to a SEC node
""" """
import threading import threading
import socket
import json
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, MASTER Device, anytype, listof, MASTER
from nicos_sinq.frappy_sinq.secop.devices import SecNodeDevice, SecopDevice, DefunctDevice from nicos.devices.secop.devices import SecNodeDevice
from nicos.core.utils import createThread from nicos.core.utils import createThread
from nicos.utils.comparestrings import compare from nicos.utils.comparestrings import compare
from nicos.devices.secop.devices import get_attaching_devices from nicos.devices.secop.devices import get_attaching_devices
@@ -40,8 +38,6 @@ from nicos.commands.basic import AddSetup, CreateAllDevices, CreateDevice
from nicos.utils import loggers from nicos.utils import loggers
from servicemanager import FrappyManager, SeaManager, Reconnect, Keep from servicemanager import FrappyManager, SeaManager, Reconnect, Keep
SECOP_UDP_PORT = 10767
SERVICES = FrappyManager.services SERVICES = FrappyManager.services
@@ -117,21 +113,6 @@ def get_frappy_config():
return None return None
def send_other_udp(uri, instrument, device=None):
"""inform the feeder about the start of a frappy server"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
msg = {
'SECoP': 'for_other_node',
'uri': uri,
'instrument': instrument,
}
if device:
msg['device'] = device
msg = json.dumps(msg, ensure_ascii=False, separators=(',', ':')).encode('utf-8')
sock.sendto(msg, ('255.255.255.255', SECOP_UDP_PORT))
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
@@ -182,17 +163,8 @@ class FrappyConfig(Device):
before_check = before_change = prev_shown = None before_check = before_change = prev_shown = None
cnt = 0 cnt = 0
self._back_to_normal = None self._back_to_normal = None
current_exp = id(session.experiment.propinfo)
exp_changed = False
envlist = []
while not self._shutdown_event.wait(1): while not self._shutdown_event.wait(1):
busy = session.daemon_device._controller.status >= 0 busy = session.daemon_device._controller.status >= 0
if id(session.experiment.propinfo) != current_exp:
# NewExperiment or FinishExperiment was called
current_exp = id(session.experiment.propinfo)
exp_changed = True
elif not exp_changed:
envlist = session.experiment.envlist
if self._restarting or (busy and cnt < 10): if self._restarting or (busy and cnt < 10):
# do not check while restarting and check only every 10 sec when busy # do not check while restarting and check only every 10 sec when busy
cnt += 1 cnt += 1
@@ -206,17 +178,6 @@ class FrappyConfig(Device):
self._back_to_normal = None self._back_to_normal = None
cnt = 0 cnt = 0
need_change, changes, fm = to_consider = self.to_consider() need_change, changes, fm = to_consider = self.to_consider()
if exp_changed:
exp_changed = False
needed = set(self.needed_envalias()[0])
if needed == needed.intersection(envlist) and not session.experiment.envlist:
# restore envlist from previous experiment, as it was cleared by New/FinishExperiment
session.experiment.setEnvironment(envlist)
session.log.info('keep environment from previous experiment: %s', ', '.join(envlist))
continue
# trigger output of proposed SE change
prev_shown = None
need_change = True
if fm.state == before_change: if fm.state == before_change:
continue continue
if not need_change: if not need_change:
@@ -366,25 +327,9 @@ class FrappyConfig(Device):
CreateDevice(nodename) CreateDevice(nodename)
cleanup_defunct() cleanup_defunct()
CreateAllDevices() CreateAllDevices()
fm = FrappyManager()
ins = config.instrument
fm.get_server_state(ins, new_cfg)
recorders = {}
for service, secnode in secnodes.items(): for service, secnode in secnodes.items():
if services.get(service) and secnode: if services.get(service) and secnode:
cfg = fm.frappy_cfgs.get(service)
seacfg = fm.frappy2sea.get(cfg)
if secnode() and not seacfg:
if cfg:
recorders[service] = f'localhost:{fm.info[ins].get(service, 0)}/{cfg}'
else:
recorders[service] = secnode.uri
secnode._secnode.connect() secnode._secnode.connect()
if recorders:
try:
fm.sea.sea_recorder(ins, recorders)
except Exception as e:
session.log.warning('error in command sea_recorder %r', e)
self.set_envalias() self.set_envalias()
for secnode in remove_cfg: for secnode in remove_cfg:
secnode.disable() secnode.disable()
@@ -403,7 +348,7 @@ class FrappyConfig(Device):
- frappy('restart') # restart all frappy servers - frappy('restart') # restart all frappy servers
- frappy('reconnect') # reconnect to running frappy servers - frappy('reconnect') # reconnect to running frappy servers
""" """
self._back_to_normal = None # reset 'back to normal' mechanism self._back_to_normal = None # reset 'back to normal' machanism
stickarg = stick stickarg = stick
need_change, changes, fm = to_consider = self.to_consider() need_change, changes, fm = to_consider = self.to_consider()
@@ -652,6 +597,8 @@ class FrappyConfig(Device):
to_remove = to_remove.difference(addedenv) to_remove = to_remove.difference(addedenv)
prevenv = [k for k in session.experiment.envlist if k not in to_remove] prevenv = [k for k in session.experiment.envlist if k not in to_remove]
envlist = prevenv + [k for k in addedenv if k not in prevenv] envlist = prevenv + [k for k in addedenv if k not in prevenv]
if set(envlist) == set(prevenv):
envlist = None
predef_changes = [] predef_changes = []
for aliasname, cfg in predef_aliases: for aliasname, cfg in predef_aliases:
@@ -662,7 +609,7 @@ class FrappyConfig(Device):
def check_envalias(self): def check_envalias(self):
envlist, new_aliases, predef_aliases = self.needed_envalias() envlist, new_aliases, predef_aliases = self.needed_envalias()
if set(envlist) != set(session.experiment.envlist): if envlist:
return f"envlist should be {', '.join(envlist)}" return f"envlist should be {', '.join(envlist)}"
anew = [k for k, v in new_aliases.items() if v is not None] anew = [k for k, v in new_aliases.items() if v is not None]
removed = set(new_aliases).difference(anew) removed = set(new_aliases).difference(anew)
@@ -670,7 +617,7 @@ class FrappyConfig(Device):
if anew: if anew:
return f"aliases {', '.join(anew)} should change" return f"aliases {', '.join(anew)} should change"
if removed: if removed:
return f"aliases {', '.join(removed)} should be removed" return f"aliases {', '.join(anew)} should be removed"
return None return None
def set_envalias(self): def set_envalias(self):
@@ -682,15 +629,9 @@ class FrappyConfig(Device):
if new_aliases or predef_aliases: if new_aliases or predef_aliases:
for aliasname, devname in new_aliases.items(): for aliasname, devname in new_aliases.items():
if devname is None: if devname is None:
aliasdev = session.devices.get(aliasname) session.destroyDevice(aliasname)
if aliasdev: session.configured_devices.pop(aliasname, None)
aliastarget = session.devices.get(aliasdev.alias) session.dynamic_devices.pop(aliasname, None)
if isinstance(aliastarget, (SecopDevice, DefunctDevice)):
session.destroyDevice(aliasname)
session.configured_devices.pop(aliasname, None)
session.dynamic_devices.pop(aliasname, None)
elif aliastarget:
session.log.info('frappy_setup does not remove %s', aliasname)
else: else:
dev = session.devices.get(devname) dev = session.devices.get(devname)
devcfg = ('nicos.core.DeviceAlias', {}) devcfg = ('nicos.core.DeviceAlias', {})
@@ -719,19 +660,15 @@ class FrappyConfig(Device):
applyAliasConfig() # for other aliases applyAliasConfig() # for other aliases
prev = set(session.experiment.envlist) if envlist is not None:
remove = ', '.join(prev.difference(envlist)) prev = session.experiment.envlist
session.experiment.setEnvironment(envlist) removed = set(prev).difference(envlist)
show = [] session.experiment.setEnvironment(envlist)
keep = ', '.join(d for d in envlist if d in prev) if removed:
if keep: session.log.info('removed %s from environment', ', '.join(removed))
show.append(f'keep {keep}') added = set(envlist).difference(prev)
add = ', '.join(d for d in envlist if d not in prev) if added:
if add: session.log.info('added %s to environment', ', '.join(added))
show.append(f'add {add}')
if remove:
show.append(f'remove {remove}')
session.log.info('environment: %s', '; '.join(show))
class FrappyNode(SecNodeDevice, Moveable): class FrappyNode(SecNodeDevice, Moveable):
@@ -750,13 +687,7 @@ class FrappyNode(SecNodeDevice, Moveable):
"set to 'general' if all parameters should appear in the datafile header", "set to 'general' if all parameters should appear in the datafile header",
type=str, default='', settable=True), type=str, default='', settable=True),
'quiet_init': Param('flag to set loglevel to error while initializing', 'quiet_init': Param('flag to set loglevel to error while initializing',
type=bool, default=True, settable=True), type=bool, default=True, settable=True)
# duplicate from SecNodeDevice. needed for the case where the code for
# the SecNodeDevcice is not up to date, but the setup is already new
# does not yet have the i
'general_stop_whitelist': Param('module names to accept general stop',
type=listof(str), prefercache=False,
default=[], userparam=False),
} }
_cfgvalue = None _cfgvalue = None
@@ -786,9 +717,6 @@ class FrappyNode(SecNodeDevice, Moveable):
def doRead(self, maxage=0): def doRead(self, maxage=0):
return self._cfgvalue or '' return self._cfgvalue or ''
def fix(self, reason=''):
"""ignore"""
def createDevices(self): def createDevices(self):
super().createDevices() super().createDevices()
if self.param_category: if self.param_category:
@@ -902,10 +830,8 @@ class FrappyNode(SecNodeDevice, Moveable):
if available_cfg is not None: if available_cfg is not None:
raise ValueError('use "frappy_list()" to get a list of valid frappy configurations') raise ValueError('use "frappy_list()" to get a list of valid frappy configurations')
uri = 'localhost:%d' % info[self.service] uri = 'localhost:%d' % info[self.service]
send_other_udp(uri, config.instrument, device=cfg)
else: else:
uri = cfg uri = cfg
send_other_udp(uri, config.instrument)
if uri != self.uri: if uri != self.uri:
self._disconnect(keeptarget=True) self._disconnect(keeptarget=True)
if uri: if uri:

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,5 @@ devices = {
device('nicos_sinq.frappy_sinq.devices.FrappyNode', device('nicos_sinq.frappy_sinq.devices.FrappyNode',
description='main SEC node', unit='', async_only=True, description='main SEC node', unit='', async_only=True,
prefix=environ.get('SE_PREFIX', 'se_'), auto_create=True, service='main', prefix=environ.get('SE_PREFIX', 'se_'), auto_create=True, service='main',
general_stop_whitelist=['om', 'stickrot'],
), ),
} }

26
setups/ppms.py Normal file
View File

@@ -0,0 +1,26 @@
from os import environ
description = 'frappy main setup'
group = 'optional'
devices = {
'se_main':
device('nicos_sinq.frappy_sinq.devices.FrappyNode',
uri='pc12694:5000',
description='main SEC node', unit='',
prefix=environ.get('SE_PREFIX', ''), auto_create=True, service='main',
),
'timestamp': device('nicos_linse.common.lab.Timestamp', description='time, a dummy detector'),
}
startupcode = '''
printinfo("=======================================================================================")
printinfo("Welcome to the NICOS frappy secnode setup for PPMS!")
printinfo(" ")
printinfo("Usage:")
printinfo(" frappy(stick='<stick cfg>') # change sample-stick configuration")
printinfo(" frappy(addons='<addon1 cfg>,<addon2 cfg> ...') # change SE addons")
printinfo(" frappy(stick=None) # remove stick")
printinfo(" frappy(addons=None) # remove addons")
printinfo("=======================================================================================")
SetDetectors(timestamp)
'''

9
setups/timestamp.py Normal file
View File

@@ -0,0 +1,9 @@
description = 'timestamp dummy detector for offline measurements'
group = 'optional'
devices = {
'timestamp': device('nicos_linse.common.lab.Timestamp', description='time, a dummy detector'),
}
startupcode = 'SetDetectors(timestamp)'