diff --git a/cfg/addons.ini b/cfg/addons.ini new file mode 100644 index 0000000..846981a --- /dev/null +++ b/cfg/addons.ini @@ -0,0 +1,4 @@ +[FRAPPY] +confdir = ~/frappy/cfg/addons:~/frappy/cfg/develop +logdir = ~/frappylog +piddir = ~/frappylog/pid diff --git a/cfg/addons/ah2700sea.cfg b/cfg/addons/ah2700sea.cfg index 2d2545f..89f4815 100644 --- a/cfg/addons/ah2700sea.cfg +++ b/cfg/addons/ah2700sea.cfg @@ -11,10 +11,10 @@ service = addons [cap] class = secop_psi.sea.SeaReadable -iodev = sea_addons +io = sea_addons sea_object = cap [capslope] class = secop_psi.sea.SeaReadable -iodev = sea_addons +io = sea_addons sea_object = capslope diff --git a/cfg/addons/focus-be-filter.cfg b/cfg/addons/focus-be-filter.cfg index 0815f77..2bdbadd 100644 --- a/cfg/addons/focus-be-filter.cfg +++ b/cfg/addons/focus-be-filter.cfg @@ -10,5 +10,5 @@ service = addons [befilter] class = secop_psi.sea.SeaReadable -iodev = sea_addons +io = sea_addons sea_object = cryo diff --git a/cfg/develop/seadesc.cfg b/cfg/develop/seadesc.cfg index 096170e..c1b9c65 100644 --- a/cfg/develop/seadesc.cfg +++ b/cfg/develop/seadesc.cfg @@ -1,5 +1,5 @@ [NODE] -description = sea client (communication only) +description = sea client (tool for creating cfg) id = comm.sea.psi.ch [seaconn] diff --git a/cfg/ls240.cfg b/cfg/ls240.cfg index c61fb85..199691f 100644 --- a/cfg/ls240.cfg +++ b/cfg/ls240.cfg @@ -8,9 +8,9 @@ uri = tcp://5000 [T] description = temperature on uniax stick class = secop_psi.ls240.Ls240 -iodev = T_iodev +io = T_io -[T_iodev] +[T_io] class = secop.bytesio.BytesIO description = IO device for LS240 uri = serial:///dev/ttyUSB0?baudrate=9600+parity=EVEN diff --git a/cfg/ls370res.cfg b/cfg/ls370res.cfg index 8f412f5..c27b644 100644 --- a/cfg/ls370res.cfg +++ b/cfg/ls370res.cfg @@ -5,7 +5,7 @@ description = Lsc370 Test [INTERFACE] uri = tcp://5000 -[lsmain_iodev] +[lsmain_io] description = the communication device class = secop_psi.ls370res.StringIO uri = lollypop-ts:3001 @@ -22,4 +22,4 @@ channel = 5 description = resistivity main = lsmain # the auto created iodev from lsmain: -iodev = lsmain_iodev +io = lsmain_io diff --git a/cfg/ls370test.cfg b/cfg/ls370test.cfg index 6ade7f7..4bbd375 100644 --- a/cfg/ls370test.cfg +++ b/cfg/ls370test.cfg @@ -18,4 +18,4 @@ channel = 3 description = resistivity main = lsmain # the auto created iodev from lsmain: -iodev = lsmain_iodev +io = lsmain_io diff --git a/cfg/main.ini b/cfg/main.ini new file mode 100644 index 0000000..004d4a4 --- /dev/null +++ b/cfg/main.ini @@ -0,0 +1,4 @@ +[FRAPPY] +confdir = ~/frappy/cfg/main:~/frappy/cfg/develop +logdir = ~/frappylog +piddir = ~/frappylog/pid diff --git a/cfg/main/ccr2.cfg b/cfg/main/ccr2.cfg index 8c0a90c..07f274a 100644 --- a/cfg/main/ccr2.cfg +++ b/cfg/main/ccr2.cfg @@ -10,11 +10,11 @@ service = main [tt] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt #[tscreen] #class = secop_psi.sea.SeaReadable -#iodev = sea_main +#io = sea_main #sea_object = tt #rel_paths = te diff --git a/cfg/main/ccr2ht.cfg b/cfg/main/ccr2ht.cfg index 1b76887..03891d0 100644 --- a/cfg/main/ccr2ht.cfg +++ b/cfg/main/ccr2ht.cfg @@ -10,18 +10,18 @@ service = main [tt] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt #[tscreen] #class = secop_psi.sea.SeaReadable -#iodev = sea_main +#io = sea_main #sea_object = tt #rel_paths = te [tcoldfinger] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = tt rel_paths = tk diff --git a/cfg/main/ccr3.cfg b/cfg/main/ccr3.cfg new file mode 100644 index 0000000..5bca77e --- /dev/null +++ b/cfg/main/ccr3.cfg @@ -0,0 +1,14 @@ +[NODE] +description = 4 K closed cycle cryostat (ZEBRA) +id = ccr3.config.sea.psi.ch + +[sea_main] +class = secop_psi.sea.SeaClient +description = main sea connection for ccr3.config +config = ccr3.config +service = main + +[tt] +class = secop_psi.sea.SeaDrivable +io = sea_main +sea_object = tt diff --git a/cfg/main/cryosim.cfg b/cfg/main/cryosim.cfg new file mode 100644 index 0000000..e19aa76 --- /dev/null +++ b/cfg/main/cryosim.cfg @@ -0,0 +1,43 @@ +[NODE] +id = cyrosim.psi.ch +description = cryo simulation (similar ppms simulation) + +[INTERFACE] +uri = tcp://5000 + +[tt] +class = secop_psi.ppms.Temp +description = main temperature +meaning = ['temperature_regulation', 10] +ramp = 20 +io = ppms + +[lev] +class = secop_psi.ppms.Level +description = helium level +io = ppms + +[ts] +class = secop_psi.ppms.UserChannel +description = sample temperature +enabled = 1 +linkenable = tv +value.unit = K +meaning = ['temperature', 10] +io = ppms + +[tv] +class = secop_psi.ppms.UserChannel +description = exchanger temperature +enabled = 1 +linkenable = ts +value.unit = K +io = ppms + +[ppms] +class = secop_psi.ppms.Main +description = the main and poller module +class_id = QD.MULTIVU.PPMS.1 +visibility = 3 +pollinterval = 2 +export = False diff --git a/cfg/main/fftf.cfg b/cfg/main/fftf.cfg index b9c2b74..75a511d 100644 --- a/cfg/main/fftf.cfg +++ b/cfg/main/fftf.cfg @@ -10,27 +10,27 @@ service = main [tt] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt [p] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = p extra_modules = vacuumpump gasflow tlimit tlimit_without_vacuum [gasflow] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main single_module = p.gasflow [vacuumpump] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = p rel_paths = vacuumpump tlimit tlimit_without_vacuum [table] class = secop_psi.sea.SeaModule -iodev = sea_main +io = sea_main sea_object = table diff --git a/cfg/main/ill4.cfg b/cfg/main/ill4.cfg new file mode 100644 index 0000000..39950d6 --- /dev/null +++ b/cfg/main/ill4.cfg @@ -0,0 +1,57 @@ +[NODE] +description = orange cryostat with 70 mm sample space (FOCUS) +id = ill4.config.sea.psi.ch + +[sea_main] +class = secop_psi.sea.SeaClient +description = main sea connection for ill4.config +config = ill4.config +service = main + +[tt] +class = secop_psi.sea.SeaDrivable +iodev = sea_main +sea_object = tt + +[cc] +class = secop_psi.sea.SeaReadable +iodev = sea_main +sea_object = cc +extra_modules = h +visibility = 3 + +[lev] +class = secop_psi.sea.SeaReadable +iodev = sea_main +single_module = cc.h + +[nv] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = nv + +[ln2fill] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = ln2fill + +[hefill] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = hefill + +[hepump] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = hepump + +[hemot] +class = secop_psi.sea.SeaDrivable +iodev = sea_main +sea_object = hemot +visibility = 3 + +[table] +class = secop_psi.sea.SeaModule +iodev = sea_main +sea_object = table diff --git a/cfg/main/ill5.cfg b/cfg/main/ill5.cfg index bd5e378..badc85f 100644 --- a/cfg/main/ill5.cfg +++ b/cfg/main/ill5.cfg @@ -10,46 +10,46 @@ service = main [t] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt [tm] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt rel_paths = tm [cc] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = cc [nv] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = nv [ln2fill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = ln2fill [hefill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hefill [hepump] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hepump [hemot] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = hemot [table] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = table diff --git a/cfg/main/ma11.cfg b/cfg/main/ma11.cfg index 86527f8..ab7cfd6 100644 --- a/cfg/main/ma11.cfg +++ b/cfg/main/ma11.cfg @@ -10,76 +10,76 @@ service = main [tt] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt rel_paths = . tm [cc] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = cc [nv] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = nv [hepump] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hepump [hemot] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = hemot [ln2fill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = ln2fill [hefill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hefill [lev] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = lev [mf] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = mf [tcoil] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = tcoil [table] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = table [ccu2] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = ccu2 [lnv] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = lnv [lpr] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = lpr [lambdawatch] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = lambdawatch diff --git a/cfg/main/ma6.cfg b/cfg/main/ma6.cfg new file mode 100644 index 0000000..68c24b3 --- /dev/null +++ b/cfg/main/ma6.cfg @@ -0,0 +1,55 @@ +[NODE] +description = compact 6 Tesla vertical cryomagnet +id = ma6.config.sea.psi.ch + +[sea_main] +class = secop_psi.sea.SeaClient +description = main sea connection for ma6.config +config = ma6.config +service = main + +[tt] +class = secop_psi.sea.SeaDrivable +io = sea_main +sea_object = tt +rel_paths = . tm + +[cc] +class = secop_psi.sea.SeaReadable +io = sea_main +sea_object = cc + +[nv] +class = secop_psi.sea.SeaWritable +io = sea_main +sea_object = nv + +[hepump] +class = secop_psi.sea.SeaWritable +io = sea_main +sea_object = hepump + +[hemot] +class = secop_psi.sea.SeaDrivable +io = sea_main +sea_object = hemot + +[ln2fill] +class = secop_psi.sea.SeaWritable +io = sea_main +sea_object = ln2fill + +[hefill] +class = secop_psi.sea.SeaWritable +io = sea_main +sea_object = hefill + +[mf] +class = secop_psi.sea.SeaReadable +io = sea_main +sea_object = mf + +[lev] +class = secop_psi.sea.SeaReadable +io = sea_main +sea_object = lev diff --git a/cfg/main/ma7.cfg b/cfg/main/ma7.cfg index 0160dd7..20a24a7 100644 --- a/cfg/main/ma7.cfg +++ b/cfg/main/ma7.cfg @@ -10,64 +10,75 @@ service = main [tt] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt rel_paths = . tm [cc] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = cc [nv] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = nv [hefill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hefill [hepump] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hepump [hemot] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = hemot [ln2fill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = ln2fill [mf] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = mf [lev] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = lev [tcoil1] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = tcoil rel_paths = ta [tcoil2] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = tcoil rel_paths = tb [table] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = table +[dom_io] +description = dom motor IO +class = secop_psi.phytron.PhytronIO +uri = ma7-ts.psi.ch:3007 + +[dom] +description = a phytron motor +class = secop_psi.phytron.Motor +io = dom_io +encoder_mode = CHECK + diff --git a/cfg/main/magsim.cfg b/cfg/main/magsim.cfg new file mode 100644 index 0000000..512e178 --- /dev/null +++ b/cfg/main/magsim.cfg @@ -0,0 +1,51 @@ +[NODE] +id = magsim.psi.ch +description = cryo magnet simulation (similar to ppms simulation) + +[INTERFACE] +uri = tcp://5000 + +[tt] +class = secop_psi.ppms.Temp +description = main temperature +meaning = ['temperature_regulation', 10] +ramp = 20 +io = ppms + +[mf] +class = secop_psi.ppms.Field +target.min = -9 +target.max = 9 +description = magnetic field +io = ppms +meaning = ['magneticfield', 10] + +[lev] +class = secop_psi.ppms.Level +description = helium level +io = ppms + +[ts] +class = secop_psi.ppms.UserChannel +description = sample temperature +enabled = 1 +linkenable = tv +value.unit = K +meaning = ['temperature', 10] +io = ppms + +[tv] +class = secop_psi.ppms.UserChannel +description = exchanger temperature +enabled = 1 +linkenable = ts +value.unit = K +io = ppms + +[ppms] +class = secop_psi.ppms.Main +description = the main and poller module +class_id = QD.MULTIVU.PPMS.1 +visibility = 3 +pollinterval = 2 +export = False diff --git a/cfg/main/ori4.cfg b/cfg/main/ori4.cfg index 40f1101..5145d10 100644 --- a/cfg/main/ori4.cfg +++ b/cfg/main/ori4.cfg @@ -10,51 +10,51 @@ service = main [t] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt [tm] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt rel_paths = tm [cc] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = cc [nv] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = nv [nvmot] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = nvmot [ln2fill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = ln2fill [hefill] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hefill [hepump] class = secop_psi.sea.SeaWritable -iodev = sea_main +io = sea_main sea_object = hepump [hemot] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = hemot [table] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = table diff --git a/cfg/main/smamor.cfg b/cfg/main/smamor.cfg index 781410a..c7e708b 100644 --- a/cfg/main/smamor.cfg +++ b/cfg/main/smamor.cfg @@ -10,15 +10,15 @@ service = main [smi] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = smi [smv] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = smv [r] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = r diff --git a/cfg/mb11.cfg b/cfg/mb11.cfg index 41a1c25..7de74e9 100644 --- a/cfg/mb11.cfg +++ b/cfg/mb11.cfg @@ -5,66 +5,66 @@ description = a SEA connection [ts] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ts.mb11.config remote_paths = . [tvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvs.mb11.config remote_paths = . [tvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvd.mb11.config remote_paths = . [pstat] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pstat.mb11.config remote_paths = . [pdyn] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pdyn.mb11.config remote_paths = . [tneck1] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck1.mb11.config remote_paths = . [tneck2] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck2.mb11.config remote_paths = . [tnvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvs.mb11.config remote_paths = . [tnvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvd.mb11.config remote_paths = . [mf] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = mf.mb11.config remote_paths = . [tcoil] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tcoil.mb11.config remote_paths = . diff --git a/cfg/phytron.cfg b/cfg/phytron.cfg index 45ae300..ee75c8a 100644 --- a/cfg/phytron.cfg +++ b/cfg/phytron.cfg @@ -5,15 +5,15 @@ description = phytron motor test [INTERFACE] uri = tcp://5000 -[drv_iodev] +[drv_io] description = class = secop_psi.phytron.PhytronIO -uri = ma15-ts.psi.ch:3005 +uri = ma10-ts.psi.ch:3004 # uri = serial:///dev/tty.usbserial?baudrate=57600 # uri = serial:///dev/ttyUSB0?baudrate=9600 [drv] description = a phytron motor class = secop_psi.phytron.Motor -iodev = drv_iodev +io = drv_io encoder_mode = CHECK diff --git a/cfg/ppms2.cfg b/cfg/ppms2.cfg index 98bf491..e93f6d7 100644 --- a/cfg/ppms2.cfg +++ b/cfg/ppms2.cfg @@ -8,113 +8,113 @@ uri = 5000 [tt] class = secop_psi.ppms.Temp description = main temperature -iodev = ppms +io = ppms [mf] class = secop_psi.ppms.Field target.min = -9 target.max = 9 .description = magnetic field -.iodev = ppms +.io = ppms [pos] class = secop_psi.ppms.Position .description = sample rotator -.iodev = ppms +.io = ppms [lev] class = secop_psi.ppms.Level .description = helium level -.iodev = ppms +.io = ppms [chamber] class = secop_psi.ppms.Chamber .description = chamber state -.iodev = ppms +.io = ppms [r1] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 1 .no = 1 value.unit = Ohm -.iodev = ppms +.io = ppms [r2] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 2 .no = 2 value.unit = Ohm -.iodev = ppms +.io = ppms [r3] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 3 .no = 3 value.unit = Ohm -.iodev = ppms +.io = ppms [r4] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 4 .no = 4 value.unit = Ohm -.iodev = ppms +.io = ppms [i1] class = secop_psi.ppms.Channel .description = current channel 1 .no = 1 value.unit = uA -.iodev = ppms +.io = ppms [i2] class = secop_psi.ppms.Channel .description = current channel 2 .no = 2 value.unit = uA -.iodev = ppms +.io = ppms [i3] class = secop_psi.ppms.Channel .description = current channel 3 .no = 3 value.unit = uA -.iodev = ppms +.io = ppms [i4] class = secop_psi.ppms.Channel .description = current channel 4 .no = 4 value.unit = uA -.iodev = ppms +.io = ppms [v1] class = secop_psi.ppms.DriverChannel .description = voltage channel 1 .no = 1 value.unit = V -.iodev = ppms +.io = ppms [v2] class = secop_psi.ppms.DriverChannel .description = voltage channel 2 .no = 2 value.unit = V -.iodev = ppms +.io = ppms [tv] class = secop_psi.ppms.UserChannel .description = VTI temperature enabled = 1 value.unit = K -.iodev = ppms +.io = ppms [ts] class = secop_psi.ppms.UserChannel .description = sample temperature enabled = 1 value.unit = K -.iodev = ppms +.io = ppms [ppms] class = secop_psi.ppms.Main diff --git a/cfg/ppms_proxy_test.cfg b/cfg/ppms_proxy_test.cfg index bbaeea0..014e8a8 100644 --- a/cfg/ppms_proxy_test.cfg +++ b/cfg/ppms_proxy_test.cfg @@ -15,7 +15,7 @@ uri = tcp://localhost:5000 class = secop.Proxy remote_class = secop_psi.ppms.Field description = magnetic field -iodev = secnode +io = secnode value.min = -0.1 value.max = 0.1 target.min = -8 diff --git a/cfg/ppmssim.cfg b/cfg/ppmssim.cfg index 8f8a927..1bc9f6b 100644 --- a/cfg/ppmssim.cfg +++ b/cfg/ppmssim.cfg @@ -8,113 +8,113 @@ uri = tcp://5000 [tt] class = secop_psi.ppms.Temp description = main temperature -iodev = ppms +io = ppms [mf] class = secop_psi.ppms.Field target.min = -9 target.max = 9 .description = magnetic field -.iodev = ppms +.io = ppms [pos] class = secop_psi.ppms.Position .description = sample rotator -.iodev = ppms +.io = ppms [lev] class = secop_psi.ppms.Level .description = helium level -.iodev = ppms +.io = ppms [chamber] class = secop_psi.ppms.Chamber .description = chamber state -.iodev = ppms +.io = ppms [r1] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 1 .no = 1 value.unit = Ohm -.iodev = ppms +.io = ppms [r2] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 2 .no = 2 value.unit = Ohm -.iodev = ppms +.io = ppms [r3] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 3 .no = 3 value.unit = Ohm -.iodev = ppms +.io = ppms [r4] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 4 .no = 4 value.unit = Ohm -.iodev = ppms +.io = ppms [i1] class = secop_psi.ppms.Channel .description = current channel 1 .no = 1 value.unit = uA -.iodev = ppms +.io = ppms [i2] class = secop_psi.ppms.Channel .description = current channel 2 .no = 2 value.unit = uA -.iodev = ppms +.io = ppms [i3] class = secop_psi.ppms.Channel .description = current channel 3 .no = 3 value.unit = uA -.iodev = ppms +.io = ppms [i4] class = secop_psi.ppms.Channel .description = current channel 4 .no = 4 value.unit = uA -.iodev = ppms +.io = ppms [v1] class = secop_psi.ppms.DriverChannel .description = voltage channel 1 .no = 1 value.unit = V -.iodev = ppms +.io = ppms [v2] class = secop_psi.ppms.DriverChannel .description = voltage channel 2 .no = 2 value.unit = V -.iodev = ppms +.io = ppms [tv] class = secop_psi.ppms.UserChannel .description = VTI temperature enabled = 1 value.unit = K -.iodev = ppms +.io = ppms [ts] class = secop_psi.ppms.UserChannel .description = sample temperature enabled = 1 value.unit = K -.iodev = ppms +.io = ppms [ppms] class = secop_psi.ppms.Main diff --git a/cfg/ppmswin.cfg b/cfg/ppmswin.cfg index 6825890..491315b 100644 --- a/cfg/ppmswin.cfg +++ b/cfg/ppmswin.cfg @@ -8,99 +8,99 @@ uri = tcp://5000 [tt] class = secop_psi.ppms.Temp description = main temperature -iodev = ppms +io = ppms [mf] class = secop_psi.ppms.Field target.min = -9 target.max = 9 .description = magnetic field -.iodev = ppms +.io = ppms [pos] class = secop_psi.ppms.Position .description = sample rotator -.iodev = ppms +.io = ppms [lev] class = secop_psi.ppms.Level .description = helium level -.iodev = ppms +.io = ppms [chamber] class = secop_psi.ppms.Chamber .description = chamber state -.iodev = ppms +.io = ppms [r1] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 1 .no = 1 value.unit = Ohm -.iodev = ppms +.io = ppms [r2] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 2 .no = 2 value.unit = Ohm -.iodev = ppms +.io = ppms [r3] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 3 .no = 3 value.unit = Ohm -.iodev = ppms +.io = ppms [r4] class = secop_psi.ppms.BridgeChannel .description = resistivity channel 4 .no = 4 value.unit = Ohm -.iodev = ppms +.io = ppms [i1] class = secop_psi.ppms.Channel .description = current channel 1 .no = 1 value.unit = uA -.iodev = ppms +.io = ppms [i2] class = secop_psi.ppms.Channel .description = current channel 2 .no = 2 value.unit = uA -.iodev = ppms +.io = ppms [i3] class = secop_psi.ppms.Channel .description = current channel 3 .no = 3 value.unit = uA -.iodev = ppms +.io = ppms [i4] class = secop_psi.ppms.Channel .description = current channel 4 .no = 4 value.unit = uA -.iodev = ppms +.io = ppms [v1] class = secop_psi.ppms.DriverChannel .description = voltage channel 1 .no = 1 value.unit = V -.iodev = ppms +.io = ppms [v2] class = secop_psi.ppms.DriverChannel .description = voltage channel 2 .no = 2 value.unit = V -.iodev = ppms +.io = ppms [tv] class = secop_psi.ppms.UserChannel @@ -108,7 +108,7 @@ class = secop_psi.ppms.UserChannel enabled = 0 linkenable = ts value.unit = K -.iodev = ppms +.io = ppms [ts] class = secop_psi.ppms.UserChannel @@ -116,7 +116,7 @@ class = secop_psi.ppms.UserChannel enabled = 0 linkenable = tv value.unit = K -.iodev = ppms +.io = ppms [ppms] class = secop_psi.ppms.Main diff --git a/cfg/prep2.cfg b/cfg/prep2.cfg index 3b012d8..d8e91b1 100644 --- a/cfg/prep2.cfg +++ b/cfg/prep2.cfg @@ -12,12 +12,12 @@ uri = tcp://samenv.psi.ch:8642 [module tt] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = tt.ori1.config remote_paths = . [module nv] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = nv.ori1.config remote_paths = . diff --git a/cfg/prep5.cfg b/cfg/prep5.cfg index 260cf20..7fb66b3 100644 --- a/cfg/prep5.cfg +++ b/cfg/prep5.cfg @@ -12,108 +12,108 @@ uri = tcp://samenv.psi.ch:8645 [module tt] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = tt.ma11.config remote_paths = . [module nv] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = nv.ma11.config remote_paths = . [module ln2fill] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ln2fill.ma11.config remote_paths = . [module hefill] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = hefill.ma11.config remote_paths = . [module tcoil] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tcoil.ma11.config remote_paths = . [module table] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = table.ma11.config remote_paths = . [module lnv] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = lnv.ma11.config remote_paths = . [module lpr] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = lpr.ma11.config remote_paths = . [module lambdawatch] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = lambdawatch.ma11.config remote_paths = . [module ts] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = ts.dil4.stick remote_paths = . [module treg] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = treg.dil4.stick remote_paths = . [module tmon] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tmon.dil4.stick remote_paths = . [module sorb] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = sorb.dil4.stick remote_paths = . [module ultrasound] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ultrasound.ultrasound.addon remote_paths = . [module fn] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = fn.ultrasound.addon remote_paths = . [module mirror] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = mirror.ultrasound.addon remote_paths = . [module f] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = f.ultrasound.addon remote_paths = . [module pars] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pars.ultrasound.addon remote_paths = . diff --git a/cfg/prep6.cfg b/cfg/prep6.cfg index 7350d68..a3509c7 100644 --- a/cfg/prep6.cfg +++ b/cfg/prep6.cfg @@ -12,54 +12,54 @@ uri = tcp://samenv.psi.ch:8646 [module tvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvs.varioxB.config remote_paths = . [module tvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvd.varioxB.config remote_paths = . [module pstat] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pstat.varioxB.config remote_paths = . [module pdyn] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pdyn.varioxB.config remote_paths = . [module tneck1] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck1.varioxB.config remote_paths = . [module tneck2] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck2.varioxB.config remote_paths = . [module tnvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvs.varioxB.config remote_paths = . [module tnvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvd.varioxB.config remote_paths = . [module ts] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ts.vb.stick remote_paths = . diff --git a/cfg/sea/ccr2ht.cfg b/cfg/sea/ccr2ht.cfg index 9dc6304..5b54a47 100644 --- a/cfg/sea/ccr2ht.cfg +++ b/cfg/sea/ccr2ht.cfg @@ -6,15 +6,15 @@ service = main [tt] class = secop_psi.sea.SeaDrivable -iodev = sea_main +io = sea_main sea_object = tt [cc] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = cc [table] class = secop_psi.sea.SeaReadable -iodev = sea_main +io = sea_main sea_object = table diff --git a/cfg/sea/ccr3.config.json b/cfg/sea/ccr3.config.json new file mode 100644 index 0000000..371e3fc --- /dev/null +++ b/cfg/sea/ccr3.config.json @@ -0,0 +1,160 @@ +{"tt": {"base": "/tt", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run tt", "description": "tt", "kids": 18}, +{"path": "send", "type": "text", "readonly": false, "cmd": "tt send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "tt is_running", "visibility": 3}, +{"path": "mainloop", "type": "text", "readonly": false, "cmd": "tt mainloop", "visibility": 3}, +{"path": "target", "type": "float"}, +{"path": "running", "type": "int"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "tt tolerance"}, +{"path": "maxwait", "type": "float", "readonly": false, "cmd": "tt maxwait"}, +{"path": "settle", "type": "float", "readonly": false, "cmd": "tt settle"}, +{"path": "log", "type": "text", "readonly": false, "cmd": "tt log", "visibility": 3, "kids": 4}, +{"path": "log/mean", "type": "float", "visibility": 3}, +{"path": "log/m2", "type": "float", "visibility": 3}, +{"path": "log/stddev", "type": "float", "visibility": 3}, +{"path": "log/n", "type": "float", "visibility": 3}, +{"path": "dblctrl", "type": "bool", "readonly": false, "cmd": "tt dblctrl", "visibility": 3, "kids": 9}, +{"path": "dblctrl/tshift", "type": "float", "readonly": false, "cmd": "tt dblctrl/tshift", "visibility": 3}, +{"path": "dblctrl/mode", "type": "enum", "enum": {"disabled": -1, "inactive": 0, "stable": 1, "up": 2, "down": 3}, "readonly": false, "cmd": "tt dblctrl/mode", "visibility": 3}, +{"path": "dblctrl/shift_up", "type": "float", "visibility": 3}, +{"path": "dblctrl/shift_lo", "type": "float", "visibility": 3}, +{"path": "dblctrl/t_min", "type": "float", "visibility": 3}, +{"path": "dblctrl/t_max", "type": "float", "visibility": 3}, +{"path": "dblctrl/int2", "type": "float", "readonly": false, "cmd": "tt dblctrl/int2", "visibility": 3}, +{"path": "dblctrl/prop_up", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_up", "visibility": 3}, +{"path": "dblctrl/prop_lo", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_lo", "visibility": 3}, +{"path": "tm", "type": "float", "kids": 4}, +{"path": "tm/curve", "type": "text", "readonly": false, "cmd": "tt tm/curve", "kids": 1}, +{"path": "tm/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt tm/curve/points", "visibility": 3}, +{"path": "tm/alarm", "type": "float", "readonly": false, "cmd": "tt tm/alarm"}, +{"path": "tm/stddev", "type": "float"}, +{"path": "tm/raw", "type": "float"}, +{"path": "te", "type": "float", "kids": 4}, +{"path": "te/curve", "type": "text", "readonly": false, "cmd": "tt te/curve", "kids": 1}, +{"path": "te/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt te/curve/points", "visibility": 3}, +{"path": "te/alarm", "type": "float", "readonly": false, "cmd": "tt te/alarm"}, +{"path": "te/stddev", "type": "float"}, +{"path": "te/raw", "type": "float"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "tt set", "kids": 18}, +{"path": "set/mode", "type": "enum", "enum": {"disabled": -1, "off": 0, "controlling": 1, "manual": 2}, "readonly": false, "cmd": "tt set/mode"}, +{"path": "set/reg", "type": "float"}, +{"path": "set/ramp", "type": "float", "readonly": false, "cmd": "tt set/ramp", "description": "maximum ramp in K/min (0: ramp off)"}, +{"path": "set/wramp", "type": "float", "readonly": false, "cmd": "tt set/wramp"}, +{"path": "set/smooth", "type": "float", "readonly": false, "cmd": "tt set/smooth", "description": "smooth time (minutes)"}, +{"path": "set/channel", "type": "text", "readonly": false, "cmd": "tt set/channel"}, +{"path": "set/limit", "type": "float", "readonly": false, "cmd": "tt set/limit"}, +{"path": "set/resist", "type": "float", "readonly": false, "cmd": "tt set/resist"}, +{"path": "set/maxheater", "type": "text", "readonly": false, "cmd": "tt set/maxheater", "description": "maximum heater limit, units should be given without space: W, mW, A, mA"}, +{"path": "set/linearpower", "type": "float", "readonly": false, "cmd": "tt set/linearpower", "description": "when not 0, it is the maximum effective power, and the power is linear to the heater output"}, +{"path": "set/maxpowerlim", "type": "float", "description": "the maximum power limit (before any booster or converter)"}, +{"path": "set/maxpower", "type": "float", "readonly": false, "cmd": "tt set/maxpower", "description": "maximum power [W]"}, +{"path": "set/maxcurrent", "type": "float", "description": "the maximum current before any booster or converter"}, +{"path": "set/manualpower", "type": "float", "readonly": false, "cmd": "tt set/manualpower"}, +{"path": "set/power", "type": "float"}, +{"path": "set/prop", "type": "float", "readonly": false, "cmd": "tt set/prop", "description": "bigger means more gain"}, +{"path": "set/integ", "type": "float", "readonly": false, "cmd": "tt set/integ", "description": "bigger means faster"}, +{"path": "set/deriv", "type": "float", "readonly": false, "cmd": "tt set/deriv"}, +{"path": "display", "type": "text", "readonly": false, "cmd": "tt display"}, +{"path": "dout", "type": "int", "readonly": false, "cmd": "tt dout"}, +{"path": "dinp", "type": "int"}, +{"path": "remote", "type": "bool"}]}, + +"cc": {"base": "/cc", "params": [ +{"path": "", "type": "bool", "kids": 96}, +{"path": "send", "type": "text", "readonly": false, "cmd": "cc send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "autodevice", "type": "bool", "readonly": false, "cmd": "cc autodevice"}, +{"path": "fav", "type": "bool", "readonly": false, "cmd": "cc fav"}, +{"path": "f", "type": "float"}, +{"path": "fs", "type": "enum", "enum": {"ok": 0, "no_sens": 1}, "readonly": false, "cmd": "cc fs"}, +{"path": "mav", "type": "bool", "readonly": false, "cmd": "cc mav"}, +{"path": "fm", "type": "enum", "enum": {"idle": 0, "opening": 1, "closing": 2, "opened": 3, "closed": 4, "no_motor": 5}}, +{"path": "fa", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "offline": 3}, "readonly": false, "cmd": "cc fa"}, +{"path": "mp", "type": "float", "readonly": false, "cmd": "cc mp"}, +{"path": "msp", "type": "float"}, +{"path": "mmp", "type": "float"}, +{"path": "mc", "type": "float", "readonly": false, "cmd": "cc mc"}, +{"path": "mfc", "type": "float", "readonly": false, "cmd": "cc mfc"}, +{"path": "moc", "type": "float", "readonly": false, "cmd": "cc moc"}, +{"path": "mtc", "type": "float", "readonly": false, "cmd": "cc mtc"}, +{"path": "mtl", "type": "float"}, +{"path": "mft", "type": "float", "readonly": false, "cmd": "cc mft"}, +{"path": "mt", "type": "float"}, +{"path": "mo", "type": "float"}, +{"path": "mcr", "type": "float"}, +{"path": "mot", "type": "float"}, +{"path": "mw", "type": "float", "readonly": false, "cmd": "cc mw", "description": "correction pulse after automatic open"}, +{"path": "hav", "type": "bool", "readonly": false, "cmd": "cc hav"}, +{"path": "h", "type": "float"}, +{"path": "hr", "type": "float"}, +{"path": "hc", "type": "float"}, +{"path": "hu", "type": "float"}, +{"path": "hh", "type": "float", "readonly": false, "cmd": "cc hh"}, +{"path": "hl", "type": "float", "readonly": false, "cmd": "cc hl"}, +{"path": "htf", "type": "float", "readonly": false, "cmd": "cc htf", "description": "meas. period in fast mode"}, +{"path": "hts", "type": "float", "readonly": false, "cmd": "cc hts", "description": "meas. period in slow mode"}, +{"path": "hd", "type": "float", "readonly": false, "cmd": "cc hd"}, +{"path": "hwr", "type": "float", "readonly": false, "cmd": "cc hwr"}, +{"path": "hem", "type": "float", "readonly": false, "cmd": "cc hem", "description": "sensor length in mm from top to empty pos."}, +{"path": "hfu", "type": "float", "readonly": false, "cmd": "cc hfu", "description": "sensor length in mm from top to full pos."}, +{"path": "hcd", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3, "manual": 7}, "readonly": false, "cmd": "cc hcd"}, +{"path": "hv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4}}, +{"path": "hsf", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "ha", "type": "bool", "readonly": false, "cmd": "cc ha"}, +{"path": "hm", "type": "bool"}, +{"path": "hf", "type": "enum", "enum": {"slow": 0, "fast": 1}, "readonly": false, "cmd": "cc hf"}, +{"path": "hbe", "type": "bool", "readonly": false, "cmd": "cc hbe"}, +{"path": "hmf", "type": "float"}, +{"path": "hms", "type": "float"}, +{"path": "hit", "type": "float", "readonly": false, "cmd": "cc hit"}, +{"path": "hft", "type": "int", "readonly": false, "cmd": "cc hft"}, +{"path": "hea", "type": "enum", "enum": {"0": 0, "1": 1, "6": 2}, "readonly": false, "cmd": "cc hea"}, +{"path": "hch", "type": "int", "readonly": false, "cmd": "cc hch"}, +{"path": "hwr0", "type": "float", "readonly": false, "cmd": "cc hwr0"}, +{"path": "hem0", "type": "float", "readonly": false, "cmd": "cc hem0", "description": "sensor length in mm from top to empty pos."}, +{"path": "hfu0", "type": "float", "readonly": false, "cmd": "cc hfu0", "description": "sensor length in mm from top to full pos."}, +{"path": "hd0", "type": "float", "readonly": false, "cmd": "cc hd0", "description": "external sensor drive current (mA)"}, +{"path": "h0", "type": "float"}, +{"path": "hs0", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h1", "type": "float"}, +{"path": "hs1", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h2", "type": "float"}, +{"path": "hs2", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h3", "type": "float"}, +{"path": "hs3", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h4", "type": "float"}, +{"path": "hs4", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h5", "type": "float"}, +{"path": "hs5", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "hfb", "type": "float"}, +{"path": "nav", "type": "bool", "readonly": false, "cmd": "cc nav"}, +{"path": "nu", "type": "float"}, +{"path": "nl", "type": "float"}, +{"path": "nth", "type": "float", "readonly": false, "cmd": "cc nth"}, +{"path": "ntc", "type": "float", "readonly": false, "cmd": "cc ntc"}, +{"path": "ntm", "type": "float", "readonly": false, "cmd": "cc ntm"}, +{"path": "ns", "type": "enum", "enum": {"sens_ok": 0, "no_sens": 1, "short_circuit": 2, "upside_down": 3, "sens_warm": 4, "empty": 5}}, +{"path": "na", "type": "bool", "readonly": false, "cmd": "cc na"}, +{"path": "nv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4, "boost": 5}}, +{"path": "nc", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3}, "readonly": false, "cmd": "cc nc"}, +{"path": "nfb", "type": "float"}, +{"path": "cda", "type": "float"}, +{"path": "cdb", "type": "float"}, +{"path": "cba", "type": "float"}, +{"path": "cbb", "type": "float"}, +{"path": "cvs", "type": "int"}, +{"path": "csp", "type": "int"}, +{"path": "cdv", "type": "text", "readonly": false, "cmd": "cc cdv"}, +{"path": "cic", "type": "text", "readonly": false, "cmd": "cc cic"}, +{"path": "cin", "type": "text"}, +{"path": "cds", "type": "enum", "enum": {"local": 0, "remote": 1, "loading": 2, "by_code": 3, "by_touch": 4}, "readonly": false, "cmd": "cc cds"}, +{"path": "timing", "type": "bool", "readonly": false, "cmd": "cc timing"}, +{"path": "tc", "type": "float"}, +{"path": "tn", "type": "float"}, +{"path": "th", "type": "float"}, +{"path": "tf", "type": "float"}, +{"path": "tm", "type": "float"}, +{"path": "tv", "type": "float"}, +{"path": "tq", "type": "float"}, +{"path": "bdl", "type": "float", "readonly": false, "cmd": "cc bdl"}]}} diff --git a/cfg/sea/focus-be-filter.addon.json b/cfg/sea/focus-be-filter.addon.json index 571dd30..2ece402 100644 --- a/cfg/sea/focus-be-filter.addon.json +++ b/cfg/sea/focus-be-filter.addon.json @@ -1,4 +1,5 @@ -{"cryo": {"base": "/cryo", "params": [{"path": "", "type": "float", "kids": 14}, +{"cryo": {"base": "/cryo", "params": [ +{"path": "", "type": "float", "kids": 14}, {"path": "send", "type": "text", "readonly": false, "cmd": "cryo send", "visibility": 3}, {"path": "status", "type": "text", "visibility": 3}, {"path": "cool", "type": "enum", "enum": {"on": 0, "off": 1}, "readonly": false, "cmd": "cryo cool"}, @@ -17,4 +18,7 @@ {"path": "filter/amplitude", "type": "float", "readonly": false, "cmd": "cryo filter/amplitude", "description": "oszillation amplitude / K (+/-)"}, {"path": "filter/precision", "type": "float", "readonly": false, "cmd": "cryo filter/precision"}, {"path": "filter/raw", "type": "float"}, -{"path": "filter/intdif", "type": "float"}]}, "addonlock_focus-be-filter": {"base": "/addonlock_focus-be-filter", "params": [{"path": "", "type": "text", "readonly": false, "cmd": "addonlock_focus-be-filter = "}]}} +{"path": "filter/intdif", "type": "float"}]}, + +"addonlock_focus-be-filter": {"base": "/addonlock_focus-be-filter", "params": [ +{"path": "", "type": "text", "readonly": false, "cmd": "addonlock_focus-be-filter = "}]}} diff --git a/cfg/sea/focus-be-filter.cfg b/cfg/sea/focus-be-filter.cfg index ef60eb5..9fdd2f4 100644 --- a/cfg/sea/focus-be-filter.cfg +++ b/cfg/sea/focus-be-filter.cfg @@ -1,15 +1,19 @@ +[NODE] +description = FOCUS CryoTel Be-filter +id = focus-be-filter.addon.sea.psi.ch + [sea_addons] class = secop_psi.sea.SeaClient -description = SEA connection to ccr2ht_focus-be-filter +description = addons sea connection for focus-be-filter.addon config = focus-be-filter.addon service = addons [cryo] class = secop_psi.sea.SeaReadable -iodev = sea_addons +io = sea_addons sea_object = cryo [addonlock_focus-be-filter] class = secop_psi.sea.SeaWritable -iodev = sea_addons +io = sea_addons sea_object = addonlock_focus-be-filter diff --git a/cfg/sea/ill4.cfg b/cfg/sea/ill4.cfg new file mode 100644 index 0000000..6cf129c --- /dev/null +++ b/cfg/sea/ill4.cfg @@ -0,0 +1,49 @@ +[NODE] +description = orange cryostat with 70 mm sample space (FOCUS) +id = ill4.config.sea.psi.ch + +[sea_main] +class = secop_psi.sea.SeaClient +description = main sea connection for ill4.config +config = ill4.config +service = main + +[tt] +class = secop_psi.sea.SeaDrivable +iodev = sea_main +sea_object = tt + +[cc] +class = secop_psi.sea.SeaReadable +iodev = sea_main +sea_object = cc + +[nv] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = nv + +[ln2fill] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = ln2fill + +[hefill] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = hefill + +[hepump] +class = secop_psi.sea.SeaWritable +iodev = sea_main +sea_object = hepump + +[hemot] +class = secop_psi.sea.SeaDrivable +iodev = sea_main +sea_object = hemot + +[table] +class = secop_psi.sea.SeaReadable +iodev = sea_main +sea_object = table diff --git a/cfg/sea/ill4.config.json b/cfg/sea/ill4.config.json new file mode 100644 index 0000000..76cdb57 --- /dev/null +++ b/cfg/sea/ill4.config.json @@ -0,0 +1,299 @@ +{"tt": {"base": "/tt", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run tt", "description": "tt", "kids": 18}, +{"path": "send", "type": "text", "readonly": false, "cmd": "tt send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "tt is_running", "visibility": 3}, +{"path": "target", "type": "float"}, +{"path": "running", "type": "int"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "tt tolerance"}, +{"path": "maxwait", "type": "float", "readonly": false, "cmd": "tt maxwait"}, +{"path": "settle", "type": "float", "readonly": false, "cmd": "tt settle"}, +{"path": "log", "type": "text", "readonly": false, "cmd": "tt log", "visibility": 3, "kids": 4}, +{"path": "log/mean", "type": "float", "visibility": 3}, +{"path": "log/m2", "type": "float", "visibility": 3}, +{"path": "log/stddev", "type": "float", "visibility": 3}, +{"path": "log/n", "type": "float", "visibility": 3}, +{"path": "dblctrl", "type": "bool", "readonly": false, "cmd": "tt dblctrl", "kids": 9}, +{"path": "dblctrl/tshift", "type": "float", "readonly": false, "cmd": "tt dblctrl/tshift"}, +{"path": "dblctrl/mode", "type": "enum", "enum": {"disabled": -1, "inactive": 0, "stable": 1, "up": 2, "down": 3}, "readonly": false, "cmd": "tt dblctrl/mode"}, +{"path": "dblctrl/shift_up", "type": "float"}, +{"path": "dblctrl/shift_lo", "type": "float"}, +{"path": "dblctrl/t_min", "type": "float"}, +{"path": "dblctrl/t_max", "type": "float"}, +{"path": "dblctrl/int2", "type": "float", "readonly": false, "cmd": "tt dblctrl/int2"}, +{"path": "dblctrl/prop_up", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_up"}, +{"path": "dblctrl/prop_lo", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_lo"}, +{"path": "tm", "type": "float", "kids": 4}, +{"path": "tm/curve", "type": "text", "readonly": false, "cmd": "tt tm/curve", "kids": 1}, +{"path": "tm/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt tm/curve/points", "visibility": 3}, +{"path": "tm/alarm", "type": "float", "readonly": false, "cmd": "tt tm/alarm"}, +{"path": "tm/stddev", "type": "float"}, +{"path": "tm/raw", "type": "float"}, +{"path": "ts", "type": "float", "kids": 4}, +{"path": "ts/curve", "type": "text", "readonly": false, "cmd": "tt ts/curve", "kids": 1}, +{"path": "ts/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt ts/curve/points", "visibility": 3}, +{"path": "ts/alarm", "type": "float", "readonly": false, "cmd": "tt ts/alarm"}, +{"path": "ts/stddev", "type": "float"}, +{"path": "ts/raw", "type": "float"}, +{"path": "ts_2", "type": "float", "visibility": 3, "kids": 4}, +{"path": "ts_2/curve", "type": "text", "readonly": false, "cmd": "tt ts_2/curve", "visibility": 3, "kids": 1}, +{"path": "ts_2/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt ts_2/curve/points", "visibility": 3}, +{"path": "ts_2/alarm", "type": "float", "readonly": false, "cmd": "tt ts_2/alarm", "visibility": 3}, +{"path": "ts_2/stddev", "type": "float", "visibility": 3}, +{"path": "ts_2/raw", "type": "float", "visibility": 3}, +{"path": "set", "type": "float", "readonly": false, "cmd": "tt set", "kids": 18}, +{"path": "set/mode", "type": "enum", "enum": {"disabled": -1, "off": 0, "controlling": 1, "manual": 2}, "readonly": false, "cmd": "tt set/mode"}, +{"path": "set/reg", "type": "float"}, +{"path": "set/ramp", "type": "float", "readonly": false, "cmd": "tt set/ramp", "description": "maximum ramp in K/min (0: ramp off)"}, +{"path": "set/wramp", "type": "float", "readonly": false, "cmd": "tt set/wramp"}, +{"path": "set/smooth", "type": "float", "readonly": false, "cmd": "tt set/smooth", "description": "smooth time (minutes)"}, +{"path": "set/channel", "type": "text", "readonly": false, "cmd": "tt set/channel"}, +{"path": "set/limit", "type": "float", "readonly": false, "cmd": "tt set/limit"}, +{"path": "set/resist", "type": "float", "readonly": false, "cmd": "tt set/resist"}, +{"path": "set/maxheater", "type": "text", "readonly": false, "cmd": "tt set/maxheater", "description": "maximum heater limit, units should be given without space: W, mW, A, mA"}, +{"path": "set/linearpower", "type": "float", "readonly": false, "cmd": "tt set/linearpower", "description": "when not 0, it is the maximum effective power, and the power is linear to the heater output"}, +{"path": "set/maxpowerlim", "type": "float", "description": "the maximum power limit (before any booster or converter)"}, +{"path": "set/maxpower", "type": "float", "readonly": false, "cmd": "tt set/maxpower", "description": "maximum power [W]"}, +{"path": "set/maxcurrent", "type": "float", "description": "the maximum current before any booster or converter"}, +{"path": "set/manualpower", "type": "float", "readonly": false, "cmd": "tt set/manualpower"}, +{"path": "set/power", "type": "float"}, +{"path": "set/prop", "type": "float", "readonly": false, "cmd": "tt set/prop", "description": "bigger means more gain"}, +{"path": "set/integ", "type": "float", "readonly": false, "cmd": "tt set/integ", "description": "bigger means faster"}, +{"path": "set/deriv", "type": "float", "readonly": false, "cmd": "tt set/deriv"}, +{"path": "display", "type": "text", "readonly": false, "cmd": "tt display"}, +{"path": "dout", "type": "int", "readonly": false, "cmd": "tt dout"}, +{"path": "dinp", "type": "int"}, +{"path": "remote", "type": "bool"}]}, + +"cc": {"base": "/cc", "params": [ +{"path": "", "type": "bool", "kids": 96}, +{"path": "send", "type": "text", "readonly": false, "cmd": "cc send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "autodevice", "type": "bool", "readonly": false, "cmd": "cc autodevice"}, +{"path": "fav", "type": "bool", "readonly": false, "cmd": "cc fav"}, +{"path": "f", "type": "float"}, +{"path": "fs", "type": "enum", "enum": {"ok": 0, "no_sens": 1}, "readonly": false, "cmd": "cc fs"}, +{"path": "mav", "type": "bool", "readonly": false, "cmd": "cc mav"}, +{"path": "fm", "type": "enum", "enum": {"idle": 0, "opening": 1, "closing": 2, "opened": 3, "closed": 4, "no_motor": 5}}, +{"path": "fa", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "offline": 3}, "readonly": false, "cmd": "cc fa"}, +{"path": "mp", "type": "float", "readonly": false, "cmd": "cc mp"}, +{"path": "msp", "type": "float"}, +{"path": "mmp", "type": "float"}, +{"path": "mc", "type": "float", "readonly": false, "cmd": "cc mc"}, +{"path": "mfc", "type": "float", "readonly": false, "cmd": "cc mfc"}, +{"path": "moc", "type": "float", "readonly": false, "cmd": "cc moc"}, +{"path": "mtc", "type": "float", "readonly": false, "cmd": "cc mtc"}, +{"path": "mtl", "type": "float"}, +{"path": "mft", "type": "float", "readonly": false, "cmd": "cc mft"}, +{"path": "mt", "type": "float"}, +{"path": "mo", "type": "float"}, +{"path": "mcr", "type": "float"}, +{"path": "mot", "type": "float"}, +{"path": "mw", "type": "float", "readonly": false, "cmd": "cc mw", "description": "correction pulse after automatic open"}, +{"path": "hav", "type": "bool", "readonly": false, "cmd": "cc hav"}, +{"path": "h", "type": "float"}, +{"path": "hr", "type": "float"}, +{"path": "hc", "type": "float"}, +{"path": "hu", "type": "float"}, +{"path": "hh", "type": "float", "readonly": false, "cmd": "cc hh"}, +{"path": "hl", "type": "float", "readonly": false, "cmd": "cc hl"}, +{"path": "htf", "type": "float", "readonly": false, "cmd": "cc htf", "description": "meas. period in fast mode"}, +{"path": "hts", "type": "float", "readonly": false, "cmd": "cc hts", "description": "meas. period in slow mode"}, +{"path": "hd", "type": "float", "readonly": false, "cmd": "cc hd"}, +{"path": "hwr", "type": "float", "readonly": false, "cmd": "cc hwr"}, +{"path": "hem", "type": "float", "readonly": false, "cmd": "cc hem", "description": "sensor length in mm from top to empty pos."}, +{"path": "hfu", "type": "float", "readonly": false, "cmd": "cc hfu", "description": "sensor length in mm from top to full pos."}, +{"path": "hcd", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3, "manual": 7}, "readonly": false, "cmd": "cc hcd"}, +{"path": "hv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4}}, +{"path": "hsf", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "ha", "type": "bool", "readonly": false, "cmd": "cc ha"}, +{"path": "hm", "type": "bool"}, +{"path": "hf", "type": "enum", "enum": {"slow": 0, "fast": 1}, "readonly": false, "cmd": "cc hf"}, +{"path": "hbe", "type": "bool", "readonly": false, "cmd": "cc hbe"}, +{"path": "hmf", "type": "float"}, +{"path": "hms", "type": "float"}, +{"path": "hit", "type": "float", "readonly": false, "cmd": "cc hit"}, +{"path": "hft", "type": "int", "readonly": false, "cmd": "cc hft"}, +{"path": "hea", "type": "enum", "enum": {"0": 0, "1": 1, "6": 2}, "readonly": false, "cmd": "cc hea"}, +{"path": "hch", "type": "int", "readonly": false, "cmd": "cc hch"}, +{"path": "hwr0", "type": "float", "readonly": false, "cmd": "cc hwr0"}, +{"path": "hem0", "type": "float", "readonly": false, "cmd": "cc hem0", "description": "sensor length in mm from top to empty pos."}, +{"path": "hfu0", "type": "float", "readonly": false, "cmd": "cc hfu0", "description": "sensor length in mm from top to full pos."}, +{"path": "hd0", "type": "float", "readonly": false, "cmd": "cc hd0", "description": "external sensor drive current (mA)"}, +{"path": "h0", "type": "float"}, +{"path": "hs0", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h1", "type": "float"}, +{"path": "hs1", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h2", "type": "float"}, +{"path": "hs2", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h3", "type": "float"}, +{"path": "hs3", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h4", "type": "float"}, +{"path": "hs4", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "h5", "type": "float"}, +{"path": "hs5", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "hfb", "type": "float"}, +{"path": "nav", "type": "bool", "readonly": false, "cmd": "cc nav"}, +{"path": "nu", "type": "float"}, +{"path": "nl", "type": "float"}, +{"path": "nth", "type": "float", "readonly": false, "cmd": "cc nth"}, +{"path": "ntc", "type": "float", "readonly": false, "cmd": "cc ntc"}, +{"path": "ntm", "type": "float", "readonly": false, "cmd": "cc ntm"}, +{"path": "ns", "type": "enum", "enum": {"sens_ok": 0, "no_sens": 1, "short_circuit": 2, "upside_down": 3, "sens_warm": 4, "empty": 5}}, +{"path": "na", "type": "bool", "readonly": false, "cmd": "cc na"}, +{"path": "nv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4, "boost": 5}}, +{"path": "nc", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3}, "readonly": false, "cmd": "cc nc"}, +{"path": "nfb", "type": "float"}, +{"path": "cda", "type": "float"}, +{"path": "cdb", "type": "float"}, +{"path": "cba", "type": "float"}, +{"path": "cbb", "type": "float"}, +{"path": "cvs", "type": "int"}, +{"path": "csp", "type": "int"}, +{"path": "cdv", "type": "text", "readonly": false, "cmd": "cc cdv"}, +{"path": "cic", "type": "text", "readonly": false, "cmd": "cc cic"}, +{"path": "cin", "type": "text"}, +{"path": "cds", "type": "enum", "enum": {"local": 0, "remote": 1, "loading": 2, "by_code": 3, "by_touch": 4}, "readonly": false, "cmd": "cc cds"}, +{"path": "timing", "type": "bool", "readonly": false, "cmd": "cc timing"}, +{"path": "tc", "type": "float", "visibility": 3}, +{"path": "tn", "type": "float", "visibility": 3}, +{"path": "th", "type": "float", "visibility": 3}, +{"path": "tf", "type": "float", "visibility": 3}, +{"path": "tm", "type": "float", "visibility": 3}, +{"path": "tv", "type": "float", "visibility": 3}, +{"path": "tq", "type": "float", "visibility": 3}, +{"path": "bdl", "type": "float", "readonly": false, "cmd": "cc bdl"}]}, + +"nv": {"base": "/nv", "params": [ +{"path": "", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "close": 3, "open": 4}, "readonly": false, "cmd": "nv", "kids": 11}, +{"path": "send", "type": "text", "readonly": false, "cmd": "nv send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "motstat", "type": "enum", "enum": {"idle": 0, "opening": 1, "closing": 2, "opened": 3, "closed": 4, "no_motor": 5}}, +{"path": "flow", "type": "float"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "nv set"}, +{"path": "flowmax", "type": "float", "readonly": false, "cmd": "nv flowmax"}, +{"path": "flowp", "type": "float"}, +{"path": "span", "type": "float"}, +{"path": "ctrl", "type": "none", "kids": 13}, +{"path": "ctrl/regtext", "type": "text"}, +{"path": "ctrl/prop_o", "type": "float", "readonly": false, "cmd": "nv ctrl/prop_o", "description": "prop [sec/mbar] when opening. above 4 mbar a 10 times lower value is used"}, +{"path": "ctrl/prop_c", "type": "float", "readonly": false, "cmd": "nv ctrl/prop_c", "description": "prop [sec/mbar] when closing. above 4 mbar a 10 times lower value is used"}, +{"path": "ctrl/deriv_o", "type": "float", "readonly": false, "cmd": "nv ctrl/deriv_o", "description": "convergence target time [sec] when opening"}, +{"path": "ctrl/deriv_c", "type": "float", "readonly": false, "cmd": "nv ctrl/deriv_c", "description": "convergence target time [sec] when closing"}, +{"path": "ctrl/minpulse_o", "type": "float", "readonly": false, "cmd": "nv ctrl/minpulse_o", "description": "minimum close pulse [sec]"}, +{"path": "ctrl/minpulse_c", "type": "float", "readonly": false, "cmd": "nv ctrl/minpulse_c", "description": "standard close pulse [sec]"}, +{"path": "ctrl/hystpulse_o", "type": "float", "readonly": false, "cmd": "nv ctrl/hystpulse_o", "description": "motor pulse to overcome hysteresis when opening"}, +{"path": "ctrl/hystpulse_c", "type": "float", "readonly": false, "cmd": "nv ctrl/hystpulse_c", "description": "motor pulse to overcome hysteresis when closing"}, +{"path": "ctrl/tol", "type": "float", "readonly": false, "cmd": "nv ctrl/tol", "description": "valid below 3 mbar"}, +{"path": "ctrl/tolhigh", "type": "float", "readonly": false, "cmd": "nv ctrl/tolhigh", "description": "valid above 4 mbar"}, +{"path": "ctrl/openpulse", "type": "float", "readonly": false, "cmd": "nv ctrl/openpulse", "description": "time to open from completely closed to a significant opening"}, +{"path": "ctrl/adjust_minpulse", "type": "bool", "readonly": false, "cmd": "nv ctrl/adjust_minpulse", "description": "adjust minpulse automatically"}, +{"path": "autoflow", "type": "none", "kids": 24}, +{"path": "autoflow/suspended", "type": "bool", "readonly": false, "cmd": "nv autoflow/suspended"}, +{"path": "autoflow/prop", "type": "float", "readonly": false, "cmd": "nv autoflow/prop"}, +{"path": "autoflow/flowstd", "type": "float", "readonly": false, "cmd": "nv autoflow/flowstd"}, +{"path": "autoflow/flowlim", "type": "float", "readonly": false, "cmd": "nv autoflow/flowlim"}, +{"path": "autoflow/smooth", "type": "float", "readonly": false, "cmd": "nv autoflow/smooth"}, +{"path": "autoflow/difSize", "type": "float", "readonly": false, "cmd": "nv autoflow/difSize"}, +{"path": "autoflow/difRange", "type": "float", "readonly": false, "cmd": "nv autoflow/difRange"}, +{"path": "autoflow/flowSize", "type": "float", "readonly": false, "cmd": "nv autoflow/flowSize"}, +{"path": "autoflow/convTime", "type": "float", "readonly": false, "cmd": "nv autoflow/convTime"}, +{"path": "autoflow/Tmin", "type": "float", "readonly": false, "cmd": "nv autoflow/Tmin"}, +{"path": "autoflow/script", "type": "text", "readonly": false, "cmd": "nv autoflow/script"}, +{"path": "autoflow/getTemp", "type": "text", "readonly": false, "cmd": "nv autoflow/getTemp"}, +{"path": "autoflow/getTset", "type": "text", "readonly": false, "cmd": "nv autoflow/getTset"}, +{"path": "autoflow/getFlow", "type": "text", "readonly": false, "cmd": "nv autoflow/getFlow"}, +{"path": "autoflow/difBuf", "type": "text"}, +{"path": "autoflow/flowBuf", "type": "text"}, +{"path": "autoflow/flowset", "type": "float"}, +{"path": "autoflow/flowmin", "type": "float"}, +{"path": "autoflow/flowmax", "type": "float"}, +{"path": "autoflow/difmin", "type": "float"}, +{"path": "autoflow/difmax", "type": "float"}, +{"path": "autoflow/setmin", "type": "float"}, +{"path": "autoflow/setmax", "type": "float"}, +{"path": "autoflow/flowtarget", "type": "float"}, +{"path": "calib", "type": "none", "kids": 2}, +{"path": "calib/ln_per_min_per_mbar", "type": "float", "readonly": false, "cmd": "nv calib/ln_per_min_per_mbar"}, +{"path": "calib/mbar_offset", "type": "float", "readonly": false, "cmd": "nv calib/mbar_offset"}]}, + +"ln2fill": {"base": "/ln2fill", "params": [ +{"path": "", "type": "enum", "enum": {"watching": 0, "fill": 1, "inactive": 2}, "readonly": false, "cmd": "ln2fill", "kids": 3}, +{"path": "send", "type": "text", "readonly": false, "cmd": "ln2fill send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "state", "type": "text"}]}, + +"hefill": {"base": "/hefill", "params": [ +{"path": "", "type": "enum", "enum": {"watching": 0, "fill": 1, "timeout": 2}, "readonly": false, "cmd": "hefill", "kids": 6}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hefill send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "fast", "type": "enum", "enum": {"slow": 0, "fast": 1}, "readonly": false, "cmd": "cc hf"}, +{"path": "state", "type": "text"}, +{"path": "hefull", "type": "float", "readonly": false, "cmd": "cc hh"}, +{"path": "helow", "type": "float", "readonly": false, "cmd": "cc hl"}]}, + +"hepump": {"base": "/hepump", "params": [ +{"path": "", "type": "enum", "enum": {"xds35_auto": 0, "xds35_manual": 1, "sv65": 2, "other": 3, "no": -1}, "readonly": false, "cmd": "hepump", "description": "xds35: scroll pump, sv65: leybold", "kids": 9}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hepump send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "running", "type": "bool", "readonly": false, "cmd": "hepump running"}, +{"path": "eco", "type": "bool", "readonly": false, "cmd": "hepump eco"}, +{"path": "auto", "type": "bool", "readonly": false, "cmd": "hepump auto"}, +{"path": "valve", "type": "enum", "enum": {"closed": 0, "closing": 1, "opening": 2, "opened": 3, "undefined": 4}, "readonly": false, "cmd": "hepump valve"}, +{"path": "eco_t_lim", "type": "float", "readonly": false, "cmd": "hepump eco_t_lim", "description": "switch off eco mode when T_set < eco_t_lim and T < eco_t_lim * 2"}, +{"path": "calib", "type": "float", "readonly": false, "cmd": "hepump calib", "visibility": 3}]}, + +"hemot": {"base": "/hepump/hemot", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run hemot", "kids": 32}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hemot send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "hemot is_running", "visibility": 3}, +{"path": "pos", "type": "float"}, +{"path": "encoder", "type": "float"}, +{"path": "zero", "type": "float", "readonly": false, "cmd": "hemot zero"}, +{"path": "lowerlimit", "type": "float", "readonly": false, "cmd": "hemot lowerlimit"}, +{"path": "upperlimit", "type": "float", "readonly": false, "cmd": "hemot upperlimit"}, +{"path": "disablelimits", "type": "bool", "readonly": false, "cmd": "hemot disablelimits"}, +{"path": "verbose", "type": "bool", "readonly": false, "cmd": "hemot verbose"}, +{"path": "target", "type": "float"}, +{"path": "runstate", "type": "enum", "enum": {"idle": 0, "running": 1, "finished": 2, "error": 3}}, +{"path": "precision", "type": "float", "readonly": false, "cmd": "hemot precision"}, +{"path": "maxencdif", "type": "float", "readonly": false, "cmd": "hemot maxencdif"}, +{"path": "id", "type": "float", "readonly": false, "cmd": "hemot id"}, +{"path": "pump_number", "type": "float", "readonly": false, "cmd": "hemot pump_number"}, +{"path": "init", "type": "float", "readonly": false, "cmd": "hemot init"}, +{"path": "maxspeed", "type": "float", "readonly": false, "cmd": "hemot maxspeed"}, +{"path": "acceleration", "type": "float", "readonly": false, "cmd": "hemot acceleration"}, +{"path": "maxcurrent", "type": "float", "readonly": false, "cmd": "hemot maxcurrent"}, +{"path": "standbycurrent", "type": "float", "readonly": false, "cmd": "hemot standbycurrent"}, +{"path": "freewheeling", "type": "bool", "readonly": false, "cmd": "hemot freewheeling"}, +{"path": "output0", "type": "bool", "readonly": false, "cmd": "hemot output0"}, +{"path": "output1", "type": "bool", "readonly": false, "cmd": "hemot output1"}, +{"path": "input3", "type": "bool"}, +{"path": "input0", "type": "float"}, +{"path": "input0raw", "type": "float"}, +{"path": "pullup", "type": "float", "readonly": false, "cmd": "hemot pullup"}, +{"path": "nopumpfeedback", "type": "bool", "readonly": false, "cmd": "hemot nopumpfeedback"}, +{"path": "eeprom", "type": "enum", "enum": {"ok": 0, "dirty": 1, "save": 2, "load": 3}, "readonly": false, "cmd": "hemot eeprom"}, +{"path": "customadr", "type": "text", "readonly": false, "cmd": "hemot customadr"}, +{"path": "custompar", "type": "float", "readonly": false, "cmd": "hemot custompar"}]}, + +"table": {"base": "/table", "params": [ +{"path": "", "type": "none", "kids": 17}, +{"path": "send", "type": "text", "readonly": false, "cmd": "table send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "fix_tt_set_prop", "type": "bool", "readonly": false, "cmd": "table fix_tt_set_prop"}, +{"path": "val_tt_set_prop", "type": "float"}, +{"path": "tbl_tt_set_prop", "type": "text", "readonly": false, "cmd": "table tbl_tt_set_prop", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_set_integ", "type": "bool", "readonly": false, "cmd": "table fix_tt_set_integ"}, +{"path": "val_tt_set_integ", "type": "float"}, +{"path": "tbl_tt_set_integ", "type": "text", "readonly": false, "cmd": "table tbl_tt_set_integ", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_dblctrl_int2", "type": "bool", "readonly": false, "cmd": "table fix_tt_dblctrl_int2"}, +{"path": "val_tt_dblctrl_int2", "type": "float"}, +{"path": "tbl_tt_dblctrl_int2", "type": "text", "readonly": false, "cmd": "table tbl_tt_dblctrl_int2", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_dblctrl_prop_up", "type": "bool", "readonly": false, "cmd": "table fix_tt_dblctrl_prop_up"}, +{"path": "val_tt_dblctrl_prop_up", "type": "float"}, +{"path": "tbl_tt_dblctrl_prop_up", "type": "text", "readonly": false, "cmd": "table tbl_tt_dblctrl_prop_up", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_dblctrl_prop_lo", "type": "bool", "readonly": false, "cmd": "table fix_tt_dblctrl_prop_lo"}, +{"path": "val_tt_dblctrl_prop_lo", "type": "float"}, +{"path": "tbl_tt_dblctrl_prop_lo", "type": "text", "readonly": false, "cmd": "table tbl_tt_dblctrl_prop_lo", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}]}} diff --git a/cfg/sea/ma11_dil4_ultrasound_sr.cfg b/cfg/sea/ma11_dil4_ultrasound_sr.cfg index 260cf20..7fb66b3 100644 --- a/cfg/sea/ma11_dil4_ultrasound_sr.cfg +++ b/cfg/sea/ma11_dil4_ultrasound_sr.cfg @@ -12,108 +12,108 @@ uri = tcp://samenv.psi.ch:8645 [module tt] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = tt.ma11.config remote_paths = . [module nv] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = nv.ma11.config remote_paths = . [module ln2fill] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ln2fill.ma11.config remote_paths = . [module hefill] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = hefill.ma11.config remote_paths = . [module tcoil] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tcoil.ma11.config remote_paths = . [module table] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = table.ma11.config remote_paths = . [module lnv] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = lnv.ma11.config remote_paths = . [module lpr] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = lpr.ma11.config remote_paths = . [module lambdawatch] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = lambdawatch.ma11.config remote_paths = . [module ts] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = ts.dil4.stick remote_paths = . [module treg] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = treg.dil4.stick remote_paths = . [module tmon] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tmon.dil4.stick remote_paths = . [module sorb] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = sorb.dil4.stick remote_paths = . [module ultrasound] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ultrasound.ultrasound.addon remote_paths = . [module fn] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = fn.ultrasound.addon remote_paths = . [module mirror] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = mirror.ultrasound.addon remote_paths = . [module f] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = f.ultrasound.addon remote_paths = . [module pars] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pars.ultrasound.addon remote_paths = . diff --git a/cfg/sea/ma6.config.json b/cfg/sea/ma6.config.json new file mode 100644 index 0000000..b16c12c --- /dev/null +++ b/cfg/sea/ma6.config.json @@ -0,0 +1,353 @@ +{"tt": {"base": "/tt", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run tt", "description": "tt", "kids": 18}, +{"path": "send", "type": "text", "readonly": false, "cmd": "tt send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "tt is_running", "visibility": 3}, +{"path": "mainloop", "type": "text", "readonly": false, "cmd": "tt mainloop", "visibility": 3}, +{"path": "target", "type": "float"}, +{"path": "running", "type": "int"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "tt tolerance"}, +{"path": "maxwait", "type": "float", "readonly": false, "cmd": "tt maxwait"}, +{"path": "settle", "type": "float", "readonly": false, "cmd": "tt settle"}, +{"path": "log", "type": "text", "readonly": false, "cmd": "tt log", "visibility": 3, "kids": 4}, +{"path": "log/mean", "type": "float", "visibility": 3}, +{"path": "log/m2", "type": "float", "visibility": 3}, +{"path": "log/stddev", "type": "float", "visibility": 3}, +{"path": "log/n", "type": "float", "visibility": 3}, +{"path": "dblctrl", "type": "bool", "readonly": false, "cmd": "tt dblctrl", "kids": 9}, +{"path": "dblctrl/tshift", "type": "float", "readonly": false, "cmd": "tt dblctrl/tshift"}, +{"path": "dblctrl/mode", "type": "enum", "enum": {"disabled": -1, "inactive": 0, "stable": 1, "up": 2, "down": 3}, "readonly": false, "cmd": "tt dblctrl/mode"}, +{"path": "dblctrl/shift_up", "type": "float"}, +{"path": "dblctrl/shift_lo", "type": "float"}, +{"path": "dblctrl/t_min", "type": "float"}, +{"path": "dblctrl/t_max", "type": "float"}, +{"path": "dblctrl/int2", "type": "float", "readonly": false, "cmd": "tt dblctrl/int2"}, +{"path": "dblctrl/prop_up", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_up"}, +{"path": "dblctrl/prop_lo", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_lo"}, +{"path": "tm", "type": "float", "kids": 4}, +{"path": "tm/curve", "type": "text", "readonly": false, "cmd": "tt tm/curve", "kids": 1}, +{"path": "tm/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt tm/curve/points", "visibility": 3}, +{"path": "tm/alarm", "type": "float", "readonly": false, "cmd": "tt tm/alarm"}, +{"path": "tm/stddev", "type": "float"}, +{"path": "tm/raw", "type": "float"}, +{"path": "ts", "type": "float", "kids": 4}, +{"path": "ts/curve", "type": "text", "readonly": false, "cmd": "tt ts/curve", "kids": 1}, +{"path": "ts/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt ts/curve/points", "visibility": 3}, +{"path": "ts/alarm", "type": "float", "readonly": false, "cmd": "tt ts/alarm"}, +{"path": "ts/stddev", "type": "float"}, +{"path": "ts/raw", "type": "float"}, +{"path": "ts_2", "type": "float", "kids": 4}, +{"path": "ts_2/curve", "type": "text", "readonly": false, "cmd": "tt ts_2/curve", "kids": 1}, +{"path": "ts_2/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt ts_2/curve/points", "visibility": 3}, +{"path": "ts_2/alarm", "type": "float", "readonly": false, "cmd": "tt ts_2/alarm"}, +{"path": "ts_2/stddev", "type": "float"}, +{"path": "ts_2/raw", "type": "float"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "tt set", "kids": 18}, +{"path": "set/mode", "type": "enum", "enum": {"disabled": -1, "off": 0, "controlling": 1, "manual": 2}, "readonly": false, "cmd": "tt set/mode"}, +{"path": "set/reg", "type": "float"}, +{"path": "set/ramp", "type": "float", "readonly": false, "cmd": "tt set/ramp", "description": "maximum ramp in K/min (0: ramp off)"}, +{"path": "set/wramp", "type": "float", "readonly": false, "cmd": "tt set/wramp"}, +{"path": "set/smooth", "type": "float", "readonly": false, "cmd": "tt set/smooth", "description": "smooth time (minutes)"}, +{"path": "set/channel", "type": "text", "readonly": false, "cmd": "tt set/channel"}, +{"path": "set/limit", "type": "float", "readonly": false, "cmd": "tt set/limit"}, +{"path": "set/resist", "type": "float", "readonly": false, "cmd": "tt set/resist"}, +{"path": "set/maxheater", "type": "text", "readonly": false, "cmd": "tt set/maxheater", "description": "maximum heater limit, units should be given without space: W, mW, A, mA"}, +{"path": "set/linearpower", "type": "float", "readonly": false, "cmd": "tt set/linearpower", "description": "when not 0, it is the maximum effective power, and the power is linear to the heater output"}, +{"path": "set/maxpowerlim", "type": "float", "description": "the maximum power limit (before any booster or converter)"}, +{"path": "set/maxpower", "type": "float", "readonly": false, "cmd": "tt set/maxpower", "description": "maximum power [W]"}, +{"path": "set/maxcurrent", "type": "float", "description": "the maximum current before any booster or converter"}, +{"path": "set/manualpower", "type": "float", "readonly": false, "cmd": "tt set/manualpower"}, +{"path": "set/power", "type": "float"}, +{"path": "set/prop", "type": "float", "readonly": false, "cmd": "tt set/prop", "description": "bigger means more gain"}, +{"path": "set/integ", "type": "float", "readonly": false, "cmd": "tt set/integ", "description": "bigger means faster"}, +{"path": "set/deriv", "type": "float", "readonly": false, "cmd": "tt set/deriv"}, +{"path": "setsamp", "type": "float", "readonly": false, "cmd": "tt setsamp", "kids": 18}, +{"path": "setsamp/mode", "type": "enum", "enum": {"disabled": -1, "off": 0, "controlling": 1, "manual": 2}, "readonly": false, "cmd": "tt setsamp/mode"}, +{"path": "setsamp/reg", "type": "float"}, +{"path": "setsamp/ramp", "type": "float", "readonly": false, "cmd": "tt setsamp/ramp", "description": "maximum ramp in K/min (0: ramp off)"}, +{"path": "setsamp/wramp", "type": "float", "readonly": false, "cmd": "tt setsamp/wramp"}, +{"path": "setsamp/smooth", "type": "float", "readonly": false, "cmd": "tt setsamp/smooth", "description": "smooth time (minutes)"}, +{"path": "setsamp/channel", "type": "text", "readonly": false, "cmd": "tt setsamp/channel"}, +{"path": "setsamp/limit", "type": "float", "readonly": false, "cmd": "tt setsamp/limit"}, +{"path": "setsamp/resist", "type": "float", "readonly": false, "cmd": "tt setsamp/resist"}, +{"path": "setsamp/maxheater", "type": "text", "readonly": false, "cmd": "tt setsamp/maxheater", "description": "maximum heater limit, units should be given without space: W, mW, A, mA"}, +{"path": "setsamp/linearpower", "type": "float", "readonly": false, "cmd": "tt setsamp/linearpower", "description": "when not 0, it is the maximum effective power, and the power is linear to the heater output"}, +{"path": "setsamp/maxpowerlim", "type": "float", "description": "the maximum power limit (before any booster or converter)"}, +{"path": "setsamp/maxpower", "type": "float", "readonly": false, "cmd": "tt setsamp/maxpower", "description": "maximum power [W]"}, +{"path": "setsamp/maxcurrent", "type": "float", "description": "the maximum current before any booster or converter"}, +{"path": "setsamp/manualpower", "type": "float", "readonly": false, "cmd": "tt setsamp/manualpower"}, +{"path": "setsamp/power", "type": "float"}, +{"path": "setsamp/prop", "type": "float", "readonly": false, "cmd": "tt setsamp/prop", "description": "bigger means more gain"}, +{"path": "setsamp/integ", "type": "float", "readonly": false, "cmd": "tt setsamp/integ", "description": "bigger means faster"}, +{"path": "setsamp/deriv", "type": "float", "readonly": false, "cmd": "tt setsamp/deriv"}, +{"path": "display", "type": "text", "readonly": false, "cmd": "tt display"}, +{"path": "remote", "type": "bool"}]}, + +"cc": {"base": "/cc", "params": [ +{"path": "", "type": "bool", "kids": 96}, +{"path": "send", "type": "text", "readonly": false, "cmd": "cc send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "autodevice", "type": "bool", "readonly": false, "cmd": "cc autodevice"}, +{"path": "fav", "type": "bool", "readonly": false, "cmd": "cc fav"}, +{"path": "f", "type": "float"}, +{"path": "fs", "type": "enum", "enum": {"ok": 0, "no_sens": 1}, "readonly": false, "cmd": "cc fs"}, +{"path": "mav", "type": "bool", "readonly": false, "cmd": "cc mav"}, +{"path": "fm", "type": "enum", "enum": {"idle": 0, "opening": 1, "closing": 2, "opened": 3, "closed": 4, "no_motor": 5}}, +{"path": "fa", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "offline": 3}, "readonly": false, "cmd": "cc fa"}, +{"path": "mp", "type": "float", "readonly": false, "cmd": "cc mp"}, +{"path": "msp", "type": "float"}, +{"path": "mmp", "type": "float"}, +{"path": "mc", "type": "float", "readonly": false, "cmd": "cc mc"}, +{"path": "mfc", "type": "float", "readonly": false, "cmd": "cc mfc"}, +{"path": "moc", "type": "float", "readonly": false, "cmd": "cc moc"}, +{"path": "mtc", "type": "float", "readonly": false, "cmd": "cc mtc"}, +{"path": "mtl", "type": "float"}, +{"path": "mft", "type": "float", "readonly": false, "cmd": "cc mft"}, +{"path": "mt", "type": "float"}, +{"path": "mo", "type": "float"}, +{"path": "mcr", "type": "float"}, +{"path": "mot", "type": "float"}, +{"path": "mw", "type": "float", "readonly": false, "cmd": "cc mw", "description": "correction pulse after automatic open"}, +{"path": "hav", "type": "bool", "readonly": false, "cmd": "cc hav"}, +{"path": "h", "type": "float"}, +{"path": "hr", "type": "float"}, +{"path": "hc", "type": "float"}, +{"path": "hu", "type": "float"}, +{"path": "hh", "type": "float", "readonly": false, "cmd": "cc hh"}, +{"path": "hl", "type": "float", "readonly": false, "cmd": "cc hl"}, +{"path": "htf", "type": "float", "readonly": false, "cmd": "cc htf", "description": "meas. period in fast mode"}, +{"path": "hts", "type": "float", "readonly": false, "cmd": "cc hts", "description": "meas. period in slow mode"}, +{"path": "hd", "type": "float", "readonly": false, "cmd": "cc hd"}, +{"path": "hwr", "type": "float", "readonly": false, "cmd": "cc hwr"}, +{"path": "hem", "type": "float", "readonly": false, "cmd": "cc hem", "description": "sensor length in mm from top to empty pos."}, +{"path": "hfu", "type": "float", "readonly": false, "cmd": "cc hfu", "description": "sensor length in mm from top to full pos."}, +{"path": "hcd", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3, "manual": 7}, "readonly": false, "cmd": "cc hcd"}, +{"path": "hv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4}}, +{"path": "hsf", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "ha", "type": "bool", "readonly": false, "cmd": "cc ha"}, +{"path": "hm", "type": "bool"}, +{"path": "hf", "type": "enum", "enum": {"slow": 0, "fast": 1}, "readonly": false, "cmd": "cc hf"}, +{"path": "hbe", "type": "bool", "readonly": false, "cmd": "cc hbe"}, +{"path": "hmf", "type": "float"}, +{"path": "hms", "type": "float"}, +{"path": "hit", "type": "float", "readonly": false, "cmd": "cc hit"}, +{"path": "hft", "type": "int", "readonly": false, "cmd": "cc hft"}, +{"path": "hea", "type": "enum", "enum": {"0": 0, "1": 1, "6": 2}, "readonly": false, "cmd": "cc hea"}, +{"path": "hch", "type": "int", "readonly": false, "cmd": "cc hch", "visibility": 3}, +{"path": "hwr0", "type": "float", "readonly": false, "cmd": "cc hwr0", "visibility": 3}, +{"path": "hem0", "type": "float", "readonly": false, "cmd": "cc hem0", "description": "sensor length in mm from top to empty pos.", "visibility": 3}, +{"path": "hfu0", "type": "float", "readonly": false, "cmd": "cc hfu0", "description": "sensor length in mm from top to full pos.", "visibility": 3}, +{"path": "hd0", "type": "float", "readonly": false, "cmd": "cc hd0", "description": "external sensor drive current (mA)", "visibility": 3}, +{"path": "h0", "type": "float", "visibility": 3}, +{"path": "hs0", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h1", "type": "float", "visibility": 3}, +{"path": "hs1", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h2", "type": "float", "visibility": 3}, +{"path": "hs2", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h3", "type": "float", "visibility": 3}, +{"path": "hs3", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h4", "type": "float", "visibility": 3}, +{"path": "hs4", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h5", "type": "float", "visibility": 3}, +{"path": "hs5", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "hfb", "type": "float"}, +{"path": "nav", "type": "bool", "readonly": false, "cmd": "cc nav"}, +{"path": "nu", "type": "float"}, +{"path": "nl", "type": "float"}, +{"path": "nth", "type": "float", "readonly": false, "cmd": "cc nth"}, +{"path": "ntc", "type": "float", "readonly": false, "cmd": "cc ntc"}, +{"path": "ntm", "type": "float", "readonly": false, "cmd": "cc ntm"}, +{"path": "ns", "type": "enum", "enum": {"sens_ok": 0, "no_sens": 1, "short_circuit": 2, "upside_down": 3, "sens_warm": 4, "empty": 5}}, +{"path": "na", "type": "bool", "readonly": false, "cmd": "cc na"}, +{"path": "nv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4, "boost": 5}}, +{"path": "nc", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3}, "readonly": false, "cmd": "cc nc"}, +{"path": "nfb", "type": "float"}, +{"path": "cda", "type": "float"}, +{"path": "cdb", "type": "float"}, +{"path": "cba", "type": "float"}, +{"path": "cbb", "type": "float"}, +{"path": "cvs", "type": "int"}, +{"path": "csp", "type": "int"}, +{"path": "cdv", "type": "text", "readonly": false, "cmd": "cc cdv"}, +{"path": "cic", "type": "text", "readonly": false, "cmd": "cc cic"}, +{"path": "cin", "type": "text"}, +{"path": "cds", "type": "enum", "enum": {"local": 0, "remote": 1, "loading": 2, "by_code": 3, "by_touch": 4}, "readonly": false, "cmd": "cc cds"}, +{"path": "timing", "type": "bool", "readonly": false, "cmd": "cc timing"}, +{"path": "tc", "type": "float", "visibility": 3}, +{"path": "tn", "type": "float", "visibility": 3}, +{"path": "th", "type": "float", "visibility": 3}, +{"path": "tf", "type": "float", "visibility": 3}, +{"path": "tm", "type": "float", "visibility": 3}, +{"path": "tv", "type": "float", "visibility": 3}, +{"path": "tq", "type": "float", "visibility": 3}, +{"path": "bdl", "type": "float", "readonly": false, "cmd": "cc bdl"}]}, + +"nv": {"base": "/nv", "params": [ +{"path": "", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "close": 3, "open": 4}, "readonly": false, "cmd": "nv", "kids": 11}, +{"path": "send", "type": "text", "readonly": false, "cmd": "nv send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "motstat", "type": "enum", "enum": {"idle": 0, "opening": 1, "closing": 2, "opened": 3, "closed": 4, "no_motor": 5}}, +{"path": "flow", "type": "float"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "nv set"}, +{"path": "flowmax", "type": "float", "readonly": false, "cmd": "nv flowmax"}, +{"path": "flowp", "type": "float"}, +{"path": "span", "type": "float"}, +{"path": "ctrl", "type": "none", "kids": 13}, +{"path": "ctrl/regtext", "type": "text"}, +{"path": "ctrl/prop_o", "type": "float", "readonly": false, "cmd": "nv ctrl/prop_o", "description": "prop [sec/mbar] when opening. above 4 mbar a 10 times lower value is used"}, +{"path": "ctrl/prop_c", "type": "float", "readonly": false, "cmd": "nv ctrl/prop_c", "description": "prop [sec/mbar] when closing. above 4 mbar a 10 times lower value is used"}, +{"path": "ctrl/deriv_o", "type": "float", "readonly": false, "cmd": "nv ctrl/deriv_o", "description": "convergence target time [sec] when opening"}, +{"path": "ctrl/deriv_c", "type": "float", "readonly": false, "cmd": "nv ctrl/deriv_c", "description": "convergence target time [sec] when closing"}, +{"path": "ctrl/minpulse_o", "type": "float", "readonly": false, "cmd": "nv ctrl/minpulse_o", "description": "minimum close pulse [sec]"}, +{"path": "ctrl/minpulse_c", "type": "float", "readonly": false, "cmd": "nv ctrl/minpulse_c", "description": "standard close pulse [sec]"}, +{"path": "ctrl/hystpulse_o", "type": "float", "readonly": false, "cmd": "nv ctrl/hystpulse_o", "description": "motor pulse to overcome hysteresis when opening"}, +{"path": "ctrl/hystpulse_c", "type": "float", "readonly": false, "cmd": "nv ctrl/hystpulse_c", "description": "motor pulse to overcome hysteresis when closing"}, +{"path": "ctrl/tol", "type": "float", "readonly": false, "cmd": "nv ctrl/tol", "description": "valid below 3 mbar"}, +{"path": "ctrl/tolhigh", "type": "float", "readonly": false, "cmd": "nv ctrl/tolhigh", "description": "valid above 4 mbar"}, +{"path": "ctrl/openpulse", "type": "float", "readonly": false, "cmd": "nv ctrl/openpulse", "description": "time to open from completely closed to a significant opening"}, +{"path": "ctrl/adjust_minpulse", "type": "bool", "readonly": false, "cmd": "nv ctrl/adjust_minpulse", "description": "adjust minpulse automatically"}, +{"path": "autoflow", "type": "none", "kids": 24}, +{"path": "autoflow/suspended", "type": "bool", "readonly": false, "cmd": "nv autoflow/suspended"}, +{"path": "autoflow/prop", "type": "float", "readonly": false, "cmd": "nv autoflow/prop"}, +{"path": "autoflow/flowstd", "type": "float", "readonly": false, "cmd": "nv autoflow/flowstd"}, +{"path": "autoflow/flowlim", "type": "float", "readonly": false, "cmd": "nv autoflow/flowlim"}, +{"path": "autoflow/smooth", "type": "float", "readonly": false, "cmd": "nv autoflow/smooth"}, +{"path": "autoflow/difSize", "type": "float", "readonly": false, "cmd": "nv autoflow/difSize"}, +{"path": "autoflow/difRange", "type": "float", "readonly": false, "cmd": "nv autoflow/difRange"}, +{"path": "autoflow/flowSize", "type": "float", "readonly": false, "cmd": "nv autoflow/flowSize"}, +{"path": "autoflow/convTime", "type": "float", "readonly": false, "cmd": "nv autoflow/convTime"}, +{"path": "autoflow/Tmin", "type": "float", "readonly": false, "cmd": "nv autoflow/Tmin"}, +{"path": "autoflow/script", "type": "text", "readonly": false, "cmd": "nv autoflow/script"}, +{"path": "autoflow/getTemp", "type": "text", "readonly": false, "cmd": "nv autoflow/getTemp"}, +{"path": "autoflow/getTset", "type": "text", "readonly": false, "cmd": "nv autoflow/getTset"}, +{"path": "autoflow/getFlow", "type": "text", "readonly": false, "cmd": "nv autoflow/getFlow"}, +{"path": "autoflow/difBuf", "type": "text"}, +{"path": "autoflow/flowBuf", "type": "text"}, +{"path": "autoflow/flowset", "type": "float"}, +{"path": "autoflow/flowmin", "type": "float"}, +{"path": "autoflow/flowmax", "type": "float"}, +{"path": "autoflow/difmin", "type": "float"}, +{"path": "autoflow/difmax", "type": "float"}, +{"path": "autoflow/setmin", "type": "float"}, +{"path": "autoflow/setmax", "type": "float"}, +{"path": "autoflow/flowtarget", "type": "float"}, +{"path": "calib", "type": "none", "kids": 2}, +{"path": "calib/ln_per_min_per_mbar", "type": "float", "readonly": false, "cmd": "nv calib/ln_per_min_per_mbar"}, +{"path": "calib/mbar_offset", "type": "float", "readonly": false, "cmd": "nv calib/mbar_offset"}]}, + +"hepump": {"base": "/hepump", "params": [ +{"path": "", "type": "enum", "enum": {"xds35_auto": 0, "xds35_manual": 1, "sv65": 2, "other": 3, "no": -1}, "readonly": false, "cmd": "hepump", "description": "xds35: scroll pump, sv65: leybold", "kids": 10}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hepump send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "running", "type": "bool", "readonly": false, "cmd": "hepump running", "visibility": 3}, +{"path": "eco", "type": "bool", "readonly": false, "cmd": "hepump eco", "visibility": 3}, +{"path": "auto", "type": "bool", "readonly": false, "cmd": "hepump auto", "visibility": 3}, +{"path": "valve", "type": "enum", "enum": {"closed": 0, "closing": 1, "opening": 2, "opened": 3, "undefined": 4}, "readonly": false, "cmd": "hepump valve", "visibility": 3}, +{"path": "eco_t_lim", "type": "float", "readonly": false, "cmd": "hepump eco_t_lim", "description": "switch off eco mode when T_set < eco_t_lim and T < eco_t_lim * 2", "visibility": 3}, +{"path": "calib", "type": "float", "readonly": false, "cmd": "hepump calib", "visibility": 3}, +{"path": "health", "type": "float"}]}, + +"hemot": {"base": "/hepump/hemot", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run hemot", "visibility": 3, "kids": 30}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hemot send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "hemot is_running", "visibility": 3}, +{"path": "pos", "type": "float"}, +{"path": "encoder", "type": "float"}, +{"path": "zero", "type": "float", "readonly": false, "cmd": "hemot zero"}, +{"path": "lowerlimit", "type": "float", "readonly": false, "cmd": "hemot lowerlimit"}, +{"path": "upperlimit", "type": "float", "readonly": false, "cmd": "hemot upperlimit"}, +{"path": "disablelimits", "type": "bool", "readonly": false, "cmd": "hemot disablelimits"}, +{"path": "verbose", "type": "bool", "readonly": false, "cmd": "hemot verbose"}, +{"path": "target", "type": "float"}, +{"path": "runstate", "type": "enum", "enum": {"idle": 0, "running": 1, "finished": 2, "error": 3}}, +{"path": "precision", "type": "float", "readonly": false, "cmd": "hemot precision"}, +{"path": "maxencdif", "type": "float", "readonly": false, "cmd": "hemot maxencdif"}, +{"path": "id", "type": "float", "readonly": false, "cmd": "hemot id"}, +{"path": "pump_number", "type": "float", "readonly": false, "cmd": "hemot pump_number"}, +{"path": "init", "type": "float", "readonly": false, "cmd": "hemot init"}, +{"path": "maxspeed", "type": "float", "readonly": false, "cmd": "hemot maxspeed"}, +{"path": "acceleration", "type": "float", "readonly": false, "cmd": "hemot acceleration"}, +{"path": "maxcurrent", "type": "float", "readonly": false, "cmd": "hemot maxcurrent"}, +{"path": "standbycurrent", "type": "float", "readonly": false, "cmd": "hemot standbycurrent"}, +{"path": "freewheeling", "type": "bool", "readonly": false, "cmd": "hemot freewheeling"}, +{"path": "output0", "type": "bool", "readonly": false, "cmd": "hemot output0"}, +{"path": "output1", "type": "bool", "readonly": false, "cmd": "hemot output1"}, +{"path": "input3", "type": "bool"}, +{"path": "pullup", "type": "float", "readonly": false, "cmd": "hemot pullup"}, +{"path": "nopumpfeedback", "type": "bool", "readonly": false, "cmd": "hemot nopumpfeedback"}, +{"path": "eeprom", "type": "enum", "enum": {"ok": 0, "dirty": 1, "save": 2, "load": 3}, "readonly": false, "cmd": "hemot eeprom"}, +{"path": "customadr", "type": "text", "readonly": false, "cmd": "hemot customadr"}, +{"path": "custompar", "type": "float", "readonly": false, "cmd": "hemot custompar"}]}, + +"ln2fill": {"base": "/ln2fill", "params": [ +{"path": "", "type": "enum", "enum": {"no fill valve": 2}, "readonly": false, "cmd": "ln2fill", "kids": 14}, +{"path": "send", "type": "text", "readonly": false, "cmd": "ln2fill send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "state", "type": "text"}, +{"path": "readlevel", "type": "text", "readonly": false, "cmd": "ln2fill readlevel", "visibility": 3}, +{"path": "lowlevel", "type": "float", "readonly": false, "cmd": "ln2fill lowlevel"}, +{"path": "highlevel", "type": "float", "readonly": false, "cmd": "ln2fill highlevel"}, +{"path": "smooth", "type": "float"}, +{"path": "minfillminutes", "type": "float", "readonly": false, "cmd": "ln2fill minfillminutes"}, +{"path": "maxfillminutes", "type": "float", "readonly": false, "cmd": "ln2fill maxfillminutes"}, +{"path": "minholdhours", "type": "float", "readonly": false, "cmd": "ln2fill minholdhours"}, +{"path": "maxholdhours", "type": "float", "readonly": false, "cmd": "ln2fill maxholdhours"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "ln2fill tolerance"}, +{"path": "badreadingminutes", "type": "float", "readonly": false, "cmd": "ln2fill badreadingminutes"}, +{"path": "tubecoolingminutes", "type": "float", "readonly": false, "cmd": "ln2fill tubecoolingminutes"}]}, + +"hefill": {"base": "/hefill", "params": [ +{"path": "", "type": "enum", "enum": {"no fill valve": 2}, "readonly": false, "cmd": "hefill", "kids": 16}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hefill send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "state", "type": "text"}, +{"path": "readlevel", "type": "text", "readonly": false, "cmd": "hefill readlevel", "visibility": 3}, +{"path": "lowlevel", "type": "float", "readonly": false, "cmd": "hefill lowlevel"}, +{"path": "highlevel", "type": "float", "readonly": false, "cmd": "hefill highlevel"}, +{"path": "smooth", "type": "float"}, +{"path": "minfillminutes", "type": "float", "readonly": false, "cmd": "hefill minfillminutes"}, +{"path": "maxfillminutes", "type": "float", "readonly": false, "cmd": "hefill maxfillminutes"}, +{"path": "minholdhours", "type": "float", "readonly": false, "cmd": "hefill minholdhours"}, +{"path": "maxholdhours", "type": "float", "readonly": false, "cmd": "hefill maxholdhours"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "hefill tolerance"}, +{"path": "badreadingminutes", "type": "float", "readonly": false, "cmd": "hefill badreadingminutes"}, +{"path": "tubecoolingminutes", "type": "float", "readonly": false, "cmd": "hefill tubecoolingminutes"}, +{"path": "vessellimit", "type": "float", "readonly": false, "cmd": "hefill vessellimit"}, +{"path": "vext", "type": "float"}]}, + +"mf": {"base": "/mf", "params": [ +{"path": "", "type": "float", "kids": 26}, +{"path": "persmode", "type": "int", "readonly": false, "cmd": "mf persmode"}, +{"path": "perswitch", "type": "int"}, +{"path": "nowait", "type": "int", "readonly": false, "cmd": "mf nowait"}, +{"path": "maxlimit", "type": "float", "visibility": 3}, +{"path": "limit", "type": "float", "readonly": false, "cmd": "mf limit"}, +{"path": "ramp", "type": "float", "readonly": false, "cmd": "mf ramp"}, +{"path": "perscurrent", "type": "float", "readonly": false, "cmd": "mf perscurrent"}, +{"path": "perslimit", "type": "float", "readonly": false, "cmd": "mf perslimit"}, +{"path": "perswait", "type": "int", "readonly": false, "cmd": "mf perswait"}, +{"path": "persdelay", "type": "int", "readonly": false, "cmd": "mf persdelay"}, +{"path": "current", "type": "float"}, +{"path": "measured", "type": "float"}, +{"path": "voltage", "type": "float"}, +{"path": "lastfield", "type": "float", "visibility": 3}, +{"path": "ampRamp", "type": "float", "visibility": 3}, +{"path": "inductance", "type": "float", "visibility": 3}, +{"path": "trainedTo", "type": "float", "readonly": false, "cmd": "mf trainedTo"}, +{"path": "trainMode", "type": "int"}, +{"path": "external", "type": "int", "readonly": false, "cmd": "mf external"}, +{"path": "startScript", "type": "text", "readonly": false, "cmd": "mf startScript", "visibility": 3}, +{"path": "is_running", "type": "int", "visibility": 3}, +{"path": "verbose", "type": "int", "readonly": false, "cmd": "mf verbose", "visibility": 3}, +{"path": "driver", "type": "text", "visibility": 3}, +{"path": "creationCmd", "type": "text", "visibility": 3}, +{"path": "targetValue", "type": "float"}, +{"path": "status", "type": "text", "readonly": false, "cmd": "mf status", "visibility": 3}]}, + +"lev": {"base": "/lev", "params": [ +{"path": "", "type": "float", "kids": 4}, +{"path": "send", "type": "text", "readonly": false, "cmd": "lev send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "mode", "type": "enum", "enum": {"slow": 0, "fast (switches to slow automatically after filling)": 1}, "readonly": false, "cmd": "lev mode"}, +{"path": "n2", "type": "float"}]}} diff --git a/cfg/sea/ori1.cfg b/cfg/sea/ori1.cfg index 3b012d8..d8e91b1 100644 --- a/cfg/sea/ori1.cfg +++ b/cfg/sea/ori1.cfg @@ -12,12 +12,12 @@ uri = tcp://samenv.psi.ch:8642 [module tt] class = secop_psi.sea.SeaDrivable -iodev = seaconn +io = seaconn json_descr = tt.ori1.config remote_paths = . [module nv] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = nv.ori1.config remote_paths = . diff --git a/cfg/sea/sch5.stick.json b/cfg/sea/sch5.stick.json index 47ff8fc..2b47748 100644 --- a/cfg/sea/sch5.stick.json +++ b/cfg/sea/sch5.stick.json @@ -6,4 +6,307 @@ {"path": "limit", "type": "float", "readonly": false, "cmd": "warmup limit", "description": "do not use warmup when target < limit"}, {"path": "timef", "type": "float", "readonly": false, "cmd": "warmup timef", "description": "reset double control after (timef * int2) sec"}, {"path": "abruptstop", "type": "bool", "readonly": false, "cmd": "warmup abruptstop", "description": "switch off sample heater immediately after tm > treg"}, -{"path": "warmup", "type": "enum", "enum": {"off": 0, "warmup": 1, "htroff": 2, "settle": 3}, "readonly": false, "cmd": "warmup warmup"}]}} +{"path": "warmup", "type": "enum", "enum": {"off": 0, "warmup": 1, "htroff": 2, "settle": 3}, "readonly": false, "cmd": "warmup warmup"}]}, +"tt": {"base": "/tt", "params": [{"path": "", "type": "float", "readonly": false, "cmd": "run tt", "description": "tt", "kids": 18}, +{"path": "send", "type": "text", "readonly": false, "cmd": "tt send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "tt is_running", "visibility": 3}, +{"path": "target", "type": "float"}, +{"path": "running", "type": "int"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "tt tolerance"}, +{"path": "maxwait", "type": "float", "readonly": false, "cmd": "tt maxwait"}, +{"path": "settle", "type": "float", "readonly": false, "cmd": "tt settle"}, +{"path": "log", "type": "text", "readonly": false, "cmd": "tt log", "visibility": 3, "kids": 4}, +{"path": "log/mean", "type": "float", "visibility": 3}, +{"path": "log/m2", "type": "float", "visibility": 3}, +{"path": "log/stddev", "type": "float", "visibility": 3}, +{"path": "log/n", "type": "float", "visibility": 3}, +{"path": "dblctrl", "type": "bool", "readonly": false, "cmd": "tt dblctrl", "kids": 9}, +{"path": "dblctrl/tshift", "type": "float", "readonly": false, "cmd": "tt dblctrl/tshift"}, +{"path": "dblctrl/mode", "type": "enum", "enum": {"disabled": -1, "inactive": 0, "stable": 1, "up": 2, "down": 3}, "readonly": false, "cmd": "tt dblctrl/mode"}, +{"path": "dblctrl/shift_up", "type": "float"}, +{"path": "dblctrl/shift_lo", "type": "float"}, +{"path": "dblctrl/t_min", "type": "float"}, +{"path": "dblctrl/t_max", "type": "float"}, +{"path": "dblctrl/int2", "type": "float", "readonly": false, "cmd": "tt dblctrl/int2"}, +{"path": "dblctrl/prop_up", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_up"}, +{"path": "dblctrl/prop_lo", "type": "float", "readonly": false, "cmd": "tt dblctrl/prop_lo"}, +{"path": "tm", "type": "float", "kids": 4}, +{"path": "tm/curve", "type": "text", "readonly": false, "cmd": "tt tm/curve", "kids": 1}, +{"path": "tm/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt tm/curve/points", "visibility": 3}, +{"path": "tm/alarm", "type": "float", "readonly": false, "cmd": "tt tm/alarm"}, +{"path": "tm/stddev", "type": "float"}, +{"path": "tm/raw", "type": "float"}, +{"path": "ts", "type": "float", "kids": 4}, +{"path": "ts/curve", "type": "text", "readonly": false, "cmd": "tt ts/curve", "kids": 1}, +{"path": "ts/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt ts/curve/points", "visibility": 3}, +{"path": "ts/alarm", "type": "float", "readonly": false, "cmd": "tt ts/alarm"}, +{"path": "ts/stddev", "type": "float"}, +{"path": "ts/raw", "type": "float"}, +{"path": "ts_2", "type": "float", "visibility": 3, "kids": 4}, +{"path": "ts_2/curve", "type": "text", "readonly": false, "cmd": "tt ts_2/curve", "visibility": 3, "kids": 1}, +{"path": "ts_2/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt ts_2/curve/points", "visibility": 3}, +{"path": "ts_2/alarm", "type": "float", "readonly": false, "cmd": "tt ts_2/alarm", "visibility": 3}, +{"path": "ts_2/stddev", "type": "float", "visibility": 3}, +{"path": "ts_2/raw", "type": "float", "visibility": 3}, +{"path": "set", "type": "float", "readonly": false, "cmd": "tt set", "kids": 18}, +{"path": "set/mode", "type": "enum", "enum": {"disabled": -1, "off": 0, "controlling": 1, "manual": 2}, "readonly": false, "cmd": "tt set/mode"}, +{"path": "set/reg", "type": "float"}, +{"path": "set/ramp", "type": "float", "readonly": false, "cmd": "tt set/ramp", "description": "maximum ramp in K/min (0: ramp off)"}, +{"path": "set/wramp", "type": "float", "readonly": false, "cmd": "tt set/wramp"}, +{"path": "set/smooth", "type": "float", "readonly": false, "cmd": "tt set/smooth", "description": "smooth time (minutes)"}, +{"path": "set/channel", "type": "text", "readonly": false, "cmd": "tt set/channel"}, +{"path": "set/limit", "type": "float", "readonly": false, "cmd": "tt set/limit"}, +{"path": "set/resist", "type": "float", "readonly": false, "cmd": "tt set/resist"}, +{"path": "set/maxheater", "type": "text", "readonly": false, "cmd": "tt set/maxheater", "description": "maximum heater limit, units should be given without space: W, mW, A, mA"}, +{"path": "set/linearpower", "type": "float", "readonly": false, "cmd": "tt set/linearpower", "description": "when not 0, it is the maximum effective power, and the power is linear to the heater output"}, +{"path": "set/maxpowerlim", "type": "float", "description": "the maximum power limit (before any booster or converter)"}, +{"path": "set/maxpower", "type": "float", "readonly": false, "cmd": "tt set/maxpower", "description": "maximum power [W]"}, +{"path": "set/maxcurrent", "type": "float", "description": "the maximum current before any booster or converter"}, +{"path": "set/manualpower", "type": "float", "readonly": false, "cmd": "tt set/manualpower"}, +{"path": "set/power", "type": "float"}, +{"path": "set/prop", "type": "float", "readonly": false, "cmd": "tt set/prop", "description": "bigger means more gain"}, +{"path": "set/integ", "type": "float", "readonly": false, "cmd": "tt set/integ", "description": "bigger means faster"}, +{"path": "set/deriv", "type": "float", "readonly": false, "cmd": "tt set/deriv"}, +{"path": "display", "type": "text", "readonly": false, "cmd": "tt display"}, +{"path": "dout", "type": "int", "readonly": false, "cmd": "tt dout"}, +{"path": "dinp", "type": "int"}, +{"path": "remote", "type": "bool"}]}, "cc": {"base": "/cc", "params": [{"path": "", "type": "bool", "kids": 96}, +{"path": "send", "type": "text", "readonly": false, "cmd": "cc send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "autodevice", "type": "bool", "readonly": false, "cmd": "cc autodevice"}, +{"path": "fav", "type": "bool", "readonly": false, "cmd": "cc fav"}, +{"path": "f", "type": "float"}, +{"path": "fs", "type": "enum", "enum": {"ok": 0, "no_sens": 1}, "readonly": false, "cmd": "cc fs"}, +{"path": "mav", "type": "bool", "readonly": false, "cmd": "cc mav"}, +{"path": "fm", "type": "enum", "enum": {"idle": 0, "opening": 1, "closing": 2, "opened": 3, "closed": 4, "no_motor": 5}}, +{"path": "fa", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "offline": 3}, "readonly": false, "cmd": "cc fa"}, +{"path": "mp", "type": "float", "readonly": false, "cmd": "cc mp"}, +{"path": "msp", "type": "float"}, +{"path": "mmp", "type": "float"}, +{"path": "mc", "type": "float", "readonly": false, "cmd": "cc mc"}, +{"path": "mfc", "type": "float", "readonly": false, "cmd": "cc mfc"}, +{"path": "moc", "type": "float", "readonly": false, "cmd": "cc moc"}, +{"path": "mtc", "type": "float", "readonly": false, "cmd": "cc mtc"}, +{"path": "mtl", "type": "float"}, +{"path": "mft", "type": "float", "readonly": false, "cmd": "cc mft"}, +{"path": "mt", "type": "float"}, +{"path": "mo", "type": "float"}, +{"path": "mcr", "type": "float"}, +{"path": "mot", "type": "float"}, +{"path": "mw", "type": "float", "readonly": false, "cmd": "cc mw", "description": "correction pulse after automatic open"}, +{"path": "hav", "type": "bool", "readonly": false, "cmd": "cc hav"}, +{"path": "h", "type": "float"}, +{"path": "hr", "type": "float"}, +{"path": "hc", "type": "float"}, +{"path": "hu", "type": "float"}, +{"path": "hh", "type": "float", "readonly": false, "cmd": "cc hh"}, +{"path": "hl", "type": "float", "readonly": false, "cmd": "cc hl"}, +{"path": "htf", "type": "float", "readonly": false, "cmd": "cc htf", "description": "meas. period in fast mode"}, +{"path": "hts", "type": "float", "readonly": false, "cmd": "cc hts", "description": "meas. period in slow mode"}, +{"path": "hd", "type": "float", "readonly": false, "cmd": "cc hd"}, +{"path": "hwr", "type": "float", "readonly": false, "cmd": "cc hwr"}, +{"path": "hem", "type": "float", "readonly": false, "cmd": "cc hem", "description": "sensor length in mm from top to empty pos."}, +{"path": "hfu", "type": "float", "readonly": false, "cmd": "cc hfu", "description": "sensor length in mm from top to full pos."}, +{"path": "hcd", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3, "manual": 7}, "readonly": false, "cmd": "cc hcd"}, +{"path": "hv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4}}, +{"path": "hsf", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}}, +{"path": "ha", "type": "bool", "readonly": false, "cmd": "cc ha"}, +{"path": "hm", "type": "bool"}, +{"path": "hf", "type": "enum", "enum": {"slow": 0, "fast": 1}, "readonly": false, "cmd": "cc hf"}, +{"path": "hbe", "type": "bool", "readonly": false, "cmd": "cc hbe"}, +{"path": "hmf", "type": "float"}, +{"path": "hms", "type": "float"}, +{"path": "hit", "type": "float", "readonly": false, "cmd": "cc hit"}, +{"path": "hft", "type": "int", "readonly": false, "cmd": "cc hft"}, +{"path": "hea", "type": "enum", "enum": {"0": 0, "1": 1, "6": 2}, "readonly": false, "cmd": "cc hea"}, +{"path": "hch", "type": "int", "readonly": false, "cmd": "cc hch", "visibility": 3}, +{"path": "hwr0", "type": "float", "readonly": false, "cmd": "cc hwr0", "visibility": 3}, +{"path": "hem0", "type": "float", "readonly": false, "cmd": "cc hem0", "description": "sensor length in mm from top to empty pos.", "visibility": 3}, +{"path": "hfu0", "type": "float", "readonly": false, "cmd": "cc hfu0", "description": "sensor length in mm from top to full pos.", "visibility": 3}, +{"path": "hd0", "type": "float", "readonly": false, "cmd": "cc hd0", "description": "external sensor drive current (mA)", "visibility": 3}, +{"path": "h0", "type": "float", "visibility": 3}, +{"path": "hs0", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h1", "type": "float", "visibility": 3}, +{"path": "hs1", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h2", "type": "float", "visibility": 3}, +{"path": "hs2", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h3", "type": "float", "visibility": 3}, +{"path": "hs3", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h4", "type": "float", "visibility": 3}, +{"path": "hs4", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "h5", "type": "float", "visibility": 3}, +{"path": "hs5", "type": "enum", "enum": {"sens_ok": 0, "sens_warm": 1, "no_sens": 2, "timeout": 3, "not_yet_read": 4, "disabled": 5}, "visibility": 3}, +{"path": "hfb", "type": "float"}, +{"path": "nav", "type": "bool", "readonly": false, "cmd": "cc nav"}, +{"path": "nu", "type": "float"}, +{"path": "nl", "type": "float"}, +{"path": "nth", "type": "float", "readonly": false, "cmd": "cc nth"}, +{"path": "ntc", "type": "float", "readonly": false, "cmd": "cc ntc"}, +{"path": "ntm", "type": "float", "readonly": false, "cmd": "cc ntm"}, +{"path": "ns", "type": "enum", "enum": {"sens_ok": 0, "no_sens": 1, "short_circuit": 2, "upside_down": 3, "sens_warm": 4, "empty": 5}}, +{"path": "na", "type": "bool", "readonly": false, "cmd": "cc na"}, +{"path": "nv", "type": "enum", "enum": {"fill_valve_off": 0, "filling": 1, "no_fill_valve": 2, "timeout": 3, "timeout1": 4, "boost": 5}}, +{"path": "nc", "type": "enum", "enum": {"stop": 0, "fill": 1, "off": 2, "auto": 3}, "readonly": false, "cmd": "cc nc"}, +{"path": "nfb", "type": "float"}, +{"path": "cda", "type": "float"}, +{"path": "cdb", "type": "float"}, +{"path": "cba", "type": "float"}, +{"path": "cbb", "type": "float"}, +{"path": "cvs", "type": "int"}, +{"path": "csp", "type": "int"}, +{"path": "cdv", "type": "text", "readonly": false, "cmd": "cc cdv"}, +{"path": "cic", "type": "text", "readonly": false, "cmd": "cc cic"}, +{"path": "cin", "type": "text"}, +{"path": "cds", "type": "enum", "enum": {"local": 0, "remote": 1, "loading": 2, "by_code": 3, "by_touch": 4}, "readonly": false, "cmd": "cc cds"}, +{"path": "timing", "type": "bool", "readonly": false, "cmd": "cc timing"}, +{"path": "tc", "type": "float", "visibility": 3}, +{"path": "tn", "type": "float", "visibility": 3}, +{"path": "th", "type": "float", "visibility": 3}, +{"path": "tf", "type": "float", "visibility": 3}, +{"path": "tm", "type": "float", "visibility": 3}, +{"path": "tv", "type": "float", "visibility": 3}, +{"path": "tq", "type": "float", "visibility": 3}, +{"path": "bdl", "type": "float", "readonly": false, "cmd": "cc bdl"}]}, "nv": {"base": "/nv", "params": [{"path": "", "type": "enum", "enum": {"fixed": 0, "controlled": 1, "automatic": 2, "close": 3, "open": 4}, "readonly": false, "cmd": "nv", "kids": 12}, +{"path": "send", "type": "text", "readonly": false, "cmd": "nv send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "flow", "type": "float"}, +{"path": "motstat", "type": "text"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "nv set"}, +{"path": "flowmax", "type": "float", "readonly": false, "cmd": "nv flowmax"}, +{"path": "ctrl", "type": "none", "kids": 4}, +{"path": "ctrl/prop", "type": "float", "readonly": false, "cmd": "nv ctrl/prop"}, +{"path": "ctrl/int", "type": "float", "readonly": false, "cmd": "nv ctrl/int"}, +{"path": "ctrl/delay", "type": "float", "readonly": false, "cmd": "nv ctrl/delay"}, +{"path": "ctrl/tol", "type": "float", "readonly": false, "cmd": "nv ctrl/tol"}, +{"path": "autoflow", "type": "none", "kids": 24}, +{"path": "autoflow/suspended", "type": "bool", "readonly": false, "cmd": "nv autoflow/suspended"}, +{"path": "autoflow/prop", "type": "float", "readonly": false, "cmd": "nv autoflow/prop"}, +{"path": "autoflow/flowstd", "type": "float", "readonly": false, "cmd": "nv autoflow/flowstd"}, +{"path": "autoflow/flowlim", "type": "float", "readonly": false, "cmd": "nv autoflow/flowlim"}, +{"path": "autoflow/smooth", "type": "float", "readonly": false, "cmd": "nv autoflow/smooth"}, +{"path": "autoflow/difSize", "type": "float", "readonly": false, "cmd": "nv autoflow/difSize"}, +{"path": "autoflow/difRange", "type": "float", "readonly": false, "cmd": "nv autoflow/difRange"}, +{"path": "autoflow/flowSize", "type": "float", "readonly": false, "cmd": "nv autoflow/flowSize"}, +{"path": "autoflow/convTime", "type": "float", "readonly": false, "cmd": "nv autoflow/convTime"}, +{"path": "autoflow/Tmin", "type": "float", "readonly": false, "cmd": "nv autoflow/Tmin"}, +{"path": "autoflow/script", "type": "text", "readonly": false, "cmd": "nv autoflow/script"}, +{"path": "autoflow/getTemp", "type": "text", "readonly": false, "cmd": "nv autoflow/getTemp"}, +{"path": "autoflow/getTset", "type": "text", "readonly": false, "cmd": "nv autoflow/getTset"}, +{"path": "autoflow/getFlow", "type": "text", "readonly": false, "cmd": "nv autoflow/getFlow"}, +{"path": "autoflow/difBuf", "type": "text"}, +{"path": "autoflow/flowBuf", "type": "text"}, +{"path": "autoflow/flowset", "type": "float"}, +{"path": "autoflow/flowmin", "type": "float"}, +{"path": "autoflow/flowmax", "type": "float"}, +{"path": "autoflow/difmin", "type": "float"}, +{"path": "autoflow/difmax", "type": "float"}, +{"path": "autoflow/setmin", "type": "float"}, +{"path": "autoflow/setmax", "type": "float"}, +{"path": "autoflow/flowtarget", "type": "float"}, +{"path": "calib", "type": "none", "kids": 2}, +{"path": "calib/ln_per_min_per_mbar", "type": "float", "readonly": false, "cmd": "nv calib/ln_per_min_per_mbar"}, +{"path": "calib/mbar_offset", "type": "float", "readonly": false, "cmd": "nv calib/mbar_offset"}, +{"path": "initialize", "type": "enum", "enum": {"check": 1, "adjust": 2, "stop": 3}, "readonly": false, "cmd": "nv initialize", "visibility": 3}, +{"path": "initstate", "type": "text", "visibility": 3}]}, "nvmot": {"base": "/nv/nvmot", "params": [{"path": "", "type": "float", "readonly": false, "cmd": "run nvmot", "kids": 32}, +{"path": "send", "type": "text", "readonly": false, "cmd": "nvmot send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "nvmot is_running", "visibility": 3}, +{"path": "pos", "type": "float"}, +{"path": "encoder", "type": "float"}, +{"path": "zero", "type": "float", "readonly": false, "cmd": "nvmot zero"}, +{"path": "lowerlimit", "type": "float", "readonly": false, "cmd": "nvmot lowerlimit"}, +{"path": "upperlimit", "type": "float", "readonly": false, "cmd": "nvmot upperlimit"}, +{"path": "disablelimits", "type": "bool", "readonly": false, "cmd": "nvmot disablelimits"}, +{"path": "verbose", "type": "bool", "readonly": false, "cmd": "nvmot verbose"}, +{"path": "target", "type": "float"}, +{"path": "runstate", "type": "enum", "enum": {"idle": 0, "running": 1, "finished": 2, "error": 3}}, +{"path": "precision", "type": "float", "readonly": false, "cmd": "nvmot precision"}, +{"path": "maxencdif", "type": "float", "readonly": false, "cmd": "nvmot maxencdif"}, +{"path": "id", "type": "float", "readonly": false, "cmd": "nvmot id"}, +{"path": "pump_number", "type": "float", "readonly": false, "cmd": "nvmot pump_number"}, +{"path": "init", "type": "float", "readonly": false, "cmd": "nvmot init"}, +{"path": "maxspeed", "type": "float", "readonly": false, "cmd": "nvmot maxspeed"}, +{"path": "acceleration", "type": "float", "readonly": false, "cmd": "nvmot acceleration"}, +{"path": "maxcurrent", "type": "float", "readonly": false, "cmd": "nvmot maxcurrent"}, +{"path": "standbycurrent", "type": "float", "readonly": false, "cmd": "nvmot standbycurrent"}, +{"path": "freewheeling", "type": "bool", "readonly": false, "cmd": "nvmot freewheeling"}, +{"path": "output0", "type": "bool", "readonly": false, "cmd": "nvmot output0"}, +{"path": "output1", "type": "bool", "readonly": false, "cmd": "nvmot output1"}, +{"path": "input3", "type": "bool"}, +{"path": "input0", "type": "float"}, +{"path": "input0raw", "type": "float"}, +{"path": "pullup", "type": "float", "readonly": false, "cmd": "nvmot pullup"}, +{"path": "nopumpfeedback", "type": "bool", "readonly": false, "cmd": "nvmot nopumpfeedback"}, +{"path": "eeprom", "type": "enum", "enum": {"ok": 0, "dirty": 1, "save": 2, "load": 3}, "readonly": false, "cmd": "nvmot eeprom"}, +{"path": "customadr", "type": "text", "readonly": false, "cmd": "nvmot customadr"}, +{"path": "custompar", "type": "float", "readonly": false, "cmd": "nvmot custompar"}]}, "ln2fill": {"base": "/ln2fill", "params": [{"path": "", "type": "enum", "enum": {"watching": 0, "fill": 1, "inactive": 2}, "readonly": false, "cmd": "ln2fill", "kids": 3}, +{"path": "send", "type": "text", "readonly": false, "cmd": "ln2fill send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "state", "type": "text"}]}, "hefill": {"base": "/hefill", "params": [{"path": "", "type": "enum", "enum": {"no fill valve": 2}, "readonly": false, "cmd": "hefill", "kids": 6}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hefill send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "fast", "type": "enum", "enum": {"slow": 0, "fast": 1}, "readonly": false, "cmd": "cc hf"}, +{"path": "state", "type": "text"}, +{"path": "hefull", "type": "float", "readonly": false, "cmd": "cc hh"}, +{"path": "helow", "type": "float", "readonly": false, "cmd": "cc hl"}]}, "hepump": {"base": "/hepump", "params": [{"path": "", "type": "enum", "enum": {"xds35_auto": 0, "xds35_manual": 1, "sv65": 2, "other": 3, "no": -1}, "readonly": false, "cmd": "hepump", "description": "xds35: scroll pump, sv65: leybold", "kids": 9}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hepump send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "running", "type": "bool", "readonly": false, "cmd": "hepump running"}, +{"path": "eco", "type": "bool", "readonly": false, "cmd": "hepump eco"}, +{"path": "auto", "type": "bool", "readonly": false, "cmd": "hepump auto"}, +{"path": "valve", "type": "enum", "enum": {"closed": 0, "closing": 1, "opening": 2, "opened": 3, "undefined": 4}, "readonly": false, "cmd": "hepump valve"}, +{"path": "eco_t_lim", "type": "float", "readonly": false, "cmd": "hepump eco_t_lim", "description": "switch off eco mode when T_set < eco_t_lim and T < eco_t_lim * 2"}, +{"path": "calib", "type": "float", "readonly": false, "cmd": "hepump calib", "visibility": 3}]}, "hemot": {"base": "/hepump/hemot", "params": [{"path": "", "type": "float", "readonly": false, "cmd": "run hemot", "kids": 32}, +{"path": "send", "type": "text", "readonly": false, "cmd": "hemot send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "hemot is_running", "visibility": 3}, +{"path": "pos", "type": "float"}, +{"path": "encoder", "type": "float"}, +{"path": "zero", "type": "float", "readonly": false, "cmd": "hemot zero"}, +{"path": "lowerlimit", "type": "float", "readonly": false, "cmd": "hemot lowerlimit"}, +{"path": "upperlimit", "type": "float", "readonly": false, "cmd": "hemot upperlimit"}, +{"path": "disablelimits", "type": "bool", "readonly": false, "cmd": "hemot disablelimits"}, +{"path": "verbose", "type": "bool", "readonly": false, "cmd": "hemot verbose"}, +{"path": "target", "type": "float"}, +{"path": "runstate", "type": "enum", "enum": {"idle": 0, "running": 1, "finished": 2, "error": 3}}, +{"path": "precision", "type": "float", "readonly": false, "cmd": "hemot precision"}, +{"path": "maxencdif", "type": "float", "readonly": false, "cmd": "hemot maxencdif"}, +{"path": "id", "type": "float", "readonly": false, "cmd": "hemot id"}, +{"path": "pump_number", "type": "float", "readonly": false, "cmd": "hemot pump_number"}, +{"path": "init", "type": "float", "readonly": false, "cmd": "hemot init"}, +{"path": "maxspeed", "type": "float", "readonly": false, "cmd": "hemot maxspeed"}, +{"path": "acceleration", "type": "float", "readonly": false, "cmd": "hemot acceleration"}, +{"path": "maxcurrent", "type": "float", "readonly": false, "cmd": "hemot maxcurrent"}, +{"path": "standbycurrent", "type": "float", "readonly": false, "cmd": "hemot standbycurrent"}, +{"path": "freewheeling", "type": "bool", "readonly": false, "cmd": "hemot freewheeling"}, +{"path": "output0", "type": "bool", "readonly": false, "cmd": "hemot output0"}, +{"path": "output1", "type": "bool", "readonly": false, "cmd": "hemot output1"}, +{"path": "input3", "type": "bool"}, +{"path": "input0", "type": "float"}, +{"path": "input0raw", "type": "float"}, +{"path": "pullup", "type": "float", "readonly": false, "cmd": "hemot pullup"}, +{"path": "nopumpfeedback", "type": "bool", "readonly": false, "cmd": "hemot nopumpfeedback"}, +{"path": "eeprom", "type": "enum", "enum": {"ok": 0, "dirty": 1, "save": 2, "load": 3}, "readonly": false, "cmd": "hemot eeprom"}, +{"path": "customadr", "type": "text", "readonly": false, "cmd": "hemot customadr"}, +{"path": "custompar", "type": "float", "readonly": false, "cmd": "hemot custompar"}]}, "table": {"base": "/table", "params": [{"path": "", "type": "none", "kids": 20}, +{"path": "send", "type": "text", "readonly": false, "cmd": "table send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "fix_tt_set_prop", "type": "bool", "readonly": false, "cmd": "table fix_tt_set_prop"}, +{"path": "val_tt_set_prop", "type": "float"}, +{"path": "tbl_tt_set_prop", "type": "text", "readonly": false, "cmd": "table tbl_tt_set_prop", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_set_integ", "type": "bool", "readonly": false, "cmd": "table fix_tt_set_integ"}, +{"path": "val_tt_set_integ", "type": "float"}, +{"path": "tbl_tt_set_integ", "type": "text", "readonly": false, "cmd": "table tbl_tt_set_integ", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_dblctrl_int2", "type": "bool", "readonly": false, "cmd": "table fix_tt_dblctrl_int2"}, +{"path": "val_tt_dblctrl_int2", "type": "float"}, +{"path": "tbl_tt_dblctrl_int2", "type": "text", "readonly": false, "cmd": "table tbl_tt_dblctrl_int2", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_dblctrl_prop_up", "type": "bool", "readonly": false, "cmd": "table fix_tt_dblctrl_prop_up"}, +{"path": "val_tt_dblctrl_prop_up", "type": "float"}, +{"path": "tbl_tt_dblctrl_prop_up", "type": "text", "readonly": false, "cmd": "table tbl_tt_dblctrl_prop_up", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_tt_dblctrl_prop_lo", "type": "bool", "readonly": false, "cmd": "table fix_tt_dblctrl_prop_lo"}, +{"path": "val_tt_dblctrl_prop_lo", "type": "float"}, +{"path": "tbl_tt_dblctrl_prop_lo", "type": "text", "readonly": false, "cmd": "table tbl_tt_dblctrl_prop_lo", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}, +{"path": "fix_warmup_weight", "type": "bool", "readonly": false, "cmd": "table fix_warmup_weight"}, +{"path": "val_warmup_weight", "type": "float"}, +{"path": "tbl_warmup_weight", "type": "text", "readonly": false, "cmd": "table tbl_warmup_weight", "description": "enter value pair separated with colon T1:par1 T2:par2 ..."}]}} diff --git a/cfg/sea/test_secop4.cfg b/cfg/sea/test_secop4.cfg index b7ba07b..879de42 100644 --- a/cfg/sea/test_secop4.cfg +++ b/cfg/sea/test_secop4.cfg @@ -12,6 +12,6 @@ uri = tcp://samenv.psi.ch:8642 [module secop] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = secop.test_secop4.config remote_paths = . diff --git a/cfg/sea/varioxB_vb.cfg b/cfg/sea/varioxB_vb.cfg index 7350d68..a3509c7 100644 --- a/cfg/sea/varioxB_vb.cfg +++ b/cfg/sea/varioxB_vb.cfg @@ -12,54 +12,54 @@ uri = tcp://samenv.psi.ch:8646 [module tvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvs.varioxB.config remote_paths = . [module tvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvd.varioxB.config remote_paths = . [module pstat] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pstat.varioxB.config remote_paths = . [module pdyn] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pdyn.varioxB.config remote_paths = . [module tneck1] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck1.varioxB.config remote_paths = . [module tneck2] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck2.varioxB.config remote_paths = . [module tnvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvs.varioxB.config remote_paths = . [module tnvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvd.varioxB.config remote_paths = . [module ts] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = ts.vb.stick remote_paths = . diff --git a/cfg/stick.ini b/cfg/stick.ini new file mode 100644 index 0000000..5a96c84 --- /dev/null +++ b/cfg/stick.ini @@ -0,0 +1,4 @@ +[FRAPPY] +confdir = ~/frappy/cfg/stick:~/frappy/cfg/develop +logdir = ~/frappylog +piddir = ~/frappylog/pid diff --git a/cfg/stick/ill4stick.cfg b/cfg/stick/ill4stick.cfg new file mode 100644 index 0000000..a50d766 --- /dev/null +++ b/cfg/stick/ill4stick.cfg @@ -0,0 +1,17 @@ +[NODE] +description = ILL4 standard sample stick +id = ill4.stick.sea.psi.ch + +[sea_stick] +class = secop_psi.sea.SeaClient +description = SEA stick connection +config = ill4.stick +service = stick + +[ts] +class = secop_psi.sea.SeaReadable +iodev = sea_stick +sea_object = tt +json_file = ill4.config.json +rel_paths = ts + diff --git a/cfg/stick/ill5stick.cfg b/cfg/stick/ill5stick.cfg index 07e8de5..0b26ed9 100644 --- a/cfg/stick/ill5stick.cfg +++ b/cfg/stick/ill5stick.cfg @@ -10,7 +10,7 @@ service = stick [ts] class = secop_psi.sea.SeaReadable -iodev = sea_stick +io = sea_stick sea_object = tt json_file = ill5.config.json rel_paths = ts diff --git a/cfg/stick/ma11stick.cfg b/cfg/stick/ma11stick.cfg index f0eb393..a162ad1 100644 --- a/cfg/stick/ma11stick.cfg +++ b/cfg/stick/ma11stick.cfg @@ -10,7 +10,7 @@ service = stick [ts] class = secop_psi.sea.SeaReadable -iodev = sea_stick +io = sea_stick sea_object = tt json_file = ma11.config.json rel_paths = ts diff --git a/cfg/stick/ma7stick.cfg b/cfg/stick/ma7stick.cfg index b66a1eb..b6e606e 100644 --- a/cfg/stick/ma7stick.cfg +++ b/cfg/stick/ma7stick.cfg @@ -10,7 +10,7 @@ service = stick [ts] class = secop_psi.sea.SeaReadable -iodev = sea_stick +io = sea_stick sea_object = tt json_file = ma7.config.json rel_paths = ts diff --git a/cfg/stick/ori4stick.cfg b/cfg/stick/ori4stick.cfg index a24e45a..f1fdb9c 100644 --- a/cfg/stick/ori4stick.cfg +++ b/cfg/stick/ori4stick.cfg @@ -10,7 +10,7 @@ service = stick [ts] class = secop_psi.sea.SeaReadable -iodev = sea_stick +io = sea_stick sea_object = tt json_file = ori4.config.json rel_paths = ts diff --git a/cfg/stick/sch5.cfg b/cfg/stick/sch5.cfg index 9ea4125..d57ae97 100644 --- a/cfg/stick/sch5.cfg +++ b/cfg/stick/sch5.cfg @@ -2,7 +2,7 @@ description = sample changer for 100 mm orange cryo (5 samples, HRPT) id = sch5.stick.sea.psi.ch -[seaconn] +[sea_stick] class = secop_psi.sea.SeaClient description = SEA connection to sch5 config = sch5.stick @@ -10,12 +10,13 @@ service = stick [warmup] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = sea_stick sea_object = warmup [ts] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = sea_stick sea_object = tt +json_file = ori4.config.json rel_paths = ts diff --git a/cfg/test_ppms_mf.cfg b/cfg/test_ppms_mf.cfg index 014e26a..88b2749 100644 --- a/cfg/test_ppms_mf.cfg +++ b/cfg/test_ppms_mf.cfg @@ -9,62 +9,62 @@ bindport = 5000 #[module tt] #class = secop_psi.ppms.Temp #.description = main temperature -#iodev = ppms +#io = ppms [module mf] class = secop_psi.ppms.Field .description = magnetic field -iodev = ppms +io = ppms #[module pos] #class = secop_psi.ppms.Position #.description = sample rotator -#iodev = ppms +#io = ppms #[module lev] #class = secop_psi.ppms.Level #.description = helium level -#iodev = ppms +#io = ppms #[module chamber] #class = secop_psi.ppms.Chamber #.description = chamber state -#iodev = ppms +#io = ppms #[module r1] #class = secop_psi.ppms.BridgeChannel #.description = resistivity channel 1 #no = 1 #value.unit = Ohm -#iodev = ppms +#io = ppms #[module i1] #class = secop_psi.ppms.Channel #.description = current channel 1 #no = 1 #value.unit = uA -#iodev = ppms +#io = ppms #[module v1] #class = secop_psi.ppms.DriverChannel #.description = voltage channel 1 #no = 1 #value.unit = V -#iodev = ppms +#io = ppms #[module tv] #class = secop_psi.ppms.UserChannel #.description = VTI temperature #enabled = 1 #value.unit = K -#iodev = ppms +#io = ppms #[module ts] #class = secop_psi.ppms.UserChannel #.description = sample temperature #enabled = 1 #value.unit = K -#iodev = ppms +#io = ppms [module ppms] class = secop_psi.ppms.Main diff --git a/cfg/trinamic.cfg b/cfg/trinamic.cfg index ca375e3..6d7424e 100644 --- a/cfg/trinamic.cfg +++ b/cfg/trinamic.cfg @@ -5,7 +5,7 @@ description = trinamic motor test [INTERFACE] uri = tcp://5000 -[drv_iodev] +[drv_io] description = class = secop.core.BytesIO uri = serial:///dev/tty.usbserial?baudrate=57600 @@ -14,7 +14,7 @@ uri = serial:///dev/tty.usbserial?baudrate=57600 [drv] description = trinamic motor test class = secop_psi.trinamic.Motor -iodev = drv_iodev +io = drv_io standby_current=0.1 maxcurrent=1.4 acceleration=150. diff --git a/cfg/uniax.cfg b/cfg/uniax.cfg index da86987..9a03b8b 100644 --- a/cfg/uniax.cfg +++ b/cfg/uniax.cfg @@ -11,7 +11,7 @@ class = secop_psi.uniax.Uniax motor = drv transducer = transducer -#[drv_iodev] +#[drv_io] #description = #class = secop.core.BytesIO # uri = serial:///dev/ttyUSB1?baudrate=57600 @@ -20,7 +20,7 @@ transducer = transducer [drv] description = trinamic motor test class = secop_psi.trinamic.Motor -# iodev = drv_iodev +# io = drv_io uri = tcp://192.168.127.254:3002 standby_current=0.1 maxcurrent=0.2 diff --git a/cfg/varioxb.cfg b/cfg/varioxb.cfg index a015874..77a99a3 100644 --- a/cfg/varioxb.cfg +++ b/cfg/varioxb.cfg @@ -12,49 +12,49 @@ uri = tcp://samenv.psi.ch:8646 [module tvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvs.varioxB.config remote_paths = . [module tvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tvd.varioxB.config remote_paths = . [module pstat] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pstat.varioxB.config remote_paths = . [module pdyn] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = pdyn.varioxB.config remote_paths = . [module tneck1] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck1.varioxB.config remote_paths = . [module tneck2] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tneck2.varioxB.config remote_paths = . [module tnvs] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvs.varioxB.config remote_paths = . [module tnvd] class = secop_psi.sea.SeaReadable -iodev = seaconn +io = seaconn json_descr = tnvd.varioxB.config remote_paths = . diff --git a/secop/errors.py b/secop/errors.py index c50cbac..5affb4a 100644 --- a/secop/errors.py +++ b/secop/errors.py @@ -17,12 +17,14 @@ # # Module authors: # Enrico Faulhaber +# Markus Zolliker # # ***************************************************************************** """Define (internal) SECoP Errors""" class SECoPError(RuntimeError): + silent = False # silent = True indicates that the error is already logged def __init__(self, *args, **kwds): super().__init__() @@ -32,7 +34,8 @@ class SECoPError(RuntimeError): def __repr__(self): args = ', '.join(map(repr, self.args)) - kwds = ', '.join(['%s=%r' % i for i in list(self.__dict__.items())]) + kwds = ', '.join(['%s=%r' % i for i in list(self.__dict__.items()) + if i[0] != 'silent']) res = [] if args: res.append(args) @@ -102,14 +105,6 @@ class CommunicationFailedError(SECoPError): pass -class SilentError(SECoPError): - pass - - -class CommunicationSilentError(SilentError, CommunicationFailedError): - name = 'CommunicationFailed' - - class IsBusyError(SECoPError): pass @@ -123,7 +118,7 @@ class DisabledError(SECoPError): class HardwareError(SECoPError): - pass + name = 'HardwareError' def make_secop_error(name, text): diff --git a/secop/io.py b/secop/io.py index d7e09df..07932ef 100644 --- a/secop/io.py +++ b/secop/io.py @@ -31,8 +31,7 @@ import threading from secop.lib.asynconn import AsynConn, ConnectionClosed from secop.datatypes import ArrayOf, BLOBType, BoolType, FloatRange, IntRange, \ StringType, TupleOf, ValueType -from secop.errors import CommunicationFailedError, CommunicationSilentError, \ - ConfigError, ProgrammingError +from secop.errors import CommunicationFailedError, ConfigError, ProgrammingError from secop.modules import Attached, Command, \ Communicator, Done, Module, Parameter, Property from secop.lib import generalConfig @@ -42,6 +41,10 @@ generalConfig.set_default('legacy_hasiodev', False) HEX_CODE = re.compile(r'[0-9a-fA-F][0-9a-fA-F]$') +class SilentError(CommunicationFailedError): + silent = True + + class HasIO(Module): """Mixin for modules using a communicator""" io = Attached() @@ -151,11 +154,10 @@ class IOBase(Communicator): self.callCallbacks() return Done except Exception as e: - if str(e) == self._last_error: - raise CommunicationSilentError(str(e)) from e - self._last_error = str(e) - self.log.error(self._last_error) - raise + if str(e) != self._last_error: + self._last_error = str(e) + self.log.error(self._last_error) + raise SilentError(repr(e)) from e return Done def write_is_connected(self, value): @@ -249,10 +251,10 @@ class StringIO(IOBase): """ command = command.encode(self.encoding) if not self.is_connected: + # do not try to reconnect here + # read_is_connected is doing this when called by its poller self.read_is_connected() # try to reconnect - if not self._conn: - self.log.debug('can not connect to %r' % self.uri) - raise CommunicationSilentError('can not connect to %r' % self.uri) + raise SilentError('disconnected') from None try: with self._lock: # read garbage and wait before send @@ -279,11 +281,12 @@ class StringIO(IOBase): self.comLog('< %s', reply) return reply except Exception as e: - if str(e) == self._last_error: - raise CommunicationSilentError(str(e)) from None - self._last_error = str(e) - self.log.error(self._last_error) - raise + if self._conn is None: + raise SilentError('disconnected') from None + if repr(e) != self._last_error: + self._last_error = str(e) + self.log.error(self._last_error) + raise SilentError(repr(e)) from e @Command(ArrayOf(StringType()), result=ArrayOf(StringType())) def multicomm(self, commands): @@ -357,9 +360,10 @@ class BytesIO(IOBase): def communicate(self, request, replylen): # pylint: disable=arguments-differ """send a request and receive (at least) bytes as reply""" if not self.is_connected: + # do not try to reconnect here + # read_is_connected is doing this when called by its poller self.read_is_connected() # try to reconnect - if not self._conn: - raise CommunicationSilentError('can not connect to %r' % self.uri) + raise SilentError('disconnected') from None try: with self._lock: # read garbage and wait before send @@ -378,11 +382,12 @@ class BytesIO(IOBase): self.comLog('< %s', hexify(reply)) return self.getFullReply(request, reply) except Exception as e: - if str(e) == self._last_error: - raise CommunicationSilentError(str(e)) from None - self._last_error = str(e) - self.log.error(self._last_error) - raise + if self._conn is None: + raise SilentError('disconnected') from None + if repr(e) != self._last_error: + self._last_error = str(e) + self.log.error(self._last_error) + raise SilentError(repr(e)) from e @Command((ArrayOf(TupleOf(BLOBType(), IntRange(0)))), result=ArrayOf(BLOBType())) def multicomm(self, requests): diff --git a/secop/lib/asynconn.py b/secop/lib/asynconn.py index 9d5df16..52d3878 100644 --- a/secop/lib/asynconn.py +++ b/secop/lib/asynconn.py @@ -167,7 +167,7 @@ class AsynTcp(AsynConn): uri = uri[6:] try: self.connection = tcpSocket(uri, self.defaultport, self.timeout) - except (ConnectionRefusedError, socket.gaierror) as e: + except (ConnectionRefusedError, socket.gaierror, socket.timeout) as e: # indicate that retrying might make sense raise CommunicationFailedError(str(e)) from None diff --git a/secop/lib/statemachine.py b/secop/lib/statemachine.py index 6d066c5..309cabf 100644 --- a/secop/lib/statemachine.py +++ b/secop/lib/statemachine.py @@ -177,9 +177,9 @@ class StateMachine: :return: a delay or None when idle """ - if self.state is None: - return None with self._lock: + if self.state is None: + return None for _ in range(999): self.now = time.time() try: @@ -236,7 +236,7 @@ class StateMachine: pass delay = self.cycle() - def _start(self, state, first_delay, **kwds): + def _start(self, state, **kwds): self._restart = None self._idle_event.clear() self.last_error = None @@ -245,10 +245,12 @@ class StateMachine: self._new_state(state) self.start_time = self.now self._last_time = self.now + first_delay = self.cycle() # important: call once (e.g. set status to busy) if self._threaded: if self._thread is None or not self._thread.is_alive(): # restart thread if dead (may happen when cleanup failed) - self._thread = mkthread(self._run, first_delay) + if first_delay is not None: + self._thread = mkthread(self._run, first_delay) else: self.trigger(first_delay) @@ -269,11 +271,9 @@ class StateMachine: self.last_error = self.stopped self.cleanup(self) # ignore return state on restart self.stopped = False - delay = self.cycle() - self._start(state, delay, **kwds) + self._start(state, **kwds) else: - delay = self.cycle() # important: call once (e.g. set status to busy) - self._start(state, delay, **kwds) + self._start(state, **kwds) def stop(self): """stop machine, go to idle state diff --git a/secop/logging.py b/secop/logging.py index cd8cf41..04ab122 100644 --- a/secop/logging.py +++ b/secop/logging.py @@ -86,7 +86,6 @@ class RemoteLogHandler(mlzlog.Handler): class LogfileHandler(mlzlog.LogfileHandler): def __init__(self, logdir, rootname, max_days=0): - self.logdir = logdir self.rootname = rootname self.max_days = max_days super().__init__(logdir, rootname) @@ -95,6 +94,11 @@ class LogfileHandler(mlzlog.LogfileHandler): if record.levelno != COMLOG: super().emit(record) + def getChild(self, name): + child = type(self)(dirname(self.baseFilename), name, self.max_days) + child.setLevel(self.level) + return child + def doRollover(self): super().doRollover() if self.max_days: @@ -157,8 +161,6 @@ class MainLogger: if self.logdir: logfile_days = generalConfig.getint('logfile_days') logfile_handler = LogfileHandler(self.logdir, self.rootname, max_days=logfile_days) - if generalConfig.logfile_days: - logfile_handler.max_days = int(generalConfig.logfile_days) logfile_handler.setLevel(LOG_LEVELS[generalConfig.get('logfile_level', 'info')]) self.log.addHandler(logfile_handler) diff --git a/secop/modules.py b/secop/modules.py index 101f50e..48ebfa5 100644 --- a/secop/modules.py +++ b/secop/modules.py @@ -31,7 +31,7 @@ from functools import wraps from secop.datatypes import ArrayOf, BoolType, EnumType, FloatRange, \ IntRange, StatusType, StringType, TextType, TupleOf, DiscouragedConversion from secop.errors import BadValueError, ConfigError, \ - ProgrammingError, SECoPError, SilentError, secop_error + ProgrammingError, SECoPError, secop_error from secop.lib import formatException, mkthread, UniqueObject, generalConfig from secop.lib.enum import Enum from secop.params import Accessible, Command, Parameter @@ -233,7 +233,7 @@ class PollInfo: self.interval = pollinterval self.last_main = 0 self.last_slow = 0 - self.last_error = None + self.last_error = {} # dict [] of (None or str(last exception)) self.polled_parameters = [] self.fast_flag = False self.trigger_event = trigger_event @@ -318,7 +318,8 @@ class Module(HasAccessibles): self.initModuleDone = False self.startModuleDone = False self.remoteLogHandler = None - self.accessLock = threading.RLock() + self.accessLock = threading.RLock() # for read_* / write_* methods + self.updateLock = threading.RLock() # for announceUpdate self.polledModules = [] # modules polled by thread started in self.startModules errors = [] @@ -495,7 +496,7 @@ class Module(HasAccessibles): def announceUpdate(self, pname, value=None, err=None, timestamp=None): """announce a changed value or readerror""" - with self.accessLock: + with self.updateLock: # TODO: remove readerror 'property' and replace value with exception pobj = self.parameters[pname] timestamp = timestamp or time.time() @@ -632,12 +633,19 @@ class Module(HasAccessibles): """call read method with proper error handling""" try: rfunc() - except SilentError: - pass - except SECoPError as e: - self.log.error(str(e)) - except Exception: - self.log.error(formatException()) + self.pollInfo.last_error[rfunc.__name__] = None + except Exception as e: + name = rfunc.__name__ + if str(e) != self.pollInfo.last_error.get(name): + self.pollInfo.last_error[name] = str(e) + if isinstance(e, SECoPError): + if e.silent: + self.log.debug('%s: %s', name, str(e)) + else: + self.log.error('%s: %s', name, str(e)) + else: + # uncatched error: this is more serious + self.log.error('%s: %s', name, formatException()) def __pollThread(self, modules, started_callback): """poll thread body @@ -692,25 +700,14 @@ class Module(HasAccessibles): pinfo = mobj.pollInfo if now > pinfo.last_main + pinfo.interval: pinfo.last_main = (now // pinfo.interval) * pinfo.interval - try: - mobj.doPoll() - pinfo.last_error = None - except Exception as e: - if str(e) != str(pinfo.last_error) and not isinstance(e, SilentError): - mobj.log.error('doPoll: %r', e) - pinfo.last_error = e + mobj.callPollFunc(mobj.doPoll) now = time.time() # find ONE due slow poll and call it loop = True while loop: # loops max. 2 times, when to_poll is at end for mobj, rfunc, pobj in to_poll: if now > pobj.timestamp + mobj.slowinterval * 0.5: - try: - prev_err = pobj.readerror - rfunc() - except Exception as e: - if not isinstance(e, SilentError) and str(pobj.readerror) != str(prev_err): - mobj.log.error('%s: %r', pobj.name, e) + mobj.callPollFunc(rfunc) loop = False # one poll done break else: @@ -736,15 +733,20 @@ class Module(HasAccessibles): value = self.writeDict.pop(pname, Done) # in the mean time, a poller or handler might already have done it if value is not Done: - try: - self.log.debug('initialize parameter %s', pname) - getattr(self, 'write_' + pname)(value) - except SilentError: - pass - except SECoPError as e: - self.log.error(str(e)) - except Exception: - self.log.error(formatException()) + wfunc = getattr(self, 'write_' + pname, None) + if wfunc is None: + setattr(self, pname, value) + else: + try: + self.log.debug('initialize parameter %s', pname) + wfunc(value) + except SECoPError as e: + if e.silent: + self.log.debug('%s: %s', pname, str(e)) + else: + self.log.error('%s: %s', pname, str(e)) + except Exception: + self.log.error(formatException()) if started_callback: started_callback() diff --git a/secop/persistent.py b/secop/persistent.py index 63ce5a1..0e7aebd 100644 --- a/secop/persistent.py +++ b/secop/persistent.py @@ -72,15 +72,16 @@ class PersistentMixin(HasAccessibles): persistentdir = os.path.join(generalConfig.logdir, 'persistent') os.makedirs(persistentdir, exist_ok=True) self.persistentFile = os.path.join(persistentdir, '%s.%s.json' % (self.DISPATCHER.equipment_id, self.name)) - self.initData = {} + self.initData = {} # "factory" settings for pname in self.parameters: pobj = self.parameters[pname] - if hasattr(self, 'write_' + pname) and getattr(pobj, 'persistent', 0): - self.initData[pname] = pobj.value - if pobj.persistent == 'auto': + flag = getattr(pobj, 'persistent', 0) + if flag: + if flag == 'auto': def cb(value, m=self): m.saveParameters() self.valueCallbacks[pname].append(cb) + self.initData[pname] = pobj.value self.writeDict.update(self.loadParameters(write=False)) def loadParameters(self, write=True): diff --git a/secop/proxy.py b/secop/proxy.py index 2c25838..b372c82 100644 --- a/secop/proxy.py +++ b/secop/proxy.py @@ -33,6 +33,7 @@ from secop.io import HasIO class ProxyModule(HasIO, Module): module = Property('remote module name', datatype=StringType(), default='') + status = Parameter('connection status', Readable.status.datatype) # add status even when not a Readable _consistency_check_done = False _secnode = None @@ -182,11 +183,12 @@ def proxy_class(remote_class, name=None): for aname, aobj in rcls.accessibles.items(): if isinstance(aobj, Parameter): - pobj = aobj.merge(dict(handler=None, needscfg=False)) + pobj = aobj.copy() + pobj.merge(dict(handler=None, needscfg=False)) attrs[aname] = pobj def rfunc(self, pname=aname): - value, _, readerror = self._secnode.getParameter(self.name, pname) + value, _, readerror = self._secnode.getParameter(self.name, pname, True) if readerror: raise readerror return value diff --git a/secop_psi/k2601b.py b/secop_psi/k2601b.py index d82a36a..926f359 100644 --- a/secop_psi/k2601b.py +++ b/secop_psi/k2601b.py @@ -41,7 +41,7 @@ SOURCECMDS = { ' smua.source.output = 0 print("ok")', 1: 'reset()' ' smua.source.func = smua.OUTPUT_DCAMPS' - ' display.smua.measure.func = display.MEASURE_VOLTS' + ' display.smua.measure.func = display.MEASURE_DCVOLTS' ' smua.source.autorangei = 1' ' smua.source.output = 1 print("ok")', 2: 'reset()' @@ -65,11 +65,11 @@ class SourceMeter(HasIO, Module): return float(self.communicate('print((smua.source.func+1)*smua.source.output)')) def write_mode(self, value): + assert self.communicate(SOURCECMDS[value]) == 'ok' if value == 'current': self.write_vlimit(self.vlimit) elif value == 'voltage': self.write_ilimit(self.ilimit) - assert self.communicate(SOURCECMDS[value]) == 'ok' return self.read_mode() def read_ilimit(self): @@ -118,6 +118,7 @@ class Current(HasIO, Writable): limit = Parameter('current limit', FloatRange(0, 2.0, unit='A'), default=2) def initModule(self): + super().initModule() self.sourcemeter.registerCallbacks(self) def read_value(self): @@ -129,9 +130,9 @@ class Current(HasIO, Writable): def write_target(self, value): if value > self.sourcemeter.ilimit: raise ValueError('current exceeds limit') - value = float(self.communicate('smua.source.leveli = %g print(smua.source.leveli)' % value)) if not self.active: self.sourcemeter.write_mode('current') # triggers update_mode -> set active to True + value = float(self.communicate('smua.source.leveli = %g print(smua.source.leveli)' % value)) return value def read_limit(self): @@ -163,6 +164,7 @@ class Voltage(HasIO, Writable): limit = Parameter('voltage limit', FloatRange(0, 2.0, unit='V'), default=2) def initModule(self): + super().initModule() self.sourcemeter.registerCallbacks(self) def read_value(self): @@ -174,9 +176,9 @@ class Voltage(HasIO, Writable): def write_target(self, value): if value > self.sourcemeter.vlimit: raise ValueError('voltage exceeds limit') - value = float(self.communicate('smua.source.levelv = %g print(smua.source.levelv)' % value)) if not self.active: self.sourcemeter.write_mode('voltage') # triggers update_mode -> set active to True + value = float(self.communicate('smua.source.levelv = %g print(smua.source.levelv)' % value)) return value def read_limit(self): diff --git a/secop_psi/mercury.py b/secop_psi/mercury.py index 599ced3..991d0fb 100644 --- a/secop_psi/mercury.py +++ b/secop_psi/mercury.py @@ -25,84 +25,147 @@ import math import re import time -from secop.core import Drivable, HasIodev, \ - Parameter, Property, Readable, StringIO -from secop.datatypes import EnumType, FloatRange, StringType, StructOf +from secop.core import Drivable, HasIO, Writable, \ + Parameter, Property, Readable, StringIO, Attached, Done, IDLE, nopoll +from secop.datatypes import EnumType, FloatRange, StringType, StructOf, BoolType from secop.errors import HardwareError -from secop.lib.statemachine import StateMachine +from secop_psi.convergence import HasConvergence +from secop.lib.enum import Enum -class MercuryIO(StringIO): +VALUE_UNIT = re.compile(r'(.*\d|inf)([A-Za-z/%]*)$') +SELF = 0 + + +def as_float(value): + if isinstance(value, str): + return float(VALUE_UNIT.match(value).group(1)) + return '%g' % value + + +def as_string(value): + return value + + +class Mapped: + def __init__(self, **kwds): + self.mapping = kwds + self.mapping.update({v: k for k, v in kwds.items()}) + + def __call__(self, value): + return self.mapping[value] + + +off_on = Mapped(OFF=False, ON=True) +fast_slow = Mapped(ON=0, OFF=1) # maps OIs slow=ON/fast=OFF to sample_rate.slow=0/sample_rate.fast=1 + + +class IO(StringIO): identification = [('*IDN?', r'IDN:OXFORD INSTRUMENTS:MERCURY*')] -VALUE_UNIT = re.compile(r'(.*\d)([A-Za-z]*)$') - - -def make_map(**kwds): - """create a dict converting internal names to values and vice versa""" - kwds.update({v: k for k, v in kwds.items()}) - return kwds - - -MODE_MAP = make_map(OFF=0, ON=1) -SAMPLE_RATE = make_map(OFF=1, ON=0) # invert the codes used by OI - - -class MercuryChannel(HasIodev): - slots = Property('''slot uids +class MercuryChannel(HasIO): + slot = Property('''slot uids - example: DB6.T1,DB1.H1 - slot ids for sensor (and control output)''', - StringType()) - channel_name = Parameter('mercury nick name', StringType()) - channel_type = '' #: channel type(s) for sensor (and control) + example: DB6.T1,DB1.H1 + slot ids for sensor (and control output)''', + StringType()) + channel_name = Parameter('mercury nick name', StringType(), default='') + channel_type = '' #: channel type(s) for sensor (and control) e.g. TEMP,HTR or PRES,AUX - def query(self, adr, value=None): - """get or set a parameter in mercury syntax + def _complete_adr(self, adr): + """complete address from channel_type and slot""" + head, sep, tail = adr.partition(':') + for i, (channel_type, slot) in enumerate(zip(self.channel_type.split(','), self.slot.split(','))): + if head == str(i): + return 'DEV:%s:%s%s%s' % (slot, channel_type, sep, tail) + if head == channel_type: + return 'DEV:%s:%s%s%s' % (slot, head, sep, tail) + return adr - :param adr: for example "TEMP:SIG:TEMP" - :param value: if given and not None, a write command is executed - :return: the value + def multiquery(self, adr, names=(), convert=as_float): + """get parameter(s) in mercury syntax - remark: the DEV: is added automatically, when adr starts with the channel type - in addition, when addr starts with '0:' or '1:', the channel type is added + :param adr: the 'address part' of the SCPI command + the DEV: is added automatically, when adr starts with the channel type + in addition, when adr starts with '0:' or '1:', channel type and slot are added + :param names: the SCPI names of the parameter(s), for example ['TEMP'] + :param convert: a converter function (converts replied string to value) + :return: the values as tuple + + Example: + adr='AUX:SIG' + names = ('PERC',) + self.channel_type='PRES,AUX' # adr starts with 'AUX' + self.slot='DB5.P1,DB3.G1' # -> take second slot + -> query command will be READ:DEV:DB3.G1:PRES:SIG:PERC """ - for i, (channel_type, slot) in enumerate(zip(self.channel_type.split(','), self.slots.split(','))): - if adr.startswith('%d:' % i): - adr = 'DEV:%s:%s:%s' % (slot, channel_type, adr[2:]) # assume i <= 9 - break - if adr.startswith(channel_type + ':'): - adr = 'DEV:%s:%s' % (slot, adr) - break - if value is not None: - try: - value = '%g' % value # this works for float, integers and enums - except ValueError: - value = str(value) # this alone would not work for enums, and not be nice for floats - cmd = 'SET:%s:%s' % (adr, value) - reply = self._iodev.communicate(cmd) - if reply != 'STAT:%s:VALID' % cmd: - raise HardwareError('bad response %r to %r' % (reply, cmd)) - # chain a read command anyway - cmd = 'READ:%s' % adr - reply = self._iodev.communicate(cmd) - head, _, result = reply.rpartition(':') - if head != 'STAT:%s' % adr: - raise HardwareError('bad response %r to %r' % (reply, cmd)) - match = VALUE_UNIT.match(result) - if match: # result can be interpreted as a float with optional units - return float(match.group(1)) - return result + adr = self._complete_adr(adr) + cmd = 'READ:%s:%s' % (adr, ':'.join(names)) + reply = self.communicate(cmd) + head = 'STAT:%s:' % adr + try: + assert reply.startswith(head) + replyiter = iter(reply[len(head):].split(':')) + keys, result = zip(*zip(replyiter, replyiter)) + assert keys == tuple(names) + return tuple(convert(r) for r in result) + except (AssertionError, AttributeError, ValueError): + raise HardwareError('invalid reply %r to cmd %r' % (reply, cmd)) from None + + def multichange(self, adr, values, convert=as_float): + """set parameter(s) in mercury syntax + + :param adr: as in see multiquery method + :param values: [(name1, value1), (name2, value2) ...] + :param convert: a converter function (converts given value to string and replied string to value) + :return: the values as tuple + + Example: + adr='0:LOOP' + values = [('P', 5), ('I', 2), ('D', 0)] + self.channel_type='TEMP,HTR' # adr starts with 0: take TEMP + self.slot='DB6.T1,DB1.H1' # and take first slot + -> change command will be SET:DEV:DB6.T1:TEMP:LOOP:P:5:I:2:D:0 + """ + adr = self._complete_adr(adr) + params = ['%s:%s' % (k, convert(v)) for k, v in values] + cmd = 'SET:%s:%s' % (adr, ':'.join(params)) + reply = self.communicate(cmd) + head = 'STAT:SET:%s:' % adr + + try: + assert reply.startswith(head) + replyiter = iter(reply[len(head):].split(':')) + keys, result, valid = zip(*zip(replyiter, replyiter, replyiter)) + assert keys == tuple(k for k, _ in values) + assert any(v == 'VALID' for v in valid) + return tuple(convert(r) for r in result) + except (AssertionError, AttributeError, ValueError) as e: + raise HardwareError('invalid reply %r to cmd %r' % (reply, cmd)) from e + + def query(self, adr, convert=as_float): + """query a single parameter + + 'adr' and 'convert' areg + """ + adr, _, name = adr.rpartition(':') + return self.multiquery(adr, [name], convert)[0] + + def change(self, adr, value, convert=as_float): + adr, _, name = adr.rpartition(':') + return self.multichange(adr, [(name, value)], convert)[0] def read_channel_name(self): - return self.query('') + if self.channel_name: + return Done # channel name will not change + return self.query('0:NICK', as_string) class TemperatureSensor(MercuryChannel, Readable): channel_type = 'TEMP' value = Parameter(unit='K') - raw = Parameter('raw value', FloatRange()) + raw = Parameter('raw value', FloatRange(unit='Ohm')) def read_value(self): return self.query('TEMP:SIG:TEMP') @@ -111,240 +174,250 @@ class TemperatureSensor(MercuryChannel, Readable): return self.query('TEMP:SIG:RES') -class HasProgressCheck: - """mixin for progress checks +class HasInput(MercuryChannel): + controlled_by = Parameter('source of target value', EnumType(members={'self': SELF}), default=0) + target = Parameter(readonly=False) + input_modules = () - Implements progress checks based on tolerance, settling time and timeout. - The algorithm does its best to support changes of these parameters on the - fly. However, the full history is not considered, which means for example - that the spent time inside tolerance stored already is not altered when - changing tolerance. - """ - tolerance = Parameter('absolute tolerance', FloatRange(0), readonly=False, default=0) - min_slope = Parameter('minimal abs(slope)', FloatRange(0), readonly=False, default=0) - settling_time = Parameter( - '''settling time + def add_input(self, modobj): + if not self.input_modules: + self.input_modules = [] + self.input_modules.append(modobj) + prev_enum = self.parameters['controlled_by'].datatype._enum + # add enum member, using autoincrement feature of Enum + self.parameters['controlled_by'].datatype = EnumType(Enum(prev_enum, **{modobj.name: None})) - total amount of time the value has to be within tolerance before switching to idle. - ''', FloatRange(0), readonly=False, default=0) - timeout = Parameter( - '''timeout - - timeout = 0: disabled, else: - A timeout event happens, when the difference (target - value) is not improved by - at least min_slope * timeout over any interval (t, t + timeout). - As soon as the value is the first time within tolerance, the criterium is changed: - then the timeout event happens after this time + settling_time + timeout. - ''', FloatRange(0, unit='sec'), readonly=False, default=3600) - status = Parameter('status determined from progress check') - value = Parameter() - target = Parameter() - - def earlyInit(self): - super().earlyInit() - self.__state = StateMachine() - - def prepare_state(self, state): - tol = self.tolerance - if not tol: - tol = 0.01 * max(abs(self.target), abs(self.value)) - dif = abs(self.target - self.value) - return dif, tol, state.now, state.delta(0) - - def state_approaching(self, state): - if self.init(): - self.status = 'BUSY', 'approaching' - dif, tol, now, delta = self.prepare_state(state) - if dif < tol: - state.timeout_base = now - state.next_step(self.state_inside) - return - if not self.timeout: - return - if state.init(): - state.timeout_base = now - state.dif_crit = dif - return - min_slope = getattr(self, 'ramp', 0) or getattr('min_slope', 0) - state.dif_crit -= min_slope * delta - if dif < state.dif_crit: - state.timeout_base = now - elif now > state.timeout_base: - self.status = 'WARNING', 'convergence timeout' - state.next_action(self.state_idle) - - def state_inside(self, state): - if state.init(): - self.status = 'BUSY', 'inside tolerance' - dif, tol, now, delta = self.prepare_state(state) - if dif > tol: - state.next_action(self.state_outside) - state.spent_inside += delta - if state.spent_inside > self.settling_time: - self.status = 'IDLE', 'reached target' - state.next_action(self.state_idle) - - def state_outside(self, state, now, dif, tol, delta): - if state.init(): - self.status = 'BUSY', 'outside tolerance' - dif, tol, now, delta = self.prepare_state(state) - if dif < tol: - state.next_action(self.state_inside) - elif now > self.timeout_base + self.settling_time + self.timeout: - self.status = 'WARNING', 'settling timeout' - state.next_action(self.state_idle) - - def start_state(self): - """must be called from write_target, whenever the target changes""" - self.__state.start(self.state_approach) - - def poll(self): - super().poll() - self.__state.poll() - - def read_status(self): - if self.status[0] == 'IDLE': - # do not change when idle already - return self.status - return self.check_progress(self.value, self.target) - - def write_target(self, value): - raise NotImplementedError() + def write_controlled_by(self, value): + if self.controlled_by == value: + return Done + self.controlled_by = value + if value == SELF: + self.log.warning('switch to manual mode') + for input_module in self.input_modules: + if input_module.control_active: + input_module.write_control_active(False) + return Done -class Loop(HasProgressCheck, MercuryChannel): +class Loop(HasConvergence, MercuryChannel, Drivable): """common base class for loops""" - mode = Parameter('control mode', EnumType(manual=0, pid=1), readonly=False) + control_active = Parameter('control mode', BoolType()) + output_module = Attached(HasInput, mandatory=False) ctrlpars = Parameter( - 'pid (proportional nad, integral time, differential time', + 'pid (proportional band, integral time, differential time', StructOf(p=FloatRange(0, unit='$'), i=FloatRange(0, unit='min'), d=FloatRange(0, unit='min')), - readonly=False, poll=True + readonly=False, ) - """pid = Parameter('control parameters', StructOf(p=FloatRange(), i=FloatRange(), d=FloatRange()),readonly=False)""" - pid_table_mode = Parameter('', EnumType(off=0, on=1), readonly=False) + enable_pid_table = Parameter('', BoolType(), readonly=False) - def read_ctrlpars(self): - return self.query('0:LOOP:P') + def initModule(self): + super().initModule() + if self.output_module: + self.output_module.add_input(self) - def read_integ(self): - return self.query('0:LOOP:I') + def set_output(self, active): + if active: + if self.output_module and self.output_module.controlled_by != self.name: + self.output_module.controlled_by = self.name + else: + if self.output_module and self.output_module.controlled_by != SELF: + self.output_module.write_controlled_by(SELF) + status = IDLE, 'control inactive' + if self.status != status: + self.status = status - def read_deriv(self): - return self.query('0:LOOP:D') - - def write_prop(self, value): - return self.query('0:LOOP:P', value) - - def write_integ(self, value): - return self.query('0:LOOP:I', value) - - def write_deriv(self, value): - return self.query('0:LOOP:D', value) + def set_target(self, target): + if self.control_active: + self.set_output(True) + else: + self.log.warning('switch loop control on') + self.write_control_active(True) + self.target = target + self.start_state() def read_enable_pid_table(self): - return self.query('0:LOOP:PIDT').lower() + return self.query('0:LOOP:PIDT', off_on) def write_enable_pid_table(self, value): - return self.query('0:LOOP:PIDT', value.upper()).lower() + return self.change('0:LOOP:PIDT', value, off_on) - def read_mode(self): - return MODE_MAP[self.query('0:LOOP:ENAB')] + def read_ctrlpars(self): + # read all in one go, in order to reduce comm. traffic + pid = self.multiquery('0:LOOP', ('P', 'I', 'D')) + return {k: float(v) for k, v in zip('pid', pid)} - def write_mode(self, value): - if value == 'manual': - self.status = 'IDLE', 'manual mode' - elif self.status[0] == 'IDLE': - self.status = 'IDLE', '' - return MODE_MAP[self.query('0:LOOP:ENAB', value)] + def write_ctrlpars(self, value): + pid = self.multichange('0:LOOP', [(k, value[k.lower()]) for k in 'PID']) + return {k.lower(): v for k, v in zip('PID', pid)} + + +class HeaterOutput(HasInput, MercuryChannel, Writable): + """heater output + + Remark: + The hardware calculates the power from the voltage and the configured + resistivity. As the measured heater current is available, the resistivity + will be adjusted automatically, when true_power is True. + """ + channel_type = 'HTR' + value = Parameter('heater output', FloatRange(unit='W'), readonly=False) + target = Parameter('heater output', FloatRange(0, 100, unit='$'), readonly=False) + resistivity = Parameter('heater resistivity', FloatRange(10, 1000, unit='Ohm'), + readonly=False) + true_power = Parameter('calculate power from measured current', BoolType(), readonly=False, default=True) + limit = Parameter('heater output limit', FloatRange(0, 1000, unit='W'), readonly=False) + volt = 0.0 # target voltage + _last_target = None + _volt_target = None + + def read_limit(self): + return self.query('HTR:VLIM') ** 2 / self.resistivity + + def write_limit(self, value): + result = self.change('HTR:VLIM', math.sqrt(value * self.resistivity)) + return result ** 2 / self.resistivity + + def read_resistivity(self): + if self.true_power: + return self.resistivity + return max(10, self.query('HTR:RES')) + + def write_resistivity(self, value): + self.resistivity = self.change('HTR:RES', max(10, value)) + if self._last_target is not None: + if not self.true_power: + self._volt_target = math.sqrt(self._last_target * self.resistivity) + self.change('HTR:SIG:VOLT', self._volt_target) + return Done + + def read_status(self): + status = IDLE, ('true power' if self.true_power else 'fixed resistivity') + if self.status != status: + return status + return Done + + def read_value(self): + if self._last_target is None: # on init + self.read_target() + if not self.true_power: + volt = self.query('HTR:SIG:VOLT') + return volt ** 2 / max(10, self.resistivity) + volt, current = self.multiquery('HTR:SIG', ('VOLT', 'CURR')) + if volt > 0 and current > 0.0001 and self._last_target: + res = volt / current + tol = res * max(max(0.0003, abs(volt - self._volt_target)) / volt, 0.0001 / current, 0.0001) + if abs(res - self.resistivity) > tol + 0.07 and self._last_target: + self.write_resistivity(round(res, 1)) + if self.controlled_by == 0: + self._volt_target = math.sqrt(self._last_target * self.resistivity) + self.change('HTR:SIG:VOLT', self._volt_target) + return volt * current + + def read_target(self): + if self.controlled_by != 0 and self.target: + return 0 + if self._last_target is not None: + return Done + self._volt_target = self.query('HTR:SIG:VOLT') + self.resistivity = max(10, self.query('HTR:RES')) + self._last_target = self._volt_target ** 2 / max(10, self.resistivity) + return self._last_target + + def set_target(self, value): + """set the target without switching to manual + + might be used by a software loop + """ + self._volt_target = math.sqrt(value * self.resistivity) + self.change('HTR:SIG:VOLT', self._volt_target) + self._last_target = value + return value def write_target(self, value): - raise NotImplementedError - - # def read_pid(self): - # # read all in one go, in order to reduce comm. traffic - # cmd = 'READ:DEV:%s:TEMP:LOOP:P:I:D' % self.slots.split(',')[0] - # reply = self._iodev.communicate(cmd) - # result = list(reply.split(':')) - # pid = result[6::2] - # del result[6::2] - # if ':'.join(result) != cmd: - # raise HardwareError('bad response %r to %r' % (reply, cmd)) - # return dict(zip('pid', pid)) - # - # def write_pid(self, value): - # # for simplicity use single writes - # return {k: self.query('LOOP:%s' % k.upper(), value[k]) for k in 'pid'} + self.write_controlled_by(SELF) + return self.set_target(value) -class TemperatureLoop(Loop, TemperatureSensor, Drivable): +class TemperatureLoop(TemperatureSensor, Loop, Drivable): channel_type = 'TEMP,HTR' - heater_limit = Parameter('heater output limit', FloatRange(0, 100, unit='W'), readonly=False) - heater_resistivity = Parameter('heater resistivity', FloatRange(10, 1000, unit='Ohm'), readonly=False) + output_module = Attached(HeaterOutput, mandatory=False) ramp = Parameter('ramp rate', FloatRange(0, unit='K/min'), readonly=False) - enable_ramp = Parameter('enable ramp rate', EnumType(off=0, on=1), readonly=False) - auto_flow = Parameter('enable auto flow', EnumType(off=0, on=1), readonly=False) - heater_output = Parameter('heater output', FloatRange(0, 100, unit='W'), readonly=False) + enable_ramp = Parameter('enable ramp rate', BoolType(), readonly=False) + setpoint = Parameter('working setpoint (differs from target when ramping)', FloatRange(0, unit='$')) + auto_flow = Parameter('enable auto flow', BoolType(), readonly=False) + _last_setpoint_change = None - def read_heater_limit(self): - return self.query('HTR:VLIM') ** 2 / self.heater_resistivity + def doPoll(self): + super().doPoll() + self.read_setpoint() - def write_heater_limit(self, value): - result = self.query('HTR:VLIM', math.sqrt(value * self.heater_resistivity)) - return result ** 2 / self.heater_resistivity + def read_control_active(self): + active = self.query('TEMP:LOOP:ENAB', off_on) + self.set_output(active) + return active - def read_heater_resistivity(self): - value = self.query('HTR:RES') - if value: - return value - return self.heater_resistivity + def write_control_active(self, value): + self.set_output(value) + return self.change('TEMP:LOOP:ENAB', value, off_on) - def write_heater_resistivity(self, value): - return self.query('HTR:RES', value) + @nopoll # polled by read_setpoint + def read_target(self): + if self.read_enable_ramp(): + return self.target + self.setpoint = self.query('TEMP:LOOP:TSET') + return self.setpoint + + def read_setpoint(self): + setpoint = self.query('TEMP:LOOP:TSET') + if self.enable_ramp: + if setpoint == self.setpoint: + # update target when working setpoint does no longer change + if setpoint != self.target and self._last_setpoint_change is not None: + unchanged_since = time.time() - self._last_setpoint_change + if unchanged_since > max(12.0, 0.06 / max(1e-4, self.ramp)): + self.target = self.setpoint + return setpoint + self._last_setpoint_change = time.time() + else: + self.target = setpoint + return setpoint + + def write_target(self, value): + target = self.change('TEMP:LOOP:TSET', value) + if self.enable_ramp: + self._last_setpoint_change = None + self.set_target(value) + else: + self.set_target(target) + return Done def read_enable_ramp(self): - return self.query('TEMP:LOOP:RENA').lower() + return self.query('TEMP:LOOP:RENA', off_on) def write_enable_ramp(self, value): - return self.query('TEMP:LOOP:RENA', EnumType(off=0, on=1)(value).name).lower() + return self.change('TEMP:LOOP:RENA', value, off_on) def read_auto_flow(self): - return self.query('TEMP:LOOP:FAUT').lower() + return self.query('TEMP:LOOP:FAUT', off_on) def write_auto_flow(self, value): - return self.query('TEMP:LOOP:FAUT', EnumType(off=0, on=1)(value).name).lower() + return self.change('TEMP:LOOP:FAUT', value, off_on) def read_ramp(self): - return self.query('TEMP:LOOP:RSET') + result = self.query('TEMP:LOOP:RSET') + return min(9e99, result) def write_ramp(self, value): + # use 0 or a very big value for switching off ramp if not value: self.write_enable_ramp(0) return 0 - if value: - self.write_enable_ramp(1) - return self.query('TEMP:LOOP:RSET', value) - - def read_target(self): - # TODO: check about working setpoint - return self.query('TEMP:LOOP:TSET') - - def write_target(self, value): - if self.mode != 'pid': - self.log.warning('switch to pid loop mode') - self.write_mode('pid') - self.reset_progress(self.value, value) - return self.query('TEMP:LOOP:TSET', value) - - def read_heater_output(self): - # TODO: check that this really works, else next line - return self.query('HTR:SIG:POWR') - # return self.query('HTR:SIG:VOLT') ** 2 / self.heater_resistivity - - def write_heater_output(self, value): - if self.mode != 'manual': - self.log.warning('switch to manual heater mode') - self.write_mode('manual') - return self.query('HTR:SIG:VOLT', math.sqrt(value * self.heater_resistivity)) + if value >= 9e99: + self.change('TEMP:LOOP:RSET', 'inf', as_string) + self.write_enable_ramp(0) + return 9e99 + self.write_enable_ramp(1) + return self.change('TEMP:LOOP:RSET', max(1e-4, value)) class PressureSensor(MercuryChannel, Readable): @@ -355,32 +428,67 @@ class PressureSensor(MercuryChannel, Readable): return self.query('PRES:SIG:PRES') -class PressureLoop(Loop, PressureSensor, Drivable): +class ValvePos(HasInput, MercuryChannel, Drivable): channel_type = 'PRES,AUX' + value = Parameter('value pos', FloatRange(unit='%'), readonly=False) + target = Parameter('valve pos target', FloatRange(0, 100, unit='$'), readonly=False) - valve_pos = Parameter('valve position', FloatRange(0, 100, unit='%'), readonly=False) + def doPoll(self): + self.read_status() - def read_valve_pos(self): + def read_value(self): return self.query('AUX:SIG:PERC') - def write_valve_pos(self, value): - if self.mode != 'manual': - self.log.warning('switch to manual valve mode') - self.write_mode('manual') - return self.query('AUX:SIG:PERC', value) + def read_status(self): + self.read_value() + if abs(self.value - self.target) < 0.01: + return 'IDLE', 'at target' + return 'BUSY', 'moving' + + def read_target(self): + return self.query('PRES:LOOP:FSET') def write_target(self, value): - self.reset_progress(self.value, value) - return self.query('PRES:LOOP:PRST', value) + self.write_controlled_by(SELF) + return self.change('PRES:LOOP:FSET', value) + + +class PressureLoop(PressureSensor, Loop, Drivable): + channel_type = 'PRES,AUX' + output_module = Attached(ValvePos, mandatory=False) + + def read_control_active(self): + active = self.query('PRES:LOOP:FAUT', off_on) + self.set_output(active) + return active + + def write_control_active(self, value): + self.set_output(value) + return self.change('PRES:LOOP:FAUT', value, off_on) + + def read_target(self): + return self.query('PRES:LOOP:PRST') + + def write_target(self, value): + target = self.change('PRES:LOOP:PRST', value) + self.set_target(target) + return Done class HeLevel(MercuryChannel, Readable): + """He level meter channel + + The Mercury system does not support automatic switching between fast + (when filling) and slow (when consuming). We have to handle this by software. + """ channel_type = 'LVL' - sample_rate = Parameter('_', EnumType(slow=0, fast=1), readonly=False, poll=True) - hysteresis = Parameter('hysteresis for detection of increase', FloatRange(0, 100, unit='%'), readonly=False) - fast_timeout = Parameter('timeout for switching to slow', FloatRange(0, unit='sec'), readonly=False) - _min_level = 200 - _max_level = -100 + sample_rate = Parameter('_', EnumType(slow=0, fast=1), readonly=False) + hysteresis = Parameter('hysteresis for detection of increase', FloatRange(0, 100, unit='%'), + default=5, readonly=False) + fast_timeout = Parameter('time to switch to slow after last increase', FloatRange(0, unit='sec'), + default=300, readonly=False) + _min_level = 999 + _max_level = -999 _last_increase = None # None when in slow mode, last increase time in fast mode def check_rate(self, sample_rate): @@ -392,18 +500,18 @@ class HeLevel(MercuryChannel, Readable): if sample_rate != 0: # fast if not self._last_increase: self._last_increase = time.time() - self._max_level = -100 + self._max_level = -999 elif self._last_increase: self._last_increase = None - self._min_level = 200 + self._min_level = 999 return sample_rate def read_sample_rate(self): - return self.check_rate(SAMPLE_RATE[self.query('LVL:HEL:PULS:SLOW')]) + return self.check_rate(self.query('LVL:HEL:PULS:SLOW', fast_slow)) def write_sample_rate(self, value): self.check_rate(value) - return SAMPLE_RATE[self.query('LVL:HEL:PULS:SLOW', SAMPLE_RATE[value])] + return self.change('LVL:HEL:PULS:SLOW', value, fast_slow) def read_value(self): level = self.query('LVL:SIG:HEL:LEV') @@ -415,11 +523,11 @@ class HeLevel(MercuryChannel, Readable): self._max_level = level elif now > self._last_increase + self.fast_timeout: # no increase since fast timeout -> slow - self.write_sample_rate('slow') + self.write_sample_rate(self.sample_rate.slow) else: if level > self._min_level + self.hysteresis: # substantial increase -> fast - self.write_sample_rate('fast') + self.write_sample_rate(self.sample_rate.fast) else: self._min_level = min(self._min_level, level) return level @@ -432,5 +540,4 @@ class N2Level(MercuryChannel, Readable): return self.query('LVL:SIG:NIT:LEV') -class MagnetOutput(MercuryChannel, Drivable): - pass +# TODO: magnet power supply diff --git a/secop_psi/motorvalve.py b/secop_psi/motorvalve.py new file mode 100644 index 0000000..0c7344f --- /dev/null +++ b/secop_psi/motorvalve.py @@ -0,0 +1,267 @@ +# -*- 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 +# +# ***************************************************************************** + +"""motor valve using a trinamic PD-1161 motor + +the valve has an end switch connected to the 'home' digital input +of the motor controller. Motor settings for the currently used valve: + +[valve_motor] +description = valve motor +class = secop_psi.trinamic.Motor +maxcurrent=0.3 # a value corresponding to the torque needed to firmly close the valve. +move_limit=9999 # no move limit needed +acceleration=150 +encoder_tolerance=3.6 # typical value +auto_reset=True # motor stalls on closing + +[valve] +description = trinamic angular motor valve +class = secop_psi.motorvalve.MotorValve +motor = valve_motor +turns = 9 # number of turns needed to open fully +speed = 400 # close to max. speed +lowspeed = 50 # speed for final closing / reference run +""" + +from secop.core import Drivable, Parameter, EnumType, Attached, FloatRange, \ + Command, IDLE, BUSY, WARN, ERROR, Done, PersistentParam, PersistentMixin +from secop.errors import HardwareError +from secop_psi.trinamic import Motor +from secop.lib.statemachine import StateMachine, Retry, Stop + + +class MotorValve(PersistentMixin, Drivable): + motor = Attached(Motor) + value = Parameter('current state', EnumType( + closed=0, opened=1, undefined=-1), default=-1) + target = Parameter('target state', EnumType(close=0, open=1)) + turns = Parameter('number of turns to open', FloatRange(), readonly=False, group='settings') + speed = Parameter('speed for far moves', FloatRange(), readonly=False, group='settings') + lowspeed = Parameter('speed for finding closed position', FloatRange(), readonly=False, group='settings') + closed_pos = PersistentParam('fully closed position', FloatRange(), + persistent='auto', export=True, default=-999) # TODO: export=False + pollinterval = Parameter(group='settings') + + _state = None + + # remark: the home button must be touched when the motor is at zero + + def earlyInit(self): + super().earlyInit() + self._state = StateMachine(logger=self.log, count=3, cleanup=self.handle_error) + + def write_target(self, target): + if self.status[0] == ERROR: + raise HardwareError('%s: need refrun' % self.status[1]) + self.target = target + self._state.start(self.goto_target, count=3) + return Done + + def goto_target(self, state): + self.value = 'undefined' + if self.motor.isBusy(): + mot_target = 0 if self.target == self.target.close else self.turns * 360 + if abs(mot_target - self.motor.target) > self.motor.tolerance: + self.motor.stop() + return self.open_valve if self.target == self.target.open else self.close_valve + + def read_value(self): + """determine value and status""" + if self.status[0] == ERROR: + return 'undefined' + if self.motor.isBusy(): + return Done + motpos = self.motor.read_value() + if self.motor.read_home(): + if motpos > 360: + self.status = ERROR, 'home button must be released at this position' + elif motpos > 5: + if self.status[0] != ERROR: + self.status = WARN, 'position undefined' + elif motpos < -360: + self.status = ERROR, 'motor must not reach -1 turn!' + elif abs(motpos - self.closed_pos) < self.motor.tolerance: + self.status = IDLE, 'closed' + return 'closed' + self.status = WARN, 'nearly closed' + return 'undefined' + if abs(motpos - self.turns * 360) < 5: + self.status = IDLE, 'opened' + return 'opened' + if motpos < 5: + self.status = ERROR, 'home button must be engaged at this position' + elif self.status[0] != ERROR: + self.status = WARN, 'position undefined' + return 'undefined' + + def open_valve(self, state): + if state.init: + self.closed_pos = -999 + self.value = 'undefined' + self.status = BUSY, 'opening' + self.motor.write_speed(self.speed) + self.motor.write_target(self.turns * 360) + if self.motor.isBusy(): + if self.motor.home and self.motor.value > 360: + self.motor.stop() + self.status = ERROR, 'opening valve failed (home switch not released)' + return None + return Retry() + motvalue = self.motor.read_value() + if abs(motvalue - self.turns * 360) < 5: + self.read_value() # value = opened, status = IDLE + else: + if state.count > 0: + state.count -= 1 + self.log.info('target %g not reached, try again', motvalue) + return self.goto_target + self.status = ERROR, 'opening valve failed (motor target not reached)' + return None + + def close_valve(self, state): + if state.init: + self.closed_pos = -999 + self.status = BUSY, 'closing' + self.motor.write_speed(self.speed) + self.motor.write_target(0) + if self.motor.isBusy(): + if self.motor.home: + return self.find_closed + return Retry() + motvalue = self.motor.read_value() + if abs(motvalue) > 5: + if state.count > 0: + state.count -= 1 + self.log.info('target %g not reached, try again', motvalue) + return self.goto_target + self.status = ERROR, 'closing valve failed (zero not reached)' + return None + if self.read_value() == self.value.undefined: + if self.status[0] != ERROR: + return self.find_closed + return None + + def find_closed(self, state): + """drive with low speed until motor stalls""" + if state.init: + self.motor.write_speed(self.lowspeed) + state.prev = self.motor.value + self.motor.write_target(-360) + if self.motor.isBusy(): + if not self.motor.home: + self.motor.stop() + return None + return Retry() + motvalue = self.motor.read_value() + if motvalue < -360: + self.read_value() # status -> error + return None + if motvalue < state.prev - 5: + # moved by more than 5 deg + state.prev = self.motor.value + self.motor.write_target(-360) + return Retry() + if motvalue > 5: + self.status = ERROR, 'closing valve failed (zero not reached)' + return None + if motvalue < -355: + self.status = ERROR, 'closing valve failed (does not stop)' + return None + self.closed_pos = motvalue + self.read_value() # value = closed, status = IDLE + return None + + @Command + def ref_run(self): + """start reference run""" + self.target = 'close' + self._state.start(self.ref_home, count=3) + + @Command + def stop(self): + self._state.stop() + self.motor.stop() + + def ref_home(self, state): + if state.init: + self.closed_pos = -999 + self.motor.write_speed(self.lowspeed) + if self.motor.read_home(): + self.status = BUSY, 'refrun: release home' + self.motor.write_target(self.motor.read_value() + 360) + return self.ref_released + self.status = BUSY, 'refrun: find home' + self.motor.write_target(self.motor.read_value() - (self.turns + 1) * 360) + if not self.motor.isBusy(): + self.status = ERROR, 'ref run failed, can not find home switch' + return None + if not self.motor.home: + return Retry() + self.motor.write_speed(self.lowspeed) + state.prev = self.motor.read_value() + self.motor.write_target(state.prev - 360) + self.status = BUSY, 'refrun: find closed' + return self.ref_closed + + def ref_released(self, state): + if self.motor.isBusy(): + if self.motor.home: + return Retry() + elif self.motor.read_home(): + if state.count > 0: + state.count -= 1 + self.log.info('home switch not released, try again') + self.motor.write_target(self.motor.target) + return Retry() + self.status = ERROR, 'ref run failed, can not release home switch' + return None + return self.ref_home + + def ref_closed(self, state): + if self.motor.isBusy(): + if not self.motor.home: + self.motor.stop() + return None + return Retry() + self.motor.set_zero(max(-50, (self.motor.read_value() - state.prev) * 0.5)) + self.read_value() # check home button is valid + if abs(self.motor.target - self.motor.value) < 5: + self.status = ERROR, 'ref run failed, does not stop' + if self.status[0] == ERROR: + return None + self.log.info('refrun successful') + return self.close_valve + + def handle_error(self, state): + if state.stopped: # stop or restart case + if state.stopped is Stop: + self.status = WARN, 'stopped' + return None + if state.count > 0: + state.count -= 1 + self.log.info('error %r, try again', state.last_error) + state.default_cleanup(state) # log error cause + state.last_error = None + return self.goto_target # try again + self.status = ERROR, str(state.last_error) + return state.default_cleanup(state) diff --git a/secop_psi/phytron.py b/secop_psi/phytron.py index 3a020a7..13cb70b 100644 --- a/secop_psi/phytron.py +++ b/secop_psi/phytron.py @@ -23,50 +23,62 @@ """driver for pythron motors""" from secop.core import Done, Command, EnumType, FloatRange, IntRange, \ - HasIodev, Parameter, Property, Drivable, PersistentMixin, PersistentParam, StringIO, StringType + HasIO, Parameter, Property, Drivable, PersistentMixin, PersistentParam, StringIO, StringType from secop.errors import CommunicationFailedError, HardwareError class PhytronIO(StringIO): end_of_line = '\x03' # ETX + timeout = 0.2 identification = [('0IVR', 'MCC Minilog .*')] - def communicate(self, command): - head, _, reply = super().communicate('\x02' + command).partition('\x02') - if reply[0] != '\x06': # ACK - raise CommunicationFailedError('missing ACK %r' % reply) + def communicate(self, command, expect_response=True): + for ntry in range(5, 0, -1): + try: + head, _, reply = super().communicate('\x02' + command).partition('\x02') + if reply[0] == '\x06': # ACK + if len(reply) == 1 and expect_response: + raise CommunicationFailedError('empty response') + break + raise CommunicationFailedError('missing ACK %r' % reply) + except Exception as e: + if ntry == 1: + raise + self.log.warning('%s - retry', e) return reply[1:] -class Motor(PersistentMixin, HasIodev, Drivable): +class Motor(PersistentMixin, HasIO, Drivable): axis = Property('motor axis X or Y', StringType(), default='X') address = Property('address', IntRange(0, 15), default=0) speed_factor = Property('steps / degree', FloatRange(0, None), default=2000) encoder_mode = Parameter('how to treat the encoder', EnumType('encoder', NO=0, READ=1, CHECK=2), default=1, readonly=False) - value = Parameter('angle', FloatRange(unit='deg'), poll=True) + value = Parameter('angle', FloatRange(unit='deg')) target = Parameter('target angle', FloatRange(unit='deg'), readonly=False) - speed = Parameter('', FloatRange(0, 20, unit='deg/s'), readonly=False, poll=True) - accel = Parameter('', FloatRange(2, 250, unit='deg/s/s'), readonly=False, poll=True) + speed = Parameter('', FloatRange(0, 20, unit='deg/s'), readonly=False) + accel = Parameter('', FloatRange(2, 250, unit='deg/s/s'), readonly=False) encoder_tolerance = Parameter('', FloatRange(unit='deg'), readonly=False, default=0.01) zero = PersistentParam('', FloatRange(unit='deg'), readonly=False, default=0) - encoder = Parameter('encoder reading', FloatRange(unit='deg'), poll=True) + encoder = Parameter('encoder reading', FloatRange(unit='deg')) sameside_offset = Parameter('offset when always approaching from the same side', - FloatRange(unit='deg'), readonly=True, default=0) + FloatRange(unit='deg'), readonly=False, default=0) - iodevClass = PhytronIO - fast_pollfactor = 0.02 + ioClass = PhytronIO + fast_poll = 0.1 _sameside_pending = False + _mismatch_count = 0 def earlyInit(self): + super().earlyInit() self.loadParameters() def get(self, cmd): - return self._iodev.communicate('\x02%x%s%s' % (self.address, self.axis, cmd)) + return self.communicate('\x02%x%s%s' % (self.address, self.axis, cmd)) def set(self, cmd, value): - self._iodev.communicate('\x02%x%s%s%g' % (self.address, self.axis, cmd, value)) + self.communicate('\x02%x%s%s%g' % (self.address, self.axis, cmd, value), False) def set_get(self, cmd, value, query): self.set(cmd, value) @@ -79,6 +91,9 @@ class Motor(PersistentMixin, HasIodev, Drivable): enc = self.read_encoder() else: enc = pos + status = self.communicate('\x02%xSE' % self.address) + status = status[0:4] if self.axis == 'X' else status[4:8] + self.log.debug('run %s enc %s end %s', status[1], status[2], status[3]) status = self.get('=H') if status == 'N': if self.encoder_mode == 'CHECK': @@ -86,9 +101,11 @@ class Motor(PersistentMixin, HasIodev, Drivable): if e1 - self.encoder_tolerance <= pos <= e2 + self.encoder_tolerance: self.status = self.Status.BUSY, 'driving' else: - self.log.error('encoder lag: %g not within %g..%g' % (pos, e1, e2)) + self.log.error('encoder lag: %g not within %g..%g', + pos, e1, e2) self.get('S') # stop self.status = self.Status.ERROR, 'encoder lag error' + self.setFastPoll(False) else: self.status = self.Status.BUSY, 'driving' else: @@ -99,9 +116,16 @@ class Motor(PersistentMixin, HasIodev, Drivable): return pos if (self.encoder_mode == 'CHECK' and abs(enc - pos) > self.encoder_tolerance): - self.status = self.Status.ERROR, 'encoder does not match pos' + if self._mismatch_count < 2: + self._mismatch_count += 1 + else: + self.log.error('encoder mismatch: abs(%g - %g) < %g', + enc, pos, self.encoder_tolerance) + self.status = self.Status.ERROR, 'encoder does not match pos' else: + self._mismatch_count = 0 self.status = self.Status.IDLE, '' + self.setFastPoll(False) return pos def read_encoder(self): @@ -113,8 +137,9 @@ class Motor(PersistentMixin, HasIodev, Drivable): return float(self.get('P14R')) / self.speed_factor def write_speed(self, value): - if abs(float(self.get('P03R')) * self.speed_factor - 1) > 0.001: - raise HardwareError('speed factor does not match') + inv_factor = float(self.get('P03R')) + if abs(inv_factor * self.speed_factor - 1) > 0.001: + raise HardwareError('speed factor does not match %g' % (1.0 / inv_factor)) return float(self.set_get('P14S', int(value * self.speed_factor), 'P14R')) / self.speed_factor def read_accel(self): @@ -136,6 +161,7 @@ class Motor(PersistentMixin, HasIodev, Drivable): self.set('A', value - self.zero + self.sameside_offset) else: self.set('A', value - self.zero) + self.setFastPoll(True, self.fast_poll) return value def write_zero(self, value): @@ -167,4 +193,4 @@ class Motor(PersistentMixin, HasIodev, Drivable): # TODO: # '=E' electronics status # '=I+' / '=I-': limit switches -# use P37 to determine if restarted \ No newline at end of file +# use P37 to determine if restarted diff --git a/secop_psi/sea.py b/secop_psi/sea.py index 0bde526..a6cbe03 100644 --- a/secop_psi/sea.py +++ b/secop_psi/sea.py @@ -62,7 +62,7 @@ service = %(service)s CFG_MODULE = """ [%(module)s] class = secop_psi.sea.%(modcls)s -iodev = %(seaconn)s +io = %(seaconn)s sea_object = %(module)s """ @@ -367,7 +367,7 @@ def get_datatype(paramdesc): class SeaModule(Module): - iodev = Attached() + io = Attached() # pollerClass=None path2param = None @@ -380,7 +380,7 @@ class SeaModule(Module): else: extra_modules = {} srv.extra_sea_modules = extra_modules - json_file = cfgdict.pop('json_file', None) or SeaClient.default_json_file[cfgdict['iodev']] + json_file = cfgdict.pop('json_file', None) or SeaClient.default_json_file[cfgdict['io']] visibility_level = cfgdict.pop('visibility_level', 2) single_module = cfgdict.pop('single_module', None) @@ -406,7 +406,9 @@ class SeaModule(Module): # with open(join(seaconfdir, json_file + '.json')) as fp: # sea_object, descr = json.load(fp) with open(join(seaconfdir, json_file)) as fp: - descr = json.load(fp)[sea_object] + content = json.load(fp) + # print(json_file, content.keys()) + descr = content[sea_object] if rel_paths == '*' or not rel_paths: # take all main = descr['params'][0] @@ -419,13 +421,14 @@ class SeaModule(Module): # filter by relative paths rel_paths = rel_paths.split() result = [] + is_running = None for rpath in rel_paths: include = True for paramdesc in descr['params']: path = paramdesc['path'] if path.endswith('is_running'): # take this always - result.append(paramdesc) + is_running = paramdesc continue if paramdesc.get('visibility', 1) > visibility_level: continue @@ -437,6 +440,8 @@ class SeaModule(Module): result.append(paramdesc) elif sub[0] == rpath: result.append(paramdesc) + if is_running: # take this at end + result.append(is_running) descr['params'] = result rel0 = '' if rel_paths[0] == '.' else rel_paths[0] if result[0]['path'] == rel0: @@ -518,7 +523,7 @@ class SeaModule(Module): # print('override %s.read_%s' % (cls.__name__, key)) def rfunc(self, cmd='hval %s/%s' % (base, path)): - reply = self._iodev.query(cmd) + reply = self.io.query(cmd) try: reply = float(reply) except ValueError: @@ -538,7 +543,7 @@ class SeaModule(Module): value = int(value) # TODO: check if more has to be done for valid tcl data (strings?) cmd = "%s %s" % (command, value) - self._iodev.query(cmd) + self.io.query(cmd) return Done attributes['write_' + key] = wfunc @@ -584,7 +589,7 @@ class SeaModule(Module): self.DISPATCHER.broadcast_event(make_update(self.name, pobj)) def initModule(self): - self._iodev.register_obj(self, self.sea_object) + self.io.register_obj(self, self.sea_object) super().initModule() @@ -623,7 +628,7 @@ class SeaDrivable(SeaModule, Drivable): # return self.target def write_target(self, value): - self._iodev.query('run %s %s' % (self.sea_object, value)) + self.io.query('run %s %s' % (self.sea_object, value)) #self.status = [self.Status.BUSY, 'driving'] return value @@ -656,4 +661,4 @@ class SeaDrivable(SeaModule, Drivable): - on stdsct drivables this will call the halt script - on EaseDriv this will set the stopped state """ - self._iodev.query('%s is_running 0' % self.sea_object) + self.io.query('%s is_running 0' % self.sea_object) diff --git a/secop_psi/softcal.py b/secop_psi/softcal.py index 8095cbf..530c7be 100644 --- a/secop_psi/softcal.py +++ b/secop_psi/softcal.py @@ -191,7 +191,7 @@ class Sensor(Readable): def initModule(self): super().initModule() - self._rawsensor.registerCallbacks(self, ['status']) # auto update status + self.rawsensor.registerCallbacks(self, ['status']) # auto update status self._calib = CalCurve(self.calib) if self.description == '_': self.description = '%r calibrated with curve %r' % (self.rawsensor, self.calib) @@ -220,4 +220,4 @@ class Sensor(Readable): self.status = self.Status.ERROR, self._value_error def read_value(self): - return self._calib(self._rawsensor.read_value()) + return self._calib(self.rawsensor.read_value()) diff --git a/secop_psi/trinamic.py b/secop_psi/trinamic.py index 9b3edad..793f502 100644 --- a/secop_psi/trinamic.py +++ b/secop_psi/trinamic.py @@ -26,10 +26,12 @@ import time import struct from secop.core import BoolType, Command, EnumType, FloatRange, IntRange, \ - HasIO, Parameter, Property, Drivable, PersistentMixin, PersistentParam, Done + HasIO, Parameter, Property, Drivable, PersistentMixin, PersistentParam, Done, \ + IDLE, BUSY, ERROR from secop.io import BytesIO from secop.errors import CommunicationFailedError, HardwareError, BadValueError, IsBusyError from secop.rwhandler import ReadHandler, WriteHandler +from secop.lib import formatStatusBits MOTOR_STOP = 3 MOVE = 4 @@ -37,6 +39,8 @@ SET_AXIS_PAR = 5 GET_AXIS_PAR = 6 SET_GLOB_PAR = 9 GET_GLOB_PAR = 10 +SET_IO = 14 +GET_IO = 15 # STORE_GLOB_PAR = 11 BAUDRATES = [9600, 0, 19200, 0, 38400, 57600, 0, 115200] @@ -80,7 +84,8 @@ def writable(*args, **kwds): class Motor(PersistentMixin, HasIO, Drivable): address = Property('module address', IntRange(0, 255), default=1) - value = Parameter('motor position', FloatRange(unit='deg', fmtstr='%.3f')) + value = Parameter('motor position', FloatRange(unit='deg', fmtstr='%.3f'), + needscfg=False) zero = PersistentParam('zero point', FloatRange(unit='$'), readonly=False, default=0) encoder = PersistentParam('encoder reading', FloatRange(unit='$', fmtstr='%.1f'), readonly=True, initwrite=False) @@ -88,12 +93,17 @@ class Motor(PersistentMixin, HasIO, Drivable): readonly=True, initwrite=False) target = Parameter('', FloatRange(unit='$'), default=0) - move_limit = Parameter('max. angle to drive in one go', FloatRange(unit='$'), + move_limit = Parameter('max. angle to drive in one go when current above safe_current', + FloatRange(unit='$'), readonly=False, default=360, group='more') + safe_current = Parameter('motor current allowed for big steps', FloatRange(unit='A'), + readonly=False, default=0.2, group='more') tolerance = Parameter('positioning tolerance', FloatRange(unit='$'), readonly=False, default=0.9) encoder_tolerance = writable('the allowed deviation between steppos and encoder\n\nmust be > tolerance', FloatRange(0, 360., unit='$', fmtstr='%.3f'), group='more') + has_encoder = Parameter('whether encoder is used or not', BoolType(), + readonly=False, default=True, group='more') speed = writable('max. speed', FloatRange(0, MAX_SPEED, unit='$/sec', fmtstr='%.1f'), default=40) minspeed = writable('min. speed', FloatRange(0, MAX_SPEED, unit='$/sec', fmtstr='%.1f'), default=SPEED_SCALE, group='motorparam') @@ -106,10 +116,16 @@ class Motor(PersistentMixin, HasIO, Drivable): acceleration = writable('', FloatRange(4.6 * ACCEL_SCALE, MAX_ACCEL, unit='deg/s^2', fmtstr='%.1f'), default=150., group='motorparam') target_reached = Parameter('', BoolType(), group='hwstatus') - move_status = Parameter('', IntRange(0, 3), group='hwstatus') + move_status = Parameter('', EnumType(ok=0, stalled=1, encoder_deviation=2, stalled_and_encoder_deviation=3), + group='hwstatus') error_bits = Parameter('', IntRange(0, 255), group='hwstatus') + home = Parameter('state of home switch (input 3)', BoolType()) + has_home = Parameter('enable home and activate pullup resistor', BoolType(), + default=True, initwrite=True, group='more') + auto_reset = Parameter('automatic reset after failure', BoolType(), readonly=False, default=False) free_wheeling = writable('', FloatRange(0, 60., unit='sec', fmtstr='%.2f'), default=0.1, group='motorparam') + power_down_delay = writable('', FloatRange(0, 60., unit='sec', fmtstr='%.2f'), default=0.1, group='motorparam') baudrate = Parameter('', EnumType({'%d' % v: i for i, v in enumerate(BAUDRATES)}), @@ -117,22 +133,24 @@ class Motor(PersistentMixin, HasIO, Drivable): pollinterval = Parameter(group='more') ioClass = BytesIO - fast_pollfactor = 0.001 # not used any more, TODO: use a statemachine for running - _started = 0 - _calcTimeout = True + fast_poll = 0.05 + _run_mode = 0 # 0: idle, 1: driving, 2: stopping + _calc_timeout = True _need_reset = None + _last_change = 0 + _loading = False # True when loading parameters def comm(self, cmd, adr, value=0, bank=0): """set or get a parameter :param adr: parameter number - :param cmd: SET command (in the GET case, 1 is added to this) + :param cmd: instruction number (SET_* or GET_*) :param bank: the bank :param value: if given, the parameter is written, else it is returned :return: the returned value """ - if self._calcTimeout and self.io._conn: - self._calcTimeout = False + if self._calc_timeout and self.io._conn: + self._calc_timeout = False baudrate = getattr(self.io._conn.connection, 'baudrate', None) if baudrate: if baudrate not in BAUDRATES: @@ -167,6 +185,8 @@ class Motor(PersistentMixin, HasIO, Drivable): super().startModule(start_events) def fix_encoder(self=self): + if not self.has_encoder: + return try: # get encoder value from motor. at this stage self.encoder contains the persistent value encoder = self._read_axispar(ENCODER_ADR, ANGLE_SCALE) + self.zero @@ -174,7 +194,8 @@ class Motor(PersistentMixin, HasIO, Drivable): except Exception as e: self.log.error('fix_encoder failed with %r', e) - start_events.queue(fix_encoder) + if self.has_encoder: + start_events.queue(fix_encoder) def fix_encoder(self, encoder_from_hw): """fix encoder value @@ -194,7 +215,7 @@ class Motor(PersistentMixin, HasIO, Drivable): if adjusted_encoder != encoder_from_hw: self.log.info('take next closest encoder value (%.2f)' % adjusted_encoder) self._need_reset = True - self.status = self.Status.ERROR, 'saved encoder value does not match reading' + self.status = ERROR, 'saved encoder value does not match reading' self._write_axispar(adjusted_encoder - self.zero, ENCODER_ADR, ANGLE_SCALE, readback=False) def _read_axispar(self, adr, scale=1): @@ -235,71 +256,123 @@ class Motor(PersistentMixin, HasIO, Drivable): """handler write for HwParam""" return self._write_axispar(value, *HW_ARGS[pname]) + def doPoll(self): + self.read_status() # read_value is called by read_status + def read_value(self): - encoder = self.read_encoder() steppos = self.read_steppos() + encoder = self.read_encoder() if self.has_encoder else steppos + if self.has_home: + self.read_home() initialized = self.comm(GET_GLOB_PAR, 255, bank=2) if initialized: # no power loss self.saveParameters() - else: # just powered up - # get persistent values - writeDict = self.loadParameters() + elif not self._loading: # just powered up + try: + self._loading = True + # get persistent values + writeDict = self.loadParameters() + finally: + self._loading = False self.log.info('set to previous saved values %r', writeDict) # self.encoder now contains the last known (persistent) value if self._need_reset is None: - if self.status[0] == self.Status.IDLE: + if self.status[0] == IDLE: # server started, power cycled and encoder value matches last one self.reset() else: - self.fix_encoder(encoder) + if self.has_encoder: + self.fix_encoder(encoder) self._need_reset = True - self.status = self.Status.ERROR, 'power loss' + self.status = ERROR, 'power loss' # or should we just fix instead of error status? # self._write_axispar(self.steppos - self.zero, readback=False) self.comm(SET_GLOB_PAR, 255, 1, bank=2) # set initialized flag - self._started = 0 + self._run_mode = 0 + self.setFastPoll(False) return encoder if abs(encoder - steppos) > self.tolerance else steppos def read_status(self): oldpos = self.steppos self.read_value() # make sure encoder and steppos are fresh - if not self._started: - if abs(self.encoder - self.steppos) > self.encoder_tolerance: + if not self._run_mode: + if self.has_encoder and abs(self.encoder - self.steppos) > self.encoder_tolerance: self._need_reset = True - if self.status[0] != self.Status.ERROR: + if self.auto_reset: + return IDLE, 'encoder does not match internal pos' + if self.status[0] != ERROR: self.log.error('encoder (%.2f) does not match internal pos (%.2f)', self.encoder, self.steppos) - return self.Status.ERROR, 'encoder does not match internal pos' + return ERROR, 'encoder does not match internal pos' return self.status - if oldpos != self.steppos or not (self.read_target_reached() or self.read_move_status() - or self.read_error_bits()): - return self.Status.BUSY, 'moving' - # TODO: handle the different errors from move_status and error_bits + now = self.parameters['steppos'].timestamp + if self.steppos != oldpos: + self._last_change = now + return BUSY, 'stopping' if self._run_mode == 2 else 'moving' + if now < self._last_change + 0.3 and not (self.read_target_reached() or self.read_move_status()): + return BUSY, 'stopping' if self._run_mode == 2 else 'moving' + if self.target_reached: + reason = '' + elif self.move_status: + reason = self.move_status.name + elif self.error_bits: + reason = formatStatusBits(self.error_bits, ( + 'stallGuard', 'over_temp', 'over_temp_warn', 'short_A', 'short_B', + 'open_load_A', 'open_load_B', 'standstill')) + else: + reason = 'unknown' + self.setFastPoll(False) + if self._run_mode == 2: + self.target = self.value # indicate to customers that this was stopped + self._run_mode = 0 + return IDLE, 'stopped' + self._run_mode = 0 diff = self.target - self.encoder if abs(diff) <= self.tolerance: - self._started = 0 - return self.Status.IDLE, '' - self.log.error('out of tolerance by %.3g', diff) - self._started = 0 - return self.Status.ERROR, 'out of tolerance' + if reason: + self.log.warning('target reached, but move_status = %s', reason) + return IDLE, '' + if self.auto_reset: + self._need_reset = True + return IDLE, 'stalled: %s' % reason + self.log.error('out of tolerance by %.3g (%s)', diff, reason) + return ERROR, 'out of tolerance (%s)' % reason def write_target(self, target): - self.read_value() # make sure encoder and steppos are fresh - if abs(target - self.encoder) > self.move_limit: - raise BadValueError('can not move more than %s deg' % self.move_limit) - diff = self.encoder - self.steppos - if self._need_reset: - raise HardwareError('need reset (%s)' % self.status[1]) + for _ in range(2): # for auto reset + self.read_value() # make sure encoder and steppos are fresh + if self.maxcurrent >= self.safe_current + CURRENT_SCALE and ( + abs(target - self.encoder) > self.move_limit + self.tolerance): + # pylint: disable=bad-string-format-type + # pylint wrongly does not recognise encoder as a descriptor + raise BadValueError('can not move more than %g deg (%g -> %g)' % + (self.move_limit, self.encoder, target)) + diff = self.encoder - self.steppos + if self._need_reset: + if self.auto_reset: + if self.isBusy(): + self.stop() + while self.isBusy(): + time.sleep(0.1) + self.read_value() + self.reset() + if self.status[0] == IDLE: + continue + raise HardwareError('auto reset failed') + raise HardwareError('need reset (%s)' % self.status[1]) + break if abs(diff) > self.tolerance: - if abs(diff) > self.encoder_tolerance: + if abs(diff) > self.encoder_tolerance and self.has_encoder: self._need_reset = True - self.status = self.Status.ERROR, 'encoder does not match internal pos' + self.status = ERROR, 'encoder does not match internal pos' raise HardwareError('need reset (encoder does not match internal pos)') - self._write_axispar(self.encoder - self.zero, STEPPOS_ADR, ANGLE_SCALE) - self._started = time.time() - self.log.info('move to %.1f', target) + self._write_axispar(self.encoder - self.zero, STEPPOS_ADR, ANGLE_SCALE, readback=False) + self._last_change = time.time() + self._run_mode = 1 # driving + self.setFastPoll(True, self.fast_poll) + self.log.debug('move to %.1f', target) self.comm(MOVE, 0, (target - self.zero) / ANGLE_SCALE) - self.status = self.Status.BUSY, 'changed target' + self.status = BUSY, 'changed target' return target def write_zero(self, value): @@ -308,71 +381,67 @@ class Motor(PersistentMixin, HasIO, Drivable): return Done def read_encoder(self): - return self._read_axispar(ENCODER_ADR, ANGLE_SCALE) + self.zero + if self.has_encoder: + return self._read_axispar(ENCODER_ADR, ANGLE_SCALE) + self.zero + return self.read_steppos() def read_steppos(self): return self._read_axispar(STEPPOS_ADR, ANGLE_SCALE) + self.zero + def read_home(self): + return not self.comm(GET_IO, 255) & 8 + + def write_has_home(self, value): + """activate pullup resistor""" + return bool(self.comm(SET_IO, 0, value)) + @Command(FloatRange()) def set_zero(self, value): - """adjust zero""" - self.write_zero(value - self.read_value()) + """adapt zero to make current position equal to given value""" + raw = self.read_value() - self.zero + self.write_zero(value - raw) def read_baudrate(self): return self.comm(GET_GLOB_PAR, 65) def write_baudrate(self, value): - self.comm(SET_GLOB_PAR, 65, int(value)) + """a baudrate change takes effect only after power cycle""" + return self.comm(SET_GLOB_PAR, 65, int(value)) @Command() def reset(self): """set steppos to encoder value, if not within tolerance""" - if self._started: + if self._run_mode: raise IsBusyError('can not reset while moving') tol = ENCODER_RESOLUTION * 1.1 for itry in range(10): diff = self.read_encoder() - self.read_steppos() if abs(diff) <= tol: self._need_reset = False - self.status = self.Status.IDLE, 'ok' + self.status = IDLE, 'ok' return self._write_axispar(self.encoder - self.zero, STEPPOS_ADR, ANGLE_SCALE, readback=False) self.comm(MOVE, 0, (self.encoder - self.zero) / ANGLE_SCALE) time.sleep(0.1) if itry > 5: tol = self.tolerance - self.status = self.Status.ERROR, 'reset failed' + self.status = ERROR, 'reset failed' return @Command() def stop(self): """stop motor immediately""" + self._run_mode = 2 # stopping self.comm(MOTOR_STOP, 0) - self.status = self.Status.IDLE, 'stopped' - self._started = 0 + self.status = BUSY, 'stopping' + self.setFastPoll(False) - @Command() - def step_forward(self): - """move one full step forwards - - for quick tests - """ - self.comm(MOVE, 1, FULL_STEP / ANGLE_SCALE) - - @Command() - def step_back(self): - """move one full step backwards - - for quick tests - """ - self.comm(MOVE, 1, - FULL_STEP / ANGLE_SCALE) - - @Command(IntRange(), result=IntRange()) + @Command(IntRange(), result=IntRange(), export=False) def get_axis_par(self, adr): """get arbitrary motor parameter""" return self.comm(GET_AXIS_PAR, adr) - @Command((IntRange(), IntRange()), result=IntRange()) + @Command((IntRange(), IntRange()), result=IntRange(), export=False) def set_axis_par(self, adr, value): """set arbitrary motor parameter""" return self.comm(SET_AXIS_PAR, adr, value) diff --git a/secop_psi/triton.py b/secop_psi/triton.py new file mode 100644 index 0000000..93a0e48 --- /dev/null +++ b/secop_psi/triton.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# -*- 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 +# ***************************************************************************** +"""oxford instruments triton (kelvinoxjt dil)""" + +from secop.core import Drivable, HasIO, Writable, \ + Parameter, Property, Readable, StringIO, Attached, Done, IDLE, nopoll +from secop.datatypes import EnumType, FloatRange, StringType, StructOf, BoolType +from secop_psi.mercury import MercuryChannel, Mapped, off_on +import secop_psi.mercury as mercury + + +opened_closed = Mapped(opened=False, closed=True) +open_close = Mapped(open=False, clos=True) + + +class DilState(MercuryChannel): + pass + # states: + # CLDN (cool down) + # PCL (precool automation) + # COND (condense mixture) + # PCOND (pause pre-cool (not condense?) automation + # RCOND (resume pre-cool (not condense?) automation + # WARM (warm-up) + # COLL (collect mixture) + # EPCL (empty pre-coll automation) + # STOP + # + + +class Valve(MercuryChannel, Writable): + channel_type = 'VALV' + value = Parameter('valve state', EnumType(closed=0, opened=1)) + target = Parameter('valve target', EnumType(close=0, open=1)) + + def read_value(self): + return self.query('VALV:SIG:STATE', opened_closed) + + def write_target(self, value): + return self.change('VALV:SIG:STATE', value, open_close) + + +class Pump(MercuryChannel, Writable): + channel_type = 'PUMP' + value = Parameter('pump state', EnumType(closed=0, opened=1)) + target = Parameter('pump target', EnumType(close=0, open=1)) + power = Parameter('pump power', FloatRange(unit='W')) + freq = Parameter('pump frequency', FloatRange(unit='Hz')) + powerstage_temp = Parameter('temperature of power stage', FloatRange(unit='K')) + motor_temp = Parameter('temperature of motor', FloatRange(unit='K')) + bearing_temp = Parameter('temperature of bearing', FloatRange(unit='K')) + pumpbase_temp = Parameter('temperature of pump base', FloatRange(unit='K')) + electronics_temp = Parameter('temperature of electronics', FloatRange(unit='K')) + + def read_value(self): + return self.query('PUMP:SIG:STATE', off_on) + + def write_target(self, value): + return self.change('PUMP:SIG:STATE', value, off_on) + + def read_status(self): + # TODO: check possible status values + return self.WARN, self.query('PUMP:SIG:STATUS') + + def read_power(self): + return self.query('PUMP:SIG:POWR') + + def read_freq(self): + return self.query('PUMP:SIG:SPD') + + def read_powerstage_temp(self): + return self.query('PUMP:SIG:PST') + + def read_motor_temp(self): + return self.query('PUMP:SIG:MT') + + def read_bearing_temp(self): + return self.query('PUMP:SIG:BT') + + def read_pumpbase_temp(self): + return self.query('PUMP:SIG:PBT') + + def read_electronics_temp(self): + return self.query('PUMP:SIG:ET') + + +class PulseTubeCompressor(MercuryChannel, Writable): + channel_type = 'PTC' + value = Parameter('compressor state', EnumType(closed=0, opened=1)) + target = Parameter('compressor target', EnumType(close=0, open=1)) + water_in_temp = Parameter('temperature of water inlet', FloatRange(unit='K')) + water_out_temp = Parameter('temperature of water outlet', FloatRange(unit='K')) + helium_temp = Parameter('temperature of helium', FloatRange(unit='K')) + helium_low_pressure = Parameter('helium pressure (low side)', FloatRange(unit='mbar')) + helium_high_pressure = Parameter('helium pressure (high side)', FloatRange(unit='mbar')) + motor_current = Parameter('motor current', FloatRange(unit='A')) + + def read_value(self): + return self.query('PTC:SIG:STATE', off_on) + + def write_target(self, value): + return self.change('PTC:SIG:STATE', value, off_on) + + def read_status(self): + # TODO: check possible status values + return self.WARN, self.query('PTC:SIG:STATUS') + + def read_water_in_temp(self): + return self.query('PTC:SIG:WIT') + + def read_water_out_temp(self): + return self.query('PTC:SIG:WOT') + + def read_helium_temp(self): + return self.query('PTC:SIG:HT') + + def read_helium_low_pressure(self): + return self.query('PTC:SIG:HLP') + + def read_helium_high_pressure(self): + return self.query('PTC:SIG:HHP') + + def read_motor_current(self): + return self.query('PTC:SIG:MCUR') + + +class FlowMeter(MercuryChannel, Readable): + channel_type = 'FLOW' + + def read_value(self): + return self.query('FLOW:SIG:FLOW') + + +class TemperatureSensor(mercury.TemperatureSensor): + # TODO: excitation, enable + filter_time = Parameter('filter time', FloatRange(1, 200, unit='sec'), readonly=False) + dwell_time = Parameter('dwell time', FloatRange(1, 200, unit='sec'), readonly=False) + pause_time = Parameter('pause time', FloatRange(3, 200, unit='sec'), readonly=False) + + def read_filter_time(self): + return self.query('TEMP:FILT:TIME') + + def write_filter_time(self, value): + self.change('TEMP:FILT:WIN', 80) + return self.change('TEMP:FILT:TIME', value) + + def read_dwell_time(self): + return self.query('TEMP:FILT:DWEL') + + def write_dwell_time(self, value): + self.change('TEMP:FILT:WIN', 80) + return self.change('TEMP:FILT:DWEL', value) + + def read_pause_time(self): + return self.query('TEMP:FILT:PAUS') + + def write_pause_time(self, value): + self.change('TEMP:FILT:WIN', 80) + return self.change('TEMP:FILT:PAUS', value) + + +class TemperatureLoop(mercury.TemperatureLoop): + pass # TODO: switch on/off filter, check diff --git a/test/test_errors.py b/test/test_errors.py new file mode 100644 index 0000000..fd455eb --- /dev/null +++ b/test/test_errors.py @@ -0,0 +1,30 @@ +# -*- 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 +# +# ***************************************************************************** +"""test data types.""" + +import secop.errors + + +def test_errors(): + """check consistence of secop.errors.EXCEPTIONS""" + for e in secop.errors.EXCEPTIONS.values(): + assert secop.errors.EXCEPTIONS[e().name] == e diff --git a/test/test_statemachine.py b/test/test_statemachine.py index b835fb3..2ea81b5 100644 --- a/test/test_statemachine.py +++ b/test/test_statemachine.py @@ -78,7 +78,6 @@ def test_fun(): s.cycle() # do nothing assert s.step == 0 s.start(rise, level=0, direction=0) - s.cycle() for i in range(1, 4): assert s.status == 'rise' assert s.step == i @@ -100,7 +99,6 @@ def test_fun(): def test_max_chain(): s = StateMachine(step=0, status='', threaded=False, logger=LoggerStub()) s.start(fall, level=999+1, direction=0) - s.cycle() assert isinstance(s.last_error, RuntimeError) assert s.state is None