Merge branch 'wip' of gitlab.psi.ch:samenv/frappy into wip

This commit is contained in:
l_samenv 2022-04-29 08:47:39 +02:00
commit 1d7351ba4f
71 changed files with 2823 additions and 698 deletions

4
cfg/addons.ini Normal file
View File

@ -0,0 +1,4 @@
[FRAPPY]
confdir = ~/frappy/cfg/addons:~/frappy/cfg/develop
logdir = ~/frappylog
piddir = ~/frappylog/pid

View File

@ -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

View File

@ -10,5 +10,5 @@ service = addons
[befilter]
class = secop_psi.sea.SeaReadable
iodev = sea_addons
io = sea_addons
sea_object = cryo

View File

@ -1,5 +1,5 @@
[NODE]
description = sea client (communication only)
description = sea client (tool for creating cfg)
id = comm.sea.psi.ch
[seaconn]

View File

@ -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

View File

@ -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

View File

@ -18,4 +18,4 @@ channel = 3
description = resistivity
main = lsmain
# the auto created iodev from lsmain:
iodev = lsmain_iodev
io = lsmain_io

4
cfg/main.ini Normal file
View File

@ -0,0 +1,4 @@
[FRAPPY]
confdir = ~/frappy/cfg/main:~/frappy/cfg/develop
logdir = ~/frappylog
piddir = ~/frappylog/pid

View File

@ -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

View File

@ -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

14
cfg/main/ccr3.cfg Normal file
View File

@ -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

43
cfg/main/cryosim.cfg Normal file
View File

@ -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

View File

@ -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

57
cfg/main/ill4.cfg Normal file
View File

@ -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

View File

@ -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

View File

@ -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

55
cfg/main/ma6.cfg Normal file
View File

@ -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

View File

@ -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

51
cfg/main/magsim.cfg Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = .

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = .

View File

@ -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 = .

View File

@ -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 = .

View File

@ -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

160
cfg/sea/ccr3.config.json Normal file
View File

@ -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"}]}}

View File

@ -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 = "}]}}

View File

@ -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

49
cfg/sea/ill4.cfg Normal file
View File

@ -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

299
cfg/sea/ill4.config.json Normal file
View File

@ -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 ..."}]}}

View File

@ -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 = .

353
cfg/sea/ma6.config.json Normal file
View File

@ -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"}]}}

View File

@ -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 = .

View File

@ -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 ..."}]}}

View File

@ -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 = .

View File

@ -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 = .

4
cfg/stick.ini Normal file
View File

@ -0,0 +1,4 @@
[FRAPPY]
confdir = ~/frappy/cfg/stick:~/frappy/cfg/develop
logdir = ~/frappylog
piddir = ~/frappylog/pid

17
cfg/stick/ill4stick.cfg Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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 = .

View File

@ -17,12 +17,14 @@
#
# Module authors:
# Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
# Markus Zolliker <markus.zolliker@psi.ch>
#
# *****************************************************************************
"""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):

View File

@ -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) <replylen> 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):

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 [<name of poll func>] 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()

View File

@ -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):

View File

@ -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

View File

@ -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):

View File

@ -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:<slot> 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:<slot> 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

267
secop_psi/motorvalve.py Normal file
View File

@ -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 <markus.zolliker@psi.ch>
#
# *****************************************************************************
"""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)

View File

@ -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
# use P37 to determine if restarted

View File

@ -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)

View File

@ -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())

View File

@ -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)

181
secop_psi/triton.py Normal file
View File

@ -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 <markus.zolliker@psi.ch>
# *****************************************************************************
"""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

30
test/test_errors.py Normal file
View File

@ -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 <markus.zolliker@psi.ch>
#
# *****************************************************************************
"""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

View File

@ -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