diff --git a/cfg/main/mb11.cfg b/cfg/main/mb11.cfg new file mode 100644 index 0000000..6c082e1 --- /dev/null +++ b/cfg/main/mb11.cfg @@ -0,0 +1,163 @@ +[NODE] +id = mb11.psi.ch +description = MB11 11 Tesla - 100 mm cryomagnet + +[INTERFACE] +uri = tcp://5000 + +[itc1] +class = secop_psi.mercury.IO +description = ITC for heat exchanger and pressures +uri = mb11-ts:3001 + +[itc2] +class = secop_psi.mercury.IO +description = ITC for neck and nv heaters +uri = mb11-ts:3002 + +[ips] +class = secop_psi.mercury.IO +description = IPS for magnet and levels +uri = mb11-ts:3003 + +[T_stat] +class = secop_psi.mercury.TemperatureLoop +description = static heat exchanger temperature +output_module = htr_stat +slot = DB6.T1,DB1.H1 +io = itc1 + +[htr_stat] +class = secop_psi.mercury.HeaterOutput +description = static heat exchanger heater +slot = DB1.H1 +io = itc1 + +[p_stat] +class = secop_psi.mercury.PressureLoop +description = static needle valve pressure +output_module = pos_stat +slot = DB5.P1,DB3.G1 +io = itc1 + +[pos_stat] +class = secop_psi.mercury.ValvePos +description = static needle valve position +slot = DB5.P1,DB3.G1 +io = itc1 + +[T_dyn] +class = secop_psi.mercury.TemperatureLoop +description = dynamic heat exchanger temperature +output_module = htr_dyn +slot = DB7.T1,DB2.H1 +io = itc1 + +[htr_dyn] +class = secop_psi.mercury.HeaterOutput +description = dynamic heat exchanger heater +slot = DB2.H1 +io = itc1 + +[p_dyn] +class = secop_psi.mercury.PressureLoop +description = dynamic needle valve pressure +output_module = pos_dyn +slot = DB8.P1,DB4.G1 +io = itc1 + +[pos_dyn] +class = secop_psi.mercury.ValvePos +description = dynamic needle valve position +slot = DB8.P1,DB4.G1 +io = itc1 + +[lev] +class = secop_psi.mercury.HeLevel +description = LHe level +slot = DB1.L1 +io = ips + +[n2lev] +class = secop_psi.mercury.N2Level +description = LHe level +slot = DB1.L1 +io = ips + +[T_neck1] +class = secop_psi.mercury.TemperatureLoop +description = neck heater 1 temperature +output_module = htr_neck1 +slot = MB1.T1,MB0.H1 +io = itc2 + +[htr_neck1] +class = secop_psi.mercury.HeaterOutput +description = neck heater 1 power +slot = MB0.H1 +io = itc2 + +[T_neck2] +class = secop_psi.mercury.TemperatureLoop +description = neck heater 2 temperature +output_module = htr_neck2 +slot = DB6.T1,DB1.H1 +io = itc2 + +[htr_neck2] +class = secop_psi.mercury.HeaterOutput +description = neck heater 2 power +slot = DB1.H1 +io = itc2 + +[T_nvs] +class = secop_psi.mercury.TemperatureLoop +description = static needle valve temperature +output_module = htr_nvs +slot = DB7.T1,DB2.H1 +io = itc2 + +[htr_nvs] +class = secop_psi.mercury.HeaterOutput +description = static needle valve heater power +slot = DB2.H1 +io = itc2 + +[T_nvd] +class = secop_psi.mercury.TemperatureLoop +description = dynamic needle valve heater temperature +output_module = htr_nvd +slot = DB8.T1,DB3.H1 +io = itc2 + +[htr_nvd] +class = secop_psi.mercury.HeaterOutput +description = dynamic needle valve heater power +slot = DB3.H1 +io = itc2 + +[T_coil] +class = secop_psi.mercury.TemperatureSensor +description = coil temperature +slot = MB1.T1 +io = ips + +[mf] +class = secop_psi.ips_mercury.Field +description = magnetic field +slot = GRPZ +io = ips +target.max = 11 + +#[om_io] +#description = dom motor IO +#class = secop_psi.phytron.PhytronIO +#uri = mb11-ts.psi.ch:3004 + +#[om] +#description = stick rotation, typically used for omega +#class = secop_psi.phytron.Motor +#io = om_io +#sign = -1 +#encoder_mode = NO + diff --git a/cfg/mb11.cfg b/cfg/mb11.cfg deleted file mode 100644 index 7de74e9..0000000 --- a/cfg/mb11.cfg +++ /dev/null @@ -1,70 +0,0 @@ -[seaconn] -class = secop_psi.sea.SeaClient -description = a SEA connection -# uri will be automatic - -[ts] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = ts.mb11.config -remote_paths = . - -[tvs] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tvs.mb11.config -remote_paths = . - -[tvd] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tvd.mb11.config -remote_paths = . - -[pstat] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = pstat.mb11.config -remote_paths = . - -[pdyn] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = pdyn.mb11.config -remote_paths = . - -[tneck1] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tneck1.mb11.config -remote_paths = . - -[tneck2] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tneck2.mb11.config -remote_paths = . - -[tnvs] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tnvs.mb11.config -remote_paths = . - -[tnvd] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tnvd.mb11.config -remote_paths = . - -[mf] -class = secop_psi.sea.SeaDrivable -io = seaconn -json_descr = mf.mb11.config -remote_paths = . - -[tcoil] -class = secop_psi.sea.SeaReadable -io = seaconn -json_descr = tcoil.mb11.config -remote_paths = . diff --git a/cfg/sea/dil2.stick.json b/cfg/sea/dil2.stick.json new file mode 100644 index 0000000..c79aa45 --- /dev/null +++ b/cfg/sea/dil2.stick.json @@ -0,0 +1,343 @@ +{"ts": {"base": "/ts", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run ts", "description": "ts", "kids": 19}, +{"path": "send", "type": "text", "readonly": false, "cmd": "ts send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "ts is_running", "visibility": 3}, +{"path": "set", "type": "float", "readonly": false, "cmd": "ts set", "visibility": 3}, +{"path": "target", "type": "float"}, +{"path": "running", "type": "int"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "ts tolerance"}, +{"path": "maxwait", "type": "float", "readonly": false, "cmd": "ts maxwait"}, +{"path": "settle", "type": "float", "readonly": false, "cmd": "ts settle"}, +{"path": "log", "type": "text", "readonly": false, "cmd": "ts 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": "ramp", "type": "float", "readonly": false, "cmd": "ts ramp", "description": "ramp [K/min]"}, +{"path": "heaterselect", "type": "enum", "enum": {"sample": 0, "mix": 1, "mix(temporarely)": 2}, "readonly": false, "cmd": "ts heaterselect"}, +{"path": "control", "type": "enum", "enum": {"off": 0, "sample": 6, "mix": 5, "samplehtr": 8}, "readonly": false, "cmd": "ts control", "description": "click off to reload list"}, +{"path": "heatermode", "type": "enum", "enum": {"disabled": -1, "off": 0, "on": 1}, "readonly": false, "cmd": "ts heatermode"}, +{"path": "heaterrange", "type": "enum", "enum": {"2uW": 1, "20uW": 2, "200uW": 3, "2mW": 4, "20mW": 5}, "readonly": false, "cmd": "ts heaterrange"}, +{"path": "autoheater", "type": "bool", "readonly": false, "cmd": "ts autoheater", "description": "automatic heater range", "kids": 12}, +{"path": "autoheater/wlp0", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp0", "description": "weak link base temperature (used for auto heater)"}, +{"path": "autoheater/wlp1", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp1", "description": "weak link temperature at 1 uW (used for auto heater)"}, +{"path": "autoheater/wlp2", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp2", "description": "weak link temperature at 10 uW (used for auto heater)"}, +{"path": "autoheater/wlp3", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp3", "description": "weak link temperature at 100 uW (used for auto heater)"}, +{"path": "autoheater/wlp4", "type": "float", "readonly": false, "cmd": "ts autoheater/wlp4", "description": "weak link temperature at 1 mW (used for auto heater)"}, +{"path": "autoheater/mxp0", "type": "float", "readonly": false, "cmd": "ts autoheater/mxp0", "description": "weak link base temperature (used for auto heater)"}, +{"path": "autoheater/mxp1", "type": "float", "readonly": false, "cmd": "ts autoheater/mxp1", "description": "mix.ch. temperature at 1 uW (used for auto heater)"}, +{"path": "autoheater/mxp2", "type": "float", "readonly": false, "cmd": "ts autoheater/mxp2", "description": "mix.ch. temperature at 10 uW (used for auto heater)"}, +{"path": "autoheater/mxp3", "type": "float", "readonly": false, "cmd": "ts autoheater/mxp3", "description": "mix.ch. temperature at 100 uW (used for auto heater)"}, +{"path": "autoheater/mxp4", "type": "float", "readonly": false, "cmd": "ts autoheater/mxp4", "description": "mix.ch. temperature at 1 mW (used for auto heater)"}, +{"path": "autoheater/switchdown", "type": "float", "readonly": false, "cmd": "ts autoheater/switchdown", "description": "percentage for auto heater switch down"}, +{"path": "autoheater/switchup", "type": "float", "readonly": false, "cmd": "ts autoheater/switchup", "description": "when the calculated power is above this percentage, use higher range"}, +{"path": "autoprop", "type": "bool", "readonly": false, "cmd": "ts autoprop", "description": "change prop value depending on actual power", "kids": 2}, +{"path": "autoprop/prop", "type": "float", "readonly": false, "cmd": "ts autoprop/prop", "description": "prop value (maximum prop value when autheater is on)"}, +{"path": "autoprop/integ", "type": "float", "readonly": false, "cmd": "ts autoprop/integ", "description": "integral value [sec], deriv is set to 0 on change"}, +{"path": "instructions", "type": "text"}, +{"path": "auto", "type": "enum", "enum": {"off": 0, "cool_vti": 1, "pipe_pump": 11, "pipes_ready": 12, "ready_for_sorbpump": 2, "sorb_pump": 3, "condense": 4, "circulate": 5, "remove_only": 60, "remove_and_warmup": 62, "remove_and_condense": 61, "remove_and_sorbpump": 63, "finished": 7}, "readonly": false, "cmd": "ts auto", "kids": 21}, +{"path": "auto/usetrap", "type": "enum", "enum": {"trap_A": 0, "trap_B": 1}, "readonly": false, "cmd": "ts auto/usetrap"}, +{"path": "auto/hasturbo", "type": "bool"}, +{"path": "auto/pipes_pumped", "type": "bool", "readonly": false, "cmd": "ts auto/pipes_pumped"}, +{"path": "auto/cool_crit", "type": "text", "readonly": false, "cmd": "ts auto/cool_crit", "description": "criterium for transition to ready_for_sorbpump"}, +{"path": "auto/pumptime1", "type": "float", "readonly": false, "cmd": "ts auto/pumptime1", "description": "pump time [sec] while sorb at 40"}, +{"path": "auto/pumptime2", "type": "float", "readonly": false, "cmd": "ts auto/pumptime2", "description": "pump time [sec] while sorb cools down"}, +{"path": "auto/pumptime_remaining", "type": "float", "description": "remeaining pump time [min]"}, +{"path": "auto/condensep", "type": "float", "readonly": false, "cmd": "ts auto/condensep"}, +{"path": "auto/dumptarget", "type": "float", "readonly": false, "cmd": "ts auto/dumptarget"}, +{"path": "auto/condenseflow", "type": "float", "readonly": false, "cmd": "ts auto/condenseflow", "description": "VTI flow for condensing and min. flow for cooling"}, +{"path": "auto/circulateflow", "type": "float", "readonly": false, "cmd": "ts auto/circulateflow", "description": "VTI flow for circulating (may be changed during circulation)"}, +{"path": "auto/onekstate", "type": "enum", "enum": {"normal": 0, "fill": 1, "optimize": 2}, "readonly": false, "cmd": "ts auto/onekstate"}, +{"path": "auto/oneklimit", "type": "float", "readonly": false, "cmd": "ts auto/oneklimit"}, +{"path": "auto/minflow", "type": "float", "readonly": false, "cmd": "ts auto/minflow", "description": "minimum VTI flow (optimize stops at this value)"}, +{"path": "auto/p1low", "type": "float", "readonly": false, "cmd": "ts auto/p1low", "description": "p1 value indicating a negligible mixture amount"}, +{"path": "auto/p2low", "type": "float", "readonly": false, "cmd": "ts auto/p2low", "description": "p2 value indicating a good vacuum"}, +{"path": "auto/warmup_t", "type": "float", "readonly": false, "cmd": "ts auto/warmup_t", "description": "VTI temperature to reach when remove_and_warmup"}, +{"path": "auto/vti_t", "type": "float", "readonly": false, "cmd": "ts auto/vti_t", "description": "VTI temperature to reach when remove_only"}, +{"path": "auto/xgas", "type": "enum", "enum": {"pump": 0, "add": 1, "empty": 2, "filled": 3}, "readonly": false, "cmd": "ts auto/xgas"}, +{"path": "auto/xgas_pulse", "type": "float", "readonly": false, "cmd": "ts auto/xgas_pulse", "description": "opening time for xgas capillary [sec]"}, +{"path": "auto/removephase", "type": "enum", "enum": {"raw_remove": 0, "wait_p1_low": 1, "wait_v6_open": 2, "wait_a_little": 3, "wait_v6_closed": 4, "wait_t_warmup": 5}, "readonly": false, "cmd": "ts auto/removephase"}]}, + +"treg": {"base": "/treg", "params": [ +{"path": "", "type": "int", "kids": 10}, +{"path": "send", "type": "text", "readonly": false, "cmd": "treg send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "autoscan", "type": "bool", "readonly": false, "cmd": "treg autoscan", "kids": 4}, +{"path": "autoscan/synchronized", "type": "bool", "readonly": false, "cmd": "treg autoscan/synchronized"}, +{"path": "autoscan/interval", "type": "text", "readonly": false, "cmd": "treg autoscan/interval"}, +{"path": "autoscan/pause", "type": "text", "readonly": false, "cmd": "treg autoscan/pause"}, +{"path": "autoscan/dwell", "type": "text", "readonly": false, "cmd": "treg autoscan/dwell"}, +{"path": "sample", "type": "float", "kids": 14}, +{"path": "sample/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "treg sample/active"}, +{"path": "sample/autorange", "type": "bool", "readonly": false, "cmd": "treg sample/autorange", "description": "autorange (common for all channels)"}, +{"path": "sample/range", "type": "text", "readonly": false, "cmd": "treg sample/range", "description": "resistance range in Ohm"}, +{"path": "sample/range_num", "type": "int"}, +{"path": "sample/excitation", "type": "text", "readonly": false, "cmd": "treg sample/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "sample/excitation_num", "type": "int"}, +{"path": "sample/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "sample/pause", "type": "int", "readonly": false, "cmd": "treg sample/pause", "description": "pause time [sec] after channel change"}, +{"path": "sample/filter", "type": "int", "readonly": false, "cmd": "treg sample/filter", "description": "filter average time [sec]"}, +{"path": "sample/dwell", "type": "int", "readonly": false, "cmd": "treg sample/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "sample/status", "type": "text"}, +{"path": "sample/curve", "type": "text", "readonly": false, "cmd": "treg sample/curve", "kids": 1}, +{"path": "sample/curve/points", "type": "floatvarar", "readonly": false, "cmd": "treg sample/curve/points", "visibility": 3}, +{"path": "sample/alarm", "type": "float", "readonly": false, "cmd": "treg sample/alarm"}, +{"path": "sample/raw", "type": "float"}, +{"path": "mix", "type": "float", "kids": 14}, +{"path": "mix/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "treg mix/active"}, +{"path": "mix/autorange", "type": "bool", "readonly": false, "cmd": "treg mix/autorange", "description": "autorange (common for all channels)"}, +{"path": "mix/range", "type": "text", "readonly": false, "cmd": "treg mix/range", "description": "resistance range in Ohm"}, +{"path": "mix/range_num", "type": "int"}, +{"path": "mix/excitation", "type": "text", "readonly": false, "cmd": "treg mix/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "mix/excitation_num", "type": "int"}, +{"path": "mix/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "mix/pause", "type": "int", "readonly": false, "cmd": "treg mix/pause", "description": "pause time [sec] after channel change"}, +{"path": "mix/filter", "type": "int", "readonly": false, "cmd": "treg mix/filter", "description": "filter average time [sec]"}, +{"path": "mix/dwell", "type": "int", "readonly": false, "cmd": "treg mix/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "mix/status", "type": "text"}, +{"path": "mix/curve", "type": "text", "readonly": false, "cmd": "treg mix/curve", "kids": 1}, +{"path": "mix/curve/points", "type": "floatvarar", "readonly": false, "cmd": "treg mix/curve/points", "visibility": 3}, +{"path": "mix/alarm", "type": "float", "readonly": false, "cmd": "treg mix/alarm"}, +{"path": "mix/raw", "type": "float"}, +{"path": "samplehtr", "type": "float", "kids": 14}, +{"path": "samplehtr/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "treg samplehtr/active"}, +{"path": "samplehtr/autorange", "type": "bool", "readonly": false, "cmd": "treg samplehtr/autorange", "description": "autorange (common for all channels)"}, +{"path": "samplehtr/range", "type": "text", "readonly": false, "cmd": "treg samplehtr/range", "description": "resistance range in Ohm"}, +{"path": "samplehtr/range_num", "type": "int"}, +{"path": "samplehtr/excitation", "type": "text", "readonly": false, "cmd": "treg samplehtr/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "samplehtr/excitation_num", "type": "int"}, +{"path": "samplehtr/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "samplehtr/pause", "type": "int", "readonly": false, "cmd": "treg samplehtr/pause", "description": "pause time [sec] after channel change"}, +{"path": "samplehtr/filter", "type": "int", "readonly": false, "cmd": "treg samplehtr/filter", "description": "filter average time [sec]"}, +{"path": "samplehtr/dwell", "type": "int", "readonly": false, "cmd": "treg samplehtr/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "samplehtr/status", "type": "text"}, +{"path": "samplehtr/curve", "type": "text", "readonly": false, "cmd": "treg samplehtr/curve", "kids": 1}, +{"path": "samplehtr/curve/points", "type": "floatvarar", "readonly": false, "cmd": "treg samplehtr/curve/points", "visibility": 3}, +{"path": "samplehtr/alarm", "type": "float", "readonly": false, "cmd": "treg samplehtr/alarm"}, +{"path": "samplehtr/raw", "type": "float"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "treg set", "kids": 18}, +{"path": "set/mode", "type": "enum", "enum": {"disabled": -1, "off": 0, "controlling": 1, "manual": 2}, "readonly": false, "cmd": "treg set/mode"}, +{"path": "set/reg", "type": "float"}, +{"path": "set/ramp", "type": "float", "readonly": false, "cmd": "treg set/ramp", "description": "maximum ramp in K/min (0: ramp off)"}, +{"path": "set/wramp", "type": "float", "readonly": false, "cmd": "treg set/wramp"}, +{"path": "set/smooth", "type": "float", "readonly": false, "cmd": "treg set/smooth", "description": "smooth time (minutes)"}, +{"path": "set/channel", "type": "text", "readonly": false, "cmd": "treg set/channel"}, +{"path": "set/limit", "type": "float", "readonly": false, "cmd": "treg set/limit"}, +{"path": "set/resist", "type": "float", "readonly": false, "cmd": "treg set/resist"}, +{"path": "set/maxheater", "type": "text", "readonly": false, "cmd": "treg set/maxheater", "description": "maximum heater limit, units should be given without space: W, mW, A, mA"}, +{"path": "set/linearpower", "type": "float", "readonly": false, "cmd": "treg 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": "treg 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": "treg set/manualpower"}, +{"path": "set/power", "type": "float"}, +{"path": "set/prop", "type": "float", "readonly": false, "cmd": "treg set/prop", "description": "bigger means more gain"}, +{"path": "set/integ", "type": "float", "readonly": false, "cmd": "treg set/integ", "description": "[sec] bigger means slower"}, +{"path": "set/deriv", "type": "float", "readonly": false, "cmd": "treg set/deriv"}, +{"path": "analog2", "type": "float", "readonly": false, "cmd": "treg analog2"}, +{"path": "remote", "type": "bool"}, +{"path": "display", "type": "text", "readonly": false, "cmd": "treg display"}]}, + +"tmon": {"base": "/tmon", "params": [ +{"path": "", "type": "int", "kids": 12}, +{"path": "send", "type": "text", "readonly": false, "cmd": "tmon send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "autoscan", "type": "bool", "readonly": false, "cmd": "tmon autoscan", "kids": 4}, +{"path": "autoscan/synchronized", "type": "bool", "readonly": false, "cmd": "tmon autoscan/synchronized"}, +{"path": "autoscan/interval", "type": "text", "readonly": false, "cmd": "tmon autoscan/interval"}, +{"path": "autoscan/pause", "type": "text", "readonly": false, "cmd": "tmon autoscan/pause"}, +{"path": "autoscan/dwell", "type": "text", "readonly": false, "cmd": "tmon autoscan/dwell"}, +{"path": "sorb", "type": "float", "kids": 14}, +{"path": "sorb/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tmon sorb/active"}, +{"path": "sorb/autorange", "type": "bool", "readonly": false, "cmd": "tmon sorb/autorange", "description": "autorange (common for all channels)"}, +{"path": "sorb/range", "type": "text", "readonly": false, "cmd": "tmon sorb/range", "description": "resistance range in Ohm"}, +{"path": "sorb/range_num", "type": "int"}, +{"path": "sorb/excitation", "type": "text", "readonly": false, "cmd": "tmon sorb/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "sorb/excitation_num", "type": "int"}, +{"path": "sorb/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "sorb/pause", "type": "int", "readonly": false, "cmd": "tmon sorb/pause", "description": "pause time [sec] after channel change"}, +{"path": "sorb/filter", "type": "int", "readonly": false, "cmd": "tmon sorb/filter", "description": "filter average time [sec]"}, +{"path": "sorb/dwell", "type": "int", "readonly": false, "cmd": "tmon sorb/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "sorb/status", "type": "text"}, +{"path": "sorb/curve", "type": "text", "readonly": false, "cmd": "tmon sorb/curve", "kids": 1}, +{"path": "sorb/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tmon sorb/curve/points", "visibility": 3}, +{"path": "sorb/alarm", "type": "float", "readonly": false, "cmd": "tmon sorb/alarm"}, +{"path": "sorb/raw", "type": "float"}, +{"path": "onek", "type": "float", "kids": 14}, +{"path": "onek/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tmon onek/active"}, +{"path": "onek/autorange", "type": "bool", "readonly": false, "cmd": "tmon onek/autorange", "description": "autorange (common for all channels)"}, +{"path": "onek/range", "type": "text", "readonly": false, "cmd": "tmon onek/range", "description": "resistance range in Ohm"}, +{"path": "onek/range_num", "type": "int"}, +{"path": "onek/excitation", "type": "text", "readonly": false, "cmd": "tmon onek/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "onek/excitation_num", "type": "int"}, +{"path": "onek/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "onek/pause", "type": "int", "readonly": false, "cmd": "tmon onek/pause", "description": "pause time [sec] after channel change"}, +{"path": "onek/filter", "type": "int", "readonly": false, "cmd": "tmon onek/filter", "description": "filter average time [sec]"}, +{"path": "onek/dwell", "type": "int", "readonly": false, "cmd": "tmon onek/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "onek/status", "type": "text"}, +{"path": "onek/curve", "type": "text", "readonly": false, "cmd": "tmon onek/curve", "kids": 1}, +{"path": "onek/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tmon onek/curve/points", "visibility": 3}, +{"path": "onek/alarm", "type": "float", "readonly": false, "cmd": "tmon onek/alarm"}, +{"path": "onek/raw", "type": "float"}, +{"path": "stillt", "type": "float", "kids": 14}, +{"path": "stillt/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tmon stillt/active"}, +{"path": "stillt/autorange", "type": "bool", "readonly": false, "cmd": "tmon stillt/autorange", "description": "autorange (common for all channels)"}, +{"path": "stillt/range", "type": "text", "readonly": false, "cmd": "tmon stillt/range", "description": "resistance range in Ohm"}, +{"path": "stillt/range_num", "type": "int"}, +{"path": "stillt/excitation", "type": "text", "readonly": false, "cmd": "tmon stillt/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "stillt/excitation_num", "type": "int"}, +{"path": "stillt/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "stillt/pause", "type": "int", "readonly": false, "cmd": "tmon stillt/pause", "description": "pause time [sec] after channel change"}, +{"path": "stillt/filter", "type": "int", "readonly": false, "cmd": "tmon stillt/filter", "description": "filter average time [sec]"}, +{"path": "stillt/dwell", "type": "int", "readonly": false, "cmd": "tmon stillt/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "stillt/status", "type": "text"}, +{"path": "stillt/curve", "type": "text", "readonly": false, "cmd": "tmon stillt/curve", "kids": 1}, +{"path": "stillt/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tmon stillt/curve/points", "visibility": 3}, +{"path": "stillt/alarm", "type": "float", "readonly": false, "cmd": "tmon stillt/alarm"}, +{"path": "stillt/raw", "type": "float"}, +{"path": "sample", "type": "float", "kids": 14}, +{"path": "sample/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tmon sample/active"}, +{"path": "sample/autorange", "type": "bool", "readonly": false, "cmd": "tmon sample/autorange", "description": "autorange (common for all channels)"}, +{"path": "sample/range", "type": "text", "readonly": false, "cmd": "tmon sample/range", "description": "resistance range in Ohm"}, +{"path": "sample/range_num", "type": "int"}, +{"path": "sample/excitation", "type": "text", "readonly": false, "cmd": "tmon sample/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "sample/excitation_num", "type": "int"}, +{"path": "sample/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "sample/pause", "type": "int", "readonly": false, "cmd": "tmon sample/pause", "description": "pause time [sec] after channel change"}, +{"path": "sample/filter", "type": "int", "readonly": false, "cmd": "tmon sample/filter", "description": "filter average time [sec]"}, +{"path": "sample/dwell", "type": "int", "readonly": false, "cmd": "tmon sample/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "sample/status", "type": "text"}, +{"path": "sample/curve", "type": "text", "readonly": false, "cmd": "tmon sample/curve", "kids": 1}, +{"path": "sample/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tmon sample/curve/points", "visibility": 3}, +{"path": "sample/alarm", "type": "float", "readonly": false, "cmd": "tmon sample/alarm"}, +{"path": "sample/raw", "type": "float"}, +{"path": "samplehtr", "type": "float", "kids": 14}, +{"path": "samplehtr/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tmon samplehtr/active"}, +{"path": "samplehtr/autorange", "type": "bool", "readonly": false, "cmd": "tmon samplehtr/autorange", "description": "autorange (common for all channels)"}, +{"path": "samplehtr/range", "type": "text", "readonly": false, "cmd": "tmon samplehtr/range", "description": "resistance range in Ohm"}, +{"path": "samplehtr/range_num", "type": "int"}, +{"path": "samplehtr/excitation", "type": "text", "readonly": false, "cmd": "tmon samplehtr/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "samplehtr/excitation_num", "type": "int"}, +{"path": "samplehtr/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "samplehtr/pause", "type": "int", "readonly": false, "cmd": "tmon samplehtr/pause", "description": "pause time [sec] after channel change"}, +{"path": "samplehtr/filter", "type": "int", "readonly": false, "cmd": "tmon samplehtr/filter", "description": "filter average time [sec]"}, +{"path": "samplehtr/dwell", "type": "int", "readonly": false, "cmd": "tmon samplehtr/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "samplehtr/status", "type": "text"}, +{"path": "samplehtr/curve", "type": "text", "readonly": false, "cmd": "tmon samplehtr/curve", "kids": 1}, +{"path": "samplehtr/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tmon samplehtr/curve/points", "visibility": 3}, +{"path": "samplehtr/alarm", "type": "float", "readonly": false, "cmd": "tmon samplehtr/alarm"}, +{"path": "samplehtr/raw", "type": "float"}, +{"path": "mix", "type": "float", "kids": 14}, +{"path": "mix/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tmon mix/active"}, +{"path": "mix/autorange", "type": "bool", "readonly": false, "cmd": "tmon mix/autorange", "description": "autorange (common for all channels)"}, +{"path": "mix/range", "type": "text", "readonly": false, "cmd": "tmon mix/range", "description": "resistance range in Ohm"}, +{"path": "mix/range_num", "type": "int"}, +{"path": "mix/excitation", "type": "text", "readonly": false, "cmd": "tmon mix/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"}, +{"path": "mix/excitation_num", "type": "int"}, +{"path": "mix/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}}, +{"path": "mix/pause", "type": "int", "readonly": false, "cmd": "tmon mix/pause", "description": "pause time [sec] after channel change"}, +{"path": "mix/filter", "type": "int", "readonly": false, "cmd": "tmon mix/filter", "description": "filter average time [sec]"}, +{"path": "mix/dwell", "type": "int", "readonly": false, "cmd": "tmon mix/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"}, +{"path": "mix/status", "type": "text"}, +{"path": "mix/curve", "type": "text", "readonly": false, "cmd": "tmon mix/curve", "kids": 1}, +{"path": "mix/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tmon mix/curve/points", "visibility": 3}, +{"path": "mix/alarm", "type": "float", "readonly": false, "cmd": "tmon mix/alarm"}, +{"path": "mix/raw", "type": "float"}, +{"path": "analog2", "type": "float", "readonly": false, "cmd": "tmon analog2"}, +{"path": "remote", "type": "bool"}, +{"path": "display", "type": "text", "readonly": false, "cmd": "tmon display"}]}, + +"dil": {"base": "/dil", "params": [ +{"path": "", "type": "float", "kids": 60}, +{"path": "Tset", "type": "float"}, +{"path": "TsorbSet", "type": "float", "readonly": false, "cmd": "dil TsorbSet"}, +{"path": "Tmix", "type": "float"}, +{"path": "T1K", "type": "float"}, +{"path": "Tsorb", "type": "float"}, +{"path": "Pmix", "type": "float", "readonly": false, "cmd": "dil Pmix"}, +{"path": "Pmax", "type": "float"}, +{"path": "HtrRange", "type": "int", "readonly": false, "cmd": "dil HtrRange"}, +{"path": "Pstill", "type": "float", "readonly": false, "cmd": "dil Pstill"}, +{"path": "Psorb", "type": "float", "readonly": false, "cmd": "dil Psorb"}, +{"path": "G1", "type": "float"}, +{"path": "G2", "type": "float"}, +{"path": "G3", "type": "float"}, +{"path": "P1", "type": "float"}, +{"path": "P2", "type": "float"}, +{"path": "V6", "type": "float", "readonly": false, "cmd": "dil V6"}, +{"path": "V12A", "type": "float", "readonly": false, "cmd": "dil V12A"}, +{"path": "V1K", "type": "float", "readonly": false, "cmd": "dil V1K"}, +{"path": "v6pos", "type": "float"}, +{"path": "V9", "type": "int", "readonly": false, "cmd": "dil V9", "visibility": 3}, +{"path": "V8", "type": "int", "readonly": false, "cmd": "dil V8", "visibility": 3}, +{"path": "V7", "type": "int", "readonly": false, "cmd": "dil V7", "visibility": 3}, +{"path": "V11A", "type": "int", "readonly": false, "cmd": "dil V11A", "visibility": 3}, +{"path": "V13A", "type": "int", "readonly": false, "cmd": "dil V13A", "visibility": 3}, +{"path": "V13B", "type": "int", "readonly": false, "cmd": "dil V13B", "visibility": 3}, +{"path": "V11B", "type": "int", "readonly": false, "cmd": "dil V11B", "visibility": 3}, +{"path": "V12B", "type": "int", "readonly": false, "cmd": "dil V12B", "visibility": 3}, +{"path": "He4", "type": "int", "readonly": false, "cmd": "dil He4", "visibility": 3}, +{"path": "V1", "type": "int", "readonly": false, "cmd": "dil V1", "visibility": 3}, +{"path": "V5", "type": "int", "readonly": false, "cmd": "dil V5", "visibility": 3}, +{"path": "V4", "type": "int", "readonly": false, "cmd": "dil V4", "visibility": 3}, +{"path": "V3", "type": "int", "readonly": false, "cmd": "dil V3", "visibility": 3}, +{"path": "V14", "type": "int", "readonly": false, "cmd": "dil V14", "visibility": 3}, +{"path": "V10", "type": "int", "readonly": false, "cmd": "dil V10", "visibility": 3}, +{"path": "V2", "type": "int", "readonly": false, "cmd": "dil V2", "visibility": 3}, +{"path": "V2A", "type": "int", "readonly": false, "cmd": "dil V2A", "visibility": 3}, +{"path": "V1A", "type": "int", "readonly": false, "cmd": "dil V1A", "visibility": 3}, +{"path": "V5A", "type": "int", "readonly": false, "cmd": "dil V5A", "visibility": 3}, +{"path": "V4A", "type": "int", "readonly": false, "cmd": "dil V4A", "visibility": 3}, +{"path": "V3A", "type": "int", "readonly": false, "cmd": "dil V3A", "visibility": 3}, +{"path": "Roots", "type": "int", "readonly": false, "cmd": "dil Roots", "visibility": 3}, +{"path": "Aux", "type": "int", "readonly": false, "cmd": "dil Aux", "visibility": 3}, +{"path": "He3", "type": "int", "readonly": false, "cmd": "dil He3", "visibility": 3}, +{"path": "closedelay", "type": "float", "readonly": false, "cmd": "dil closedelay", "visibility": 3}, +{"path": "extVersion", "type": "int", "readonly": false, "cmd": "dil extVersion", "visibility": 3}, +{"path": "pumpoff", "type": "int"}, +{"path": "upperN2", "type": "float"}, +{"path": "lowerN2", "type": "float"}, +{"path": "maxtry", "type": "int", "readonly": false, "cmd": "dil maxtry", "visibility": 3}, +{"path": "upperLimit", "type": "float", "readonly": false, "cmd": "dil upperLimit"}, +{"path": "lowerLimit", "type": "float", "readonly": false, "cmd": "dil lowerLimit", "visibility": 3}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "dil tolerance"}, +{"path": "maxwait", "type": "int", "readonly": false, "cmd": "dil maxwait"}, +{"path": "settle", "type": "int", "readonly": false, "cmd": "dil settle"}, +{"path": "targetValue", "type": "float"}, +{"path": "is_running", "type": "int", "visibility": 3}, +{"path": "verbose", "type": "int", "readonly": false, "cmd": "dil verbose", "visibility": 3}, +{"path": "driver", "type": "text", "visibility": 3}, +{"path": "creationCmd", "type": "text", "visibility": 3}, +{"path": "status", "type": "text", "readonly": false, "cmd": "dil status", "visibility": 3}]}, + +"sorb": {"base": "/sorb", "params": [ +{"path": "", "type": "float", "readonly": false, "cmd": "run sorb", "description": "sorb", "kids": 28}, +{"path": "send", "type": "text", "readonly": false, "cmd": "sorb send", "visibility": 3}, +{"path": "status", "type": "text", "visibility": 3}, +{"path": "is_running", "type": "int", "readonly": false, "cmd": "sorb is_running", "visibility": 3}, +{"path": "mode", "type": "enum", "enum": {"off": 0, "on": 1}, "readonly": false, "cmd": "sorb mode"}, +{"path": "reg", "type": "float"}, +{"path": "output", "type": "float", "readonly": false, "cmd": "sorb output"}, +{"path": "ramptime", "type": "float", "readonly": false, "cmd": "sorb ramptime", "description": "time for ramping [sec] deltax = 1 or a factor 10"}, +{"path": "ramptol", "type": "float", "readonly": false, "cmd": "sorb ramptol", "description": "log of max. deviation when ramping"}, +{"path": "smoothtime", "type": "float", "readonly": false, "cmd": "sorb smoothtime", "description": "time for smoothing ramp near setpoint"}, +{"path": "invar", "type": "text", "readonly": false, "cmd": "sorb invar", "visibility": 3}, +{"path": "outvar", "type": "text", "readonly": false, "cmd": "sorb outvar", "visibility": 3}, +{"path": "prop", "type": "float", "readonly": false, "cmd": "sorb prop", "description": "smaller means more sensitive. a change of 'prop' on input -> a change of 100 % or a factor 10 on output"}, +{"path": "int", "type": "float", "readonly": false, "cmd": "sorb int", "description": "integration time (sec)"}, +{"path": "outmin", "type": "float", "readonly": false, "cmd": "sorb outmin", "description": "output for maximal decrease of input var."}, +{"path": "outmax", "type": "float", "readonly": false, "cmd": "sorb outmax", "description": "output for maximal increase of input var."}, +{"path": "inpfunction", "type": "enum", "enum": {"linear": 0, "logarithmic": 1}, "readonly": false, "cmd": "sorb inpfunction"}, +{"path": "inplinear", "type": "float", "readonly": false, "cmd": "sorb inplinear", "description": "function gets linear below about this value"}, +{"path": "outfunction", "type": "enum", "enum": {"linear": 0, "exponential": 1}, "readonly": false, "cmd": "sorb outfunction"}, +{"path": "outlinear", "type": "float", "readonly": false, "cmd": "sorb outlinear", "description": "function gets linear below about this value"}, +{"path": "precision", "type": "float", "readonly": false, "cmd": "sorb precision"}, +{"path": "deadband", "type": "float", "readonly": false, "cmd": "sorb deadband"}, +{"path": "maxdelta", "type": "float", "readonly": false, "cmd": "sorb maxdelta"}, +{"path": "set", "type": "float", "readonly": false, "cmd": "sorb set"}, +{"path": "target", "type": "float"}, +{"path": "running", "type": "int"}, +{"path": "tolerance", "type": "float", "readonly": false, "cmd": "sorb tolerance"}, +{"path": "maxwait", "type": "float", "readonly": false, "cmd": "sorb maxwait"}, +{"path": "settle", "type": "float", "readonly": false, "cmd": "sorb settle"}]}} diff --git a/cfg/stick/dil2.cfg b/cfg/stick/dil2.cfg new file mode 100644 index 0000000..0f94369 --- /dev/null +++ b/cfg/stick/dil2.cfg @@ -0,0 +1,34 @@ +[NODE] +description = dilution insert +id = dil2.stick.sea.psi.ch + +[sea_stick] +class = secop_psi.sea.SeaClient +description = stick sea connection for dil2.stick +config = dil2.stick +service = stick + +[ts] +class = secop_psi.sea.SeaDrivable +io = sea_stick +sea_object = ts + +[treg] +class = secop_psi.sea.SeaReadable +io = sea_stick +sea_object = treg + +[tmon] +class = secop_psi.sea.SeaReadable +io = sea_stick +sea_object = tmon + +[dil] +class = secop_psi.sea.SeaReadable +io = sea_stick +sea_object = dil + +[sorb] +class = secop_psi.sea.SeaDrivable +io = sea_stick +sea_object = sorb diff --git a/cfg/stick/dil5.cfg b/cfg/stick/dil5.cfg new file mode 100644 index 0000000..05d70a1 --- /dev/null +++ b/cfg/stick/dil5.cfg @@ -0,0 +1,190 @@ +[NODE] +id = triton.psi.ch +description = triton test + +[INTERFACE] +uri = tcp://5000 + +[triton] +class = secop_psi.mercury.IO +description = connection to triton software +uri = tcp://linse-dil5:33576 + +[action] +class = secop_psi.triton.Action +description = higher level scripts +io = triton +slot = DR + +[T_sorb] +class = secop_psi.triton.TemperatureSensor +description = sorb temperature +slot = T1 +io = triton + +[T_ivc] +class = secop_psi.triton.TemperatureSensor +description = IVC temperature +slot = T2 +io = triton + +[T_still] +class = secop_psi.triton.TemperatureSensor +description = still temperature +slot = T3 +io = triton + +[T_cp] +class = secop_psi.triton.TemperatureSensor +description = cold plate temperature +slot = T4 +io = triton + +[T_mix] +class = secop_psi.triton.TemperatureSensor +description = mix. chamber temperature +slot = T5 +io = triton + +[p_dump] +class = secop_psi.mercury.PressureSensor +description = dump pressure +slot = P1 +io = triton + +[p_cond] +class = secop_psi.mercury.PressureSensor +description = condenser pressure +slot = P2 +io = triton + +[p_still] +class = secop_psi.mercury.PressureSensor +description = still pressure +slot = P3 +io = triton + +[p_fore] +class = secop_psi.mercury.PressureSensor +description = pressure on the pump side +slot = P4 +io = triton + +[p_back] +class = secop_psi.mercury.PressureSensor +description = pressure on the back side of the pump +slot = P5 +io = triton + +[itc] +class = secop_psi.mercury.IO +description = connection to MercuryiTC +uri = tcp://linse-dil5:3000 + +[T_still_wup] +class = secop_psi.mercury.TemperatureLoop +description = still warmup temperature +slot = MB1.T1 +io = itc + +[P_still_wup] +class = secop_psi.mercury.HeaterOutput +description = still warmup heater +slot = MB0.H1 +io = itc + +[T_one_K] +class = secop_psi.mercury.TemperatureLoop +description = 1 K plate warmup temperature +slot = DB5.T1 +io = itc + +[P_one_K] +class = secop_psi.mercury.HeaterOutput +description = 1 K plate warmup heater +slot = DB3.H1 +io = itc + +[T_mix_wup] +class = secop_psi.mercury.TemperatureLoop +description = mix. chamber warmup temperature +slot = DB6.T1 +io = itc + +[P_mix_wup] +class = secop_psi.mercury.HeaterOutput +description = mix. chamber warmup heater +slot = DB1.H1 +io = itc + +[T_ivc_wup] +class = secop_psi.mercury.TemperatureLoop +description = IVC warmup temperature +slot = DB7.T1 +io = itc + +[P_ivc_wup] +class = secop_psi.mercury.HeaterOutput +description = IVC warmup heater +slot = DB2.H1 +io = itc + +[T_cond] +class = secop_psi.mercury.TemperatureLoop +description = condenser temperature +slot = DB8.T1 +io = itc + +[P_cond] +class = secop_psi.mercury.HeaterOutput +description = condenser heater +slot = DB3.H1 +io = itc + +[V1] +class = secop_psi.triton.Valve +description = valve V1 +slot = V1 +io = triton + +[V2] +class = secop_psi.triton.Valve +description = valve V2 +slot = V2 +io = triton + +[V4] +class = secop_psi.triton.Valve +description = valve V4 +slot = V4 +io = triton + +[V5] +class = secop_psi.triton.Valve +description = valve V5 +slot = V5 +io = triton + +[V9] +class = secop_psi.triton.Valve +description = valve V9 +slot = V9 +io = triton + +[turbo] +class = secop_psi.triton.TurboPump +description = still turbo pump +slot = TURB1 +io = triton + +[fp] +class = secop_psi.triton.Pump +description = still fore pump +slot = FP +io = triton + +[compressor] +class = secop_psi.triton.Pump +description = compressor +slot = COMP +io = triton diff --git a/secop_psi/ips_mercury.py b/secop_psi/ips_mercury.py new file mode 100644 index 0000000..27c78e5 --- /dev/null +++ b/secop_psi/ips_mercury.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ***************************************************************************** +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Module authors: +# Markus Zolliker +# ***************************************************************************** +"""oxford instruments mercury IPS power supply""" + +from secop.core import Parameter, EnumType, FloatRange, BoolType +from secop.lib.enum import Enum +from secop.errors import BadValueError +from secop_psi.magfield import Magfield +from secop_psi.mercury import MercuryChannel, off_on, Mapped + +Action = Enum(hold=0, run_to_set=1, run_to_zero=2, clamped=3) +hold_rtoz_rtos_clmp = Mapped(HOLD=Action.hold, RTOS=Action.run_to_set, + RTOZ=Action.run_to_zero, CLMP=Action.clamped) +CURRENT_CHECK_SIZE = 2 + + +class Field(MercuryChannel, Magfield): + action = Parameter('action', EnumType(Action), readonly=False) + setpoint = Parameter('field setpoint', FloatRange(unit='T'), readonly=False, default=0) + atob = Parameter('field to amp', FloatRange(0, unit='A/T'), default=0) + forced_persistent_field = Parameter( + 'manual indication that persistent field is bad', BoolType(), readonly=False, default=False) + + channel_type = 'PSU' + _field_mismatch = None + nslaves = 3 + slave_currents = None + _init = True + + def read_value(self): + self.current = self.query('PSU:SIG:FLD') + pf = self.query('PSU:SIG:PFLD') + if self._init: + self._init = False + self.persistent_field = pf + if self.switch_heater != 0 or self._field_mismatch is None: + self.forced_persistent_field = False + self._field_mismatch = False + return self.current + self._field_mismatch = abs(self.persistent_field - pf) > self.tolerance + return pf + + def write_persistent_field(self, value): + if self.forced_persistent_field: + self._field_mismatch = False + return value + raise BadValueError('changing persistent field needs forced_persistent_field=True') + + def write_target(self, target): + if self._field_mismatch: + self.forced_persistent_field = True + raise BadValueError('persistent field does not match - set persistent field to guessed value first') + return super().write_target(target) + + def read_ramp(self): + return self.query('PSU:SIG:RFST') + + def write_ramp(self, value): + return self.change('PSU:SIG:RFST', value) + + def read_action(self): + return self.query('PSU:ACTN', hold_rtoz_rtos_clmp) + + def write_action(self, value): + return self.change('PSU:ACTN', value, hold_rtoz_rtos_clmp) + + def read_switch_heater(self): + return self.query('PSU:SIG:SWHT', off_on) + + def write_switch_heater(self, value): + super().write_switch_heater(value) + return self.change('PSU:SIG:SWHT', value, off_on) + + def read_atob(self): + return self.query('PSU:ATOB') + + def read_setpoint(self): + return self.query('PSU:SIG:FSET') + + def write_setpoint(self, value): + return self.query('PSU:SIG:FSET', value) + + def read_current(self): + if self.slave_currents is None: + self.slave_currents = [[] for _ in range(self.nslaves + 1)] + current = self.query('PSU:SIG:CURR') + for i in range(self.nslaves + 1): + if i: + self.slave_currents[i].append(self.query('DEV:PSU.M%d:PSU:SIG:CURR' % i)) + else: + self.slave_currents[i].append(current) + min_i = min(self.slave_currents[i]) + max_i = max(self.slave_currents[i]) + min_ = min(self.slave_currents[0]) / self.nslaves + max_ = max(self.slave_currents[0]) / self.nslaves + if len(self.slave_currents[i]) > CURRENT_CHECK_SIZE: + self.slave_currents[i] = self.slave_currents[i][-CURRENT_CHECK_SIZE:] + if i and (min_i -1 > max_ or min_ > max_i + 1): + self.log.warning('individual currents mismatch %r', self.slave_currents) + if self.atob: + return current / self.atob + return 0 + + def start_ramp_to_field(self, state): + self.change('PSU:SIG:FSET', self.persistent_field) + assert self.write_action('hold') == 'hold' + assert self.write_action('run_to_set') == 'run_to_set' + return self.ramp_to_field + + def start_ramp_to_target(self, state): + self.change('PSU:SIG:FSET', self.target) + assert self.write_action('hold') == 'hold' + assert self.write_action('run_to_set') == 'run_to_set' + return self.ramp_to_target + + def start_ramp_to_zero(self, state): + assert self.write_action('hold') == 'hold' + assert self.write_action('run_to_zero') == 'run_to_zero' + return self.ramp_to_zero + + def finish_state(self, state): + self.write_action('hold') + super().finish_state(state) diff --git a/secop_psi/magfield.py b/secop_psi/magfield.py new file mode 100644 index 0000000..7858505 --- /dev/null +++ b/secop_psi/magfield.py @@ -0,0 +1,289 @@ +# -*- 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 +# ***************************************************************************** +"""generic persistent magnet driver""" + +import time +from secop.core import Drivable, Parameter, Done +from secop.datatypes import FloatRange, EnumType, ArrayOf, TupleOf, StatusType +from secop.features import HasLimits +from secop.errors import ConfigError, ProgrammingError +from secop.lib.enum import Enum +from secop.lib.statemachine import Retry, StateMachine + +UNLIMITED = FloatRange() + +Mode = Enum( + DISABLED=0, + PERSISTENT=30, + DRIVEN=50, +) + +Status = Enum( + Drivable.Status, + PREPARED=150, + PREPARING=340, + RAMPING=370, + STABILIZING=380, + FINALIZING=390, +) + + +class Magfield(HasLimits, Drivable): + value = Parameter('magnetic field', datatype=FloatRange(unit='T')) + status = Parameter(datatype=StatusType(Status)) + mode = Parameter( + 'persistent mode', EnumType(Mode), readonly=False, default=Mode.PERSISTENT) + tolerance = Parameter( + 'tolerance', FloatRange(0, unit='$'), readonly=False, default=0.0002) + switch_heater = Parameter('switch heater', EnumType(off=0, on=1), + readonly=False, default=0) + persistent_field = Parameter( + 'persistent field', FloatRange(unit='$'), readonly=False) + current = Parameter( + 'leads current (in units of field)', FloatRange(unit='$')) + ramp = Parameter( + 'ramp rate for field', FloatRange(unit='$/min'), readonly=False) + trained = Parameter( + 'trained field (positive)', + TupleOf(FloatRange(-99, 0, unit='$'), FloatRange(0, unit='$')), + readonly=False, default=(0, 0)) + # TODO: time_to_target + # profile = Parameter( + # 'ramp limit table', ArrayOf(TupleOf(FloatRange(unit='$'), FloatRange(unit='$/min'))), + # readonly=False) + # profile_training = Parameter( + # 'ramp limit table when in training', + # ArrayOf(TupleOf(FloatRange(unit='$'), FloatRange(unit='$/min'))), readonly=False) + # TODO: the following parameters should be changed into properties after tests + wait_switch_on = Parameter( + 'wait time to ensure switch is on', FloatRange(0, unit='s'), readonly=False, default=61) + wait_switch_off = Parameter( + 'wait time to ensure switch is off', FloatRange(0, unit='s'), readonly=False, default=61) + wait_stable_leads = Parameter( + 'wait time to ensure current is stable', FloatRange(0, unit='s'), readonly=False, default=6) + wait_stable_field = Parameter( + 'wait time to ensure field is stable', FloatRange(0, unit='s'), readonly=False, default=31) + + _state = None + _init = True + _super_sw_check = False + switch_time = None + + def doPoll(self): + if self._init: + self._init = False + self.switch_time = time.time() + if self.read_switch_heater() and self.mode == Mode.PERSISTENT: + self.read_value() # check for persistent field mismatch + # switch off heater from previous live or manual intervention + self.write_target(self.persistent_value) + else: + self.read_value() + self._state.cycle() + + def checkProperties(self): + dt = self.parameters['target'].datatype + max_ = dt.max + if max_ == UNLIMITED.max: + raise ConfigError('target.max not configured') + if dt.min == UNLIMITED.min: # not given: assume bipolar symmetric + dt.min = -max_ + super().checkProperties() + + def initModule(self): + super().initModule() + self._state = StateMachine(logger=self.log, threaded=False, cleanup=self.cleanup_state) + + def write_target(self, target): + self.check_limits(target) + self.target = target + if not self._state.is_active: # as long as the state machine is still running, it takes care of changing targets + self._state.start(self.start_field_change) + self.doPoll() + return Done + + def write_mode(self, value): + self.mode = value + if not self._state.is_active: + self._state.start(self.start_field_change) + self.doPoll() + return Done + + def cleanup_state(self, state): + self.status = Status.ERROR, repr(state.last_error) + self.log.error('in state %s: %r', state.state.__name__, state.last_error) + self.setFastPoll(False) + if self.switch_heater != 0: + self.persistent_field = self.read_value() + if self.mode != Mode.DRIVEN: + self.log.warning('turn switch heater off') + self.write_switch_heater(0) + + def stop(self): + """keep field at current value""" + # let the state machine do the needed steps to finish + self.write_target(self.value) + + def start_field_change(self, state): + self.setFastPoll(True, 1.0) + self.status = Status.PREPARING, 'changed target field' + if self.persistent_field == self.target: + return self.check_switch_off + return self.start_ramp_to_field + + def start_ramp_to_field(self, state): + """start ramping current to persistent field + + should return ramp_to_field + """ + raise NotImplementedError + + def ramp_to_field(self, state): + """ramping, wait for current at persistent field""" + if self.persistent_field == self.target: # short cut + return self.check_switch_off + if abs(self.current - self.persistent_field) > self.tolerance: + if state.init: + self.status = Status.PREPARING, 'ramping leads current to field' + return Retry() + state.stabilize_start = time.time() + return self.stabilize_current + + def stabilize_current(self, state): + """wait for stable current at persistent field""" + if state.now - state.stabilize_start < self.wait_stable_leads: + if state.init: + self.status = Status.PREPARING, 'stabilizing leads current' + return Retry() + return self.start_switch_on + + def write_switch_heater(self, value): + """implementations must super call this!""" + self._super_sw_check = True + if value != self.switch_heater: + self.switch_time = time.time() + return value + + def start_switch_on(self, state): + """switch heater on""" + self._super_sw_check = False + if self.switch_heater != 0: + self.status = Status.PREPARING, 'wait for heater on' + else: + self.status = Status.PREPARING, 'turn switch heater on' + self.write_switch_heater(True) + if not self._super_sw_check: + raise ProgrammingError('missing super call in write_switch_heater') + return self.switch_on + + def switch_on(self, state): + """wait for switch heater open""" + if self.persistent_field == self.target: # short cut + return self.check_switch_off + if state.now - self.switch_time < self.wait_switch_on: + return Retry() + state.set_point = self.target + return self.start_ramp_to_target + + def start_ramp_to_target(self, state): + """start ramping current to target + + should return ramp_to_target + """ + raise NotImplementedError + + def ramp_to_target(self, state): + """ramp field to target""" + if state.set_point != self.target: # target changed + state.set_point = self.target + return self.start_ramp_to_target + self.persistent_field = self.value + # Remarks: assume there is a ramp limiting feature + if abs(self.value - self.target) > self.tolerance: + if state.init: + self.status = Status.RAMPING, 'ramping field' + return Retry() + state.stabilize_start = time.time() + return self.stabilize_field + + def stabilize_field(self, state): + """stabilize field""" + if state.now - state.stabilize_start < self.wait_stable_field: + if state.init: + self.status = Status.STABILIZING, 'stabilizing field' + self.persistent_field = self.value + return Retry() + self.persistent_field = state.set_point + return self.check_switch_off + + def check_switch_off(self, state): + if self.mode == Mode.DRIVEN: + self.status = Status.PREPARED, 'driven' + return self.finish_state + return self.start_switch_off + + def start_switch_off(self, state): + """turn off switch heater""" + if self.switch_heater != 0: + self.status = Status.FINALIZING, 'turn switch heater off' + else: + self.status = Status.FINALIZING, 'wait for heater off' + self._super_sw_check = False + self.write_switch_heater(False) + if not self._super_sw_check: + raise ProgrammingError('missing super call in write_switch_heater') + return self.switch_off + + def switch_off(self, state): + """wait for switch heater closed""" + if self.persistent_field != self.target: # redo + return self.start_switch_on + if self.mode == Mode.DRIVEN: + return self.start_switch_on + if state.now - self.switch_time < self.wait_switch_off: + return Retry() + return self.start_ramp_to_zero + + def start_ramp_to_zero(self, state): + """start ramping current to target + + initiate ramp to zero (with corresponding ramp rate + should return ramp_to_zero + """ + raise NotImplementedError + + def ramp_to_zero(self, state): + """ramp field to zero""" + if self.persistent_field != self.target or self.mode == Mode.DRIVEN: # redo + return self.start_field_change + if abs(self.current) > self.tolerance: + if state.init: + self.status = Status.FINALIZING, 'ramp leads to zero' + return Retry() + if self.mode == Mode.DISABLED and self.persistent_field == 0: + self.status = Status.DISABLED, 'disabled' + else: + self.status = Status.IDLE, 'persistent mode' + return self.finish_state + + def finish_state(self, state): + """finish""" + self.setFastPoll(False) + return None