implement HALT and improve recovery

r2967 | dcl | 2010-07-01 12:39:42 +1000 (Thu, 01 Jul 2010) | 2 lines
This commit is contained in:
Douglas Clowes
2010-07-01 12:39:42 +10:00
parent 9ec08cbf85
commit eebe078118

View File

@@ -43,13 +43,23 @@ debug_log "chkWrite resp=$data sct=[sct] tc_root=$tc_root"
proc setPoint {tc_root nextState cmd} {
set catch_status [ catch {
debug_log "setPoint $tc_root $nextState $cmd sct=[sct]"
debug_log "setPoint: sct=[sct] target=[sct target] writestatus=[sct writestatus]"
sct print "setPoint: sct=[sct] target=[sct target] writestatus=[sct writestatus]"
set err_msg ""
if { [hval $tc_root/Display/A] == 4 } {
set err_msg "Output is clamped (A=[hval $tc_root/Display/A])"
if { [hget $tc_root/drive_state] == "HALT" } {
sct print "Output is HALTed, cannot drive"
return idle
} elseif { [hval $tc_root/Display/A] == 4 } {
set err_msg "Output is clamped (A=[hval $tc_root/Display/A]), to unclamp enter \"hset $tc_root/Control/A 0\""
} elseif { [hval $tc_root/Display/C] != 3 } {
set err_msg "Control is not remote (C=[hval $tc_root/Display/C])"
} elseif { [hval $tc_root/Display/PstntField] == [sct target] } {
} elseif { [hval $tc_root/Display/H] == 0 && [hval $tc_root/Display/PstntField] == [sct target] } {
sct print "Persistent Field ([hval $tc_root/Display/PstntField]) already at target ([sct target])"
return idle
} elseif { [hval $tc_root/Display/H] == 1 && [hval $tc_root/Display/OutputField] == [sct target] } {
sct print "Output Field ([hval $tc_root/Display/PstntField]) already at target ([sct target])"
# return idle
} elseif { [hval $tc_root/Display/H] == 2 && [hval $tc_root/Display/PstntField] == [sct target] } {
sct print "Persistent Field ([hval $tc_root/Display/PstntField]) already at target ([sct target])"
return idle
}
@@ -58,7 +68,11 @@ debug_log "setPoint $tc_root $nextState $cmd sct=[sct]"
debug_log "error:$err_msg"
return -code error "$err_msg"
}
if { [hval $tc_root/Display/H] == 1 } {
sct print "Driving Field ([hval $tc_root/Display/OutputField]) to target ([sct target])"
} else {
sct print "Driving Persistent Field ([hval $tc_root/Display/PstntField]) to target ([sct target])"
}
set par "[sct target]"
hset $tc_root/status "busy"
sct print "status: busy"
@@ -87,6 +101,9 @@ debug_log "rdValue $tc_root failure"
sct geterror "Error: $data"
set nextState idle
} else {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
if {[string index $data 0] == "R"} {
set data [string range $data 1 end]
set rslt [scan $data %f data]
@@ -182,12 +199,25 @@ debug_log "rdState $tc_root state=$my_state"
debug_log "rdState my_status=$my_status"
set rslt [scan $my_status "X%dA%dC%dH%dM%dP%d" the_x the_a the_c the_h the_m the_p]
if {$rslt == 6} {
if { [hval $tc_root/Display/X] != $the_x } { hset $tc_root/Display/X $the_x }
if { [hval $tc_root/Display/A] != $the_a } { hset $tc_root/Display/A $the_a }
if { [hval $tc_root/Display/C] != $the_c } { hset $tc_root/Display/C $the_c }
if { [hval $tc_root/Display/H] != $the_h } { hset $tc_root/Display/H $the_h }
if { [hval $tc_root/Display/M] != $the_m } { hset $tc_root/Display/M $the_m }
if { [hval $tc_root/Display/P] != $the_p } { hset $tc_root/Display/P $the_p }
if { [hval $tc_root/Display/X] != $the_x } {
hset $tc_root/Display/X $the_x
}
if { [hval $tc_root/Display/A] != $the_a } {
hset $tc_root/Display/A $the_a
}
if { [hval $tc_root/Display/C] != $the_c } {
hset $tc_root/Display/C $the_c
}
if { [hval $tc_root/Display/H] != $the_h } {
hset $tc_root/Display/H $the_h
hsetprop $tc_root/setpoint hold_time [expr {[clock seconds] + 30}]
}
if { [hval $tc_root/Display/M] != $the_m } {
hset $tc_root/Display/M $the_m
}
if { [hval $tc_root/Display/P] != $the_p } {
hset $tc_root/Display/P $the_p
}
debug_log "rdState $tc_root status($rslt)= X[format %02d $the_x] A$the_a C$the_c H$the_h M[format %02d $the_m] P[format %02d $the_p]"
# make decisions on next state
if { $the_c == 0 && $the_a == 4 && $the_m % 10 == 0 } {
@@ -196,16 +226,28 @@ debug_log "rdState $tc_root status($rslt)= X[format %02d $the_x] A$the_a C$the_c
}
if { [catch {
if { $the_h == 2 && "[hval $tc_root/Display/PstntCurrent]" != 0 && "[hval $tc_root/Display/OutputCurrent]" == 0 } {
if { [hval $tc_root/Display/Persistent] != 1 } { hset $tc_root/Display/Persistent 1 }
if { [hval $tc_root/Display/Persistent] != 1 } {
hset $tc_root/Display/Persistent 1
sct print "[hget $tc_root/Display/Persistent]"
}
} else {
if { [hval $tc_root/Display/Persistent] != 0 } { hset $tc_root/Display/Persistent 0 }
if { [hval $tc_root/Display/Persistent] != 0 } {
hset $tc_root/Display/Persistent 0
sct print "[hget $tc_root/Display/Persistent]"
}
}
} catch_message] } {
debug_log "rdState catch triggered on Persistent determination: $catch_message"
if { [hval $tc_root/Display/Persistent] != 0 } { hset $tc_root/Display/Persistent 0 }
if { [hval $tc_root/Display/Persistent] != 0 } {
hset $tc_root/Display/Persistent 0
sct print "[hget $tc_root/Display/Persistent]"
sct print "catch=$catch_message"
}
}
if { [catch {
if { [hpropexists $tc_root/sensor/value geterror] } { hdelprop $tc_root/sensor/value geterror }
if { [hpropexists $tc_root/sensor/value geterror] } {
hdelprop $tc_root/sensor/value geterror
}
if { $the_h == 0 || $the_h == 2 } {
if { [hval $tc_root/sensor/value] != [hval $tc_root/Display/PstntField] } {
hset $tc_root/sensor/value [hval $tc_root/Display/PstntField]
@@ -217,8 +259,12 @@ debug_log "rdState catch triggered on Persistent determination: $catch_message"
}
} catch_message] } {
debug_log "rdState catch triggered on Sensor determination: $catch_message"
if { [hpropexists $tc_root/sensor/value geterror] } { hdelprop $tc_root/sensor/value geterror }
if { [hval $tc_root/sensor/value] != 0 } { hset $tc_root/sensor/value 0 }
if { [hpropexists $tc_root/sensor/value geterror] } {
hdelprop $tc_root/sensor/value geterror
}
if { [hval $tc_root/sensor/value] != 0 } {
hset $tc_root/sensor/value 0
}
}
set my_driving [SplitReply [hgetprop $tc_root/setpoint driving]]
if { $the_c != 3 } {
@@ -226,6 +272,22 @@ debug_log "rdState catch triggered on Sensor determination: $catch_message"
set nextState read
} elseif { $my_driving } {
if { [hval $tc_root/drive_state] == "IDLE" } {
} elseif { [hval $tc_root/drive_state] == "HALT" } {
if { $the_m % 10 != 0 || $the_a != 0 } {
hsetprop $tc_root/ips120_state my_state "STATE_A0"
set nextState read
} elseif { [hval $tc_root/Display/H] == 1 } {
hsetprop $tc_root/ips120_state my_state "STATE_H0"
set nextState read
} elseif { [clock seconds] < [SplitReply [hgetprop $tc_root/setpoint hold_time]] } {
hsetprop $tc_root/ips120_state my_state "STATE_H0"
set nextState read
} else {
hset $tc_root/drive_state "IDLE"
hset $tc_root/status "idle"
hsetprop $tc_root/setpoint driving 0
set nextState idle
}
} elseif { [hval $tc_root/drive_state] == "START" } {
if { [hval $tc_root/Display/H] == 1 && [hval $tc_root/Display/OutputCurrent] != [hval $tc_root/Display/TargetCurrent] } {
hsetprop $tc_root/ips120_state my_state "STATE_I"
@@ -290,12 +352,10 @@ debug_log "rdState $tc_root error scan status = $rslt on $my_status"
set nextState idle
} elseif {$my_state == "STATE_H0"} {
hsetprop $tc_root/ips120_state my_state "STATE_X"
hsetprop $tc_root/setpoint hold_time [expr [clock seconds] + 30]
hset $tc_root/drive_state "HOLDING"
set nextState idle
} elseif {$my_state == "STATE_H1"} {
hsetprop $tc_root/ips120_state my_state "STATE_X"
hsetprop $tc_root/setpoint hold_time [expr [clock seconds] + 30]
hset $tc_root/drive_state "HOLDING"
set nextState idle
} elseif {$my_state == "STATE_I"} {
@@ -359,6 +419,7 @@ debug_log "rdState $tc_root error scan status = $rslt on $my_status"
} catch_message ]} {
debug_log "rdState error: $catch_message"
}
if { "$nextState" == "" } { set nextState "idle" }
debug_log "rdState returns: $nextState"
return $nextState
}
@@ -415,11 +476,14 @@ debug_log "checktol $tc_root $currtime $timecheck"
proc halt {tc_root} {
debug_log "halt $tc_root"
hset $tc_root/setpoint [hval $tc_root/sensor/value]
hset $tc_root/drive_state "IDLE"
hset $tc_root/status "idle"
hsetprop $tc_root/setpoint driving 0
sct print "halt $tc_root"
set my_driving [SplitReply [hgetprop $tc_root/setpoint driving]]
hset $tc_root/drive_state "HALT"
hsetprop $tc_root/ips120_state my_state "STATE_X"
if { $my_driving } {
hsetprop $tc_root/ips120_state my_state "STATE_A0"
return read
}
return idle
}