From 94e2e06f22c9d6b5c0986e532b5f43e85416712b Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 18 Mar 2014 12:42:56 +1100 Subject: [PATCH] Wrap generated driver code in 'catch' and handle_exception blocks --- .../bilby/config/motors/sct_shutters.tcl | 229 +++++++------ .../bilby/config/motors/sct_tank.tcl | 188 +++++----- site_ansto/instrument/util/gen_sct.py | 324 ++++++++++-------- 3 files changed, 408 insertions(+), 333 deletions(-) diff --git a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl index b66d6716..a451c0a5 100644 --- a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl +++ b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl @@ -7,67 +7,79 @@ namespace eval ::scobj::shutters { } proc ::scobj::shutters::debug_log {debug_level debug_string} { - if {${debug_level} >= ${::scobj::shutters::debug_threshold}} { - set fd [open "/tmp/shutters.log" "a"] - set line "[clock format [clock seconds] -format "%T"] ${debug_string}" - puts ${fd} "${line}" - close ${fd} - } + set catch_status [ catch { + if {${debug_level} >= ${::scobj::shutters::debug_threshold}} { + set fd [open "/tmp/shutters.log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] } # check function for hset change proc ::scobj::shutters::checkrange {tc_root} { - debug_log 1 "checkrange tc_root=${tc_root} sct=[sct] target=[sct target]" - set setpoint [sct target] - if { [hpropexists [sct] lowerlimit] } { - set lolimit [sct lowerlimit] - } else { - # lowerlimit not set, use target - set lolimit [sct target] - } - if { [hpropexists [sct] upperlimit] } { - set hilimit [sct upperlimit] - } else { - # upperlimit not set, use target - set hilimit [sct target] - } - if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { - error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" - } - return OK + set catch_status [ catch { + debug_log 1 "checkrange tc_root=${tc_root} sct=[sct] target=[sct target]" + set setpoint [sct target] + if { [hpropexists [sct] lowerlimit] } { + set lolimit [sct lowerlimit] + } else { + # lowerlimit not set, use target + set lolimit [sct target] + } + if { [hpropexists [sct] upperlimit] } { + set hilimit [sct upperlimit] + } else { + # upperlimit not set, use target + set hilimit [sct target] + } + if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { + error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" + } + return OK + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to request the read of a parameter on a device proc ::scobj::shutters::getValue {tc_root nextState cmd_str} { - debug_log 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" - debug_log 1 "getValue sct send ${cmd}" - sct send "${cmd}" - return ${nextState} + set catch_status [ catch { + debug_log 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set cmd "${cmd_str}" + debug_log 1 "getValue sct send ${cmd}" + sct send "${cmd}" + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to check the write parameter on a device proc ::scobj::shutters::noResponse {tc_root} { - debug_log 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" - return "idle" + set catch_status [ catch { + debug_log 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" + return "idle" + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to parse the read of a parameter on a device proc ::scobj::shutters::read_switch_pair {tc_root} { - debug_log 1 "read_switch_pair tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - return -code error "[sct geterror]" - } + set catch_status [ catch { + debug_log 1 "read_switch_pair tc_root=${tc_root} sct=[sct] result=[sct result]" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set data [sct result] + set nextState "idle" + if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { + # the protocol driver has reported an error + sct geterror "${data}" + error "[sct geterror]" + } # hook code starts if { [string equal -nocase -length 1 "${data}" "?"] } { sct geterror "Galil error in: '${data}'" @@ -91,47 +103,53 @@ proc ::scobj::shutters::read_switch_pair {tc_root} { } } # hook code ends - if { [hpropexists [sct] geterror] } { - debug_log 1 "[sct] error: [sct geterror]" - return -code error "[sct geterror]" - } - if { ${data} != [sct oldval] } { - debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime + if { [hpropexists [sct] geterror] } { + debug_log 1 "[sct] error: [sct geterror]" + error "[sct geterror]" } - return ${nextState} + if { ${data} != [sct oldval] } { + debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to write a parameter value on a device proc ::scobj::shutters::setValue {tc_root nextState cmd_str} { - debug_log 1 "setValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 + set catch_status [ catch { + debug_log 1 "setValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror } - } - debug_log 1 "setValue sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} + set par [sct target] + set cmd "${cmd_str}${par}" + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log 1 "setValue sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to write a parameter value on a device proc ::scobj::shutters::write_switch {tc_root nextState cmd_str} { - debug_log 1 "write_switch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" + set catch_status [ catch { + debug_log 1 "write_switch tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set par [sct target] + set cmd "${cmd_str}${par}" # hook code starts if { [string equal -nocase -length 2 "${par}" "in"] } { set cmd "SB${cmd_str}" @@ -141,20 +159,22 @@ proc ::scobj::shutters::write_switch {tc_root nextState cmd_str} { sct geterror "Value error: '${par}' not in ('in', 'out')" } # hook code ends - if { [hpropexists [sct] geterror] } { - debug_log 1 "[sct] error: [sct geterror]" - return -code error "[sct geterror]" - } - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 + if { [hpropexists [sct] geterror] } { + debug_log 1 "[sct] error: [sct geterror]" + error "[sct geterror]" } - } - debug_log 1 "write_switch sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log 1 "write_switch sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } proc ::scobj::shutters::mk_sct_shutters { sct_controller name } { @@ -230,7 +250,7 @@ proc ::scobj::shutters::mk_sct_shutters { sct_controller name } { # hook code starts # hook code ends } catch_message ] - handle_exception ${catch_status} ${catch_message} "in ${ns}::mk_sct_shutters" + handle_exception ${catch_status} ${catch_message} } namespace eval ::scobj::shutters { @@ -239,20 +259,23 @@ namespace eval ::scobj::shutters { } proc add_shutters {name IP port} { - set ns "::scobj::shutters" - ${ns}::debug_log 1 "add_shutters ${name} ${IP} ${port}" - if {[SplitReply [motor_simulation]]=="false"} { - if {[string equal -nocase "aqadapter" "${IP}"]} { - ${ns}::debug_log 1 "makesctcontroller sct_${name} aqadapter ${port}" - makesctcontroller sct_${name} aqadapter ${port} - } else { - ${ns}::debug_log 1 "makesctcontroller sct_${name} dmc2280 ${IP}:${port}" - makesctcontroller sct_${name} dmc2280 ${IP}:${port} + set catch_status [ catch { + set ns "::scobj::shutters" + ${ns}::debug_log 1 "add_shutters ${name} ${IP} ${port}" + if {[SplitReply [motor_simulation]]=="false"} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ${ns}::debug_log 1 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ${ns}::debug_log 1 "makesctcontroller sct_${name} dmc2280 ${IP}:${port}" + makesctcontroller sct_${name} dmc2280 ${IP}:${port} + } } - } - ${ns}::debug_log 1 "mk_sct_shutters sct_${name} ${name}" - ${ns}::mk_sct_shutters sct_${name} ${name} - close ${fd} + ${ns}::debug_log 1 "mk_sct_shutters sct_${name} ${name}" + ${ns}::mk_sct_shutters sct_${name} ${name} + close ${fd} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } puts stdout "file evaluation of sct_shutters.tcl" diff --git a/site_ansto/instrument/bilby/config/motors/sct_tank.tcl b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl index 977a5ede..6ca6031d 100644 --- a/site_ansto/instrument/bilby/config/motors/sct_tank.tcl +++ b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl @@ -7,67 +7,79 @@ namespace eval ::scobj::tank { } proc ::scobj::tank::debug_log {debug_level debug_string} { - if {${debug_level} >= ${::scobj::tank::debug_threshold}} { - set fd [open "/tmp/tank.log" "a"] - set line "[clock format [clock seconds] -format "%T"] ${debug_string}" - puts ${fd} "${line}" - close ${fd} - } + set catch_status [ catch { + if {${debug_level} >= ${::scobj::tank::debug_threshold}} { + set fd [open "/tmp/tank.log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] } # check function for hset change proc ::scobj::tank::checkrange {tc_root} { - debug_log 1 "checkrange tc_root=${tc_root} sct=[sct] target=[sct target]" - set setpoint [sct target] - if { [hpropexists [sct] lowerlimit] } { - set lolimit [sct lowerlimit] - } else { - # lowerlimit not set, use target - set lolimit [sct target] - } - if { [hpropexists [sct] upperlimit] } { - set hilimit [sct upperlimit] - } else { - # upperlimit not set, use target - set hilimit [sct target] - } - if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { - error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" - } - return OK + set catch_status [ catch { + debug_log 1 "checkrange tc_root=${tc_root} sct=[sct] target=[sct target]" + set setpoint [sct target] + if { [hpropexists [sct] lowerlimit] } { + set lolimit [sct lowerlimit] + } else { + # lowerlimit not set, use target + set lolimit [sct target] + } + if { [hpropexists [sct] upperlimit] } { + set hilimit [sct upperlimit] + } else { + # upperlimit not set, use target + set hilimit [sct target] + } + if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { + error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" + } + return OK + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to request the read of a parameter on a device proc ::scobj::tank::getValue {tc_root nextState cmd_str} { - debug_log 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set cmd "${cmd_str}" - debug_log 1 "getValue sct send ${cmd}" - sct send "${cmd}" - return ${nextState} + set catch_status [ catch { + debug_log 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set cmd "${cmd_str}" + debug_log 1 "getValue sct send ${cmd}" + sct send "${cmd}" + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to check the write parameter on a device proc ::scobj::tank::noResponse {tc_root} { - debug_log 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" - return "idle" + set catch_status [ catch { + debug_log 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" + return "idle" + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to parse the read of a parameter on a device proc ::scobj::tank::read_switch {tc_root} { - debug_log 1 "read_switch tc_root=${tc_root} sct=[sct] result=[sct result]" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set data [sct result] - set nextState "idle" - if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { - # the protocol driver has reported an error - sct geterror "${data}" - return -code error "[sct geterror]" - } + set catch_status [ catch { + debug_log 1 "read_switch tc_root=${tc_root} sct=[sct] result=[sct result]" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set data [sct result] + set nextState "idle" + if {[string equal -nocase -length 7 ${data} "ASCERR:"]} { + # the protocol driver has reported an error + sct geterror "${data}" + error "[sct geterror]" + } # hook code starts if { [string equal -nocase -length 1 "${data}" "?"] } { sct geterror "Galil error in: '${data}'" @@ -88,37 +100,42 @@ proc ::scobj::tank::read_switch {tc_root} { } } # hook code ends - if { [hpropexists [sct] geterror] } { - debug_log 1 "[sct] error: [sct geterror]" - return -code error "[sct geterror]" - } - if { ${data} != [sct oldval] } { - debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]" - sct oldval ${data} - sct update ${data} - sct utime readtime + if { [hpropexists [sct] geterror] } { + debug_log 1 "[sct] error: [sct geterror]" + error "[sct geterror]" } - return ${nextState} + if { ${data} != [sct oldval] } { + debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } # function to write a parameter value on a device proc ::scobj::tank::setValue {tc_root nextState cmd_str} { - debug_log 1 "setValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" - if { [hpropexists [sct] geterror] } { - hdelprop [sct] geterror - } - set par [sct target] - set cmd "${cmd_str}${par}" - if { [hpropexists [sct] driving] } { - if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { - sct driving 1 + set catch_status [ catch { + debug_log 1 "setValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror } - } - debug_log 1 "setValue sct send ${cmd}" - if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { - sct send "${cmd}" - } - return ${nextState} + set par [sct target] + set cmd "${cmd_str}${par}" + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log 1 "setValue sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } proc ::scobj::tank::mk_sct_tank { sct_controller name } { @@ -186,7 +203,7 @@ proc ::scobj::tank::mk_sct_tank { sct_controller name } { # hook code starts # hook code ends } catch_message ] - handle_exception ${catch_status} ${catch_message} "in ${ns}::mk_sct_tank" + handle_exception ${catch_status} ${catch_message} } namespace eval ::scobj::tank { @@ -195,20 +212,23 @@ namespace eval ::scobj::tank { } proc add_tank {name IP port} { - set ns "::scobj::tank" - ${ns}::debug_log 1 "add_tank ${name} ${IP} ${port}" - if {[SplitReply [motor_simulation]]=="false"} { - if {[string equal -nocase "aqadapter" "${IP}"]} { - ${ns}::debug_log 1 "makesctcontroller sct_${name} aqadapter ${port}" - makesctcontroller sct_${name} aqadapter ${port} - } else { - ${ns}::debug_log 1 "makesctcontroller sct_${name} dmc2280 ${IP}:${port}" - makesctcontroller sct_${name} dmc2280 ${IP}:${port} + set catch_status [ catch { + set ns "::scobj::tank" + ${ns}::debug_log 1 "add_tank ${name} ${IP} ${port}" + if {[SplitReply [motor_simulation]]=="false"} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ${ns}::debug_log 1 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ${ns}::debug_log 1 "makesctcontroller sct_${name} dmc2280 ${IP}:${port}" + makesctcontroller sct_${name} dmc2280 ${IP}:${port} + } } - } - ${ns}::debug_log 1 "mk_sct_tank sct_${name} ${name}" - ${ns}::mk_sct_tank sct_${name} ${name} - close ${fd} + ${ns}::debug_log 1 "mk_sct_tank sct_${name} ${name}" + ${ns}::mk_sct_tank sct_${name} ${name} + close ${fd} + } catch_message ] + handle_exception ${catch_status} ${catch_message} } puts stdout "file evaluation of sct_tank.tcl" diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index c3e55fff..66dd7aab 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -745,12 +745,14 @@ def put_preamble(MyDriver): txt += ['}'] txt += [''] txt += ['proc %s::debug_log {debug_level debug_string} {' % MyDriver['namespace']] - txt += [' if {${debug_level} >= ${%s::debug_threshold}} {' % MyDriver['namespace']] - txt += [' set fd [open "/tmp/%s.log" "a"]' % MyDriver['name']] - txt += [' set line "[clock format [clock seconds] -format "%T"] ${debug_string}"'] - txt += [' puts ${fd} "${line}"'] - txt += [' close ${fd}'] - txt += [' }'] + txt += [' set catch_status [ catch {'] + txt += [' if {${debug_level} >= ${%s::debug_threshold}} {' % MyDriver['namespace']] + txt += [' set fd [open "/tmp/%s.log" "a"]' % MyDriver['name']] + txt += [' set line "[clock format [clock seconds] -format "%T"] ${debug_string}"'] + txt += [' puts ${fd} "${line}"'] + txt += [' close ${fd}'] + txt += [' }'] + txt += [' } catch_message ]'] txt += ['}'] emit(txt) @@ -758,30 +760,33 @@ def put_write_function(MyDriver, func): txt = [''] txt += ['# function to write a parameter value on a device'] txt += ['proc %s::%s {tc_root nextState cmd_str} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' hdelprop [sct] geterror'] - txt += [' }'] - txt += [' set par [sct target]'] - txt += [' set cmd "${cmd_str}${par}"'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' hdelprop [sct] geterror'] + txt += [' }'] + txt += [' set par [sct target]'] + txt += [' set cmd "${cmd_str}${par}"'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' debug_log 1 "[sct] error: [sct geterror]"'] - txt += [' return -code error "[sct geterror]"'] - txt += [' }'] - txt += [' if { [hpropexists [sct] driving] } {'] - txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {'] - txt += [' sct driving 1'] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' debug_log 1 "[sct] error: [sct geterror]"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] + txt += [' if { [hpropexists [sct] driving] } {'] + txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {'] + txt += [' sct driving 1'] + txt += [' }'] txt += [' }'] - txt += [' }'] - txt += [' debug_log 1 "%s sct send ${cmd}"' % func] - txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] - txt += [' sct send "${cmd}"'] - txt += [' }'] - txt += [' return ${nextState}'] + txt += [' debug_log 1 "%s sct send ${cmd}"' % func] + txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] + txt += [' sct send "${cmd}"'] + txt += [' }'] + txt += [' return ${nextState}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -789,12 +794,15 @@ def put_check_function(MyDriver, func): txt = [''] txt += ['# function to check the write parameter on a device'] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] resp=[sct result]"' % func] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] resp=[sct result]"' % func] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' return "idle"'] + txt += [' return "idle"'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -802,22 +810,25 @@ def put_fetch_function(MyDriver, func): txt = [''] txt += ['# function to request the read of a parameter on a device'] txt += ['proc %s::%s {tc_root nextState cmd_str} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' hdelprop [sct] geterror'] - txt += [' }'] - txt += [' set cmd "${cmd_str}"'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' hdelprop [sct] geterror'] + txt += [' }'] + txt += [' set cmd "${cmd_str}"'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' debug_log 1 "[sct] error: [sct geterror]"'] - txt += [' return -code error "[sct geterror]"'] - txt += [' }'] - txt += [' debug_log 1 "%s sct send ${cmd}"' % func] - txt += [' sct send "${cmd}"'] - txt += [' return ${nextState}'] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' debug_log 1 "[sct] error: [sct geterror]"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] + txt += [' debug_log 1 "%s sct send ${cmd}"' % func] + txt += [' sct send "${cmd}"'] + txt += [' return ${nextState}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -825,32 +836,35 @@ def put_read_function(MyDriver, func): txt = [''] txt += ['# function to parse the read of a parameter on a device'] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] result=[sct result]"' % func] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' hdelprop [sct] geterror'] - txt += [' }'] - txt += [' set data [sct result]'] - txt += [' set nextState "idle"'] - txt += [' if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {'] - txt += [' # the protocol driver has reported an error'] - txt += [' sct geterror "${data}"'] - txt += [' return -code error "[sct geterror]"'] - txt += [' }'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] result=[sct result]"' % func] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' hdelprop [sct] geterror'] + txt += [' }'] + txt += [' set data [sct result]'] + txt += [' set nextState "idle"'] + txt += [' if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {'] + txt += [' # the protocol driver has reported an error'] + txt += [' sct geterror "${data}"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' debug_log 1 "[sct] error: [sct geterror]"'] - txt += [' return -code error "[sct geterror]"'] - txt += [' }'] - txt += [' if { ${data} != [sct oldval] } {'] - txt += [' debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]"'] - txt += [' sct oldval ${data}'] - txt += [' sct update ${data}'] - txt += [' sct utime readtime'] - txt += [' }'] - txt += [' return ${nextState}'] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' debug_log 1 "[sct] error: [sct geterror]"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] + txt += [' if { ${data} != [sct oldval] } {'] + txt += [' debug_log 1 "[sct] changed to new:${data}, from old:[sct oldval]"'] + txt += [' sct oldval ${data}'] + txt += [' sct update ${data}'] + txt += [' sct utime readtime'] + txt += [' }'] + txt += [' return ${nextState}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -858,28 +872,31 @@ def put_checkrange_function(MyDriver, func): txt = [''] txt += ['# check function for hset change'] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] - txt += [' set setpoint [sct target]'] - txt += [' if { [hpropexists [sct] lowerlimit] } {'] - txt += [' set lolimit [sct lowerlimit]'] - txt += [' } else {'] - txt += [' # lowerlimit not set, use target'] - txt += [' set lolimit [sct target]'] - txt += [' }'] - txt += [' if { [hpropexists [sct] upperlimit] } {'] - txt += [' set hilimit [sct upperlimit]'] - txt += [' } else {'] - txt += [' # upperlimit not set, use target'] - txt += [' set hilimit [sct target]'] - txt += [' }'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] + txt += [' set setpoint [sct target]'] + txt += [' if { [hpropexists [sct] lowerlimit] } {'] + txt += [' set lolimit [sct lowerlimit]'] + txt += [' } else {'] + txt += [' # lowerlimit not set, use target'] + txt += [' set lolimit [sct target]'] + txt += [' }'] + txt += [' if { [hpropexists [sct] upperlimit] } {'] + txt += [' set hilimit [sct upperlimit]'] + txt += [' } else {'] + txt += [' # upperlimit not set, use target'] + txt += [' set hilimit [sct target]'] + txt += [' }'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] - txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] - txt += [' }'] - txt += [' return OK'] + txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] + txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] + txt += [' }'] + txt += [' return OK'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -887,29 +904,32 @@ def put_checklimits_function(MyDriver, func): txt = [''] txt += ['# checklimits function for driveable interface'] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] - txt += [' set setpoint [sct target]'] - txt += [' if { [hpropexists [sct] lowerlimit] } {'] - txt += [' set lolimit [sct lowerlimit]'] - txt += [' } else {'] - txt += [' # lowerlimit not set, use target'] - txt += [' set lolimit [sct target]'] - txt += [' }'] - txt += [' if { [hpropexists [sct] upperlimit] } {'] - txt += [' set hilimit [sct upperlimit]'] - txt += [' } else {'] - txt += [' # upperlimit not set, use target'] - txt += [' set hilimit [sct target]'] - txt += [' }'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] + txt += [' set setpoint [sct target]'] + txt += [' if { [hpropexists [sct] lowerlimit] } {'] + txt += [' set lolimit [sct lowerlimit]'] + txt += [' } else {'] + txt += [' # lowerlimit not set, use target'] + txt += [' set lolimit [sct target]'] + txt += [' }'] + txt += [' if { [hpropexists [sct] upperlimit] } {'] + txt += [' set hilimit [sct upperlimit]'] + txt += [' } else {'] + txt += [' # upperlimit not set, use target'] + txt += [' set hilimit [sct target]'] + txt += [' }'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] - txt += [' sct driving 0'] - txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] - txt += [' }'] - txt += [' return OK'] + txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] + txt += [' sct driving 0'] + txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] + txt += [' }'] + txt += [' return OK'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -917,21 +937,24 @@ def put_checkstatus_function(MyDriver, func): txt = [''] txt += ['# checkstatus function for driveable interface'] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' if {[sct driving]} {'] - txt += [' set sp "[sct target]"'] - txt += [' set pv "[hval ${tc_root}/[sct driveable]]"'] - txt += [' if { ${pv} > ${sp} - [sct tolerance] && ${pv} < ${sp} + [sct tolerance] } {'] - txt += [' sct driving 0'] + txt += [' if {[sct driving]} {'] + txt += [' set sp "[sct target]"'] + txt += [' set pv "[hval ${tc_root}/[sct driveable]]"'] + txt += [' if { ${pv} > ${sp} - [sct tolerance] && ${pv} < ${sp} + [sct tolerance] } {'] + txt += [' sct driving 0'] + txt += [' return "idle"'] + txt += [' }'] + txt += [' return "busy"'] + txt += [' } else {'] txt += [' return "idle"'] txt += [' }'] - txt += [' return "busy"'] - txt += [' } else {'] - txt += [' return "idle"'] - txt += [' }'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -939,14 +962,17 @@ def put_halt_function(MyDriver, func): txt = [''] txt += ['# halt function for driveable interface'] txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] driving=[sct driving]"' % func] - txt += [' ### TODO hset [sct] [hval [sct]]'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] driving=[sct driving]"' % func] + txt += [' ### TODO hset [sct] [hval [sct]]'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' sct driving 0'] - txt += [' return "idle"'] + txt += [' sct driving 0'] + txt += [' return "idle"'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -954,25 +980,28 @@ def put_pid_function(MyDriver, func): txt = [''] txt += ['# pid function for PID control'] txt += ['proc %s::%s {tc_root sp pv} {' % (MyDriver['namespace'], func)] - txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] pv=${pv} sp=${sp}"' % func] - txt += [' sct pid_error [expr ${sp} - ${pv}]'] - txt += [' set p_value [expr [sct pid_pvalue] * [sct pid_error]]'] - txt += [' set d_value [expr [sct pid_dvalue] * (${pv} - [sct oldval])]'] - txt += [' sct pid_deriv [sct pid_error]'] - txt += [' sct pid_integ [expr [sct pid_integ] + [sct pid_error]]'] - txt += [' if { [sct pid_integ] > [sct pid_imax] } {'] - txt += [' sct pid_integ [sct pid_imax]'] - txt += [' }'] - txt += [' if { [sct pid_integ] < -[sct pid_imax] } {'] - txt += [' sct pid_integ -[sct pid_imax]'] - txt += [' }'] - txt += [' set i_value [expr [sct pid_ivalue] * [sct pid_integ]]'] - txt += [' set pid [expr ${p_value} + ${i_value} + ${d_value}]'] + txt += [' set catch_status [ catch {'] + txt += [' debug_log 1 "%s tc_root=${tc_root} sct=[sct] pv=${pv} sp=${sp}"' % func] + txt += [' sct pid_error [expr ${sp} - ${pv}]'] + txt += [' set p_value [expr [sct pid_pvalue] * [sct pid_error]]'] + txt += [' set d_value [expr [sct pid_dvalue] * (${pv} - [sct oldval])]'] + txt += [' sct pid_deriv [sct pid_error]'] + txt += [' sct pid_integ [expr [sct pid_integ] + [sct pid_error]]'] + txt += [' if { [sct pid_integ] > [sct pid_imax] } {'] + txt += [' sct pid_integ [sct pid_imax]'] + txt += [' }'] + txt += [' if { [sct pid_integ] < -[sct pid_imax] } {'] + txt += [' sct pid_integ -[sct pid_imax]'] + txt += [' }'] + txt += [' set i_value [expr [sct pid_ivalue] * [sct pid_integ]]'] + txt += [' set pid [expr ${p_value} + ${i_value} + ${d_value}]'] if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: txt += ['# hook code starts'] txt += MyDriver['Funcs'][func]['text'] txt += ['# hook code ends'] - txt += [' sct pid_output ${pid}'] + txt += [' sct pid_output ${pid}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += [' return ${pid}'] txt += ['}'] emit(txt) @@ -1134,7 +1163,7 @@ def put_mk_sct_driver(MyDriver): txt += MyDriver['Funcs']['mkDriver']['text'] txt += ['# hook code ends'] txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message} "in ${ns}::mk_sct_%s"' % MyDriver['name']] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] emit(txt) @@ -1150,37 +1179,40 @@ def put_postamble(MyDriver): else: line = 'proc add_%s {name IP port} {' % MyDriver['name'] txt += [line] - txt += [' set ns "%s"' % MyDriver['namespace']] - txt += [' ${ns}::debug_log 1 "add_%s ${name} ${IP} ${port}"' % MyDriver['name']] - txt += [' if {[SplitReply [%s]]=="false"} {' % MyDriver['simulation_group']] - txt += [' if {[string equal -nocase "aqadapter" "${IP}"]} {'] - txt += [' ${ns}::debug_log 1 "makesctcontroller sct_${name} aqadapter ${port}"'] - txt += [' makesctcontroller sct_${name} aqadapter ${port}'] - txt += [' } else {'] + txt += [' set catch_status [ catch {'] + txt += [' set ns "%s"' % MyDriver['namespace']] + txt += [' ${ns}::debug_log 1 "add_%s ${name} ${IP} ${port}"' % MyDriver['name']] + txt += [' if {[SplitReply [%s]]=="false"} {' % MyDriver['simulation_group']] + txt += [' if {[string equal -nocase "aqadapter" "${IP}"]} {'] + txt += [' ${ns}::debug_log 1 "makesctcontroller sct_${name} aqadapter ${port}"'] + txt += [' makesctcontroller sct_${name} aqadapter ${port}'] + txt += [' } else {'] if 'protocol_args' in MyDriver: protocol_args = MyDriver['protocol_args'].replace('\\', '\\\\').replace('"', '\\"') - txt += [' ${ns}::debug_log 1 "makesctcontroller sct_${name} %s ${IP}:${port} %s"' % (MyDriver['protocol'], protocol_args)] - txt += [' makesctcontroller sct_${name} %s ${IP}:${port} %s' % (MyDriver['protocol'], MyDriver['protocol_args'])] + txt += [' ${ns}::debug_log 1 "makesctcontroller sct_${name} %s ${IP}:${port} %s"' % (MyDriver['protocol'], protocol_args)] + txt += [' makesctcontroller sct_${name} %s ${IP}:${port} %s' % (MyDriver['protocol'], MyDriver['protocol_args'])] else: - txt += [' ${ns}::debug_log 1 "makesctcontroller sct_${name} %s ${IP}:${port}"' % MyDriver['protocol']] - txt += [' makesctcontroller sct_${name} %s ${IP}:${port}' % MyDriver['protocol']] + txt += [' ${ns}::debug_log 1 "makesctcontroller sct_${name} %s ${IP}:${port}"' % MyDriver['protocol']] + txt += [' makesctcontroller sct_${name} %s ${IP}:${port}' % MyDriver['protocol']] + txt += [' }'] txt += [' }'] - txt += [' }'] make_args = '' if 'make_args' in MyDriver: for arg in MyDriver['make_args'].split(): if len(make_args) > 0: make_args += ' ' make_args += '${' + arg + '}' - txt += [' ${ns}::debug_log 1 "mk_sct_%s sct_${name} ${name} %s"' % (MyDriver['name'], make_args)] - txt += [' ${ns}::mk_sct_%s sct_${name} ${name} %s' % (MyDriver['name'], make_args)] + txt += [' ${ns}::debug_log 1 "mk_sct_%s sct_${name} ${name} %s"' % (MyDriver['name'], make_args)] + txt += [' ${ns}::mk_sct_%s sct_${name} ${name} %s' % (MyDriver['name'], make_args)] else: - txt += [' ${ns}::debug_log 1 "mk_sct_%s sct_${name} ${name}"' % MyDriver['name']] - txt += [' ${ns}::mk_sct_%s sct_${name} ${name}' % MyDriver['name']] + txt += [' ${ns}::debug_log 1 "mk_sct_%s sct_${name} ${name}"' % MyDriver['name']] + txt += [' ${ns}::mk_sct_%s sct_${name} ${name}' % MyDriver['name']] # TODO -#txt += [' ${ns}::debug_log 1 "makesctemon ${name} /sics/${name}/emon/monmode /sics/${name}/emon/isintol /sics/${name}/emon/errhandler"'] -# txt += [' makesctemon ${name} /sics/${name}/emon/monmode /sics/${name}/emon/isintol /sics/${name}/emon/errhandler'] - txt += [' close ${fd}'] +#txt += [' ${ns}::debug_log 1 "makesctemon ${name} /sics/${name}/emon/monmode /sics/${name}/emon/isintol /sics/${name}/emon/errhandler"'] +# txt += [' makesctemon ${name} /sics/${name}/emon/monmode /sics/${name}/emon/isintol /sics/${name}/emon/errhandler'] + txt += [' close ${fd}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] txt += ['}'] txt += [''] txt += ['puts stdout "file evaluation of sct_%s.tcl"' % MyDriver['name']]