diff --git a/asynnet.c b/asynnet.c index d59c854d..a30e209a 100644 --- a/asynnet.c +++ b/asynnet.c @@ -45,7 +45,7 @@ #define MAXCONNECTIONS 1024 #define RBUFFERSIZE 262144 /* 256kb */ #define WBUFFERSIZE 20*262144 -/* #define WBUFFERSIZE 100*262144 /* +/* #define WBUFFERSIZE 100*262144 */ /*--------------------------------------------------------------------------*/ typedef struct { int socket; diff --git a/commandlog.c b/commandlog.c index e6439ec7..50192665 100644 --- a/commandlog.c +++ b/commandlog.c @@ -536,7 +536,7 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData, if (iCompact > 0) iIntervall = 0; } - SCPrintf(pCon, eValue, "%s.compact [sec] = %d", argv[0], iCompact); + SCPrintf(pCon, eValue, "%s.compact [sec] = %d", argv[0], (int)iCompact); return 1; } else if (strcmp(argv[1], "close") == 0) { /* close command */ fclose(fd); diff --git a/counter.c b/counter.c index 0c820901..b5d0cea6 100644 --- a/counter.c +++ b/counter.c @@ -1142,7 +1142,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData, iRet = self->pDriv->Get(self->pDriv, PaRes.Arg[0].text, PaRes.Arg[1].iVal, &fVal); if (iRet == 1) { - snprintf(pBueffel,255, "%s.%s %d = %f", argv[0], PaRes.Arg[0].text, + snprintf(pBueffel,255, "%s.%s %s = %f", argv[0], PaRes.Arg[0].text, PaRes.Arg[1].text, fVal); SCWrite(pCon, pBueffel, eValue); return 1; diff --git a/diffscan.c b/diffscan.c index 6334b0c3..284cb8bb 100644 --- a/diffscan.c +++ b/diffscan.c @@ -376,7 +376,7 @@ static int DiffScanTask(void *pData) status = GetDrivablePosition(pVar->pObject, self->scanObject->pCon, &fPos); if (status == 0) { - ReleaseCountLock(pCount->pCountInt); + ReleaseCountLock(pCount->pCountInt); return finish; } AppendScanVar(pVar, fPos); @@ -396,21 +396,21 @@ static int DiffScanTask(void *pData) rawCount = data->lCount; rawMon = data->Monitors[self->scaleMonitor - 1]; if(rawMon > 100){ - self->normalizationScale = rawMon; - traceSys("diffscan","START:normalizing on %d, scale monitor is %d", - self->normalizationScale, self->scaleMonitor); + self->normalizationScale = rawMon; + traceSys("diffscan","START:normalizing on %d, scale monitor is %d", + self->normalizationScale, self->scaleMonitor); } else { - traceSys("diffscan","START:normalization count %d, on scale monitor is %d and is to low", - rawMon, self->scaleMonitor); - SCWrite(self->scanObject->pCon,"WARNING: Skipping first point because of low count rate", eWarning); - return finish; + traceSys("diffscan","START:normalization count %ld, on scale monitor is %d and is to low", + rawMon, self->scaleMonitor); + SCWrite(self->scanObject->pCon,"WARNING: Skipping first point because of low count rate", eWarning); + return finish; } } else { if (data->Monitors[self->scaleMonitor - 1] - self->last.Monitors[self->scaleMonitor - 1] < 5) { SCWrite(self->scanObject->pCon, "WARNING: low count rate", eLog); - traceSys("diffscan","RUN:low monitor difference from %d to %d",data->Monitors[self->scaleMonitor-1], - self->last.Monitors[self->scaleMonitor -1]); + traceSys("diffscan","RUN:low monitor difference from %ld to %ld",data->Monitors[self->scaleMonitor-1], + self->last.Monitors[self->scaleMonitor -1]); } rawCount = data->lCount; rawMon = data->Monitors[self->scaleMonitor - 1]; @@ -441,8 +441,8 @@ static int DiffScanTask(void *pData) ReleaseHdbValue(&v); } InvokeCallBack(self->scanObject->pCall, SCANPOINT, self->scanObject); - traceSys("diffscan","RUN: pos, count, rawcount, rawmon: %f, %d, %d, %d", - fPos, countValue, rawCount, rawMon); + traceSys("diffscan","RUN: pos, count, rawcount, rawmon: %f, %f, %ld, %ld", + fPos, countValue, rawCount, rawMon); /* check for interrupt @@ -455,7 +455,7 @@ static int DiffScanTask(void *pData) } if(finish == 0) { - ReleaseCountLock(pCount->pCountInt); + ReleaseCountLock(pCount->pCountInt); } return finish; diff --git a/nxxml.c b/nxxml.c index 12f4de16..131b3afe 100644 --- a/nxxml.c +++ b/nxxml.c @@ -779,7 +779,7 @@ NXstatus NXXputdatatable (NXhandle fid, const void *data){ } /*------------------------------------------------------------------------*/ -NXstatus NXXputdata (NXhandle fid, void *data){ +NXstatus NXXputdata (NXhandle fid, const void *data){ pXMLNexus xmlHandle = NULL; mxml_node_t *userData = NULL; mxml_node_t *current = NULL; @@ -1074,8 +1074,8 @@ NXstatus NXXputslabtable (NXhandle fid, const void *data, return NX_OK; } /*----------------------------------------------------------------------*/ -NXstatus NXXputslab64 (NXhandle fid, void *data, - int64_t iStart[], int64_t iSize[]){ +NXstatus NXXputslab64 (NXhandle fid, const void *data, + const int64_t iStart[], const int64_t iSize[]){ pXMLNexus xmlHandle = NULL; mxml_node_t *userData = NULL; @@ -1295,7 +1295,7 @@ static char *formatAttributeData(const void *data, int datalen, int iType){ return number; } /*---------------------------------------------------------------------*/ -NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, void *data, +NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, const void *data, int datalen, int iType){ char buffer[256]; pXMLNexus xmlHandle = NULL; diff --git a/nxxml.h b/nxxml.h index ee7e9ece..03c09a2c 100644 --- a/nxxml.h +++ b/nxxml.h @@ -44,15 +44,15 @@ NXstatus NXXmakedata64 (NXhandle fid, int rank, int64_t dimensions[]); NXstatus NXXopendata (NXhandle fid, CONSTCHAR *name); NXstatus NXXclosedata (NXhandle fid); -NXstatus NXXputdata (NXhandle fid, void *data); +NXstatus NXXputdata (NXhandle fid, const void *data); NXstatus NXXgetdata (NXhandle fid, void *data); NXstatus NXXgetinfo64 (NXhandle fid, int *rank, int64_t dimension[], int *iType); -NXstatus NXXputslab64 (NXhandle fid, void *data, - int64_t iStart[], int64_t iSize[]); +NXstatus NXXputslab64 (NXhandle fid, const void *data, + const int64_t iStart[], const int64_t iSize[]); NXstatus NXXgetslab64 (NXhandle fid, void *data, const int64_t iStart[], const int64_t iSize[]); -NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, void *data, +NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, const void *data, int datalen, int iType); NXstatus NXXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType); diff --git a/sansbc.c b/sansbc.c index 985d70ea..e40e1e44 100644 --- a/sansbc.c +++ b/sansbc.c @@ -204,7 +204,7 @@ static int StatCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, } average = (double)sum/(double)length; - SCPrintf(pCon,eValue,"Stat:sum,max,min,av = %d,%d,%d,%f", sum,max,min,average); + SCPrintf(pCon,eValue,"Stat:sum,max,min,av = %ld,%ld,%ld,%f", sum,max,min,average); return 1; } diff --git a/simidx.h b/simidx.h index 17668ecc..b29d14df 100644 --- a/simidx.h +++ b/simidx.h @@ -85,6 +85,7 @@ int SimIdxRun(); * \param errCode pointer to an integer error code * \param error A text buffer to hold a description of the error * \param errLen The length of error + */ void SimIdxGetError(int *errCode, char *error, int errLen); /** diff --git a/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl b/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl index eae91283..38e8926b 100644 --- a/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl +++ b/site_ansto/instrument/bilby/config/motors/motor_configuration.tcl @@ -1,11 +1,15 @@ # @file Loads the generated_motor_configuration.tcl file which is created by util/genmotconf.tcl from CSV files. fileeval config/motors/generated_motor_configuration.tcl +fileeval config/motors/sct_shutters.tcl +fileeval config/motors/sct_tank.tcl +add_shutters shutters aqadapter mc4 +add_tank tank aqadapter mc8 # Motors which should not be driven should be set as "fixed" here. # Configurable virtual motors can be defined here. # Eg, mot fixed 1 # Define "proc motor_set_sobj_attributes {}" if we need to define extra sicslist attributes for some motors. -for {set n 1} {$n < 8} {incr n} { +for {set n 1} {$n <= 8} {incr n} { make_coll_motor_1 c$n c$n col$n count make_coll_motor_1 a$n a$n ap$n count } diff --git a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl new file mode 100644 index 00000000..383e71be --- /dev/null +++ b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl @@ -0,0 +1,245 @@ +# Generated driver for shutters +# vim: tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::shutters { + set debug_threshold 0 +} + +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} + } +} + +# 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 +} + +# 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} +} + +# 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" +} + +# 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]" + } +# hook code starts + if { [string equal -nocase -length 1 "${data}" "?"] } { + sct geterror "Galil error in: '${data}'" + } else { + set data_list [split [string trim "${data}"]] + if { [llength ${data_list}] > 2 && [lindex ${data_list} end] == ":" } { + set data_list [lrange ${data_list} 0 1] + } + if { [llength ${data_list}] == 2 } { + set left [expr [lindex ${data_list} 0]] + set right [expr [lindex ${data_list} 1]] + if { ${left} == 1 && ${right} == 0 } { # open + set data "out" + } elseif { ${left} == 0 && ${right} == 1 } { # closed + set data "in" + } else { # indeterminate + set data "moving" + } + } else { + sct geterror "Syntax error in: '${data}'=>'${data_list}'" + } + } +# 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 + } + return ${nextState} +} + +# 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}" + debug_log 1 "setValue sct send ${cmd}" + sct send "${cmd}" + return ${nextState} +} + +# 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}" +# hook code starts + if { [string equal -nocase -length 2 "${par}" "in"] } { + set cmd "SB${cmd_str}" + } elseif { [string equal -nocase -length 2 "${par}" "out"] } { + set cmd "CB${cmd_str}" + } else { + 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]" + } + debug_log 1 "write_switch sct send ${cmd}" + sct send "${cmd}" + return ${nextState} +} + +proc ::scobj::shutters::mk_sct_shutters { sct_controller name } { + debug_log 1 "mk_sct_shutters for ${name}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass collimator + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + + hfactory ${scobj_hpath}/fast_shutter plain user text + hsetprop ${scobj_hpath}/fast_shutter read ${ns}::getValue ${scobj_hpath} read_switch_pair {MG @IN[5], @IN[6]} + hsetprop ${scobj_hpath}/fast_shutter read_switch_pair ${ns}::read_switch_pair ${scobj_hpath} + hsetprop ${scobj_hpath}/fast_shutter control true + hsetprop ${scobj_hpath}/fast_shutter data true + hsetprop ${scobj_hpath}/fast_shutter mutable false + hsetprop ${scobj_hpath}/fast_shutter nxsave true + hsetprop ${scobj_hpath}/fast_shutter oldval UNKNOWN + hsetprop ${scobj_hpath}/fast_shutter klass "collimator" + hsetprop ${scobj_hpath}/fast_shutter nxalias "fast_shutter" + hsetprop ${scobj_hpath}/fast_shutter sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/fast_shutter type "part" + + hfactory ${scobj_hpath}/rough_100 plain user text + hsetprop ${scobj_hpath}/rough_100 read ${ns}::getValue ${scobj_hpath} read_switch_pair {MG @IN[15], @IN[16]} + hsetprop ${scobj_hpath}/rough_100 read_switch_pair ${ns}::read_switch_pair ${scobj_hpath} + hsetprop ${scobj_hpath}/rough_100 write ${ns}::write_switch ${scobj_hpath} noResponse {11} + hsetprop ${scobj_hpath}/rough_100 noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/rough_100 check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/rough_100 control true + hsetprop ${scobj_hpath}/rough_100 data true + hsetprop ${scobj_hpath}/rough_100 mutable false + hsetprop ${scobj_hpath}/rough_100 nxsave true + hsetprop ${scobj_hpath}/rough_100 values in,out + hsetprop ${scobj_hpath}/rough_100 oldval UNKNOWN + hsetprop ${scobj_hpath}/rough_100 klass "collimator" + hsetprop ${scobj_hpath}/rough_100 nxalias "rough_100" + hsetprop ${scobj_hpath}/rough_100 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/rough_100 type "part" + + hfactory ${scobj_hpath}/rough_40 plain user text + hsetprop ${scobj_hpath}/rough_40 read ${ns}::getValue ${scobj_hpath} read_switch_pair {MG @IN[13], @IN[14]} + hsetprop ${scobj_hpath}/rough_40 read_switch_pair ${ns}::read_switch_pair ${scobj_hpath} + hsetprop ${scobj_hpath}/rough_40 write ${ns}::write_switch ${scobj_hpath} noResponse {10} + hsetprop ${scobj_hpath}/rough_40 noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/rough_40 check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/rough_40 control true + hsetprop ${scobj_hpath}/rough_40 data true + hsetprop ${scobj_hpath}/rough_40 mutable false + hsetprop ${scobj_hpath}/rough_40 nxsave true + hsetprop ${scobj_hpath}/rough_40 values in,out + hsetprop ${scobj_hpath}/rough_40 oldval UNKNOWN + hsetprop ${scobj_hpath}/rough_40 klass "collimator" + hsetprop ${scobj_hpath}/rough_40 nxalias "rough_40" + hsetprop ${scobj_hpath}/rough_40 sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/rough_40 type "part" + + hsetprop ${scobj_hpath} data "true" + hsetprop ${scobj_hpath} nxsave "true" + + if {[SplitReply [motor_simulation]]=="false"} { + ${sct_controller} poll ${scobj_hpath}/fast_shutter 1 + ${sct_controller} poll ${scobj_hpath}/rough_100 1 + ${sct_controller} poll ${scobj_hpath}/rough_40 1 + ${sct_controller} write ${scobj_hpath}/rough_100 + ${sct_controller} write ${scobj_hpath}/rough_40 + } + hsetprop ${scobj_hpath} klass collimator +# hook code starts +# hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} "in ${ns}::mk_sct_shutters" +} + +namespace eval ::scobj::shutters { + namespace export debug_log + namespace export mk_sct_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} + } + } + ${ns}::debug_log 1 "mk_sct_shutters sct_${name} ${name}" + ${ns}::mk_sct_shutters sct_${name} ${name} + close ${fd} +} + +puts stdout "file evaluation of sct_shutters.tcl" +::scobj::shutters::debug_log 1 "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 new file mode 100644 index 00000000..6aa06101 --- /dev/null +++ b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl @@ -0,0 +1,208 @@ +# Generated driver for tank +# vim: tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::tank { + set debug_threshold 0 +} + +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} + } +} + +# 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 +} + +# 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} +} + +# 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" +} + +# 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]" + } +# hook code starts + if { [string equal -nocase -length 1 "${data}" "?"] } { + sct geterror "Galil error in: '${data}'" + } else { + set data_list [split [string trim "${data}"]] + if { [llength ${data_list}] > 1 && [lindex ${data_list} end] == ":" } { + set data_list [lrange ${data_list} 0 0] + } + if { [llength ${data_list}] == 1 } { + set left [expr [lindex ${data_list} 0]] + if { ${left} == 1 } { # open + set data "open" + } else { # closed + set data "closed" + } + } else { + sct geterror "Syntax error in: '${data}'=>'${data_list}'" + } + } +# 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 + } + return ${nextState} +} + +# 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}" + debug_log 1 "setValue sct send ${cmd}" + sct send "${cmd}" + return ${nextState} +} + +proc ::scobj::tank::mk_sct_tank { sct_controller name } { + debug_log 1 "mk_sct_tank for ${name}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass instrument + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + + hfactory ${scobj_hpath}/limits plain spy none + + hfactory ${scobj_hpath}/limits/forward plain user text + hsetprop ${scobj_hpath}/limits/forward read ${ns}::getValue ${scobj_hpath} read_switch {MG _LFH} + hsetprop ${scobj_hpath}/limits/forward read_switch ${ns}::read_switch ${scobj_hpath} + hsetprop ${scobj_hpath}/limits/forward control true + hsetprop ${scobj_hpath}/limits/forward data true + hsetprop ${scobj_hpath}/limits/forward mutable false + hsetprop ${scobj_hpath}/limits/forward nxsave true + hsetprop ${scobj_hpath}/limits/forward oldval UNKNOWN + + hfactory ${scobj_hpath}/limits/reverse plain user text + hsetprop ${scobj_hpath}/limits/reverse read ${ns}::getValue ${scobj_hpath} read_switch {MG _LRH} + hsetprop ${scobj_hpath}/limits/reverse read_switch ${ns}::read_switch ${scobj_hpath} + hsetprop ${scobj_hpath}/limits/reverse control true + hsetprop ${scobj_hpath}/limits/reverse data true + hsetprop ${scobj_hpath}/limits/reverse mutable false + hsetprop ${scobj_hpath}/limits/reverse nxsave true + hsetprop ${scobj_hpath}/limits/reverse oldval UNKNOWN + + if {[SplitReply [motor_simulation]]=="false"} { + ${sct_controller} poll ${scobj_hpath}/limits/forward 1 + ${sct_controller} poll ${scobj_hpath}/limits/reverse 1 + } + + hfactory ${scobj_hpath}/switches plain spy none + + hfactory ${scobj_hpath}/switches/forward plain user text + hsetprop ${scobj_hpath}/switches/forward read ${ns}::getValue ${scobj_hpath} read_switch {MG @IN[5]} + hsetprop ${scobj_hpath}/switches/forward read_switch ${ns}::read_switch ${scobj_hpath} + hsetprop ${scobj_hpath}/switches/forward control true + hsetprop ${scobj_hpath}/switches/forward data true + hsetprop ${scobj_hpath}/switches/forward mutable false + hsetprop ${scobj_hpath}/switches/forward nxsave true + hsetprop ${scobj_hpath}/switches/forward oldval UNKNOWN + + hfactory ${scobj_hpath}/switches/reverse plain user text + hsetprop ${scobj_hpath}/switches/reverse read ${ns}::getValue ${scobj_hpath} read_switch {MG @IN[6]} + hsetprop ${scobj_hpath}/switches/reverse read_switch ${ns}::read_switch ${scobj_hpath} + hsetprop ${scobj_hpath}/switches/reverse control true + hsetprop ${scobj_hpath}/switches/reverse data true + hsetprop ${scobj_hpath}/switches/reverse mutable false + hsetprop ${scobj_hpath}/switches/reverse nxsave true + hsetprop ${scobj_hpath}/switches/reverse oldval UNKNOWN + + if {[SplitReply [motor_simulation]]=="false"} { + ${sct_controller} poll ${scobj_hpath}/switches/forward 1 + ${sct_controller} poll ${scobj_hpath}/switches/reverse 1 + } + hsetprop ${scobj_hpath} klass instrument +# hook code starts +# hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} "in ${ns}::mk_sct_tank" +} + +namespace eval ::scobj::tank { + namespace export debug_log + namespace export mk_sct_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} + } + } + ${ns}::debug_log 1 "mk_sct_tank sct_${name} ${name}" + ${ns}::mk_sct_tank sct_${name} ${name} + close ${fd} +} + +puts stdout "file evaluation of sct_tank.tcl" +::scobj::tank::debug_log 1 "file evaluation of sct_tank.tcl" diff --git a/site_ansto/instrument/bilby/config/motors/shutters.sct b/site_ansto/instrument/bilby/config/motors/shutters.sct new file mode 100644 index 00000000..d1f99bba --- /dev/null +++ b/site_ansto/instrument/bilby/config/motors/shutters.sct @@ -0,0 +1,93 @@ +# +# Simple driver generator for the non-motor galil controls on mc4 +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +# +driver shutters = { + usecreatenode = false + vendor = galil; device = mc4; protocol = dmc2280; + class = collimator + simulation_group = motor_simulation +# +# Unnamed group has variables at device level +# +# +# The named group is at the device level, variables below that +# + group = { + type = text + priv = user + group_property 'data' = 'true' + group_property 'nxsave' = 'true' + property 'type' = 'part' + property 'klass' = 'collimator' + property 'sdsinfo' = '::nexus::scobj::sdsinfo' + var fast_shutter = { + readable = 1 + read_command = 'MG @IN[5], @IN[6]' + read_function = read_switch_pair + property 'nxalias' = 'fast_shutter' + } + var rough_40 = { + readable = 1; + read_function = read_switch_pair; + read_command = 'MG @IN[13], @IN[14]' + writeable = 1 + write_function = write_switch; + write_command = '10' + allowed = 'in,out' + property 'nxalias' = 'rough_40' + } + var rough_100 = { + readable = 1; + read_function = read_switch_pair; + read_command = 'MG @IN[15], @IN[16]' + writeable = 1 + write_function = write_switch; + write_command = '11' + allowed = 'in,out' + property 'nxalias' = 'rough_100' + } + }; + +# +# Code lines start with '@' which is stripped before being emitted +# The code is emitted at the appropriate place in the given function +# + code read_function read_switch_pair = { +@ if { [string equal -nocase -length 1 "${data}" "?"] } { +@ sct geterror "Galil error in: '${data}'" +@ } else { +@ set data_list [split [string trim "${data}"]] +@ if { [llength ${data_list}] > 2 && [lindex ${data_list} end] == ":" } { +@ set data_list [lrange ${data_list} 0 1] +@ } +@ if { [llength ${data_list}] == 2 } { +@ set left [expr [lindex ${data_list} 0]] +@ set right [expr [lindex ${data_list} 1]] +@ if { ${left} == 1 && ${right} == 0 } { # open +@ set data "out" +@ } elseif { ${left} == 0 && ${right} == 1 } { # closed +@ set data "in" +@ } else { # indeterminate +@ set data "moving" +@ } +@ } else { +@ sct geterror "Syntax error in: '${data}'=>'${data_list}'" +@ } +@ } + } + code write_function write_switch = { +@ if { [string equal -nocase -length 2 "${par}" "in"] } { +@ set cmd "SB${cmd_str}" +@ } elseif { [string equal -nocase -length 2 "${par}" "out"] } { +@ set cmd "CB${cmd_str}" +@ } else { +@ sct geterror "Value error: '${par}' not in ('in', 'out')" +@ } + } +# +# This code is after database creation +# + code mkDriver = { + } +}; diff --git a/site_ansto/instrument/bilby/config/motors/tank.sct b/site_ansto/instrument/bilby/config/motors/tank.sct new file mode 100644 index 00000000..b22d752f --- /dev/null +++ b/site_ansto/instrument/bilby/config/motors/tank.sct @@ -0,0 +1,70 @@ +# +# Simple driver generator for the non-motor galil controls on mc8 +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +# +driver tank = { + usecreatenode = false + vendor = galil; device = mc8; protocol = dmc2280; + class = instrument + simulation_group = motor_simulation +# +# Unnamed group has variables at device level +# +# +# The named group is at the device level, variables below that +# + group switches = { + type = text; + priv = user; + readable = 1; + read_function = read_switch; + var forward = { + read_command = 'MG @IN[5]' + } + var reverse = { + read_command = 'MG @IN[6]' + } + }; + group limits = { + type = text; + priv = user; + readable = 1; + read_function = read_switch; + var forward = { + read_command = 'MG _LFH' + } + var reverse = { + read_command = 'MG _LRH' + } + }; + +# +# Code lines start with '@' which is stripped before being emitted +# The code is emitted at the appropriate place in the given function +# + code read_function read_switch = { +@ if { [string equal -nocase -length 1 "${data}" "?"] } { +@ sct geterror "Galil error in: '${data}'" +@ } else { +@ set data_list [split [string trim "${data}"]] +@ if { [llength ${data_list}] > 1 && [lindex ${data_list} end] == ":" } { +@ set data_list [lrange ${data_list} 0 0] +@ } +@ if { [llength ${data_list}] == 1 } { +@ set left [expr [lindex ${data_list} 0]] +@ if { ${left} == 1 } { # open +@ set data "open" +@ } else { # closed +@ set data "closed" +@ } +@ } else { +@ sct geterror "Syntax error in: '${data}'=>'${data_list}'" +@ } +@ } + } +# +# This code is after database creation +# + code mkDriver = { + } +}; diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 7db82017..1d03a201 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -768,6 +768,10 @@ def put_write_function(MyDriver, func): 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}'] @@ -800,6 +804,10 @@ def put_fetch_function(MyDriver, func): 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}'] @@ -825,10 +833,10 @@ def put_read_function(MyDriver, func): 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] 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}'] diff --git a/statistics.c b/statistics.c index 406be5a4..da2a622d 100644 --- a/statistics.c +++ b/statistics.c @@ -58,7 +58,7 @@ int StatisticsCommand(SConnection * con, SicsInterp * pSics, void *pData, gettimeofday(&now, 0); dif = timeFloat(timeDif(lastStat, now)); - SCPrintf(con, eLog, "calls/s time[%] full[%] mean[ms] command"); + SCPrintf(con, eLog, "calls/s time[%%] full[%%] mean[ms] command"); SCPrintf(con, eLog, "----------------------------------------------"); for (p = list; p != NULL; p = p->next) { if (dif > 0) {