From 202bb2869aa00b14d1132f455888131f3cf22cf9 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 2 Dec 2010 14:03:44 +1100 Subject: [PATCH] servlog.c Fix month in logfile name and put date in all log file names. sct_protek_common.tcl Catch non-numeric readings from main multimeter display Added support for a callbank function which is called after reportVal sct_julabo_lh45.tcl Clear the geterror property when getting a new reading. Don't set the overtemp and subtemp warning limits because this can cause the julabo to alarm. Do nothing if the setpoint hasn't been updated. Set default settletime to 60s and the default error handler to "lazy". Added start_temperature and end_temperature which are updated by callbacks on the histogram memory control. sct_lakeshore_340.tcl Set the type for the setpoint nodes to drivable r3032 | ffr | 2010-12-02 14:03:44 +1100 (Thu, 02 Dec 2010) | 15 lines --- servlog.c | 16 ++- .../config/environment/sct_protek_common.tcl | 24 ++-- .../temperature/sct_julabo_lh45.tcl | 104 +++++++++++------- .../temperature/sct_lakeshore_340.tcl | 2 + 4 files changed, 91 insertions(+), 55 deletions(-) diff --git a/servlog.c b/servlog.c index 2b4bbf6b..01a7a3d4 100644 --- a/servlog.c +++ b/servlog.c @@ -248,10 +248,9 @@ static const char* timestamp(struct timeval *tp) { #define MAXFILES 100 static FILE *fLogFile = NULL; - static int iFile = 0; + static int iFile = -1; static int iLineCount = 0; static int iLogUsable = 1; - char * fPath = "./../log/"; /*---------------------------------------------------------------------------*/ int OpenVerifyLogFile() @@ -259,6 +258,10 @@ static const char* timestamp(struct timeval *tp) { char pFile[256]; char filnam[512]; char *pChar = NULL; + char fPath[1024]; + +/* snprintf(fPath, 1023, "%s/", getenv("SICS_INIT_LOGPATH")); */ +snprintf(fPath, 1023, "%s/", "../log"); pChar = IFindOption(pSICSOptions,"LogFileBaseName"); if(!pChar) @@ -271,7 +274,6 @@ static const char* timestamp(struct timeval *tp) { } // Jing added here to add timestamp info for the server00.log file name as server00_hh:mm:sec-daymonyear.log - if(iFile==0){ int hh, mm, ss, day, mon, year; struct timeval tv; struct tm *time; @@ -282,12 +284,14 @@ static const char* timestamp(struct timeval *tp) { mm = time->tm_min; ss = time->tm_sec; day = time->tm_mday; - mon = time->tm_mon; + mon = time->tm_mon+1; year = time->tm_year + 1900; - snprintf(filnam,511,"%s%s%2.2d_%02d:%02d:%02d-%02d%02d%04d.log", fPath, pFile, iFile, hh, mm, ss, day, mon, year); + if(iFile==-1){ + snprintf(filnam,511,"%s%s_%04d-%02d-%02dT%02d:%02d:%02d.000.log", fPath, pFile, year, mon, day, hh, mm, ss); + iFile = 0; }else - snprintf(filnam,511,"%s%s%2.2d.log", fPath, pFile, iFile); + snprintf(filnam,511,"%s%s_%04d-%02d-%02dT%02d:%02d:%02d.%2.2d.log", fPath, pFile, year, mon, day, hh, mm, ss, iFile); fLogFile = fopen(filnam,"w"); if(!fLogFile) diff --git a/site_ansto/instrument/config/environment/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index ba950cb8..03fbaa51 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -72,10 +72,10 @@ proc rdStateRep {} { return idle } -proc rqVal {} { - return reportVal +proc rqVal {nextState} { + return $nextState } -proc ProtekMainDisplay {protek} { +proc ProtekMainDisplay {protek nextState} { if [catch { set stateRep [hval $protek/state] set MDpath [sct] @@ -88,6 +88,9 @@ proc ProtekMainDisplay {protek} { set sign1 "" } set MDISP "$sign1$SA(MD5)$SA(MD4)$SA(MD3)$SA(MD2)$SA(MD1)" + if {[string is double $MDISP] == 0} { + error "Non-numeric reading ($MDISP) from Protek main display" + } set MDISP [expr {$scale * $MDISP + $offset}] set oldval [sct oldval] if {$MDISP != $oldval} { @@ -95,9 +98,9 @@ proc ProtekMainDisplay {protek} { sct oldval $MDISP } } msg ] { - return -code error "[info level 0] $msg" + return -code error "[info level 0]: $msg" } - return idle + return $nextState } ## @@ -109,11 +112,12 @@ proc ProtekMainDisplay {protek} { # @param scale, scales reading to physical units # @param offset, offset for main display reading # @param interval, polling interval in seconds (optional, default = 0.5seconds) +# @param cbFunc, this function will be called after the voltage reading has been updated # NOTE: If the interval is negative then the multimeter will be polled on every cycle of # the SICS task loop. -proc MakeProtek {name IP PORT {scale 1.0} {offset 0.0} {interval 0.5}} { +proc MakeProtek {name IP PORT {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "return idle"}} { set sctName "sct_$name" - set sobjName "so_$name" + set sobjName "$name" set soState "so_state_$name" puts "MakeSICSObj $sobjName SCT_OBJECT" MakeSICSObj $soState SCT_OBJECT @@ -124,8 +128,9 @@ proc MakeProtek {name IP PORT {scale 1.0} {offset 0.0} {interval 0.5}} { hsetprop /sics/$soState/state read rqStateRep hsetprop /sics/$soState/state rdStateRep rdStateRep hsetprop /sics/$soState/state oldval "UNKNOWN" - hsetprop /sics/$sobjName read rqVal - hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState + hsetprop /sics/$sobjName read rqVal "reportVal" + hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState callBack + hsetprop /sics/$sobjName callBack $cbFunc hfactory /sics/$sobjName/scale plain user float hset /sics/$sobjName/scale $scale hfactory /sics/$sobjName/offset plain user float @@ -142,4 +147,5 @@ sicslist setatt $sobjName long_name $name $sctName poll /sics/$soState/state $interval $sctName poll /sics/$sobjName $interval } + return /sics/$sobjName } diff --git a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl index 1bf69aba..b1bcbd08 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl @@ -8,6 +8,9 @@ namespace eval ::scobj::lh45 { # /tempcont/setpoint # /tempcont/sensor/value proc getValue {nextState cmd} { + if [hpropexists [sct] geterror] { + hdelprop [sct] geterror + } sct send $cmd return $nextState } @@ -23,11 +26,11 @@ namespace eval ::scobj::lh45 { } set par [sct target] - if {[hval $tc_root/apply_tolerance]} { - set tol [hval $tc_root/tolerance] - hset $tc_root/subtemp_warnlimit [expr {$par - $tol}] - hset $tc_root/overtemp_warnlimit [expr {$par + $tol}] - } +# if {[hval $tc_root/apply_tolerance]} { +# set tol [hval $tc_root/tolerance] +# hset $tc_root/subtemp_warnlimit [expr {$par - $tol}] +# hset $tc_root/overtemp_warnlimit [expr {$par + $tol}] +# } hset $tc_root/power 1 hset $tc_root/status "busy" if {[sct writestatus] == "start"} { @@ -35,6 +38,7 @@ namespace eval ::scobj::lh45 { hsetprop $tc_root/setpoint driving 1 } sct send "$cmd $par" + sct updated 0 return $nextState } @@ -49,6 +53,7 @@ namespace eval ::scobj::lh45 { sct oldval $data sct update $data sct utime readtime + sct updated 1 } } } @@ -83,17 +88,37 @@ namespace eval ::scobj::lh45 { sct update $power } if {$power==1} { - set intol [::scobj::lh45::checktol $tc_root [sct readtime] [sct timecheck]] - if {$intol==0} { sct utime timecheck } + set setpoint_updated [hgetpropval $tc_root/setpoint updated] + if {$setpoint_updated != 1} { + return idle + } + set currtime [sct readtime] + set timecheck [sct timecheck] + set temp [hval $tc_root/sensor/value] + set setpoint [hval $tc_root/setpoint] + set tol [hval $tc_root/tolerance] + if { abs($temp - $setpoint) > $tol } { + hset $tc_root/emon/isintol 0 + set intol 0 + sct utime timecheck + } else { + set timeout [hval $tc_root/tolerance/settletime] + if { [expr $currtime - $timecheck] > $timeout } { + hset $tc_root/emon/isintol 1 + set intol 1 + } else { + set intol 0 + } + } set setpt [hval $tc_root/setpoint] set temp [hval $tc_root/sensor/value] - if { abs($setpt - $temp) > 0.2} { - hset $tc_root/emon/monmode "drive" - hset $tc_root/status "busy" - } else { + if { $intol } { hsetprop $tc_root/setpoint driving 0 - hset $tc_root/emon/monmode "monitor" - hset $tc_root/status "idle" + hset $tc_root/emon/monmode "monitor" + hset $tc_root/status "idle" + } else { + hset $tc_root/emon/monmode "drive" + hset $tc_root/status "busy" } } else { hset $tc_root/emon/monmode "idle" @@ -106,30 +131,25 @@ namespace eval ::scobj::lh45 { } proc getState {tc_root nextState cmd} { - # Apply tolerance - if {[hval $tc_root/apply_tolerance]} { - set tol [hval $tc_root/tolerance] - set setpt [hval $tc_root/setpoint] - hset $tc_root/subtemp_warnlimit [expr {$setpt - $tol}] - hset $tc_root/overtemp_warnlimit [expr {$setpt + $tol}] - } sct send $cmd return $nextState } proc checktol {tc_root currtime timecheck} { set temp [hval $tc_root/sensor/value] - set lotemp [hval $tc_root/subtemp_warnlimit] - set hitemp [hval $tc_root/overtemp_warnlimit] - if { $temp < $lotemp || $temp > $hitemp} { + set setpoint [hval $tc_root/setpoint] + set tol [hval $tc_root/tolerance] + if { abs($temp - $setpoint) > $tol } { hset $tc_root/emon/isintol 0 return 0 } else { set timeout [hval $tc_root/tolerance/settletime] - if { ($currtime - $timecheck) > $timeout} { + if { [expr $currtime - $timecheck] > $timeout } { hset $tc_root/emon/isintol 1 + return 1 + } else { + return 0 } - return 1 } } @@ -218,6 +238,8 @@ namespace eval ::scobj::lh45 { hsetprop $scobj_hpath/setpoint oldval UNKNOWN hsetprop $scobj_hpath/setpoint driving 0 hsetprop $scobj_hpath/setpoint writestatus UNKNOWN + hsetprop $scobj_hpath/setpoint type drivable + hsetprop $scobj_hpath/setpoint updated 0 # Drive adapter interface hsetprop $scobj_hpath/setpoint checklimits ${ns}::check $scobj_hpath hsetprop $scobj_hpath/setpoint checkstatus ${ns}::drivestatus $scobj_hpath @@ -225,14 +247,14 @@ namespace eval ::scobj::lh45 { hfactory $scobj_hpath/overtemp_warnlimit plain user float hsetprop $scobj_hpath/overtemp_warnlimit read ${ns}::getValue rdValue "in_sp_03" - hsetprop $scobj_hpath/overtemp_warnlimit write ${ns}::setValue noResponse "out_sp_03" +# hsetprop $scobj_hpath/overtemp_warnlimit write ${ns}::setValue noResponse "out_sp_03" hsetprop $scobj_hpath/overtemp_warnlimit rdValue ${ns}::rdValue hsetprop $scobj_hpath/overtemp_warnlimit noResponse ${ns}::noResponse hsetprop $scobj_hpath/overtemp_warnlimit oldval UNKNOWN hfactory $scobj_hpath/subtemp_warnlimit plain user float hsetprop $scobj_hpath/subtemp_warnlimit read ${ns}::getValue rdValue "in_sp_04" - hsetprop $scobj_hpath/subtemp_warnlimit write ${ns}::setValue noResponse "out_sp_04" +# hsetprop $scobj_hpath/subtemp_warnlimit write ${ns}::setValue noResponse "out_sp_04" hsetprop $scobj_hpath/subtemp_warnlimit rdValue ${ns}::rdValue hsetprop $scobj_hpath/subtemp_warnlimit noResponse ${ns}::noResponse hsetprop $scobj_hpath/subtemp_warnlimit oldval UNKNOWN @@ -245,15 +267,15 @@ namespace eval ::scobj::lh45 { hsetprop $scobj_hpath/sensor/value units "C" hfactory $scobj_hpath/sensor/start_temperature plain user float hfactory $scobj_hpath/sensor/end_temperature plain user float - proc ${ns}::OnFirstSave {} [subst -nocommands { - hset $scobj_hpath/sensor/start_temperature [hval $scobj_hpath/sensor/value] - hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value] - }] - proc ${ns}::OnLastSave {} [subst -nocommands { - hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value] - }] - ::nexus::OnFirstSave ${ns}::OnFirstSave - ::nexus::OnLastSave ${ns}::OnLastSave +# proc ${ns}::OnFirstSave {} [subst -nocommands { +# hset $scobj_hpath/sensor/start_temperature [hval $scobj_hpath/sensor/value] +# hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value] +# }] +# proc ${ns}::OnLastSave {} [subst -nocommands { +# hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value] +# }] +# ::nexus::OnFirstSave ${ns}::OnFirstSave +# ::nexus::OnLastSave ${ns}::OnLastSave hfactory $scobj_hpath/heating_power_percent plain internal float hsetprop $scobj_hpath/heating_power_percent read ${ns}::getValue rdValue "in_pv_01" @@ -275,7 +297,7 @@ namespace eval ::scobj::lh45 { hfactory $scobj_hpath/tolerance plain user float hsetprop $scobj_hpath/tolerance units "C" hfactory $scobj_hpath/tolerance/settletime plain user float - hset $scobj_hpath/tolerance/settletime 5.0 + hset $scobj_hpath/tolerance/settletime 60.0 hsetprop $scobj_hpath/tolerance/settletime units "s" hset $scobj_hpath/tolerance $tol @@ -309,15 +331,15 @@ namespace eval ::scobj::lh45 { hfactory $scobj_hpath/emon/isintol plain user int hset $scobj_hpath/emon/isintol 1 hfactory $scobj_hpath/emon/errhandler plain user text - hset $scobj_hpath/emon/errhandler "pause" + hset $scobj_hpath/emon/errhandler "lazy" if {[SplitReply [environment_simulation]]=="false"} { $sct_controller poll $scobj_hpath/setpoint $sct_controller write $scobj_hpath/setpoint $sct_controller poll $scobj_hpath/subtemp_warnlimit - $sct_controller write $scobj_hpath/subtemp_warnlimit +# $sct_controller write $scobj_hpath/subtemp_warnlimit $sct_controller poll $scobj_hpath/overtemp_warnlimit - $sct_controller write $scobj_hpath/overtemp_warnlimit +# $sct_controller write $scobj_hpath/overtemp_warnlimit $sct_controller poll $scobj_hpath/heating_power_percent $sct_controller poll $scobj_hpath/power $sct_controller write $scobj_hpath/power @@ -343,6 +365,8 @@ namespace eval ::scobj::lh45 { hsetprop $scobj_hpath privilege spy ::scobj::hinitprops $tempobj setpoint sensor/start_temperature sensor/end_temperature + hsetprop $scobj_hpath/sensor/start_temperature mutable true + hsetprop $scobj_hpath/sensor/end_temperature mutable true if {[SplitReply [environment_simulation]]=="false"} { ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/setpoint $scobj_hpath/sensor/value $sct_controller } diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl index 9724162f..3980e626 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl @@ -2061,6 +2061,8 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # How can I make it write the NAME (or any character/string variable) to the hdf file? # ::scobj::hinitprops $tempobj/sensor sampleSensor + hsetprop $scobj_hpath/sensor/setpoint1 type drivable + hsetprop $scobj_hpath/sensor/setpoint2 type drivable ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/sensor/setpoint1 $scobj_hpath/sensor/ctrlLp1_value $sct_controller ansto_makesctdrive ${tempobj}_driveable2 $scobj_hpath/sensor/setpoint2 $scobj_hpath/sensor/ctrlLp2_value $sct_controller