From 12d4e7dce5dba57bbc2d133445a525c82ff76fa5 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Thu, 18 Sep 2014 17:07:00 +1000 Subject: [PATCH] First pass driver for the Knauer BlueShadow Pump 40P --- .../config/environment/knauer_pump.sct | 286 ++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 site_ansto/instrument/config/environment/knauer_pump.sct diff --git a/site_ansto/instrument/config/environment/knauer_pump.sct b/site_ansto/instrument/config/environment/knauer_pump.sct new file mode 100644 index 00000000..e2288c48 --- /dev/null +++ b/site_ansto/instrument/config/environment/knauer_pump.sct @@ -0,0 +1,286 @@ +# +# Template driver for the Knauer BlueShadow Pump 40P +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +# +driver knauer_pump = { + debug_threshold = 0; + vendor = knauer; device = pump40p; protocol = knauer_ap; + class = environment; + simulation_group = environment_simulation +# + group dummy = { + type = text; readable = 1; data = false; control = false; nxsave = false; + var status = { read_command = 'STATUS?'; read_function = read_status; } + var glp = { read_command = 'GLP?'; read_function = read_glp; } + } + + group volume = { + type = float; + property 'units' = 'mL'; + var sensor = { + readable = 1; + read_command = ' '; + fetch_function = volume_fetch; + #checkrange_function = volume_reject; + } + var setpoint = { + writeable = 1; + write_command = ' '; + write_function = volume_write; + driveable = volume/sensor; + checkstatus_function = volume_checkstatus; + halt_function = volume_halt; + lowerlimit = 0; upperlimit = 100; tolerance = 0.01; + readable = 1; + read_command = ' '; + fetch_function = volume_checkpumping; + } + } + group ratios = { + type = text; + property 'units' = 'percent'; + var sensor = { + readable = 1; read_command = ' '; fetch_function = ratios_fetch; + } + var setpoint = { + writeable = 1; write_command = ' '; write_function = ratios_write; checkrange_function = ratios_check; + } + } + group flow = { + type = float; + property 'units' = 'mL/min'; + var sensor = { + readable = 1; read_command = ' '; fetch_function = flow_fetch; + } + var setpoint = { + writeable = 1; write_command = ' '; write_function = flow_write; + lowerlimit = 0; upperlimit = 10; + } + } + + group stuff = { + readable = 60; + type = text; + var an_out = { read_command = 'AN_OUT?'; } + var boardinfo = { read_command = 'BOARDINFO?'; } + var config = { read_command = 'CONFIG?'; } + var cprofinfo = { read_command = 'CPROFINFO?'; } + var dout = { read_command = 'DOUT?'; } + var error = { read_command = 'ERROR?'; } + var errors = { read_command = 'ERRORS?'; } + var flushpmp = { read_command = 'FLUSHPMP?'; } + var head = { read_command = 'HEAD?'; } + var head_par = { read_command = 'HEAD_PAR?'; } + var identify = { read_command = 'IDENTIFY?'; } + var lpg = { read_command = 'LPG?'; } + var oem = { read_command = 'OEM?'; } + var opt = { read_command = 'OPT?'; } + var plim = { read_command = 'PLIM?'; } + var pressure = { read_command = 'PRESSURE?'; } + var prfastacq = { read_command = 'PRFASTACQ?'; } + var purge = { read_command = 'PURGE?'; } + var remote = { read_command = 'REMOTE?'; } + var rfid = { read_command = 'RFID?'; } + var service = { read_command = 'SERVICE?'; } + var sysinfo = { read_command = 'SYSINFO?'; } + var 'units' = { read_command = 'UNITS?'; } + var valves = { read_command = 'VALVES?'; } + } + group prog = { + readable = 30; + type = text; + var line_01 = { read_command = "TT_GET:1,1"; } + var line_02 = { read_command = "TT_GET:1,2"; } + var line_03 = { read_command = "TT_GET:1,3"; } + var line_04 = { read_command = "TT_GET:1,4"; } + var line_05 = { read_command = "TT_GET:1,5"; } + } + group glp = { + type = text; + readable = 1; + fetch_function = fetch_from_glp; + var board_time = { read_command = '0'; } + var motor_time = { read_command = '1'; } + var head_count = { read_command = '3'; } + var head_time = { read_command = '4'; } + var head_volm = { read_command = '5'; } + var head_voln = { read_command = '6'; } + var head_pwrhi = { read_command = '7'; } + var head_pwrlo = { read_command = '8'; } + var pump_revs = { read_command = '9'; } + var pump_volm = { read_command = '10'; } + var pump_voln = { read_command = '11'; } + var pump_pwrhi = { read_command = '12'; } + var pump_pwrlo = { read_command = '13'; } + } + group status = { + type = text; + readable = 1; + fetch_function = fetch_from_status; + var state = { read_command = '1'; } + var cur_error = { read_command = '2'; } + var cur_run_time = { read_command = '3'; } + var flow_rate = { read_command = '4'; } + var lpg_0 = { read_command = '5'; } + var lpg_1 = { read_command = '6'; } + var lpg_2 = { read_command = '7'; } + var lpg_3 = { read_command = '8'; } + var evt_0 = { read_command = '9'; } + var evt_1 = { read_command = '10'; } + var evt_2 = { read_command = '11'; } + var evt_3 = { read_command = '12'; } + var evt_4 = { read_command = '13'; } + var evt_5 = { read_command = '14'; } + var evt_6 = { read_command = '15'; } + var evt_7 = { read_command = '16'; } + var cur_pres = { read_command = '17'; } + var start_in = { read_command = '18'; } + var error_in = { read_command = '19'; } + } + + code fetch_from_glp = {%% + set index ${cmd_str} + set data [hgetpropval ${tc_root}/dummy/glp real_data] + set dlist [split ${data} ","] + sct result [lindex ${dlist} ${index}] + set cmd "@@NOSEND@@" + %%} + + code fetch_from_status = {%% + set index ${cmd_str} + set data [hgetpropval ${tc_root}/dummy/status real_data] + set dlist [split ${data} ","] + sct result [lindex ${dlist} ${index}] + set cmd "@@NOSEND@@" + %%} + + code read_glp = {%% + set dlist [split [lindex [split ${data} ":"] 1] ","] + sct real_data "[join [lrange ${dlist} 0 end] ,]" + set data "Hidden in real_data property" + %%} + code read_status = {%% + set dlist [split [lindex [split ${data} ":"] 1] ","] + sct real_data "[join [lrange ${dlist} 0 end] ,]" + set data "Hidden in real_data property" + %%} + + code halt = {%% + set ratios [hval ${tc_root}/ratios/setpoint] + set ratios [join [split ${ratios} /] ,] + set cmd "RAMP:0,0,${ratios},0,0,0,0,0,0,0,0,2" + %%} + + code flow_fetch = {%% + set data [hgetpropval ${tc_root}/dummy/status real_data] + set dlist [split ${data} ","] + set flow [lindex ${dlist} 4] + sct result [expr {0.001 * ${flow}}] + set cmd "@@NOSEND@@" + %%} + code flow_write = {%% + set data [sct target] + set cmd "@@NOSEND@@" + set nextState idle + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } + %%} + + code ratios_check = {%% + set ratios [split ${setpoint} /] + if { [llength ${ratios}] != 4 } { + sct geterror "${setpoint} has [llength ${ratios}] components, needs 4" + error [sct geterror] + } + set sum [expr [lindex ${ratios} 0] + [lindex ${ratios} 1] + [lindex ${ratios} 2] + [lindex ${ratios} 3]] + if { ${sum} != 100 } { + sct geterror "sum is ${sum}, must be 100" + error [sct geterror] + } + %%} + + code ratios_fetch = {%% + set data [hgetpropval ${tc_root}/dummy/status real_data] + set dlist [split ${data} ","] + set ratios "[lindex ${dlist} 5]/[lindex ${dlist} 6]/[lindex ${dlist} 7]/[lindex ${dlist} 8]" + sct result ${ratios} + set cmd "@@NOSEND@@" + %%} + code ratios_write = {%% + set data [sct target] + set cmd "@@NOSEND@@" + set nextState idle + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } + %%} + + code volume_fetch = {%% + set data [hgetpropval ${tc_root}/dummy/glp real_data] + set dlist [split ${data} ","] + if { [llength ${dlist}] > 11 } { + set pump_volm [lindex ${dlist} 10] + set pump_voln [lindex ${dlist} 11] + set volume [expr {${pump_volm} + 0.000001 * ${pump_voln}}] + } else { + set volume 0.0 + } + sct raw_volume ${volume} + if { [hpropexists [sct] base_volume] } { + set volume [expr {${volume} - [sct base_volume]}] + } else { + sct base_volume [sct raw_volume] + } + sct result ${volume} + set cmd "@@NOSEND@@" + %%} + code volume_write = {%% + hsetprop ${tc_root}/[sct driveable] base_volume [hgetpropval ${tc_root}/[sct driveable] raw_volume] + hset ${tc_root}/[sct driveable] 0.0 + set flow [expr {int(1000.0 * [hval ${tc_root}/flow/setpoint])}] + set ratios [hval ${tc_root}/ratios/setpoint] + set ratios [join [split ${ratios} /] ,] + set cmd "RAMP:0,${flow},${ratios},0,0,0,0,0,0,0,0,3" + sct pumping 1 + %%} + + code volume_checkpumping = {%% + set cmd "@@NOSEND@@" + set nextState idle + if { [hpropexists [sct] pumping] && [sct pumping] } { + if { [hpropexists [sct] driving] && [sct driving] } { + volume_checkstatus "${tc_root}" + } + set sp "[sct target]" + set pv "[hval ${tc_root}/[sct driveable]]" + if { (${sp} - ${pv}) <= [sct tolerance] } { + set flow 0 + set ratios [hval ${tc_root}/ratios/setpoint] + set ratios [join [split ${ratios} /] ,] + set cmd "RAMP:0,${flow},${ratios},0,0,0,0,0,0,0,0,2" + set nextState noResponse + sct pumping 0 + } + } + %%} + + code volume_halt = {%% + set flow 0 + set ratios [hval ${tc_root}/ratios/setpoint] + set ratios [join [split ${ratios} /] ,] + set cmd "RAMP:0,${flow},${ratios},0,0,0,0,0,0,0,0,2" + sct send ${cmd} + %%} + + code volume_reject = {%% + sct geterror "cannot use hset on [sct]" + error "[sct geterror]" + %%} +}