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
This commit is contained in:
Ferdi Franceschini
2010-12-02 14:03:44 +11:00
committed by Douglas Clowes
parent 7bf2d4d9f0
commit 202bb2869a
4 changed files with 91 additions and 55 deletions

View File

@@ -248,10 +248,9 @@ static const char* timestamp(struct timeval *tp) {
#define MAXFILES 100 #define MAXFILES 100
static FILE *fLogFile = NULL; static FILE *fLogFile = NULL;
static int iFile = 0; static int iFile = -1;
static int iLineCount = 0; static int iLineCount = 0;
static int iLogUsable = 1; static int iLogUsable = 1;
char * fPath = "./../log/";
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int OpenVerifyLogFile() int OpenVerifyLogFile()
@@ -259,6 +258,10 @@ static const char* timestamp(struct timeval *tp) {
char pFile[256]; char pFile[256];
char filnam[512]; char filnam[512];
char *pChar = NULL; char *pChar = NULL;
char fPath[1024];
/* snprintf(fPath, 1023, "%s/", getenv("SICS_INIT_LOGPATH")); */
snprintf(fPath, 1023, "%s/", "../log");
pChar = IFindOption(pSICSOptions,"LogFileBaseName"); pChar = IFindOption(pSICSOptions,"LogFileBaseName");
if(!pChar) 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 // 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; int hh, mm, ss, day, mon, year;
struct timeval tv; struct timeval tv;
struct tm *time; struct tm *time;
@@ -282,12 +284,14 @@ static const char* timestamp(struct timeval *tp) {
mm = time->tm_min; mm = time->tm_min;
ss = time->tm_sec; ss = time->tm_sec;
day = time->tm_mday; day = time->tm_mday;
mon = time->tm_mon; mon = time->tm_mon+1;
year = time->tm_year + 1900; 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 }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"); fLogFile = fopen(filnam,"w");
if(!fLogFile) if(!fLogFile)

View File

@@ -72,10 +72,10 @@ proc rdStateRep {} {
return idle return idle
} }
proc rqVal {} { proc rqVal {nextState} {
return reportVal return $nextState
} }
proc ProtekMainDisplay {protek} { proc ProtekMainDisplay {protek nextState} {
if [catch { if [catch {
set stateRep [hval $protek/state] set stateRep [hval $protek/state]
set MDpath [sct] set MDpath [sct]
@@ -88,6 +88,9 @@ proc ProtekMainDisplay {protek} {
set sign1 "" set sign1 ""
} }
set MDISP "$sign1$SA(MD5)$SA(MD4)$SA(MD3)$SA(MD2)$SA(MD1)" 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 MDISP [expr {$scale * $MDISP + $offset}]
set oldval [sct oldval] set oldval [sct oldval]
if {$MDISP != $oldval} { if {$MDISP != $oldval} {
@@ -95,9 +98,9 @@ proc ProtekMainDisplay {protek} {
sct oldval $MDISP sct oldval $MDISP
} }
} msg ] { } 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 scale, scales reading to physical units
# @param offset, offset for main display reading # @param offset, offset for main display reading
# @param interval, polling interval in seconds (optional, default = 0.5seconds) # @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 # NOTE: If the interval is negative then the multimeter will be polled on every cycle of
# the SICS task loop. # 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 sctName "sct_$name"
set sobjName "so_$name" set sobjName "$name"
set soState "so_state_$name" set soState "so_state_$name"
puts "MakeSICSObj $sobjName SCT_OBJECT" puts "MakeSICSObj $sobjName SCT_OBJECT"
MakeSICSObj $soState 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 read rqStateRep
hsetprop /sics/$soState/state rdStateRep rdStateRep hsetprop /sics/$soState/state rdStateRep rdStateRep
hsetprop /sics/$soState/state oldval "UNKNOWN" hsetprop /sics/$soState/state oldval "UNKNOWN"
hsetprop /sics/$sobjName read rqVal hsetprop /sics/$sobjName read rqVal "reportVal"
hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState callBack
hsetprop /sics/$sobjName callBack $cbFunc
hfactory /sics/$sobjName/scale plain user float hfactory /sics/$sobjName/scale plain user float
hset /sics/$sobjName/scale $scale hset /sics/$sobjName/scale $scale
hfactory /sics/$sobjName/offset plain user float 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/$soState/state $interval
$sctName poll /sics/$sobjName $interval $sctName poll /sics/$sobjName $interval
} }
return /sics/$sobjName
} }

View File

@@ -8,6 +8,9 @@ namespace eval ::scobj::lh45 {
# /tempcont/setpoint # /tempcont/setpoint
# /tempcont/sensor/value # /tempcont/sensor/value
proc getValue {nextState cmd} { proc getValue {nextState cmd} {
if [hpropexists [sct] geterror] {
hdelprop [sct] geterror
}
sct send $cmd sct send $cmd
return $nextState return $nextState
} }
@@ -23,11 +26,11 @@ namespace eval ::scobj::lh45 {
} }
set par [sct target] set par [sct target]
if {[hval $tc_root/apply_tolerance]} { # if {[hval $tc_root/apply_tolerance]} {
set tol [hval $tc_root/tolerance] # set tol [hval $tc_root/tolerance]
hset $tc_root/subtemp_warnlimit [expr {$par - $tol}] # hset $tc_root/subtemp_warnlimit [expr {$par - $tol}]
hset $tc_root/overtemp_warnlimit [expr {$par + $tol}] # hset $tc_root/overtemp_warnlimit [expr {$par + $tol}]
} # }
hset $tc_root/power 1 hset $tc_root/power 1
hset $tc_root/status "busy" hset $tc_root/status "busy"
if {[sct writestatus] == "start"} { if {[sct writestatus] == "start"} {
@@ -35,6 +38,7 @@ namespace eval ::scobj::lh45 {
hsetprop $tc_root/setpoint driving 1 hsetprop $tc_root/setpoint driving 1
} }
sct send "$cmd $par" sct send "$cmd $par"
sct updated 0
return $nextState return $nextState
} }
@@ -49,6 +53,7 @@ namespace eval ::scobj::lh45 {
sct oldval $data sct oldval $data
sct update $data sct update $data
sct utime readtime sct utime readtime
sct updated 1
} }
} }
} }
@@ -83,17 +88,37 @@ namespace eval ::scobj::lh45 {
sct update $power sct update $power
} }
if {$power==1} { if {$power==1} {
set intol [::scobj::lh45::checktol $tc_root [sct readtime] [sct timecheck]] set setpoint_updated [hgetpropval $tc_root/setpoint updated]
if {$intol==0} { sct utime timecheck } 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 setpt [hval $tc_root/setpoint]
set temp [hval $tc_root/sensor/value] set temp [hval $tc_root/sensor/value]
if { abs($setpt - $temp) > 0.2} { if { $intol } {
hset $tc_root/emon/monmode "drive"
hset $tc_root/status "busy"
} else {
hsetprop $tc_root/setpoint driving 0 hsetprop $tc_root/setpoint driving 0
hset $tc_root/emon/monmode "monitor" hset $tc_root/emon/monmode "monitor"
hset $tc_root/status "idle" hset $tc_root/status "idle"
} else {
hset $tc_root/emon/monmode "drive"
hset $tc_root/status "busy"
} }
} else { } else {
hset $tc_root/emon/monmode "idle" hset $tc_root/emon/monmode "idle"
@@ -106,30 +131,25 @@ namespace eval ::scobj::lh45 {
} }
proc getState {tc_root nextState cmd} { 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 sct send $cmd
return $nextState return $nextState
} }
proc checktol {tc_root currtime timecheck} { proc checktol {tc_root currtime timecheck} {
set temp [hval $tc_root/sensor/value] set temp [hval $tc_root/sensor/value]
set lotemp [hval $tc_root/subtemp_warnlimit] set setpoint [hval $tc_root/setpoint]
set hitemp [hval $tc_root/overtemp_warnlimit] set tol [hval $tc_root/tolerance]
if { $temp < $lotemp || $temp > $hitemp} { if { abs($temp - $setpoint) > $tol } {
hset $tc_root/emon/isintol 0 hset $tc_root/emon/isintol 0
return 0 return 0
} else { } else {
set timeout [hval $tc_root/tolerance/settletime] set timeout [hval $tc_root/tolerance/settletime]
if { ($currtime - $timecheck) > $timeout} { if { [expr $currtime - $timecheck] > $timeout } {
hset $tc_root/emon/isintol 1 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 oldval UNKNOWN
hsetprop $scobj_hpath/setpoint driving 0 hsetprop $scobj_hpath/setpoint driving 0
hsetprop $scobj_hpath/setpoint writestatus UNKNOWN hsetprop $scobj_hpath/setpoint writestatus UNKNOWN
hsetprop $scobj_hpath/setpoint type drivable
hsetprop $scobj_hpath/setpoint updated 0
# Drive adapter interface # Drive adapter interface
hsetprop $scobj_hpath/setpoint checklimits ${ns}::check $scobj_hpath hsetprop $scobj_hpath/setpoint checklimits ${ns}::check $scobj_hpath
hsetprop $scobj_hpath/setpoint checkstatus ${ns}::drivestatus $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 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 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 rdValue ${ns}::rdValue
hsetprop $scobj_hpath/overtemp_warnlimit noResponse ${ns}::noResponse hsetprop $scobj_hpath/overtemp_warnlimit noResponse ${ns}::noResponse
hsetprop $scobj_hpath/overtemp_warnlimit oldval UNKNOWN hsetprop $scobj_hpath/overtemp_warnlimit oldval UNKNOWN
hfactory $scobj_hpath/subtemp_warnlimit plain user float 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 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 rdValue ${ns}::rdValue
hsetprop $scobj_hpath/subtemp_warnlimit noResponse ${ns}::noResponse hsetprop $scobj_hpath/subtemp_warnlimit noResponse ${ns}::noResponse
hsetprop $scobj_hpath/subtemp_warnlimit oldval UNKNOWN hsetprop $scobj_hpath/subtemp_warnlimit oldval UNKNOWN
@@ -245,15 +267,15 @@ namespace eval ::scobj::lh45 {
hsetprop $scobj_hpath/sensor/value units "C" hsetprop $scobj_hpath/sensor/value units "C"
hfactory $scobj_hpath/sensor/start_temperature plain user float hfactory $scobj_hpath/sensor/start_temperature plain user float
hfactory $scobj_hpath/sensor/end_temperature plain user float hfactory $scobj_hpath/sensor/end_temperature plain user float
proc ${ns}::OnFirstSave {} [subst -nocommands { # proc ${ns}::OnFirstSave {} [subst -nocommands {
hset $scobj_hpath/sensor/start_temperature [hval $scobj_hpath/sensor/value] # hset $scobj_hpath/sensor/start_temperature [hval $scobj_hpath/sensor/value]
hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value] # hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value]
}] # }]
proc ${ns}::OnLastSave {} [subst -nocommands { # proc ${ns}::OnLastSave {} [subst -nocommands {
hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value] # hset $scobj_hpath/sensor/end_temperature [hval $scobj_hpath/sensor/value]
}] # }]
::nexus::OnFirstSave ${ns}::OnFirstSave # ::nexus::OnFirstSave ${ns}::OnFirstSave
::nexus::OnLastSave ${ns}::OnLastSave # ::nexus::OnLastSave ${ns}::OnLastSave
hfactory $scobj_hpath/heating_power_percent plain internal float hfactory $scobj_hpath/heating_power_percent plain internal float
hsetprop $scobj_hpath/heating_power_percent read ${ns}::getValue rdValue "in_pv_01" 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 hfactory $scobj_hpath/tolerance plain user float
hsetprop $scobj_hpath/tolerance units "C" hsetprop $scobj_hpath/tolerance units "C"
hfactory $scobj_hpath/tolerance/settletime plain user float 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" hsetprop $scobj_hpath/tolerance/settletime units "s"
hset $scobj_hpath/tolerance $tol hset $scobj_hpath/tolerance $tol
@@ -309,15 +331,15 @@ namespace eval ::scobj::lh45 {
hfactory $scobj_hpath/emon/isintol plain user int hfactory $scobj_hpath/emon/isintol plain user int
hset $scobj_hpath/emon/isintol 1 hset $scobj_hpath/emon/isintol 1
hfactory $scobj_hpath/emon/errhandler plain user text 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"} { if {[SplitReply [environment_simulation]]=="false"} {
$sct_controller poll $scobj_hpath/setpoint $sct_controller poll $scobj_hpath/setpoint
$sct_controller write $scobj_hpath/setpoint $sct_controller write $scobj_hpath/setpoint
$sct_controller poll $scobj_hpath/subtemp_warnlimit $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 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/heating_power_percent
$sct_controller poll $scobj_hpath/power $sct_controller poll $scobj_hpath/power
$sct_controller write $scobj_hpath/power $sct_controller write $scobj_hpath/power
@@ -343,6 +365,8 @@ namespace eval ::scobj::lh45 {
hsetprop $scobj_hpath privilege spy hsetprop $scobj_hpath privilege spy
::scobj::hinitprops $tempobj setpoint sensor/start_temperature sensor/end_temperature ::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"} { if {[SplitReply [environment_simulation]]=="false"} {
ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/setpoint $scobj_hpath/sensor/value $sct_controller ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/setpoint $scobj_hpath/sensor/value $sct_controller
} }

View File

@@ -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? # How can I make it write the NAME (or any character/string variable) to the hdf file?
# ::scobj::hinitprops $tempobj/sensor sampleSensor # ::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}_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 ansto_makesctdrive ${tempobj}_driveable2 $scobj_hpath/sensor/setpoint2 $scobj_hpath/sensor/ctrlLp2_value $sct_controller