# vim: ft=tcl ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent driver oxford10tlv = { protocol = std class = environment simulation_group = environment_simulation add_args = 'id datype interval' make_args = 'id datype interval' group magnet = { type = float; var setpoint = { driveable = 'magnet/field'; lowerlimit = -10; upperlimit = 10; tolerance = 0.01; property settle_time = 30; write_function = write_setpoint; checkrange_function = check_error; } var htr_sw = { type = int; writeable = 1; write_function = write_heater; read_function = read_heater; # Used in the write function allowed = '0,1'; } var rate = { writeable = 1; write_function = write_rate; read_function = read_rate; # Used in the write function } var field = { readable = 5; read_command = "getF"; read_function = read_field; } var current = { } var state = { type = text; data = false; nxsave = false; mutable = false; readable = 1; fetch_function = fetch_state; read_function = read_state; value = 'IDLE'; property htron_delay = 10; property htroff_delay = 10; } } code check_error = { @TCL if { [hpropexists [sct] driving] } { if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { set my_state [hval ${tc_root}/magnet/state] if {${my_state} != "IDLE"} { error "Cannot run/drive in state '${my_state}', must be 'IDLE'" } } else { error "Use run/drive and not hset" } } @END } code checkstatus = { @TCL @END } code fetch_state = { @TCL set my_state [hval [sct]] set cmd "@@NOSEND@@" if {${my_state} == "START"} { set cmd "setHS ON\r\n@@NOREPLY@@" sct utime start_time hupdate [sct] "HTRON" } elseif {${my_state} == "HTRON"} { if {[hpropexists [sct] htron_delay]} { set htron_delay [sct htron_delay] if {$htron_delay < 10} { set htron_delay 30 } elseif {$htron_delay > 60} { set htron_delay 30 } } else { set htron_delay 30 } if {[sct utime] - [sct start_time] > $htron_delay} { set cmd "setF [hval ${tc_root}/magnet/setpoint]\r\n@@NOREPLY@@" hupdate [sct] "DRIVE" } else { set nextState "idle" } } elseif {${my_state} == "DRIVE"} { if {[hgetpropval ${tc_root}/magnet/setpoint driving] == 0} { set cmd "setHS OFF\r\n@@NOREPLY@@" sct utime start_time hupdate [sct] "HTROFF" } else { set nextState "idle" } } elseif {${my_state} == "HTROFF"} { if {[hpropexists [sct] htroff_delay]} { set htroff_delay [sct htroff_delay] if {$htroff_delay <= 10} { set htroff_delay 30 } elseif {$htroff_delay >= 60} { set htroff_delay 30 } } else { set htroff_delay 30 } if {[sct utime] - [sct start_time] > $htroff_delay} { hupdate [sct] "IDLE" } else { set nextState "idle" } } elseif {${my_state} == "IDLE"} { set nextState "idle" } @END } code read_field = { @TCL set s1 [string trimright [sct result] "\n"] set s2 [split $s1 ";"] if {[llength $s2] > 1} { if {[string equal -nocase -length 14 "Field_Current=" [lindex $s2 0]]} { #hupdateif ${tc_root}/magnet/current [string range [lindex $s2 0] 14 end] set current [string range [lindex $s2 0] 14 end] hsetprop ${tc_root}/magnet/current result ${current} set ns [namespace current] sct with ${tc_root}/magnet/current "${ns}::rdValue ${tc_root}" } if {[string equal -nocase -length 12 "Field_Tesla=" [lindex $s2 1]]} { set data [string range [lindex $s2 1] 12 end] } } @END } code read_state = { @TCL return "idle" @END } code write_heater = { @TCL if {${par} == 0} { set cmd "setHS OFF\r\n@@NOREPLY@@" } elseif {${par} == 1} { set cmd "setHS ON\r\n@@NOREPLY@@" } else { error "Invalid parameter '${par}' should be 0 or 1" } # Invoke the read function to set the value as if read back sct result $par read_heater ${tc_root} @END } code write_setpoint = { @TCL hset ${tc_root}/magnet/state "START" # Force the driving flag for the state check sct driving 1 # Set the value on the field hupdateif [sct] $par # It's all over now set cmd "@@NOSEND@@" set nextState "idle" @END } code write_rate = { @TCL if {${par} >= 0 && ${par} <= 10} { set cmd "setR ${par}\r\n@@NOREPLY@@" } else { error "Invalid parameter '${par}' should be 0 to 10" } # Invoke the read function to set the value as if read back sct result $par read_rate ${tc_root} @END } }