diff --git a/asyncprotocol.c b/asyncprotocol.c index 9fcf6827..fc243d1a 100644 --- a/asyncprotocol.c +++ b/asyncprotocol.c @@ -269,17 +269,17 @@ int AsyncProtocolAction(SConnection * pCon, SicsInterp * pSics, SCWrite(pCon, line, eValue); } return 1; + } else if (strcasecmp(argv[1], "list") == 0) { + int ac = 2; + char *av[3] = { argv[0], 0, 0 }; + av[1] = "sendterminator"; + AsyncProtocolAction(pCon, pSics, pData, ac, av); + av[1] = "replyterminator"; + AsyncProtocolAction(pCon, pSics, pData, ac, av); + return 1; } - } else if (strcasecmp(argv[1], "list") == 0) { - int ac = 2; - char *av[3] = { argv[0], 0, 0 }; - av[1] = "sendterminator"; - AsyncProtocolAction(pCon, pSics, pData, ac, av); - av[1] = "replyterminator"; - AsyncProtocolAction(pCon, pSics, pData, ac, av); - return 1; - } /* handle any other actions here */ + } return AsyncProtocolNoAction(pCon, pSics, pData, argc, argv); } diff --git a/asyncqueue.c b/asyncqueue.c index 20814358..1d1359bd 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -67,6 +67,8 @@ struct __AsyncQueue { mkChannel *pSock; /* socket address */ AsyncState state; /* Queue Connection State */ pAsyncProtocol protocol; + char *noreply_text; + int noreply_len; void *context; /**< opaque caller queue context */ }; @@ -374,6 +376,10 @@ static int StartCommand(pAsyncQueue self) /* * Handle case of no response expected */ + if (myCmd->tran->inp_len == 0 || myCmd->tran->inp_buf == NULL) { + myCmd->tran->txn_status = ATX_COMPLETE; + return PopCommand(self); + } if (iRet > 0) if (myCmd->tran->txn_status == ATX_COMPLETE) return PopCommand(self); @@ -634,6 +640,23 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit, return NULL; } memset(myTxn, 0, sizeof(AsyncTxn)); + if (unit->queue->noreply_text) { + if (cmd_len > unit->queue->noreply_len + && strncasecmp(&command[cmd_len - unit->queue->noreply_len], + unit->queue->noreply_text, unit->queue->noreply_len) == 0) { + rsp_len = 0; + cmd_len -= unit->queue->noreply_len; + } + } else { + if (cmd_len > 3 && strncmp(&command[cmd_len - 3], "{0}", 3) == 0) { + rsp_len = 0; + cmd_len -= 3; + } + else if (cmd_len > 11 && strncasecmp(&command[cmd_len - 11], "@@NOREPLY@@", 11) == 0) { + rsp_len = 0; + cmd_len -= 11; + } + } if (unit->queue->protocol->prepareTxn) { int iRet; iRet = @@ -1047,12 +1070,25 @@ int AsyncQueueAction(SConnection * pCon, SicsInterp * pSics, } return OKOK; } + if (strcasecmp(argv[1], "noreply") == 0) { + if (argc > 2) { + if (self->noreply_text) + free(self->noreply_text); + self->noreply_text = strdup(argv[2]); + self->noreply_len = strlen(argv[2]); + } else { + SCPrintf(pCon, eValue, "%s.noreply = %s", argv[0], self->noreply_text); + } + return OKOK; + } if (strcasecmp(argv[1], "list") == 0) { SCPrintf(pCon, eValue, "%s.delay = %d", argv[0], self->iDelay); SCPrintf(pCon, eValue, "%s.timeout = %d", argv[0], self->timeout); SCPrintf(pCon, eValue, "%s.retries = %d", argv[0], self->retries); SCPrintf(pCon, eValue, "%s.translate = %d", argv[0], self->translate); SCPrintf(pCon, eValue, "%s.trace = %d", argv[0], self->trace); + if (self->noreply_text) + SCPrintf(pCon, eValue, "%s.noreply = %s", argv[0], self->noreply_text); return OKOK; } } diff --git a/site_ansto/hardsup/sct_asyncqueue.c b/site_ansto/hardsup/sct_asyncqueue.c index e39a2436..1fec9251 100644 --- a/site_ansto/hardsup/sct_asyncqueue.c +++ b/site_ansto/hardsup/sct_asyncqueue.c @@ -127,6 +127,7 @@ static void SCAQTransact(Ascon *a) AsyncUnit *unit = NULL; const char *command = GetCharArray(a->wrBuffer); int cmd_len = GetDynStringLength(a->wrBuffer); + int rsp_len = 1024; pp = (pPrivate) a->private; assert(pp); unit = pp->unit; @@ -134,7 +135,15 @@ static void SCAQTransact(Ascon *a) txn = &pp->txn; txn->transWait = 1; DynStringClear(a->rdBuffer); - AsyncUnitSendTxn(unit, command, cmd_len, TransCallback, a, 1024); + if (cmd_len > 3 && strncmp(&command[cmd_len - 3], "{0}", 3) == 0) { + rsp_len = 0; + cmd_len -= 3; + } + else if (cmd_len > 11 && strncasecmp(&command[cmd_len - 11], "@@NOREPLY@@", 11) == 0) { + rsp_len = 0; + cmd_len -= 11; + } + AsyncUnitSendTxn(unit, command, cmd_len, TransCallback, a, rsp_len); } static int scaqaNullHandler(Ascon *a) diff --git a/site_ansto/instrument/TEST_SICS/fakeGalil/galilmotor.py b/site_ansto/instrument/TEST_SICS/fakeGalil/galilmotor.py index ce5f8c41..c6fb73f9 100644 --- a/site_ansto/instrument/TEST_SICS/fakeGalil/galilmotor.py +++ b/site_ansto/instrument/TEST_SICS/fakeGalil/galilmotor.py @@ -236,6 +236,8 @@ class GalilMotor(object): self.accel = max(1, abs(int(arg))) elif cmd == "DC": self.decel = max(1, abs(int(arg))) + elif cmd == "DP": + self.currentSteps = int(arg) else: print "Unknown assignment", cmd, arg diff --git a/site_ansto/instrument/bilby/config/chopper/sct_astrium_chopper.tcl b/site_ansto/instrument/bilby/config/chopper/sct_astrium_chopper.tcl index 9ccd49a5..e537f5bb 100644 --- a/site_ansto/instrument/bilby/config/chopper/sct_astrium_chopper.tcl +++ b/site_ansto/instrument/bilby/config/chopper/sct_astrium_chopper.tcl @@ -132,7 +132,7 @@ proc ::scobj::astrium_chopper::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -200,7 +200,7 @@ proc ::scobj::astrium_chopper::readState {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -567,14 +567,17 @@ clientput "file evaluation of sct_astrium_chopper.tcl" proc ::scobj::astrium_chopper::read_config {} { set catch_status [ catch { set ns "::scobj::astrium_chopper" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -583,31 +586,37 @@ proc ::scobj::astrium_chopper::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "astrium_chopper"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [chopper_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[chopper_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [chopper_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[chopper_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_astrium_chopper ${name} ${IP} ${PORT} + } else { add_astrium_chopper ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl index 6dd435fa..64fe832b 100644 --- a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl +++ b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl @@ -127,7 +127,7 @@ proc ::scobj::shutters::read_switch_pair {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -305,14 +305,17 @@ clientput "file evaluation of sct_shutters.tcl" proc ::scobj::shutters::read_config {} { set catch_status [ catch { set ns "::scobj::shutters" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -321,31 +324,37 @@ proc ::scobj::shutters::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "shutters"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [motor_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[motor_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [motor_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[motor_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_shutters ${name} ${IP} ${PORT} + } else { add_shutters ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/bilby/config/motors/sct_tank.tcl b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl index 5ae2c9b9..08f2bd51 100644 --- a/site_ansto/instrument/bilby/config/motors/sct_tank.tcl +++ b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl @@ -122,7 +122,7 @@ proc ::scobj::tank::read_pos {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -171,7 +171,7 @@ proc ::scobj::tank::read_switch {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -340,14 +340,17 @@ clientput "file evaluation of sct_tank.tcl" proc ::scobj::tank::read_config {} { set catch_status [ catch { set ns "::scobj::tank" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -356,31 +359,37 @@ proc ::scobj::tank::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "tank"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [motor_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[motor_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [motor_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[motor_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_tank ${name} ${IP} ${PORT} + } else { add_tank ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/agilent_33220A.sct b/site_ansto/instrument/config/environment/agilent_33220A.sct new file mode 100644 index 00000000..b731a821 --- /dev/null +++ b/site_ansto/instrument/config/environment/agilent_33220A.sct @@ -0,0 +1,9 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver agilent_33220A = { + protocol = std + class = environment + simulation_group = environment_simulation + code mkDriver = {%% + makesctcontroller $name $ip $port + %%} +} diff --git a/site_ansto/instrument/config/environment/keithley_m2700.sct b/site_ansto/instrument/config/environment/keithley_m2700.sct new file mode 100644 index 00000000..48ea8d2a --- /dev/null +++ b/site_ansto/instrument/config/environment/keithley_m2700.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver keithley_m2700 = { + protocol = std + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'id datype tol' + make_args = 'id datype tol' + code mkDriver = {%% + mk_sct_keithley_2700 $sct_controller environment $name $tol $id $datype + %%} +} diff --git a/site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl b/site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl index 28ca6165..4f5c187a 100644 --- a/site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl +++ b/site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl @@ -517,8 +517,8 @@ proc ::scobj::oxford_labview::sics_log {debug_level debug_string} { } catch_message ] } -clientput "file evaluation of sct_lakeshore_336.tcl" -::scobj::lakeshore_336::sics_log 9 "file evaluation of sct_lakeshore_336.tcl" +clientput "file evaluation of sct_oxford_labview.tcl" +::scobj::oxford_labview::sics_log 9 "file evaluation of sct_oxford_labview.tcl" proc ::scobj::oxford_labview::read_config {} { set catch_status [ catch { @@ -538,7 +538,9 @@ proc ::scobj::oxford_labview::read_config {} { if { !([dict exists $v "driver"]) } { continue } - if { [string equal -nocase [dict get $v "driver"] "lakeshore_336"] } { + if { [string equal -nocase [dict get $v "driver"] "oxford_labview"] } { + set driver [dict get $v driver] + ${ns}::sics_log 9 "Found ${name}: $driver" if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" @@ -550,6 +552,7 @@ proc ::scobj::oxford_labview::read_config {} { set asyncprotocol [dict get $v "asyncprotocol"] } else { set asyncprotocol ${name}_protocol + ${ns}::sics_log 9 "${name}:${driver}: MakeAsyncProtocol ${asyncprotocol}" MakeAsyncProtocol ${asyncprotocol} if { [dict exists $v "terminator"] } { ${asyncprotocol} sendterminator "[dict get $v "terminator"]" @@ -559,6 +562,7 @@ proc ::scobj::oxford_labview::read_config {} { set asyncqueue ${name}_queue set IP [dict get $v ip] set PORT [dict get $v port] + ${ns}::sics_log 9 "${name}:${driver}: MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT}" MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} if { [dict exists $v "timeout"] } { ${asyncqueue} timeout "[dict get $v "timeout"]" @@ -573,6 +577,7 @@ proc ::scobj::oxford_labview::read_config {} { error "Missing configuration value $arg" } } + ${ns}::sics_log 9 "add_oxford_labview ${name} aqadapter ${asyncqueue} {*}$arg_list" add_oxford_labview ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl new file mode 100644 index 00000000..1cab0f7e --- /dev/null +++ b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl @@ -0,0 +1,605 @@ +# Generated driver for tsi_smc +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::tsi_smc { + set debug_threshold 5 +} + +proc ::scobj::tsi_smc::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/tsi_smc_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::tsi_smc::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::tsi_smc::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::tsi_smc::${debug_string}" + } + } catch_message ] +} + +# checklimits function for driveable interface +proc ::scobj::tsi_smc::checklimits {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "checklimits 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] + } +# checklimits hook code goes here + if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { + sct driving 0 + error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" + } + return OK + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# check function for hset change +proc ::scobj::tsi_smc::checkrange {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 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] + } +# checkrange hook code goes here + if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { + error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" + } + return OK + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# checkstatus function for driveable interface +proc ::scobj::tsi_smc::checkstatus {tc_root} { + set catch_status [ catch { +# checkstatus hook code goes here + if {[sct driving]} { + set sp "[sct target]" + set pv "[hval ${tc_root}/[sct driveable]]" + if { abs(${pv} - ${sp}) <= [sct tolerance] } { + if { [hpropexists [sct] settle_time] } { + if { [hpropexists [sct] settle_time_start] } { + if { [sct utime] - [sct settle_time_start] >= [sct settle_time]} { + sct driving 0 + return "idle" + } + return "busy" + } else { + sct utime settle_time_start + return "busy" + } + } + sct driving 0 + return "idle" + } + if { [hpropexists [sct] settle_time_start] } { + hdelprop [sct] settle_time_start + } + return "busy" + } else { + return "idle" + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to request the read of a parameter on a device +proc ::scobj::tsi_smc::getValue {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set cmd "${cmd_str}" +# getValue hook code goes here + debug_log ${tc_root} 1 "getValue sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# halt function for driveable interface +proc ::scobj::tsi_smc::halt {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "halt tc_root=${tc_root} sct=[sct] driving=[sct driving]" + ### TODO hset [sct] [hval [sct]] +# halt hook code goes here + sct driving 0 + return "idle" + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to check the write parameter on a device +proc ::scobj::tsi_smc::noResponse {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" +# noResponse hook code goes here + return "idle" + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to parse the read of a parameter on a device +proc ::scobj::tsi_smc::rdValue {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "rdValue 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]" + } +# rdValue hook code starts + if {[basename [sct]] == "G"} { + set value [expr {[string range ${data} 1 8]}] + set value [expr {${value} * 2.5177E+02 - 1.6116E+01}] + if {[hpropexists [sct] offset]} { + set value [expr {${value} + [hgetpropval [sct] offset]}] + } + if {${value} != [hgetpropval ${tc_root}/value oldval]} { + debug_log ${tc_root} 1 "${tc_root}/value changed to new:${value}, from old:[hgetpropval ${tc_root}/value oldval]" + hupdate ${tc_root}/value ${value} + hsetprop ${tc_root}/value oldval ${value} + hsetprop ${tc_root}/value readtime [sct utime] + } + } + if {[basename [sct]] == "S"} { + set value [expr {[string range ${data} 11 17]}] + set value [expr {${value} * 2.5177E+02 - 1.6116E+01}] + if {${value} != [hgetpropval ${tc_root}/value oldval]} { + debug_log ${tc_root} 1 "${tc_root}/setpoint changed to new:${value}, from old:[hgetpropval ${tc_root}/setpoint oldval]" + hupdate ${tc_root}/setpoint ${value} + hsetprop ${tc_root}/setpoint oldval ${value} + hsetprop ${tc_root}/setpoint readtime [sct utime] + } + } +# rdValue hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 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::tsi_smc::setGauss {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "setGauss 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}" +# setGauss hook code starts + set amps [expr {(${par} + 1.6116E+01) / 2.5177E+02}] + hset ${tc_root}/b/Lower ${amps} +# setGauss hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log ${tc_root} 1 "setGauss 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::tsi_smc::setValue {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 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}" +# setValue hook code goes here + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log ${tc_root} 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::tsi_smc::mkDriver { sct_controller name id } { + ::scobj::tsi_smc::sics_log 9 "::scobj::tsi_smc::mkDriver ${sct_controller} ${name} ${id}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + + hfactory ${scobj_hpath}/setpoint plain user float + hsetprop ${scobj_hpath}/setpoint write ${ns}::setGauss ${scobj_hpath} noResponse {} + hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint driving 0 + hsetprop ${scobj_hpath}/setpoint checklimits ${ns}::checklimits ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint checkstatus ${ns}::checkstatus ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint halt ${ns}::halt ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint driveable value + hsetprop ${scobj_hpath}/setpoint control true + hsetprop ${scobj_hpath}/setpoint data true + hsetprop ${scobj_hpath}/setpoint mutable true + hsetprop ${scobj_hpath}/setpoint nxsave true + hsetprop ${scobj_hpath}/setpoint lowerlimit 0 + hsetprop ${scobj_hpath}/setpoint upperlimit 500.0 + hsetprop ${scobj_hpath}/setpoint tolerance 10 + hsetprop ${scobj_hpath}/setpoint permlink data_set "B[format "%02d" ${id}]SP01" + hsetprop ${scobj_hpath}/setpoint @description "B[format "%02d" ${id}]SP01" + hsetprop ${scobj_hpath}/setpoint oldval 0.0 + hsetprop ${scobj_hpath}/setpoint klass "sensor" + hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/setpoint settle_time "5" + hsetprop ${scobj_hpath}/setpoint type "drivable" + hsetprop ${scobj_hpath}/setpoint units "G" + hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint" + + hfactory ${scobj_hpath}/value plain user float + hsetprop ${scobj_hpath}/value control true + hsetprop ${scobj_hpath}/value data true + hsetprop ${scobj_hpath}/value mutable true + hsetprop ${scobj_hpath}/value nxsave true + hsetprop ${scobj_hpath}/value permlink data_set "B[format "%02d" ${id}]S01" + hsetprop ${scobj_hpath}/value @description "B[format "%02d" ${id}]S01" + hsetprop ${scobj_hpath}/value oldval 0.0 + hsetprop ${scobj_hpath}/value klass "NXsensor" + hsetprop ${scobj_hpath}/value sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/value type "part" + hsetprop ${scobj_hpath}/value units "G" + hsetprop ${scobj_hpath}/value nxalias "${name}_value" + + hsetprop ${scobj_hpath} control "true" + hsetprop ${scobj_hpath} data "true" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} write ${scobj_hpath}/setpoint + } else { + ::scobj::tsi_smc::sics_log 9 "[environment_simulation] => No poll/write for tsi_smc" + } + + hfactory ${scobj_hpath}/a plain spy none + + hfactory ${scobj_hpath}/a/G plain user text + hsetprop ${scobj_hpath}/a/G read ${ns}::getValue ${scobj_hpath} rdValue {G} + hsetprop ${scobj_hpath}/a/G rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/a/G control false + hsetprop ${scobj_hpath}/a/G data false + hsetprop ${scobj_hpath}/a/G mutable false + hsetprop ${scobj_hpath}/a/G nxsave true + hsetprop ${scobj_hpath}/a/G oldval UNKNOWN + hsetprop ${scobj_hpath}/a/G offset "16.116" + hsetprop ${scobj_hpath}/a/G sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/a/G type "part" + hsetprop ${scobj_hpath}/a/G nxalias "${name}_a_G" + + hfactory ${scobj_hpath}/a/J plain user text + hsetprop ${scobj_hpath}/a/J read ${ns}::getValue ${scobj_hpath} rdValue {J} + hsetprop ${scobj_hpath}/a/J rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/a/J control false + hsetprop ${scobj_hpath}/a/J data false + hsetprop ${scobj_hpath}/a/J mutable false + hsetprop ${scobj_hpath}/a/J nxsave true + hsetprop ${scobj_hpath}/a/J oldval UNKNOWN + hsetprop ${scobj_hpath}/a/J sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/a/J type "part" + hsetprop ${scobj_hpath}/a/J nxalias "${name}_a_J" + + hfactory ${scobj_hpath}/a/K plain user text + hsetprop ${scobj_hpath}/a/K read ${ns}::getValue ${scobj_hpath} rdValue {K} + hsetprop ${scobj_hpath}/a/K rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/a/K control false + hsetprop ${scobj_hpath}/a/K data false + hsetprop ${scobj_hpath}/a/K mutable false + hsetprop ${scobj_hpath}/a/K nxsave true + hsetprop ${scobj_hpath}/a/K oldval UNKNOWN + hsetprop ${scobj_hpath}/a/K sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/a/K type "part" + hsetprop ${scobj_hpath}/a/K nxalias "${name}_a_K" + + hfactory ${scobj_hpath}/a/N plain user text + hsetprop ${scobj_hpath}/a/N read ${ns}::getValue ${scobj_hpath} rdValue {N} + hsetprop ${scobj_hpath}/a/N rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/a/N control false + hsetprop ${scobj_hpath}/a/N data false + hsetprop ${scobj_hpath}/a/N mutable false + hsetprop ${scobj_hpath}/a/N nxsave true + hsetprop ${scobj_hpath}/a/N oldval UNKNOWN + hsetprop ${scobj_hpath}/a/N sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/a/N type "part" + hsetprop ${scobj_hpath}/a/N nxalias "${name}_a_N" + + hfactory ${scobj_hpath}/a/O plain user text + hsetprop ${scobj_hpath}/a/O read ${ns}::getValue ${scobj_hpath} rdValue {O} + hsetprop ${scobj_hpath}/a/O rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/a/O control false + hsetprop ${scobj_hpath}/a/O data false + hsetprop ${scobj_hpath}/a/O mutable false + hsetprop ${scobj_hpath}/a/O nxsave true + hsetprop ${scobj_hpath}/a/O oldval UNKNOWN + hsetprop ${scobj_hpath}/a/O sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/a/O type "part" + hsetprop ${scobj_hpath}/a/O nxalias "${name}_a_O" + + hfactory ${scobj_hpath}/a/S plain user text + hsetprop ${scobj_hpath}/a/S read ${ns}::getValue ${scobj_hpath} rdValue {S} + hsetprop ${scobj_hpath}/a/S rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/a/S control false + hsetprop ${scobj_hpath}/a/S data false + hsetprop ${scobj_hpath}/a/S mutable false + hsetprop ${scobj_hpath}/a/S nxsave true + hsetprop ${scobj_hpath}/a/S oldval UNKNOWN + hsetprop ${scobj_hpath}/a/S sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/a/S type "part" + hsetprop ${scobj_hpath}/a/S nxalias "${name}_a_S" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/a/G 1 + ${sct_controller} poll ${scobj_hpath}/a/J 1 + ${sct_controller} poll ${scobj_hpath}/a/K 1 + ${sct_controller} poll ${scobj_hpath}/a/N 1 + ${sct_controller} poll ${scobj_hpath}/a/O 1 + ${sct_controller} poll ${scobj_hpath}/a/S 1 + } else { + ::scobj::tsi_smc::sics_log 9 "[environment_simulation] => No poll/write for tsi_smc" + } + + hfactory ${scobj_hpath}/b plain spy none + + hfactory ${scobj_hpath}/b/Lower plain user float + hsetprop ${scobj_hpath}/b/Lower write ${ns}::setValue ${scobj_hpath} noResponse {L} + hsetprop ${scobj_hpath}/b/Lower noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Lower check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Lower control true + hsetprop ${scobj_hpath}/b/Lower data true + hsetprop ${scobj_hpath}/b/Lower mutable false + hsetprop ${scobj_hpath}/b/Lower nxsave true + hsetprop ${scobj_hpath}/b/Lower lowerlimit 0 + hsetprop ${scobj_hpath}/b/Lower upperlimit 2 + hsetprop ${scobj_hpath}/b/Lower oldval 0.0 + hsetprop ${scobj_hpath}/b/Lower sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/b/Lower type "part" + hsetprop ${scobj_hpath}/b/Lower units "A" + hsetprop ${scobj_hpath}/b/Lower nxalias "${name}_b_Lower" + + hfactory ${scobj_hpath}/b/Pause plain user int + hsetprop ${scobj_hpath}/b/Pause write ${ns}::setValue ${scobj_hpath} noResponse {P} + hsetprop ${scobj_hpath}/b/Pause noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Pause check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Pause control true + hsetprop ${scobj_hpath}/b/Pause data true + hsetprop ${scobj_hpath}/b/Pause mutable false + hsetprop ${scobj_hpath}/b/Pause nxsave true + hsetprop ${scobj_hpath}/b/Pause lowerlimit 0 + hsetprop ${scobj_hpath}/b/Pause upperlimit 1 + hsetprop ${scobj_hpath}/b/Pause values 0,1 + hsetprop ${scobj_hpath}/b/Pause oldval 0 + hsetprop ${scobj_hpath}/b/Pause sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/b/Pause type "part" + hsetprop ${scobj_hpath}/b/Pause nxalias "${name}_b_Pause" + + hfactory ${scobj_hpath}/b/Ramp plain user int + hsetprop ${scobj_hpath}/b/Ramp write ${ns}::setValue ${scobj_hpath} noResponse {R} + hsetprop ${scobj_hpath}/b/Ramp noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Ramp check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Ramp control true + hsetprop ${scobj_hpath}/b/Ramp data true + hsetprop ${scobj_hpath}/b/Ramp mutable false + hsetprop ${scobj_hpath}/b/Ramp nxsave true + hsetprop ${scobj_hpath}/b/Ramp lowerlimit 0 + hsetprop ${scobj_hpath}/b/Ramp upperlimit 1 + hsetprop ${scobj_hpath}/b/Ramp values 0,1 + hsetprop ${scobj_hpath}/b/Ramp oldval 0 + hsetprop ${scobj_hpath}/b/Ramp sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/b/Ramp type "part" + hsetprop ${scobj_hpath}/b/Ramp nxalias "${name}_b_Ramp" + + hfactory ${scobj_hpath}/b/Rate plain user float + hsetprop ${scobj_hpath}/b/Rate write ${ns}::setValue ${scobj_hpath} noResponse {A} + hsetprop ${scobj_hpath}/b/Rate noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Rate check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/b/Rate control true + hsetprop ${scobj_hpath}/b/Rate data true + hsetprop ${scobj_hpath}/b/Rate mutable false + hsetprop ${scobj_hpath}/b/Rate nxsave true + hsetprop ${scobj_hpath}/b/Rate oldval 0.0 + hsetprop ${scobj_hpath}/b/Rate sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/b/Rate type "part" + hsetprop ${scobj_hpath}/b/Rate nxalias "${name}_b_Rate" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} write ${scobj_hpath}/b/Lower + ${sct_controller} write ${scobj_hpath}/b/Pause + ${sct_controller} write ${scobj_hpath}/b/Ramp + ${sct_controller} write ${scobj_hpath}/b/Rate + } else { + ::scobj::tsi_smc::sics_log 9 "[environment_simulation] => No poll/write for tsi_smc" + } + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_setpoint ${scobj_hpath}/setpoint ${scobj_hpath}/value ${sct_controller} + } +# mkDriver hook code goes here + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::tsi_smc { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_tsi_smc {name IP port {id 1}} { + set catch_status [ catch { + ::scobj::tsi_smc::sics_log 9 "add_tsi_smc ${name} ${IP} ${port} ${id}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::tsi_smc::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::tsi_smc::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::tsi_smc::sics_log 9 "[environment_simulation] => No sctcontroller for tsi_smc" + } + ::scobj::tsi_smc::sics_log 1 "::scobj::tsi_smc::mkDriver sct_${name} ${name} ${id}" + ::scobj::tsi_smc::mkDriver sct_${name} ${name} ${id} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_tsi_smc.tcl" +::scobj::tsi_smc::sics_log 9 "file evaluation of sct_tsi_smc.tcl" + +proc ::scobj::tsi_smc::read_config {} { + set catch_status [ catch { + set ns "::scobj::tsi_smc" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "tsi_smc"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_tsi_smc ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_tsi_smc ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::tsi_smc::read_config +} else { + ::scobj::tsi_smc::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct new file mode 100644 index 00000000..704f6d83 --- /dev/null +++ b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct @@ -0,0 +1,86 @@ +# Script Context Driver for the Twickenham Scientific Instruments Superconducting Magnet Controller +driver tsi_smc = { + vendor = Twickenham_Scientific_Instruments; + device = Superconducting_Magnet_Controller; + protocol = std; + class = environment; simulation_group = environment_simulation; + add_args = '{id 1}'; + make_args = 'id'; + + group = { + priv = user; + type = float; + property 'units' = 'G'; + control = true; + data = true; + nxsave = true; + group_property 'data' = true + group_property 'control' = true + + var 'value' = {permlink = 'B.S01'; mutable = true; property klass = 'NXsensor'}; + var setpoint = { + permlink = 'B.SP01'; + writeable = 1; + write_function = setGauss; + lowerlimit = 0; upperlimit = 500.0; tolerance = 10; + property settle_time = 5; + mutable = true; + property klass = 'sensor'; + driveable = 'value'; + }; + }; + + group a = { + readable = 1; + priv = user; + type = text; + control = false; + data = false; + var G = { read_command = "G"; property offset = 16.116; }; + var J = { read_command = "J"; }; + var K = { read_command = "K"; }; + var N = { read_command = "N"; }; + var O = { read_command = "O"; }; + var S = { read_command = "S"; }; + }; + + group b = { + writeable = 1; + priv = user; + type = text; + var Rate = { type = float; write_command = "A"; }; + var Lower = { type = float; write_command = "L"; lowerlimit = 0; upperlimit = 2; property 'units' = "A"; }; + var Ramp = { type = int; write_command = "R"; allowed = "0,1"; lowerlimit = 0; upperlimit = 1; }; + var Pause = { type = int; write_command = "P"; allowed = "0,1"; lowerlimit = 0; upperlimit = 1; }; + }; + + code rdValue = {%% + if {[basename [sct]] == "G"} { + set value [expr {[string range ${data} 1 8]}] + set value [expr {${value} * 2.5177E+02 - 1.6116E+01}] + if {[hpropexists [sct] offset]} { + set value [expr {${value} + [hgetpropval [sct] offset]}] + } + if {${value} != [hgetpropval ${tc_root}/value oldval]} { + debug_log ${tc_root} 1 "${tc_root}/value changed to new:${value}, from old:[hgetpropval ${tc_root}/value oldval]" + hupdate ${tc_root}/value ${value} + hsetprop ${tc_root}/value oldval ${value} + hsetprop ${tc_root}/value readtime [sct utime] + } + } + if {[basename [sct]] == "S"} { + set value [expr {[string range ${data} 11 17]}] + set value [expr {${value} * 2.5177E+02 - 1.6116E+01}] + if {${value} != [hgetpropval ${tc_root}/value oldval]} { + debug_log ${tc_root} 1 "${tc_root}/setpoint changed to new:${value}, from old:[hgetpropval ${tc_root}/setpoint oldval]" + hupdate ${tc_root}/setpoint ${value} + hsetprop ${tc_root}/setpoint oldval ${value} + hsetprop ${tc_root}/setpoint readtime [sct utime] + } + } + %%} + code setGauss = {%% + set amps [expr {(${par} + 1.6116E+01) / 2.5177E+02}] + hset ${tc_root}/b/Lower ${amps} + %%} +}; diff --git a/site_ansto/instrument/config/environment/protekmm.sct b/site_ansto/instrument/config/environment/protekmm.sct new file mode 100644 index 00000000..e5e3e2f6 --- /dev/null +++ b/site_ansto/instrument/config/environment/protekmm.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver protekmm = { + protocol = protek608 + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'id datype' + make_args = 'id datype' + code mkDriver = {%% + MakeProtek $name $sct_controller $id $datype + %%} +} diff --git a/site_ansto/instrument/config/environment/sct_agilent_33220A.tcl b/site_ansto/instrument/config/environment/sct_agilent_33220A.tcl new file mode 100644 index 00000000..e0668a36 --- /dev/null +++ b/site_ansto/instrument/config/environment/sct_agilent_33220A.tcl @@ -0,0 +1,146 @@ +# Generated driver for agilent_33220A +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::agilent_33220A { + set debug_threshold 5 +} + +proc ::scobj::agilent_33220A::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/agilent_33220A_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::agilent_33220A::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::agilent_33220A::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::agilent_33220A::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::agilent_33220A::mkDriver { sct_controller name } { + ::scobj::agilent_33220A::sics_log 9 "::scobj::agilent_33220A::mkDriver for ${name}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + makesctcontroller $name $ip $port +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::agilent_33220A { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_agilent_33220A {name IP port} { + set catch_status [ catch { + ::scobj::agilent_33220A::sics_log 9 "add_agilent_33220A ${name} ${IP} ${port}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::agilent_33220A::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::agilent_33220A::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::agilent_33220A::sics_log 9 "[environment_simulation] => No sctcontroller for agilent_33220A" + } + ::scobj::agilent_33220A::sics_log 1 "::scobj::agilent_33220A::mkDriver sct_${name} ${name}" + ::scobj::agilent_33220A::mkDriver sct_${name} ${name} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_agilent_33220A.tcl" +::scobj::agilent_33220A::sics_log 9 "file evaluation of sct_agilent_33220A.tcl" + +proc ::scobj::agilent_33220A::read_config {} { + set catch_status [ catch { + set ns "::scobj::agilent_33220A" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "agilent_33220A"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_agilent_33220A ${name} ${IP} ${PORT} + } else { + add_agilent_33220A ${name} "aqadapter" ${asyncqueue} + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::agilent_33220A::read_config +} else { + ::scobj::agilent_33220A::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl b/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl index 32f05421..3dca8897 100644 --- a/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl +++ b/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl @@ -250,19 +250,19 @@ proc ::scobj::hiden_xcs::no_op {tc_root nextState cmd_str} { proc ::scobj::hiden_xcs::pid_flow {tc_root sp pv} { set catch_status [ catch { debug_log ${tc_root} 1 "pid_flow tc_root=${tc_root} sct=[sct] pv=${pv} sp=${sp}" - sct pid_error [expr ${sp} - ${pv}] - set p_value [expr [sct pid_pvalue] * [sct pid_error]] - set d_value [expr [sct pid_dvalue] * (${pv} - [sct oldval])] + sct pid_error [expr {${sp} - ${pv}}] + set p_value [expr {[sct pid_pvalue] * [sct pid_error]}] + set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}] sct pid_deriv [sct pid_error] - sct pid_integ [expr [sct pid_integ] + [sct pid_error]] + sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}] if { [sct pid_integ] > [sct pid_imax] } { sct pid_integ [sct pid_imax] } if { [sct pid_integ] < -[sct pid_imax] } { sct pid_integ -[sct pid_imax] } - set i_value [expr [sct pid_ivalue] * [sct pid_integ]] - set pid [expr ${p_value} + ${i_value} + ${d_value}] + set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] + set pid [expr {${p_value} + ${i_value} + ${d_value}}] # pid_flow hook code starts foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { if { !([hpropexists ${node} bias_flow] && [hgetpropval ${node} bias_flow] == ${pid}) } { @@ -285,19 +285,19 @@ proc ::scobj::hiden_xcs::pid_flow {tc_root sp pv} { proc ::scobj::hiden_xcs::pid_humidity {tc_root sp pv} { set catch_status [ catch { debug_log ${tc_root} 1 "pid_humidity tc_root=${tc_root} sct=[sct] pv=${pv} sp=${sp}" - sct pid_error [expr ${sp} - ${pv}] - set p_value [expr [sct pid_pvalue] * [sct pid_error]] - set d_value [expr [sct pid_dvalue] * (${pv} - [sct oldval])] + sct pid_error [expr {${sp} - ${pv}}] + set p_value [expr {[sct pid_pvalue] * [sct pid_error]}] + set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}] sct pid_deriv [sct pid_error] - sct pid_integ [expr [sct pid_integ] + [sct pid_error]] + sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}] if { [sct pid_integ] > [sct pid_imax] } { sct pid_integ [sct pid_imax] } if { [sct pid_integ] < -[sct pid_imax] } { sct pid_integ -[sct pid_imax] } - set i_value [expr [sct pid_ivalue] * [sct pid_integ]] - set pid [expr ${p_value} + ${i_value} + ${d_value}] + set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] + set pid [expr {${p_value} + ${i_value} + ${d_value}}] # pid_humidity hook code starts set sign 1 foreach node [list ${tc_root}/analog/sp1 ${tc_root}/analog/sp2] { @@ -339,7 +339,7 @@ proc ::scobj::hiden_xcs::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -389,7 +389,7 @@ proc ::scobj::hiden_xcs::read_all_data {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -430,7 +430,7 @@ proc ::scobj::hiden_xcs::read_digital {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -456,7 +456,7 @@ proc ::scobj::hiden_xcs::read_flow {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -507,7 +507,7 @@ proc ::scobj::hiden_xcs::read_sixteen {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -558,7 +558,7 @@ proc ::scobj::hiden_xcs::read_twelve {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -1050,7 +1050,6 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name id } { if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { ${sct_controller} poll ${scobj_hpath}/flow/sensor 1 ${sct_controller} write ${scobj_hpath}/flow/setpoint - ansto_makesctdrive ${name}_flow_setpoint ${scobj_hpath}/flow/setpoint ${scobj_hpath}/flow/sensor ${sct_controller} } else { ::scobj::hiden_xcs::sics_log 9 "[environment_simulation] => No poll/write for hiden_xcs" } @@ -1109,12 +1108,15 @@ proc ::scobj::hiden_xcs::mkDriver { sct_controller name id } { if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { ${sct_controller} poll ${scobj_hpath}/humidity/sensor 1 ${sct_controller} write ${scobj_hpath}/humidity/setpoint - ansto_makesctdrive ${name}_humidity_setpoint ${scobj_hpath}/humidity/setpoint ${scobj_hpath}/humidity/sensor ${sct_controller} } else { ::scobj::hiden_xcs::sics_log 9 "[environment_simulation] => No poll/write for hiden_xcs" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_flow_setpoint ${scobj_hpath}/flow/setpoint ${scobj_hpath}/flow/sensor ${sct_controller} + ansto_makesctdrive ${name}_humidity_setpoint ${scobj_hpath}/humidity/setpoint ${scobj_hpath}/humidity/sensor ${sct_controller} + } # mkDriver hook code starts # mkDriver hook code ends } catch_message ] @@ -1154,14 +1156,17 @@ clientput "file evaluation of sct_hiden_xcs.tcl" proc ::scobj::hiden_xcs::read_config {} { set catch_status [ catch { set ns "::scobj::hiden_xcs" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -1170,40 +1175,52 @@ proc ::scobj::hiden_xcs::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "hiden_xcs"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_hiden_xcs ${name} ${IP} ${PORT} {*}$arg_list + } else { add_hiden_xcs ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/sct_huber_pilot.tcl b/site_ansto/instrument/config/environment/sct_huber_pilot.tcl index 4b91c45a..52e6f55f 100644 --- a/site_ansto/instrument/config/environment/sct_huber_pilot.tcl +++ b/site_ansto/instrument/config/environment/sct_huber_pilot.tcl @@ -200,7 +200,7 @@ proc ::scobj::huber_pilot::rdStatus {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -249,7 +249,7 @@ proc ::scobj::huber_pilot::rdTemp {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -414,12 +414,14 @@ proc ::scobj::huber_pilot::mkDriver { sct_controller name } { ${sct_controller} poll ${scobj_hpath}/Loop1/vTmpActive 1 ${sct_controller} poll ${scobj_hpath}/Loop1/vTmpMode 1 ${sct_controller} write ${scobj_hpath}/Loop1/setpoint - ansto_makesctdrive ${name}_Loop1_setpoint ${scobj_hpath}/Loop1/setpoint ${scobj_hpath}/Loop1/sensor_int ${sct_controller} } else { ::scobj::huber_pilot::sics_log 9 "[environment_simulation] => No poll/write for huber_pilot" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 1 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_Loop1_setpoint ${scobj_hpath}/Loop1/setpoint ${scobj_hpath}/Loop1/sensor_int ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -458,14 +460,17 @@ clientput "file evaluation of sct_huber_pilot.tcl" proc ::scobj::huber_pilot::read_config {} { set catch_status [ catch { set ns "::scobj::huber_pilot" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -474,31 +479,37 @@ proc ::scobj::huber_pilot::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "huber_pilot"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_huber_pilot ${name} ${IP} ${PORT} + } else { add_huber_pilot ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/sct_isotech_ps.tcl b/site_ansto/instrument/config/environment/sct_isotech_ps.tcl index 9df15015..fe4088f6 100644 --- a/site_ansto/instrument/config/environment/sct_isotech_ps.tcl +++ b/site_ansto/instrument/config/environment/sct_isotech_ps.tcl @@ -107,7 +107,7 @@ proc ::scobj::isotech_ps::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -145,7 +145,7 @@ proc ::scobj::isotech_ps::read_relay {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -345,14 +345,17 @@ clientput "file evaluation of sct_isotech_ps.tcl" proc ::scobj::isotech_ps::read_config {} { set catch_status [ catch { set ns "::scobj::isotech_ps" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -361,31 +364,37 @@ proc ::scobj::isotech_ps::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "isotech_ps"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_isotech_ps ${name} ${IP} ${PORT} + } else { add_isotech_ps ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/sct_keithley_2700.tcl b/site_ansto/instrument/config/environment/sct_keithley_2700.tcl index e1d5be76..8005978f 100644 --- a/site_ansto/instrument/config/environment/sct_keithley_2700.tcl +++ b/site_ansto/instrument/config/environment/sct_keithley_2700.tcl @@ -574,7 +574,6 @@ debug_log "Registering node $nodeName for write callback" # set ns ::scobj::k2700 set ns "[namespace current]" - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klass sicslist setatt $tempobj long_name $tempobj @@ -680,88 +679,4 @@ set fd [open "../log/k2700.log" w] puts $fd "file evaluation of sct_keithley_2700.tcl" close $fd -namespace eval ::scobj::add_keithley_2700 { -set debug_threshold 5 -} -proc ::scobj::add_keithley_2700::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::add_keithley_2700::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::add_keithley_2700::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_keithley_2700.tcl" -::scobj::add_keithley_2700::sics_log 9 "file evaluation of sct_keithley_2700.tcl" - -proc ::scobj::add_keithley_2700::read_config {} { - set catch_status [ catch { - set ns "::scobj::add_keithley_2700" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "keithley_2700"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {term tol id datype} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_keithley_2700 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::add_keithley_2700::read_config -} else { - ::scobj::add_keithley_2700::sics_log 5 "No config dict" -} - - namespace import ::scobj::k2700::* diff --git a/site_ansto/instrument/config/environment/sct_keithley_m2700.tcl b/site_ansto/instrument/config/environment/sct_keithley_m2700.tcl new file mode 100644 index 00000000..6f278a2a --- /dev/null +++ b/site_ansto/instrument/config/environment/sct_keithley_m2700.tcl @@ -0,0 +1,161 @@ +# Generated driver for keithley_m2700 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::keithley_m2700 { + set debug_threshold 5 +} + +proc ::scobj::keithley_m2700::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/keithley_m2700_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::keithley_m2700::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::keithley_m2700::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::keithley_m2700::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::keithley_m2700::mkDriver { sct_controller name id datype tol } { + ::scobj::keithley_m2700::sics_log 9 "::scobj::keithley_m2700::mkDriver ${sct_controller} ${name} ${id} ${datype} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_keithley_2700 $sct_controller environment $name $tol $id $datype +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::keithley_m2700 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_keithley_m2700 {name IP port id datype tol} { + set catch_status [ catch { + ::scobj::keithley_m2700::sics_log 9 "add_keithley_m2700 ${name} ${IP} ${port} ${id} ${datype} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::keithley_m2700::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::keithley_m2700::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::keithley_m2700::sics_log 9 "[environment_simulation] => No sctcontroller for keithley_m2700" + } + ::scobj::keithley_m2700::sics_log 1 "::scobj::keithley_m2700::mkDriver sct_${name} ${name} ${id} ${datype} ${tol}" + ::scobj::keithley_m2700::mkDriver sct_${name} ${name} ${id} ${datype} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_keithley_m2700.tcl" +::scobj::keithley_m2700::sics_log 9 "file evaluation of sct_keithley_m2700.tcl" + +proc ::scobj::keithley_m2700::read_config {} { + set catch_status [ catch { + set ns "::scobj::keithley_m2700" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "keithley_m2700"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_keithley_m2700 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_keithley_m2700 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::keithley_m2700::read_config +} else { + ::scobj::keithley_m2700::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/sct_nhq_200.tcl b/site_ansto/instrument/config/environment/sct_nhq_200.tcl index 46e3c84b..fe1ce39e 100644 --- a/site_ansto/instrument/config/environment/sct_nhq_200.tcl +++ b/site_ansto/instrument/config/environment/sct_nhq_200.tcl @@ -180,7 +180,7 @@ proc ::scobj::nhq_200::rdCurrent {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -206,7 +206,7 @@ proc ::scobj::nhq_200::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -239,7 +239,7 @@ proc ::scobj::nhq_200::rdVoltage {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -484,7 +484,6 @@ proc ::scobj::nhq_200::mkDriver { sct_controller name } { ${sct_controller} write ${scobj_hpath}/ch1/i_trip ${sct_controller} write ${scobj_hpath}/ch1/v_ramp ${sct_controller} write ${scobj_hpath}/ch1/v_sp - ansto_makesctdrive ${name}_ch1_v_sp ${scobj_hpath}/ch1/v_sp ${scobj_hpath}/ch1/voltage ${sct_controller} } else { ::scobj::nhq_200::sics_log 9 "[environment_simulation] => No poll/write for nhq_200" } @@ -661,12 +660,15 @@ proc ::scobj::nhq_200::mkDriver { sct_controller name } { ${sct_controller} write ${scobj_hpath}/ch2/i_trip ${sct_controller} write ${scobj_hpath}/ch2/v_ramp ${sct_controller} write ${scobj_hpath}/ch2/v_sp - ansto_makesctdrive ${name}_ch2_v_sp ${scobj_hpath}/ch2/v_sp ${scobj_hpath}/ch2/voltage ${sct_controller} } else { ::scobj::nhq_200::sics_log 9 "[environment_simulation] => No poll/write for nhq_200" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 1 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_ch1_v_sp ${scobj_hpath}/ch1/v_sp ${scobj_hpath}/ch1/voltage ${sct_controller} + ansto_makesctdrive ${name}_ch2_v_sp ${scobj_hpath}/ch2/v_sp ${scobj_hpath}/ch2/voltage ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -705,14 +707,17 @@ clientput "file evaluation of sct_nhq_200.tcl" proc ::scobj::nhq_200::read_config {} { set catch_status [ catch { set ns "::scobj::nhq_200" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -721,31 +726,37 @@ proc ::scobj::nhq_200::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "nhq_200"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_nhq_200 ${name} ${IP} ${PORT} + } else { add_nhq_200 ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/sct_omron_hldc.tcl b/site_ansto/instrument/config/environment/sct_omron_hldc.tcl index b04e62cb..50254576 100644 --- a/site_ansto/instrument/config/environment/sct_omron_hldc.tcl +++ b/site_ansto/instrument/config/environment/sct_omron_hldc.tcl @@ -117,7 +117,7 @@ proc ::scobj::omron_hldc::read_id {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -160,7 +160,7 @@ proc ::scobj::omron_hldc::read_mm {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -272,14 +272,17 @@ clientput "file evaluation of sct_omron_hldc.tcl" proc ::scobj::omron_hldc::read_config {} { set catch_status [ catch { set ns "::scobj::omron_hldc" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -288,31 +291,37 @@ proc ::scobj::omron_hldc::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "omron_hldc"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_omron_hldc ${name} ${IP} ${PORT} + } else { add_omron_hldc ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index 23ec88d8..7ac292d4 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -60,10 +60,10 @@ proc rdStateRep {} { array set stateArr [split $stateRep "|:"] if {$stateArr(AUTOOFF)} { - broadcast "PROTEK608:[sct IP]:[sct PORT] WARNING AUTO OFF IS ENABLED" + broadcast "PROTEK608:[sct] WARNING AUTO OFF IS ENABLED" } if {$stateArr(LOBAT)} { - broadcast "PROTEK608: LOW BATTERY WARNING" + broadcast "PROTEK608:[sct] LOW BATTERY WARNING" } if {$stateRep != [sct oldval]} { sct update $stateRep @@ -122,20 +122,21 @@ close $fd # @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} {cbFunc "return idle"}} { +proc MakeProtek {name sctName CID CTYPE {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "return idle"}} { set catch_status [ catch { set sctName "sct_$name" set sobjName "$name" set soState "so_state_$name" - clientput "MakeSICSObj $sobjName SCT_OBJECT" + clientput "MakeSICSObj $soState SCT_OBJECT" MakeSICSObj $soState SCT_OBJECT - MakeSICSObj $sobjName SCT_OBJECT user float sicslist setatt $sobjName long_name $sobjName hfactory /sics/$soState/state plain user text hsetprop /sics/$soState/state read rqStateRep hsetprop /sics/$soState/state rdStateRep rdStateRep hsetprop /sics/$soState/state oldval "UNKNOWN" + hsetprop /sics/$sobjName permlink data_set ${CTYPE}${CID}S1 + hsetprop /sics/$sobjName @description ${CTYPE}${CID}S1 hsetprop /sics/$sobjName read rqVal "reportVal" hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState callBack hsetprop /sics/$sobjName callBack $cbFunc @@ -149,107 +150,19 @@ proc MakeProtek {name IP PORT {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "r ::scobj::hinitprops $sobjName sicslist setatt $sobjName long_name $name if {[SplitReply [environment_simulation]] == false} { - makesctcontroller $sctName protek608 $IP:$PORT - hsetprop /sics/$soState/state IP $IP - hsetprop /sics/$soState/state PORT $PORT $sctName poll /sics/$soState/state $interval $sctName poll /sics/$sobjName $interval } - } catch_message ] { - handle_exception ${catch_status} ${catch_message} - } - return /sics/$sobjName -} - - -proc add_protekmm {name IP PORT CTYPE CID {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "return idle"}} { - set catch_status [ catch { - MakeProtek $name $IP $PORT $scale $offset $interval $cbFunc - hsetprop /sics/$name permlink data_set ${CTYPE}${CID}S1 - } catch_message ] { - handle_exception ${catch_status} ${catch_message} - } -} - -namespace eval ::scobj::add_protekmm { -set debug_threshold 5 -} -proc ::scobj::add_protekmm::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::add_protekmm::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::add_protekmm::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_protekmm.tcl" -::scobj::add_protekmm::sics_log 9 "file evaluation of sct_protekmm.tcl" - -proc ::scobj::add_protekmm::read_config {} { - set catch_status [ catch { - set ns "::scobj::add_protekmm" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "protekmm"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {name ip port datype id scale offset interval} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_protekmm ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } } catch_message ] handle_exception ${catch_status} ${catch_message} } -if { [info exists ::config_dict] } { - ::scobj::add_protekmm::read_config -} else { - ::scobj::add_protekmm::sics_log 5 "No config dict" -} + +# proc add_protekmm {name IP PORT CTYPE CID {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "return idle"}} { +# set catch_status [ catch { +# MakeProtek $name $IP $PORT $scale $offset $interval $cbFunc +# hsetprop /sics/$name permlink data_set ${CTYPE}${CID}S1 +# } catch_message ] { +# handle_exception ${catch_status} ${catch_message} +# } +# } diff --git a/site_ansto/instrument/config/environment/sct_protekmm.tcl b/site_ansto/instrument/config/environment/sct_protekmm.tcl new file mode 100644 index 00000000..9c8581cb --- /dev/null +++ b/site_ansto/instrument/config/environment/sct_protekmm.tcl @@ -0,0 +1,161 @@ +# Generated driver for protekmm +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::protekmm { + set debug_threshold 5 +} + +proc ::scobj::protekmm::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/protekmm_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::protekmm::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::protekmm::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::protekmm::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::protekmm::mkDriver { sct_controller name id datype } { + ::scobj::protekmm::sics_log 9 "::scobj::protekmm::mkDriver ${sct_controller} ${name} ${id} ${datype}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + MakeProtek $name $sct_controller $id $datype +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::protekmm { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_protekmm {name IP port id datype} { + set catch_status [ catch { + ::scobj::protekmm::sics_log 9 "add_protekmm ${name} ${IP} ${port} ${id} ${datype}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::protekmm::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::protekmm::sics_log 9 "makesctcontroller sct_${name} protek608 ${IP}:${port}" + makesctcontroller sct_${name} protek608 ${IP}:${port} + } + } else { + ::scobj::protekmm::sics_log 9 "[environment_simulation] => No sctcontroller for protekmm" + } + ::scobj::protekmm::sics_log 1 "::scobj::protekmm::mkDriver sct_${name} ${name} ${id} ${datype}" + ::scobj::protekmm::mkDriver sct_${name} ${name} ${id} ${datype} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_protekmm.tcl" +::scobj::protekmm::sics_log 9 "file evaluation of sct_protekmm.tcl" + +proc ::scobj::protekmm::read_config {} { + set catch_status [ catch { + set ns "::scobj::protekmm" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "protekmm"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_protekmm ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_protekmm ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::protekmm::read_config +} else { + ::scobj::protekmm::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/eurotherm_m2000.sct b/site_ansto/instrument/config/environment/temperature/eurotherm_m2000.sct new file mode 100644 index 00000000..4db47fd1 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/eurotherm_m2000.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver eurotherm_m2000 = { + protocol = std + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'id datype dev_id tol' + make_args = 'id datype dev_id tol' + code mkDriver = {%% + mk_sct_eurotherm_et2000 sct_controller environment $name $dev_id $tol $id $datype + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct b/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct index 1dd946b6..e7e78ca5 100644 --- a/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct +++ b/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct @@ -4,53 +4,45 @@ # driver julabo_lh45_gen = { vendor = julabo; device = lh45; protocol = std; - class = environment + class = environment; simulation_group = environment_simulation - add_args = '{sensor "bath"} {tol 5.0}'; - make_args = 'sensor tol'; + debug_threshold = 1; + add_args = '{id 1} {ctrl_sensor "bath"} {tol 5.0}'; + make_args = 'id ctrl_sensor tol'; protocol_args = '"\r"'; # # Unnamed group has variables at device level # group = { - priv = user - type = float + priv = user; + type = float; + readable = 1; var setpoint = { - driveable = sensor/'value' - readable = 1 - read_command = 'in_sp_00' - write_function = setPoint - write_command = 'out_sp_00' - lowerlimit = 10 - upperlimit = 90 - tolerance = 2 + property 'units' = C; + read_command = 'in_sp_00'; + permlink = 'T.SP01'; + writeable = 1; write_function = setPoint; write_command = 'out_sp_00'; + driveable = sensor/'value'; + lowerlimit = 10; upperlimit = 90; tolerance = '${tol}'; } var overtemp_warnlimit = { - readable = 1 - read_command = 'in_sp_03' - #write_command = 'out_sp_03' + read_command = 'in_sp_03'; + # writeable = 1; write_command = 'out_sp_03'; } var subtemp_warnlimit = { - readable = 1 - read_command = 'in_sp_04' - #write_command = 'out_sp_04' + read_command = 'in_sp_04'; + # writeable = 1; write_command = 'out_sp_04'; } var heating_power_percent = { - readable = 1 read_command = 'in_pv_01'; }; - var power = { - readable = 1 - read_command = 'in_mode_05'; - writeable = 1; - write_command = 'out_mode_05'; - }; var lh45_state = { - readable = 1 + type = text; read_command = 'status'; - fetch_function = getState - read_function = rdState + fetch_function = getState; + read_function = rdState; } + readable = 0; var lh45_lasterror = { type = text; } var remote_ctrl = { type = text; priv = spy; } } @@ -61,51 +53,94 @@ driver julabo_lh45_gen = { type = float; priv = internal; readable = 1; - var 'value' = { read_command = 'in_pv_00'; units = 'C' }; - var bathtemp = { read_command = 'in_pv_00'; units = 'C' }; + property 'units' = 'C'; + var bathtemp = { read_function = rdSensor; read_command = 'in_pv_00'; property external = 0; }; + var external = { read_function = rdSensor; read_command = 'in_pv_02'; property external = 1; }; + readable = 0; + var 'value' = { permlink = 'T.S01'; }; + var start_temperature = {}; + var end_temperature; }; + group mode = { + type = int; + priv = user; + readable = 1; + writeable = 1; + var on_else_off = { read_command = 'in_mode_05'; write_command = 'out_mode_05'; }; + var ext_else_bath = { read_command = 'in_mode_04'; write_command = 'out_mode_04'; }; + }; # # Code lines start with '@' which is stripped before being emitted into generated driver # The code is emitted at the appropriate place in the given function # - code read_function rdValue = { - } - code Write_function setPoint = { - } + code read_function rdSensor = {%% + if { [string equal -length 6 [sct result] "---.--"] } { + return ${nextState} + } + if { [hval ${tc_root}/mode/ext_else_bath] == [sct external] } { + set target [pathname [sct]]/value + set oldval [hgetpropval ${target} oldval] + if {${data} != ${oldval} } { + debug_log ${tc_root} 1 "[sct] changed ${target} to new:${data}, from old:${oldval}" + hsetprop ${target} oldval ${data} + hupdate ${target} ${data} + hsetprop ${target} readtime [sct utime] + } + } + %%} + + code Write_function setPoint = {%% + # Put a space between command and param + set cmd "${cmd_str} ${par}" + # Hack to get a response + set cmd "${cmd}@@NOREPLY@@" + %%} + + code Write_function setValue = {%% + # Put a space between command and param + set cmd "${cmd_str} ${par}" + # Hack to get a response + set cmd "${cmd}@@NOREPLY@@" + %%} # # This code is after database creation # - code mkDriver = { - @# TODO use the ${sensor} and ${tol} arguments - } + code mkDriver = {%% + if { ${ctrl_sensor} == "external" } { + hset ${scobj_hpath}/mode/ext_else_bath 1 + } else { + hset ${scobj_hpath}/mode/ext_else_bath 0 + } + hsetprop ${scobj_hpath}/setpoint tolerance ${tol} + %%} - code read_function rdState = { - @ if {${data} != [sct oldval]} { - @ debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" - @ sct oldval ${data} - @ sct update ${data} - @ sct utime readtime - @ switch -- [lindex ${data} 0] { - @ "00" { - @ hset ${tc_root}/remote_ctrl False - @ } - @ "01" { - @ hset ${tc_root}/remote_ctrl False - @ } - @ "02" { - @ hset ${tc_root}/remote_ctrl True - @ } - @ "03" { - @ hset ${tc_root}/remote_ctrl True - @ } - @ default { - @ hset ${tc_root}/remote_ctrl UNKNOWN - @ hset ${tc_root}/lh45_lasterror ${data} - @ sct geterror ${data} - @ } - @ } - @ } - } + code read_function rdState = {%% + if {${data} != [sct oldval]} { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + switch -- [lindex ${data} 0] { + "00" { + hset ${tc_root}/remote_ctrl False + } + "01" { + hset ${tc_root}/remote_ctrl False + } + "02" { + hset ${tc_root}/remote_ctrl True + } + "03" { + hset ${tc_root}/remote_ctrl True + } + default { + hset ${tc_root}/remote_ctrl UNKNOWN + hset ${tc_root}/lh45_lasterror ${data} + sct geterror ${data} + } + } + } + %%} }; diff --git a/site_ansto/instrument/config/environment/temperature/lakeshore_m370.sct b/site_ansto/instrument/config/environment/temperature/lakeshore_m370.sct new file mode 100644 index 00000000..50c451e9 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/lakeshore_m370.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver lakeshore_m370 = { + protocol = std + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'tol' + make_args = 'tol' + code mkDriver = {%% + mk_sct_driver $sct_controller environment $name $tol + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/ls336.sct b/site_ansto/instrument/config/environment/temperature/ls336.sct new file mode 100644 index 00000000..498a6f78 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/ls336.sct @@ -0,0 +1,11 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver ls336 = { + protocol = std + class = environment + simulation_group = environment_simulation + add_args = 'id datype {tol1 1.0} {tol2 1.0}' + make_args = 'id datype tol1 tol2' + code mkDriver = {%% + ::scobj::ls336::mk_sct_lakeshore_336 $sct_controller environment $name $id $datype $tol1 $tol2 0 + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/ls340.sct b/site_ansto/instrument/config/environment/temperature/ls340.sct new file mode 100644 index 00000000..6ac3fcdf --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/ls340.sct @@ -0,0 +1,11 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver ls340 = { + protocol = std + class = environment + simulation_group = environment_simulation + add_args = 'id datype {tol1 1.0} {tol2 1.0}' + make_args = 'id datype tol1 tol2' + code mkDriver = {%% + ::scobj::ls340::mk_sct_lakeshore_340 $sct_controller environment $name $id $datype $tol1 $tol2 0 + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/nprvasm2.sct b/site_ansto/instrument/config/environment/temperature/nprvasm2.sct new file mode 100644 index 00000000..b018e832 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/nprvasm2.sct @@ -0,0 +1,11 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver nprvasm2 = { + protocol = std + class = environment + simulation_group = environment_simulation + add_args = '{tol 1.0}' + make_args = 'tol' + code mkDriver = {%% + mk_sct_newport_rva sct_${name} environment $name $tol + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl b/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl index d6c2e1a7..3c12aa1a 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl @@ -167,7 +167,6 @@ debug_log "halt $tc_root" if {[ catch { set ns ::scobj::et2000 - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klass sicslist setatt $tempobj long_name $tempobj @@ -366,90 +365,6 @@ set fd [open "../log/et2000.log" w] puts $fd "file evaluation of sct_eurotherm_2000.tcl" close $fd -namespace eval ::scobj::eurotherm_2000 { -set debug_threshold 5 -} -proc ::scobj::eurotherm_2000::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::eurotherm_2000::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::eurotherm_2000::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_eurotherm_2000.tcl" -::scobj::eurotherm_2000::sics_log 9 "file evaluation of sct_eurotherm_2000.tcl" - -proc ::scobj::eurotherm_2000::read_config {} { - set catch_status [ catch { - set ns "::scobj::eurotherm_2000" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "eurotherm_2000"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {devid tol id type} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_eurotherm_2000 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::eurotherm_2000::read_config -} else { - ::scobj::eurotherm_2000::sics_log 5 "No config dict" -} - - namespace import ::scobj::et2000::* #add_et2000 et2000 137.157.201.213 502 1 5 diff --git a/site_ansto/instrument/config/environment/temperature/sct_eurotherm_m2000.tcl b/site_ansto/instrument/config/environment/temperature/sct_eurotherm_m2000.tcl new file mode 100644 index 00000000..c443fa26 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_eurotherm_m2000.tcl @@ -0,0 +1,161 @@ +# Generated driver for eurotherm_m2000 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::eurotherm_m2000 { + set debug_threshold 5 +} + +proc ::scobj::eurotherm_m2000::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/eurotherm_m2000_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::eurotherm_m2000::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::eurotherm_m2000::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::eurotherm_m2000::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::eurotherm_m2000::mkDriver { sct_controller name id datype dev_id tol } { + ::scobj::eurotherm_m2000::sics_log 9 "::scobj::eurotherm_m2000::mkDriver ${sct_controller} ${name} ${id} ${datype} ${dev_id} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_eurotherm_et2000 sct_controller environment $name $dev_id $tol $id $datype +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::eurotherm_m2000 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_eurotherm_m2000 {name IP port id datype dev_id tol} { + set catch_status [ catch { + ::scobj::eurotherm_m2000::sics_log 9 "add_eurotherm_m2000 ${name} ${IP} ${port} ${id} ${datype} ${dev_id} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::eurotherm_m2000::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::eurotherm_m2000::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::eurotherm_m2000::sics_log 9 "[environment_simulation] => No sctcontroller for eurotherm_m2000" + } + ::scobj::eurotherm_m2000::sics_log 1 "::scobj::eurotherm_m2000::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol}" + ::scobj::eurotherm_m2000::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_eurotherm_m2000.tcl" +::scobj::eurotherm_m2000::sics_log 9 "file evaluation of sct_eurotherm_m2000.tcl" + +proc ::scobj::eurotherm_m2000::read_config {} { + set catch_status [ catch { + set ns "::scobj::eurotherm_m2000" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "eurotherm_m2000"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype dev_id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_eurotherm_m2000 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_eurotherm_m2000 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::eurotherm_m2000::read_config +} else { + ::scobj::eurotherm_m2000::sics_log 5 "No config dict" +} 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 cd5649a6..9dfb08ca 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl @@ -405,6 +405,7 @@ namespace eval ::scobj::lh45 { } namespace export mk_sct_julabo_lh45 } +namespace import ::scobj::lh45::* ## # @brief Create a Julabo lh45 temperature controller @@ -416,9 +417,14 @@ namespace eval ::scobj::lh45 { # @param _tol (optional), this is the initial tolerance setting proc add_julabo_lh45 { name IP port {sensor "bath"} {_tol 5.0} {CID 1} {CTYPE T} } { if {[SplitReply [environment_simulation]]=="false"} { - makesctcontroller sct_lh45 std ${IP}:$port "\r" + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::julabo_lh45::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + makesctcontroller sct_${name} std ${IP}:$port "\r" + } } - mk_sct_julabo_lh45 sct_lh45 environment $name $_tol $CID $CTYPE + mk_sct_julabo_lh45 sct_${name} environment $name $_tol $CID $CTYPE set scobj_hpath /sics/$name switch $sensor { "bath" { @@ -433,89 +439,3 @@ proc add_julabo_lh45 { name IP port {sensor "bath"} {_tol 5.0} {CID 1} {CTYPE T} } makesctemon $name /sics/$name/emon/monmode /sics/$name/emon/isintol /sics/$name/emon/errhandler } - -namespace eval ::scobj::julabo_lh45 { -set debug_threshold 5 -} -proc ::scobj::julabo_lh45::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::julabo_lh45::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::julabo_lh45::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_julabo_lh45.tcl" -::scobj::julabo_lh45::sics_log 9 "file evaluation of sct_julabo_lh45.tcl" - -proc ::scobj::julabo_lh45::read_config {} { - set catch_status [ catch { - set ns "::scobj::julabo_lh45" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "julabo_lh45"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {ctrl_sensor tol id type} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_julabo_lh45 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::julabo_lh45::read_config -} else { - ::scobj::julabo_lh45::sics_log 5 "No config dict" -} - - -namespace import ::scobj::lh45::* diff --git a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl new file mode 100644 index 00000000..6fe8aa75 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl @@ -0,0 +1,724 @@ +# Generated driver for julabo_lh45_gen +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::julabo_lh45_gen { + set debug_threshold 1 +} + +proc ::scobj::julabo_lh45_gen::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/julabo_lh45_gen_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::julabo_lh45_gen::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::julabo_lh45_gen::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::julabo_lh45_gen::${debug_string}" + } + } catch_message ] +} + +# checklimits function for driveable interface +proc ::scobj::julabo_lh45_gen::checklimits {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "checklimits 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] + } +# checklimits hook code goes here + if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { + sct driving 0 + error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" + } + return OK + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# check function for hset change +proc ::scobj::julabo_lh45_gen::checkrange {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 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] + } +# checkrange hook code goes here + if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } { + error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]" + } + return OK + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# checkstatus function for driveable interface +proc ::scobj::julabo_lh45_gen::checkstatus {tc_root} { + set catch_status [ catch { +# checkstatus hook code goes here + if {[sct driving]} { + set sp "[sct target]" + set pv "[hval ${tc_root}/[sct driveable]]" + if { abs(${pv} - ${sp}) <= [sct tolerance] } { + if { [hpropexists [sct] settle_time] } { + if { [hpropexists [sct] settle_time_start] } { + if { [sct utime] - [sct settle_time_start] >= [sct settle_time]} { + sct driving 0 + return "idle" + } + return "busy" + } else { + sct utime settle_time_start + return "busy" + } + } + sct driving 0 + return "idle" + } + if { [hpropexists [sct] settle_time_start] } { + hdelprop [sct] settle_time_start + } + return "busy" + } else { + return "idle" + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to request the read of a parameter on a device +proc ::scobj::julabo_lh45_gen::getState {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "getState tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set cmd "${cmd_str}" +# getState hook code goes here + debug_log ${tc_root} 1 "getState 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 request the read of a parameter on a device +proc ::scobj::julabo_lh45_gen::getValue {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "getValue tc_root=${tc_root} sct=[sct] cmd=${cmd_str}" + if { [hpropexists [sct] geterror] } { + hdelprop [sct] geterror + } + set cmd "${cmd_str}" +# getValue hook code goes here + debug_log ${tc_root} 1 "getValue sct send ${cmd}" + if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} { + sct send "${cmd}" + } + return ${nextState} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# halt function for driveable interface +proc ::scobj::julabo_lh45_gen::halt {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "halt tc_root=${tc_root} sct=[sct] driving=[sct driving]" + ### TODO hset [sct] [hval [sct]] +# halt hook code goes here + sct driving 0 + return "idle" + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to check the write parameter on a device +proc ::scobj::julabo_lh45_gen::noResponse {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "noResponse tc_root=${tc_root} sct=[sct] resp=[sct result]" +# noResponse hook code goes here + return "idle" + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +# function to parse the read of a parameter on a device +proc ::scobj::julabo_lh45_gen::rdSensor {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "rdSensor 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]" + } +# rdSensor hook code starts + if { [string equal -length 6 [sct result] "---.--"] } { + return ${nextState} + } + if { [hval ${tc_root}/mode/ext_else_bath] == [sct external] } { + set target [pathname [sct]]/value + set oldval [hgetpropval ${target} oldval] + if {${data} != ${oldval} } { + debug_log ${tc_root} 1 "[sct] changed ${target} to new:${data}, from old:${oldval}" + hsetprop ${target} oldval ${data} + hupdate ${target} ${data} + hsetprop ${target} readtime [sct utime] + } + } +# rdSensor hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 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 parse the read of a parameter on a device +proc ::scobj::julabo_lh45_gen::rdState {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "rdState 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]" + } +# rdState hook code starts + if {${data} != [sct oldval]} { + debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]" + sct oldval ${data} + sct update ${data} + sct utime readtime + switch -- [lindex ${data} 0] { + "00" { + hset ${tc_root}/remote_ctrl False + } + "01" { + hset ${tc_root}/remote_ctrl False + } + "02" { + hset ${tc_root}/remote_ctrl True + } + "03" { + hset ${tc_root}/remote_ctrl True + } + default { + hset ${tc_root}/remote_ctrl UNKNOWN + hset ${tc_root}/lh45_lasterror ${data} + sct geterror ${data} + } + } + } +# rdState hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 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 parse the read of a parameter on a device +proc ::scobj::julabo_lh45_gen::rdValue {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "rdValue 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]" + } +# rdValue hook code goes here + if { ${data} != [sct oldval] } { + debug_log ${tc_root} 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::julabo_lh45_gen::setPoint {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 1 "setPoint 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}" +# setPoint hook code starts + # Put a space between command and param + set cmd "${cmd_str} ${par}" + # Hack to get a response + set cmd "${cmd}@@NOREPLY@@" +# setPoint hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log ${tc_root} 1 "setPoint 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::julabo_lh45_gen::setValue {tc_root nextState cmd_str} { + set catch_status [ catch { + debug_log ${tc_root} 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}" +# setValue hook code starts + # Put a space between command and param + set cmd "${cmd_str} ${par}" + # Hack to get a response + set cmd "${cmd}@@NOREPLY@@" +# setValue hook code ends + if { [hpropexists [sct] geterror] } { + debug_log ${tc_root} 9 "[sct] error: [sct geterror]" + error "[sct geterror]" + } + if { [hpropexists [sct] driving] } { + if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } { + sct driving 1 + } + } + debug_log ${tc_root} 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::julabo_lh45_gen::mkDriver { sct_controller name id ctrl_sensor tol } { + ::scobj::julabo_lh45_gen::sics_log 9 "::scobj::julabo_lh45_gen::mkDriver ${sct_controller} ${name} ${id} ${ctrl_sensor} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + + hfactory ${scobj_hpath}/heating_power_percent plain user float + hsetprop ${scobj_hpath}/heating_power_percent read ${ns}::getValue ${scobj_hpath} rdValue {in_pv_01} + hsetprop ${scobj_hpath}/heating_power_percent rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/heating_power_percent control true + hsetprop ${scobj_hpath}/heating_power_percent data true + hsetprop ${scobj_hpath}/heating_power_percent mutable false + hsetprop ${scobj_hpath}/heating_power_percent nxsave true + hsetprop ${scobj_hpath}/heating_power_percent oldval 0.0 + hsetprop ${scobj_hpath}/heating_power_percent sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/heating_power_percent type "part" + hsetprop ${scobj_hpath}/heating_power_percent nxalias "${name}_heating_power_percent" + + hfactory ${scobj_hpath}/lh45_lasterror plain user text + hsetprop ${scobj_hpath}/lh45_lasterror control true + hsetprop ${scobj_hpath}/lh45_lasterror data true + hsetprop ${scobj_hpath}/lh45_lasterror mutable false + hsetprop ${scobj_hpath}/lh45_lasterror nxsave true + hsetprop ${scobj_hpath}/lh45_lasterror oldval UNKNOWN + hsetprop ${scobj_hpath}/lh45_lasterror sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/lh45_lasterror type "part" + hsetprop ${scobj_hpath}/lh45_lasterror nxalias "${name}_lh45_lasterror" + + hfactory ${scobj_hpath}/lh45_state plain user text + hsetprop ${scobj_hpath}/lh45_state read ${ns}::getState ${scobj_hpath} rdState {status} + hsetprop ${scobj_hpath}/lh45_state rdState ${ns}::rdState ${scobj_hpath} + hsetprop ${scobj_hpath}/lh45_state control true + hsetprop ${scobj_hpath}/lh45_state data true + hsetprop ${scobj_hpath}/lh45_state mutable false + hsetprop ${scobj_hpath}/lh45_state nxsave true + hsetprop ${scobj_hpath}/lh45_state oldval UNKNOWN + hsetprop ${scobj_hpath}/lh45_state sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/lh45_state type "part" + hsetprop ${scobj_hpath}/lh45_state nxalias "${name}_lh45_state" + + hfactory ${scobj_hpath}/overtemp_warnlimit plain user float + hsetprop ${scobj_hpath}/overtemp_warnlimit read ${ns}::getValue ${scobj_hpath} rdValue {in_sp_03} + hsetprop ${scobj_hpath}/overtemp_warnlimit rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/overtemp_warnlimit control true + hsetprop ${scobj_hpath}/overtemp_warnlimit data true + hsetprop ${scobj_hpath}/overtemp_warnlimit mutable false + hsetprop ${scobj_hpath}/overtemp_warnlimit nxsave true + hsetprop ${scobj_hpath}/overtemp_warnlimit oldval 0.0 + hsetprop ${scobj_hpath}/overtemp_warnlimit sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/overtemp_warnlimit type "part" + hsetprop ${scobj_hpath}/overtemp_warnlimit nxalias "${name}_overtemp_warnlimit" + + hfactory ${scobj_hpath}/remote_ctrl plain spy text + hsetprop ${scobj_hpath}/remote_ctrl control true + hsetprop ${scobj_hpath}/remote_ctrl data true + hsetprop ${scobj_hpath}/remote_ctrl mutable false + hsetprop ${scobj_hpath}/remote_ctrl nxsave true + hsetprop ${scobj_hpath}/remote_ctrl oldval UNKNOWN + hsetprop ${scobj_hpath}/remote_ctrl sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/remote_ctrl type "part" + hsetprop ${scobj_hpath}/remote_ctrl nxalias "${name}_remote_ctrl" + + hfactory ${scobj_hpath}/setpoint plain user float + hsetprop ${scobj_hpath}/setpoint read ${ns}::getValue ${scobj_hpath} rdValue {in_sp_00} + hsetprop ${scobj_hpath}/setpoint rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint write ${ns}::setPoint ${scobj_hpath} noResponse {out_sp_00} + hsetprop ${scobj_hpath}/setpoint noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint driving 0 + hsetprop ${scobj_hpath}/setpoint checklimits ${ns}::checklimits ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint checkstatus ${ns}::checkstatus ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint halt ${ns}::halt ${scobj_hpath} + hsetprop ${scobj_hpath}/setpoint driveable sensor/value + hsetprop ${scobj_hpath}/setpoint control true + hsetprop ${scobj_hpath}/setpoint data true + hsetprop ${scobj_hpath}/setpoint mutable false + hsetprop ${scobj_hpath}/setpoint nxsave true + hsetprop ${scobj_hpath}/setpoint lowerlimit 10 + hsetprop ${scobj_hpath}/setpoint upperlimit 90 + hsetprop ${scobj_hpath}/setpoint tolerance ${tol} + hsetprop ${scobj_hpath}/setpoint permlink data_set "T[format "%02d" ${id}]SP01" + hsetprop ${scobj_hpath}/setpoint @description "T[format "%02d" ${id}]SP01" + hsetprop ${scobj_hpath}/setpoint oldval 0.0 + hsetprop ${scobj_hpath}/setpoint sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/setpoint type "drivable" + hsetprop ${scobj_hpath}/setpoint units "C" + hsetprop ${scobj_hpath}/setpoint nxalias "${name}_setpoint" + + hfactory ${scobj_hpath}/subtemp_warnlimit plain user float + hsetprop ${scobj_hpath}/subtemp_warnlimit read ${ns}::getValue ${scobj_hpath} rdValue {in_sp_04} + hsetprop ${scobj_hpath}/subtemp_warnlimit rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/subtemp_warnlimit control true + hsetprop ${scobj_hpath}/subtemp_warnlimit data true + hsetprop ${scobj_hpath}/subtemp_warnlimit mutable false + hsetprop ${scobj_hpath}/subtemp_warnlimit nxsave true + hsetprop ${scobj_hpath}/subtemp_warnlimit oldval 0.0 + hsetprop ${scobj_hpath}/subtemp_warnlimit sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/subtemp_warnlimit type "part" + hsetprop ${scobj_hpath}/subtemp_warnlimit nxalias "${name}_subtemp_warnlimit" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/heating_power_percent 1 + ${sct_controller} poll ${scobj_hpath}/lh45_state 1 + ${sct_controller} poll ${scobj_hpath}/overtemp_warnlimit 1 + ${sct_controller} poll ${scobj_hpath}/setpoint 1 + ${sct_controller} poll ${scobj_hpath}/subtemp_warnlimit 1 + ${sct_controller} write ${scobj_hpath}/setpoint + } else { + ::scobj::julabo_lh45_gen::sics_log 9 "[environment_simulation] => No poll/write for julabo_lh45_gen" + } + + hfactory ${scobj_hpath}/mode plain spy none + + hfactory ${scobj_hpath}/mode/ext_else_bath plain user int + hsetprop ${scobj_hpath}/mode/ext_else_bath read ${ns}::getValue ${scobj_hpath} rdValue {in_mode_04} + hsetprop ${scobj_hpath}/mode/ext_else_bath rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/mode/ext_else_bath write ${ns}::setValue ${scobj_hpath} noResponse {out_mode_04} + hsetprop ${scobj_hpath}/mode/ext_else_bath noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/mode/ext_else_bath check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/mode/ext_else_bath control true + hsetprop ${scobj_hpath}/mode/ext_else_bath data true + hsetprop ${scobj_hpath}/mode/ext_else_bath mutable false + hsetprop ${scobj_hpath}/mode/ext_else_bath nxsave true + hsetprop ${scobj_hpath}/mode/ext_else_bath oldval 0 + hsetprop ${scobj_hpath}/mode/ext_else_bath sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/mode/ext_else_bath type "part" + hsetprop ${scobj_hpath}/mode/ext_else_bath nxalias "${name}_mode_ext_else_bath" + + hfactory ${scobj_hpath}/mode/on_else_off plain user int + hsetprop ${scobj_hpath}/mode/on_else_off read ${ns}::getValue ${scobj_hpath} rdValue {in_mode_05} + hsetprop ${scobj_hpath}/mode/on_else_off rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/mode/on_else_off write ${ns}::setValue ${scobj_hpath} noResponse {out_mode_05} + hsetprop ${scobj_hpath}/mode/on_else_off noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/mode/on_else_off check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/mode/on_else_off control true + hsetprop ${scobj_hpath}/mode/on_else_off data true + hsetprop ${scobj_hpath}/mode/on_else_off mutable false + hsetprop ${scobj_hpath}/mode/on_else_off nxsave true + hsetprop ${scobj_hpath}/mode/on_else_off oldval 0 + hsetprop ${scobj_hpath}/mode/on_else_off sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/mode/on_else_off type "part" + hsetprop ${scobj_hpath}/mode/on_else_off nxalias "${name}_mode_on_else_off" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/mode/ext_else_bath 1 + ${sct_controller} poll ${scobj_hpath}/mode/on_else_off 1 + ${sct_controller} write ${scobj_hpath}/mode/ext_else_bath + ${sct_controller} write ${scobj_hpath}/mode/on_else_off + } else { + ::scobj::julabo_lh45_gen::sics_log 9 "[environment_simulation] => No poll/write for julabo_lh45_gen" + } + + hfactory ${scobj_hpath}/sensor plain spy none + + hfactory ${scobj_hpath}/sensor/bathtemp plain internal float + hsetprop ${scobj_hpath}/sensor/bathtemp read ${ns}::getValue ${scobj_hpath} rdSensor {in_pv_00} + hsetprop ${scobj_hpath}/sensor/bathtemp rdSensor ${ns}::rdSensor ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/bathtemp control true + hsetprop ${scobj_hpath}/sensor/bathtemp data true + hsetprop ${scobj_hpath}/sensor/bathtemp mutable false + hsetprop ${scobj_hpath}/sensor/bathtemp nxsave true + hsetprop ${scobj_hpath}/sensor/bathtemp oldval 0.0 + hsetprop ${scobj_hpath}/sensor/bathtemp external "0" + hsetprop ${scobj_hpath}/sensor/bathtemp sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/bathtemp type "part" + hsetprop ${scobj_hpath}/sensor/bathtemp units "C" + hsetprop ${scobj_hpath}/sensor/bathtemp nxalias "${name}_sensor_bathtemp" + + hfactory ${scobj_hpath}/sensor/end_temperature plain internal float + hsetprop ${scobj_hpath}/sensor/end_temperature control true + hsetprop ${scobj_hpath}/sensor/end_temperature data true + hsetprop ${scobj_hpath}/sensor/end_temperature mutable false + hsetprop ${scobj_hpath}/sensor/end_temperature nxsave true + hsetprop ${scobj_hpath}/sensor/end_temperature oldval 0.0 + hsetprop ${scobj_hpath}/sensor/end_temperature sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/end_temperature type "part" + hsetprop ${scobj_hpath}/sensor/end_temperature units "C" + hsetprop ${scobj_hpath}/sensor/end_temperature nxalias "${name}_sensor_end_temperature" + + hfactory ${scobj_hpath}/sensor/external plain internal float + hsetprop ${scobj_hpath}/sensor/external read ${ns}::getValue ${scobj_hpath} rdSensor {in_pv_02} + hsetprop ${scobj_hpath}/sensor/external rdSensor ${ns}::rdSensor ${scobj_hpath} + hsetprop ${scobj_hpath}/sensor/external control true + hsetprop ${scobj_hpath}/sensor/external data true + hsetprop ${scobj_hpath}/sensor/external mutable false + hsetprop ${scobj_hpath}/sensor/external nxsave true + hsetprop ${scobj_hpath}/sensor/external oldval 0.0 + hsetprop ${scobj_hpath}/sensor/external external "1" + hsetprop ${scobj_hpath}/sensor/external sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/external type "part" + hsetprop ${scobj_hpath}/sensor/external units "C" + hsetprop ${scobj_hpath}/sensor/external nxalias "${name}_sensor_external" + + hfactory ${scobj_hpath}/sensor/start_temperature plain internal float + hsetprop ${scobj_hpath}/sensor/start_temperature control true + hsetprop ${scobj_hpath}/sensor/start_temperature data true + hsetprop ${scobj_hpath}/sensor/start_temperature mutable false + hsetprop ${scobj_hpath}/sensor/start_temperature nxsave true + hsetprop ${scobj_hpath}/sensor/start_temperature oldval 0.0 + hsetprop ${scobj_hpath}/sensor/start_temperature sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/start_temperature type "part" + hsetprop ${scobj_hpath}/sensor/start_temperature units "C" + hsetprop ${scobj_hpath}/sensor/start_temperature nxalias "${name}_sensor_start_temperature" + + hfactory ${scobj_hpath}/sensor/value plain internal float + hsetprop ${scobj_hpath}/sensor/value control true + hsetprop ${scobj_hpath}/sensor/value data true + hsetprop ${scobj_hpath}/sensor/value mutable false + hsetprop ${scobj_hpath}/sensor/value nxsave true + hsetprop ${scobj_hpath}/sensor/value permlink data_set "T[format "%02d" ${id}]S01" + hsetprop ${scobj_hpath}/sensor/value @description "T[format "%02d" ${id}]S01" + hsetprop ${scobj_hpath}/sensor/value oldval 0.0 + hsetprop ${scobj_hpath}/sensor/value sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/sensor/value type "part" + hsetprop ${scobj_hpath}/sensor/value units "C" + hsetprop ${scobj_hpath}/sensor/value nxalias "${name}_sensor_value" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/sensor/bathtemp 1 + ${sct_controller} poll ${scobj_hpath}/sensor/external 1 + } else { + ::scobj::julabo_lh45_gen::sics_log 9 "[environment_simulation] => No poll/write for julabo_lh45_gen" + } + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 1 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_setpoint ${scobj_hpath}/setpoint ${scobj_hpath}/sensor/value ${sct_controller} + } +# mkDriver hook code starts + if { ${ctrl_sensor} == "external" } { + hset ${scobj_hpath}/mode/ext_else_bath 1 + } else { + hset ${scobj_hpath}/mode/ext_else_bath 0 + } + hsetprop ${scobj_hpath}/setpoint tolerance ${tol} +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::julabo_lh45_gen { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_julabo_lh45_gen {name IP port {id 1} {ctrl_sensor "bath"} {tol 5.0}} { + set catch_status [ catch { + ::scobj::julabo_lh45_gen::sics_log 9 "add_julabo_lh45_gen ${name} ${IP} ${port} ${id} ${ctrl_sensor} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::julabo_lh45_gen::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::julabo_lh45_gen::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port} \"\\r\"" + makesctcontroller sct_${name} std ${IP}:${port} "\r" + } + } else { + ::scobj::julabo_lh45_gen::sics_log 9 "[environment_simulation] => No sctcontroller for julabo_lh45_gen" + } + ::scobj::julabo_lh45_gen::sics_log 1 "::scobj::julabo_lh45_gen::mkDriver sct_${name} ${name} ${id} ${ctrl_sensor} ${tol}" + ::scobj::julabo_lh45_gen::mkDriver sct_${name} ${name} ${id} ${ctrl_sensor} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_julabo_lh45_gen.tcl" +::scobj::julabo_lh45_gen::sics_log 9 "file evaluation of sct_julabo_lh45_gen.tcl" + +proc ::scobj::julabo_lh45_gen::read_config {} { + set catch_status [ catch { + set ns "::scobj::julabo_lh45_gen" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "julabo_lh45_gen"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id ctrl_sensor tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_julabo_lh45_gen ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_julabo_lh45_gen ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::julabo_lh45_gen::read_config +} else { + ::scobj::julabo_lh45_gen::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_218.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_218.tcl index a5dfd21c..88a5c78a 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_218.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_218.tcl @@ -127,7 +127,7 @@ proc ::scobj::lakeshore_218::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -338,14 +338,17 @@ clientput "file evaluation of sct_lakeshore_218.tcl" proc ::scobj::lakeshore_218::read_config {} { set catch_status [ catch { set ns "::scobj::lakeshore_218" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -354,31 +357,37 @@ proc ::scobj::lakeshore_218::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "lakeshore_218"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_lakeshore_218 ${name} ${IP} ${PORT} + } else { add_lakeshore_218 ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl index a7a201dd..08bb5196 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl @@ -4,7 +4,7 @@ ## # /*-------------------------------------------------------------------------- -# L A K E S H O R E 3 x x S E R I E S D R I V E R +# L A K E S H O R E 3 x x S E R I E S D R I V E R # # @file: This file contains the implementation of a driver for the # Lakeshore 336 and 340 Temperature controller implemented as a scriptcontext @@ -83,20 +83,20 @@ namespace eval ::scobj::ls336 { set_param $tc_root ls340_settleTime 30 # default Heater Range (0,..,5) zero is off, hence the least dangerous set_param $tc_root ls336_range 0 - # upper and lower temperature limit in Kelvin + # upper and lower temperature limit in Kelvin set_param $tc_root ls336_upperlimit 500.0 set_param $tc_root ls336_lowerlimit 4.0 - # temperature units are Kelvin + # temperature units are Kelvin set_param $tc_root ls336_tempUnits "K" - # ls336 status byte + # ls336 status byte # enable extra logging - can produce huge stout****.log file in /usr/local/sics/log/ set_param $tc_root ls336_verbose 0 - # a list of available sensors (not all may be connected/active) + # a list of available sensors (not all may be connected/active) set_param $tc_root this_sensorlist [list A B C D] - # a list of controler loops + # a list of controler loops set_param $tc_root this_controlerlist [list 1 2] - # set device ID to unknown - # set self-test result to unknown + # set device ID to unknown + # set self-test result to unknown set_param $tc_root this_selfTestResult -1 # status of input channels - unknown at startup set_param $tc_root ls336_sampleSensor "UNKNOWN" @@ -267,7 +267,7 @@ proc getValue {tc_root nextState cmd idx} { # Keep track of the time at which data was observed ** NXsensor allows float values only, not text if {0 == [string compare -length 9 $lastQueryCmd "DATETIME?"] } { # DATETIME «MM»,«DD»,«YYYY»,«HH»,«mm»,«SS»,«sss» Configure Date and Time. - regsub -all {,} $data {:} data + regsub -all {,} $data {:} data # data=08:31:2009:12:58:58:910 set separator {:} set amonth [::scobj::ls336::getValFromString $data 0 $separator] @@ -452,54 +452,54 @@ proc rdBitValue {tc_root rdCmd iSensor} { set data [sct result] switch -glob -- $data { "ASCERR:*" { - clientput "$data in rdBitValue" - sct geterror $data + clientput "$data in rdBitValue" + sct geterror $data } default { - if {$data != [sct oldval]} { - sct oldval $data - sct utime readtime - # RDGST? A/B/C/D Read input status returns an integer with the following meaning - # Bit Weighting StatusIndicator - # 0 1 invalid reading - # 1 2 old reading (not an error, ignored in ls336) - # 4 16 temp underrange - # 5 32 temp overrange - # 6 64 sensor units zero - # 7 128 sensor units overrange - set sValue "" - # Remove any leading zeros from string 'data' which ought to represent an integer, - # ("001" => "1", "096" => "96") else the string may be misinterpreted as an octal number. - if {0 == [string compare -length 1 $data "0"] } { - set data [string range $data 1 5] - } - if {0 == [string compare -length 1 $data "0"] } { - set data [string range $data 1 5] - } - set i $data - # clientput "rdBitValue(): iSensor:$iSensor, data:$data" - set bitValue [expr {$i & 1}] - if {$bitValue == 1} {set sValue "Invalid reading, "} - #set i [expr $i >> 1] - # set bitValue [expr $i & 1] - # if {$bitValue == 1} {set sValue "old reading"} - set i [expr {$i >> 4}] - set bitValue [expr {$i & 1}] - if {$bitValue == 1} { set sValue [append sValue "temp underrange, "] } - set i [expr {$i >> 1}] - set bitValue [expr {$i & 1}] - if {$bitValue == 1} { set sValue [append sValue "temp overrange, "] } - set i [expr {$i >> 1}] - set bitValue [expr {$i & 1}] - if {$bitValue == 1} { set sValue [append sValue "sensor units zero, "] } - set i [expr {$i >> 1}] - set bitValue [expr {$i & 1}] - if {$bitValue == 1} { set sValue [append sValue "sensor units overrange, "] } - if { [string length $sValue] < 4 } { - set sValue "ok" - } - sct update $sValue - } + if {$data != [sct oldval]} { + sct oldval $data + sct utime readtime + # RDGST? A/B/C/D Read input status returns an integer with the following meaning + # Bit Weighting StatusIndicator + # 0 1 invalid reading + # 1 2 old reading (not an error, ignored in ls336) + # 4 16 temp underrange + # 5 32 temp overrange + # 6 64 sensor units zero + # 7 128 sensor units overrange + set sValue "" + # Remove any leading zeros from string 'data' which ought to represent an integer, + # ("001" => "1", "096" => "96") else the string may be misinterpreted as an octal number. + if {0 == [string compare -length 1 $data "0"] } { + set data [string range $data 1 5] + } + if {0 == [string compare -length 1 $data "0"] } { + set data [string range $data 1 5] + } + set i $data + # clientput "rdBitValue(): iSensor:$iSensor, data:$data" + set bitValue [expr {$i & 1}] + if {$bitValue == 1} {set sValue "Invalid reading, "} + #set i [expr $i >> 1] + # set bitValue [expr $i & 1] + # if {$bitValue == 1} {set sValue "old reading"} + set i [expr {$i >> 4}] + set bitValue [expr {$i & 1}] + if {$bitValue == 1} { set sValue [append sValue "temp underrange, "] } + set i [expr {$i >> 1}] + set bitValue [expr {$i & 1}] + if {$bitValue == 1} { set sValue [append sValue "temp overrange, "] } + set i [expr {$i >> 1}] + set bitValue [expr {$i & 1}] + if {$bitValue == 1} { set sValue [append sValue "sensor units zero, "] } + set i [expr {$i >> 1}] + set bitValue [expr {$i & 1}] + if {$bitValue == 1} { set sValue [append sValue "sensor units overrange, "] } + if { [string length $sValue] < 4 } { + set sValue "ok" + } + sct update $sValue + } } } } message ]} { @@ -1581,7 +1581,6 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # @return nothing (well, the sct object) proc mk_sct_lakeshore_336 {sct_controller klasse tempobj CID CTYPE tol1 tol2 verbose} { if {[ catch { - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klasse sicslist setatt $tempobj long_name $tempobj # Create a base node for all the state machines of this sics object @@ -1628,84 +1627,84 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # wrFunc Function to be called to send the wrCmd to the device, typically setValue() # allowedValues allowed values for the node data - does not permit other set deviceCommandToplevel { - sensor sampleSensor 0 1 0 0 1 1 1 text user {CSET? 1} {rdValue} {InpSample } {setPseudoValue} {A,B,C,D} - sensor Tsample 1 0 0 0 1 1 1 float spy {KRDG? A} {rdValue} {} {setValue} {} - sensor ctrl_Loop_1 1 0 0 0 1 1 1 text user {CSET? 1} {rdValue} {} {setValue} {} - sensor ctrlLp1_value 1 0 0 0 1 1 1 float spy {KRDG? A} {rdValue} {} {setValue} {} - sensor setpoint1 1 1 1 1 1 1 1 float user {SETP? 1} {rdValue} {SETP 1,} {setPoint} {} - sensor ctrl_Loop_2 1 0 0 0 2 1 1 text user {CSET? 2} {rdValue} {} {setValue} {} - sensor ctrlLp2_value 1 0 0 0 2 1 1 float spy {KRDG? B} {rdValue} {} {setValue} {} - sensor setpoint2 1 1 1 1 2 1 1 float user {SETP? 2} {rdValue} {SETP 2,} {setPoint} {} - sensor ctrl_Loop_3 1 0 0 0 3 0 1 text user {CSET? 3} {rdValue} {} {setValue} {} - sensor ctrlLp3_value 1 0 0 0 3 0 1 float spy {KRDG? C} {rdValue} {} {setValue} {} - sensor setpoint3 1 1 1 1 3 0 1 float user {SETP? 3} {rdValue} {SETP 3,} {setPoint} {} - sensor ctrl_Loop_4 1 0 0 0 4 0 1 text user {CSET? 4} {rdValue} {} {setValue} {} - sensor ctrlLp4_value 1 0 0 0 4 0 1 float spy {KRDG? D} {rdValue} {} {setValue} {} - sensor setpoint4 1 1 1 1 4 0 1 float user {SETP? 4} {rdValue} {SETP 4,} {setPoint} {} - sensor sensorValueA 1 0 1 0 A 1 1 float spy {KRDG? A} {rdInpValue} {} {setValue} {} - sensor sensorValueB 1 0 1 0 B 1 1 float spy {KRDG? B} {rdInpValue} {} {setValue} {} - sensor sensorValueC 1 0 1 0 C 1 1 float spy {KRDG? C} {rdInpValue} {} {setValue} {} - sensor sensorValueD 1 0 1 0 D 1 1 float spy {KRDG? D} {rdInpValue} {} {setValue} {} + sensor sampleSensor 0 1 0 0 1 1 1 text user {CSET? 1} {rdValue} {InpSample } {setPseudoValue} {A,B,C,D} + sensor Tsample 1 0 0 0 1 1 1 float spy {KRDG? A} {rdValue} {} {setValue} {} + sensor ctrl_Loop_1 1 0 0 0 1 1 1 text user {CSET? 1} {rdValue} {} {setValue} {} + sensor ctrlLp1_value 1 0 0 0 1 1 1 float spy {KRDG? A} {rdValue} {} {setValue} {} + sensor setpoint1 1 1 1 1 1 1 1 float user {SETP? 1} {rdValue} {SETP 1,} {setPoint} {} + sensor ctrl_Loop_2 1 0 0 0 2 1 1 text user {CSET? 2} {rdValue} {} {setValue} {} + sensor ctrlLp2_value 1 0 0 0 2 1 1 float spy {KRDG? B} {rdValue} {} {setValue} {} + sensor setpoint2 1 1 1 1 2 1 1 float user {SETP? 2} {rdValue} {SETP 2,} {setPoint} {} + sensor ctrl_Loop_3 1 0 0 0 3 0 1 text user {CSET? 3} {rdValue} {} {setValue} {} + sensor ctrlLp3_value 1 0 0 0 3 0 1 float spy {KRDG? C} {rdValue} {} {setValue} {} + sensor setpoint3 1 1 1 1 3 0 1 float user {SETP? 3} {rdValue} {SETP 3,} {setPoint} {} + sensor ctrl_Loop_4 1 0 0 0 4 0 1 text user {CSET? 4} {rdValue} {} {setValue} {} + sensor ctrlLp4_value 1 0 0 0 4 0 1 float spy {KRDG? D} {rdValue} {} {setValue} {} + sensor setpoint4 1 1 1 1 4 0 1 float user {SETP? 4} {rdValue} {SETP 4,} {setPoint} {} + sensor sensorValueA 1 0 1 0 A 1 1 float spy {KRDG? A} {rdInpValue} {} {setValue} {} + sensor sensorValueB 1 0 1 0 B 1 1 float spy {KRDG? B} {rdInpValue} {} {setValue} {} + sensor sensorValueC 1 0 1 0 C 1 1 float spy {KRDG? C} {rdInpValue} {} {setValue} {} + sensor sensorValueD 1 0 1 0 D 1 1 float spy {KRDG? D} {rdInpValue} {} {setValue} {} } set deviceCommand { - input alarm_Limits_A 1 1 1 0 A 1 1 text spy {ALARM? A} {rdAlarmVal} {ALARM A,} {setValue} {} - input alarm_Limits_B 1 1 1 0 B 1 1 text spy {ALARM? B} {rdAlarmVal} {ALARM B,} {setValue} {} - input alarm_Limits_C 1 1 1 0 C 1 1 text spy {ALARM? C} {rdAlarmVal} {ALARM C,} {setValue} {} - input alarm_Limits_D 1 1 1 0 D 1 1 text spy {ALARM? D} {rdAlarmVal} {ALARM D,} {setValue} {} - input alarmStatusA 1 0 1 0 A 1 1 text spy {ALARMST? A} {rdValue} {} {setValue} {} - input alarmStatusB 1 0 1 0 B 1 1 text spy {ALARMST? B} {rdValue} {} {setValue} {} - input alarmStatusC 1 0 1 0 C 1 1 text spy {ALARMST? C} {rdValue} {} {setValue} {} - input alarmStatusD 1 0 1 0 D 1 1 text spy {ALARMST? D} {rdValue} {} {setValue} {} - input inpCalCurve_A 1 1 1 0 A 1 1 int user {INCRV? A} {rdCrvValue} {INCRV A,} {setValue} {} - input calCurveHdr_A 1 0 1 0 A 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} - input inpCalCurve_B 1 1 1 0 B 1 1 int user {INCRV? B} {rdCrvValue} {INCRV B,} {setValue} {} - input calCurveHdr_B 1 0 1 0 B 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} - input inpCalCurve_C 1 1 1 0 C 1 1 int user {INCRV? C} {rdCrvValue} {INCRV C,} {setValue} {} - input calCurveHdr_C 1 0 1 0 C 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} - input inpCalCurve_D 1 1 1 0 D 1 1 int user {INCRV? D} {rdCrvValue} {INCRV D,} {setValue} {} - input calCurveHdr_D 1 0 1 0 D 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} + input alarm_Limits_A 1 1 1 0 A 1 1 text spy {ALARM? A} {rdAlarmVal} {ALARM A,} {setValue} {} + input alarm_Limits_B 1 1 1 0 B 1 1 text spy {ALARM? B} {rdAlarmVal} {ALARM B,} {setValue} {} + input alarm_Limits_C 1 1 1 0 C 1 1 text spy {ALARM? C} {rdAlarmVal} {ALARM C,} {setValue} {} + input alarm_Limits_D 1 1 1 0 D 1 1 text spy {ALARM? D} {rdAlarmVal} {ALARM D,} {setValue} {} + input alarmStatusA 1 0 1 0 A 1 1 text spy {ALARMST? A} {rdValue} {} {setValue} {} + input alarmStatusB 1 0 1 0 B 1 1 text spy {ALARMST? B} {rdValue} {} {setValue} {} + input alarmStatusC 1 0 1 0 C 1 1 text spy {ALARMST? C} {rdValue} {} {setValue} {} + input alarmStatusD 1 0 1 0 D 1 1 text spy {ALARMST? D} {rdValue} {} {setValue} {} + input inpCalCurve_A 1 1 1 0 A 1 1 int user {INCRV? A} {rdCrvValue} {INCRV A,} {setValue} {} + input calCurveHdr_A 1 0 1 0 A 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} + input inpCalCurve_B 1 1 1 0 B 1 1 int user {INCRV? B} {rdCrvValue} {INCRV B,} {setValue} {} + input calCurveHdr_B 1 0 1 0 B 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} + input inpCalCurve_C 1 1 1 0 C 1 1 int user {INCRV? C} {rdCrvValue} {INCRV C,} {setValue} {} + input calCurveHdr_C 1 0 1 0 C 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} + input inpCalCurve_D 1 1 1 0 D 1 1 int user {INCRV? D} {rdCrvValue} {INCRV D,} {setValue} {} + input calCurveHdr_D 1 0 1 0 D 1 1 text user {CRVHDR? } {rdValue} {} {setValue} {} input inputTypeA 1 1 1 0 A 0 1 text user {INTYPE? A} {rdValue} {INTYPE A,} {setValue} {} input inputTypeB 1 1 1 0 B 0 1 text user {INTYPE? B} {rdValue} {INTYPE B,} {setValue} {} input inputTypeC 1 1 1 0 C 0 1 text user {INTYPE? C} {rdValue} {INTYPE C,} {setValue} {} input inputTypeD 1 1 1 0 D 0 1 text user {INTYPE? D} {rdValue} {INTYPE D,} {setValue} {} - input sensorStatusA 1 0 1 0 A 1 1 text spy {RDGST? A} {rdBitValue} {} {setValue} {} - input sensorStatusB 1 0 1 0 B 1 1 text spy {RDGST? B} {rdBitValue} {} {setValue} {} - input sensorStatusC 1 0 1 0 C 1 1 text spy {RDGST? C} {rdBitValue} {} {setValue} {} - input sensorStatusD 1 0 1 0 D 1 1 text spy {RDGST? D} {rdBitValue} {} {setValue} {} - control outMode_1 1 1 1 0 1 0 1 text user {OUTMODE? 1} {rdCfgValue} {OUTMODE 1,} {setValue} {} - control outMode_2 1 1 1 0 2 0 1 text user {OUTMODE? 2} {rdCfgValue} {OUTMODE 2,} {setValue} {} - control outMode_3 1 1 1 0 3 0 1 text user {OUTMODE? 3} {rdCfgValue} {OUTMODE 3,} {setValue} {} - control outMode_4 1 1 1 0 4 0 1 text user {OUTMODE? 4} {rdCfgValue} {OUTMODE 4,} {setValue} {} - control manualOut_1 1 1 1 0 1 1 1 text user {MOUT? 1} {rdValue} {MOUT 1,} {setValue} {} - control manualOut_2 1 1 1 0 2 1 1 text user {MOUT? 2} {rdValue} {MOUT 2,} {setValue} {} - control manualOut_3 1 1 1 0 3 0 1 text user {MOUT? 3} {rdValue} {MOUT 3,} {setValue} {} - control manualOut_4 1 1 1 0 4 0 1 text user {MOUT? 4} {rdValue} {MOUT 4,} {setValue} {} - control pid_Loop_1 1 1 1 0 1 1 1 text user {PID? 1} {rdValue} {PID 1,} {setValue} {} - control pid_Loop_2 1 1 1 0 2 1 1 text user {PID? 2} {rdValue} {PID 2,} {setValue} {} - control ramp_Loop_1 1 1 1 0 1 1 1 text user {RAMP? 1} {rdValue} {RAMP 1,} {setValue} {} - control ramp_Loop_2 1 1 1 0 2 1 1 text user {RAMP? 2} {rdValue} {RAMP 2,} {setValue} {} - control rampStatus_Loop_1 1 0 1 0 1 1 1 int spy {RAMPST? 1} {rdValue} {} {setValue} {} - control rampStatus_Loop_2 1 0 1 0 2 1 1 int spy {RAMPST? 2} {rdValue} {} {setValue} {} - heater heaterOutput_1 1 1 1 0 1 0 1 float user {HTR? 1} {rdValue} {} {setValue} {} - heater heaterOutput_2 1 1 1 0 2 0 1 float user {HTR? 2} {rdValue} {} {setValue} {} - heater heaterStatus_1 1 0 1 0 1 0 1 int spy {HTRST? 1} {rdValue} {} {setValue} {} - heater heaterStatus_2 1 0 1 0 2 0 1 int spy {HTRST? 2} {rdValue} {} {setValue} {} - heater heaterRange_1 1 1 1 0 0 0 1 int user {RANGE? 1} {rdValue} {RANGE 1,} {setValue} {0,1,2,3} - heater heaterRange_2 1 1 1 0 0 0 1 int user {RANGE? 2} {rdValue} {RANGE 2,} {setValue} {0,1,2,3} - heater heaterRange_3 1 1 1 0 0 0 1 int user {RANGE? 3} {rdValue} {RANGE 3,} {setValue} {0,1} - heater heaterRange_4 1 1 1 0 0 0 1 int user {RANGE? 4} {rdValue} {RANGE 4,} {setValue} {0,1} - other deviceID_idn 1 0 1 0 0 1 1 text spy {*IDN?} {inTolerance} {} {setValue} {} - other selftest 1 0 0 0 0 1 1 int user {*TST?} {rdValue} {} {setValue} {} - other relayStatusHi 1 0 1 0 1 1 1 int spy {RELAYST? 1} {rdValue} {} {setValue} {} - other relayStatusLo 1 0 1 0 2 1 1 int spy {RELAYST? 2} {rdValue} {} {setValue} {} - other relayCtrlParmHi 1 1 1 0 0 1 1 int spy {RELAY? 1} {rdValue} {RELAY 1,} {setValue} {} - other relayCtrlParmLo 1 1 1 0 0 1 1 int spy {RELAY? 2} {rdValue} {RELAY 2,} {setValue} {} - other statusByte 1 0 1 0 0 1 1 int spy {*STB?} {rdValue} {} {setValue} {} + input sensorStatusA 1 0 1 0 A 1 1 text spy {RDGST? A} {rdBitValue} {} {setValue} {} + input sensorStatusB 1 0 1 0 B 1 1 text spy {RDGST? B} {rdBitValue} {} {setValue} {} + input sensorStatusC 1 0 1 0 C 1 1 text spy {RDGST? C} {rdBitValue} {} {setValue} {} + input sensorStatusD 1 0 1 0 D 1 1 text spy {RDGST? D} {rdBitValue} {} {setValue} {} + control outMode_1 1 1 1 0 1 0 1 text user {OUTMODE? 1} {rdCfgValue} {OUTMODE 1,} {setValue} {} + control outMode_2 1 1 1 0 2 0 1 text user {OUTMODE? 2} {rdCfgValue} {OUTMODE 2,} {setValue} {} + control outMode_3 1 1 1 0 3 0 1 text user {OUTMODE? 3} {rdCfgValue} {OUTMODE 3,} {setValue} {} + control outMode_4 1 1 1 0 4 0 1 text user {OUTMODE? 4} {rdCfgValue} {OUTMODE 4,} {setValue} {} + control manualOut_1 1 1 1 0 1 1 1 text user {MOUT? 1} {rdValue} {MOUT 1,} {setValue} {} + control manualOut_2 1 1 1 0 2 1 1 text user {MOUT? 2} {rdValue} {MOUT 2,} {setValue} {} + control manualOut_3 1 1 1 0 3 0 1 text user {MOUT? 3} {rdValue} {MOUT 3,} {setValue} {} + control manualOut_4 1 1 1 0 4 0 1 text user {MOUT? 4} {rdValue} {MOUT 4,} {setValue} {} + control pid_Loop_1 1 1 1 0 1 1 1 text user {PID? 1} {rdValue} {PID 1,} {setValue} {} + control pid_Loop_2 1 1 1 0 2 1 1 text user {PID? 2} {rdValue} {PID 2,} {setValue} {} + control ramp_Loop_1 1 1 1 0 1 1 1 text user {RAMP? 1} {rdValue} {RAMP 1,} {setValue} {} + control ramp_Loop_2 1 1 1 0 2 1 1 text user {RAMP? 2} {rdValue} {RAMP 2,} {setValue} {} + control rampStatus_Loop_1 1 0 1 0 1 1 1 int spy {RAMPST? 1} {rdValue} {} {setValue} {} + control rampStatus_Loop_2 1 0 1 0 2 1 1 int spy {RAMPST? 2} {rdValue} {} {setValue} {} + heater heaterOutput_1 1 1 1 0 1 0 1 float user {HTR? 1} {rdValue} {} {setValue} {} + heater heaterOutput_2 1 1 1 0 2 0 1 float user {HTR? 2} {rdValue} {} {setValue} {} + heater heaterStatus_1 1 0 1 0 1 0 1 int spy {HTRST? 1} {rdValue} {} {setValue} {} + heater heaterStatus_2 1 0 1 0 2 0 1 int spy {HTRST? 2} {rdValue} {} {setValue} {} + heater heaterRange_1 1 1 1 0 0 0 1 int user {RANGE? 1} {rdValue} {RANGE 1,} {setValue} {0,1,2,3} + heater heaterRange_2 1 1 1 0 0 0 1 int user {RANGE? 2} {rdValue} {RANGE 2,} {setValue} {0,1,2,3} + heater heaterRange_3 1 1 1 0 0 0 1 int user {RANGE? 3} {rdValue} {RANGE 3,} {setValue} {0,1} + heater heaterRange_4 1 1 1 0 0 0 1 int user {RANGE? 4} {rdValue} {RANGE 4,} {setValue} {0,1} + other deviceID_idn 1 0 1 0 0 1 1 text spy {*IDN?} {inTolerance} {} {setValue} {} + other selftest 1 0 0 0 0 1 1 int user {*TST?} {rdValue} {} {setValue} {} + other relayStatusHi 1 0 1 0 1 1 1 int spy {RELAYST? 1} {rdValue} {} {setValue} {} + other relayStatusLo 1 0 1 0 2 1 1 int spy {RELAYST? 2} {rdValue} {} {setValue} {} + other relayCtrlParmHi 1 1 1 0 0 1 1 int spy {RELAY? 1} {rdValue} {RELAY 1,} {setValue} {} + other relayCtrlParmLo 1 1 1 0 0 1 1 int spy {RELAY? 2} {rdValue} {RELAY 2,} {setValue} {} + other statusByte 1 0 1 0 0 1 1 int spy {*STB?} {rdValue} {} {setValue} {} } # The following 2 commands take no parameter - this makes them difficult to implement in a hipadaba structure # because they would be nodes without values... - # input alarmResetAll 0 1 0 0 0 1 1 text user {} {rdValue} {ALMRST} {setValue} {} - # other reset_rst 0 1 0 0 0 1 1 text user {} {rdValue} {*RST} {setValue} {} + # input alarmResetAll 0 1 0 0 0 1 1 text user {} {rdValue} {ALMRST} {setValue} {} + # other reset_rst 0 1 0 0 0 1 1 text user {} {rdValue} {*RST} {setValue} {} hfactory $scobj_hpath/status plain spy text hsetprop $scobj_hpath/status values busy,idle @@ -1896,10 +1895,10 @@ proc add_lakeshore_336 {name IP port {terminator \r\n} {_tol1 1.0} {_tol2 1.0} { if {[ catch { if {[string equal -nocase "aqadapter" "${IP}"]} { # dcl 2013-05-27: in this case the port is the name of the AsyncQueue - clientput "\add_lakeshore_336: makesctcontroller sct_ls336_$name aqadapter ${port} for Lakeshore model 336" + clientput "add_lakeshore_336: makesctcontroller sct_ls336_$name aqadapter ${port} for Lakeshore model 336" makesctcontroller sct_ls336_$name aqadapter ${port} } else { - clientput "\add_lakeshore_336: makesctcontroller sct_ls336_$name std ${IP}:$port $terminator for Lakeshore model 336" + clientput "add_lakeshore_336: makesctcontroller sct_ls336_$name std ${IP}:$port $terminator for Lakeshore model 336" makesctcontroller sct_ls336_$name std ${IP}:$port $terminator } ::scobj::ls336::mk_sct_lakeshore_336 sct_ls336_$name environment $name $CID $CTYPE $_tol1 $_tol2 $_verbose @@ -1910,91 +1909,3 @@ proc add_lakeshore_336 {name IP port {terminator \r\n} {_tol1 1.0} {_tol2 1.0} { return -code error "in add_ls336: $message" } } - -namespace eval ::scobj::lakeshore_336 { -set debug_threshold 5 -} -proc ::scobj::lakeshore_336::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::lakeshore_336::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::lakeshore_336::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_lakeshore_336.tcl" -::scobj::lakeshore_336::sics_log 9 "file evaluation of sct_lakeshore_336.tcl" - -proc ::scobj::lakeshore_336::read_config {} { - set catch_status [ catch { - set ns "::scobj::lakeshore_336" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "lakeshore_336"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {tol1 tol2 id} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_lakeshore_336 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::lakeshore_336::read_config -} else { - ::scobj::lakeshore_336::sics_log 5 "No config dict" -} - - - - -namespace import ::scobj::ls336::* 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 eb678312..6965a276 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl @@ -1755,8 +1755,9 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # @param tempobj short name for the temperature controller scriptcontext object (typ. tc1 or tc2) # @param tol temperature tolerance in Kelvin (typ. 1) # @return nothing (well, the sct object) - proc mk_sct_lakeshore_340 {sct_controller klasse tempobj CID CTYPE LSmodel tol1 tol2 verbose} { + proc mk_sct_lakeshore_340 {sct_controller klasse tempobj CID CTYPE tol1 tol2 verbose} { if {[ catch { + set LSmodel "ls340" set ::scobj::ls340::ls340_driveTolerance1 $tol1 set ::scobj::ls340::ls340_driveTolerance2 $tol2 set ::scobj::ls340::ls340_LSmodel $LSmodel @@ -1770,7 +1771,6 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p #Wombat uses only CR not CRLF #set ::scobj::ls340::ls340_term "" ! obsolete - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klasse sicslist setatt $tempobj long_name $tempobj # Create a base node for all the state machines of this sics object @@ -2100,10 +2100,10 @@ proc add_lakeshore_340 {name IP port {terminator \r\n} {_tol1 1.0} {_tol2 1.0} { if {[ catch { set _ls340_LSmodel 340 if {[string equal -nocase "aqadapter" "${IP}"]} { - clientput "\add_lakeshore_340: makesctcontroller sct_ls340_$name aqadapter ${port} for Lakeshore model 340" + clientput "add_lakeshore_340: makesctcontroller sct_ls340_$name aqadapter ${port} for Lakeshore model 340" makesctcontroller sct_ls340_$name aqadapter ${port} } else { - clientput "\add_lakeshore_340: makesctcontroller sct_ls340_$name std ${IP}:$port $terminator for Lakeshore model 340" + clientput "add_lakeshore_340: makesctcontroller sct_ls340_$name std ${IP}:$port $terminator for Lakeshore model 340" makesctcontroller sct_ls340_$name std ${IP}:$port $terminator } ::scobj::ls340::mk_sct_lakeshore_340 sct_ls340_$name environment $name $CID $CTYPE $_ls340_LSmodel $_tol1 $_tol2 $_verbose @@ -2114,87 +2114,3 @@ proc add_lakeshore_340 {name IP port {terminator \r\n} {_tol1 1.0} {_tol2 1.0} { return -code error "in add_lakeshore_340: $message" } } - -namespace eval ::scobj::lakeshore_340 { -set debug_threshold 5 -} -proc ::scobj::lakeshore_340::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::lakeshore_340::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::lakeshore_340::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_lakeshore_336.tcl" -::scobj::lakeshore_336::sics_log 9 "file evaluation of sct_lakeshore_336.tcl" - -proc ::scobj::lakeshore_340::read_config {} { - set catch_status [ catch { - set ns "::scobj::lakeshore_340" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "lakeshore_340"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {tol1 tol2 id} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_lakeshore_340 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} - } - -if { [info exists ::config_dict] } { - ::scobj::lakeshore_340::read_config -} else { - ::scobj::lakeshore_340::sics_log 5 "No config dict" -} -namespace import ::scobj::ls340::* diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_370.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_370.tcl index e7032d2f..6b4750c0 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_370.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_370.tcl @@ -785,7 +785,6 @@ namespace eval ::scobj::[set vendor]_[set device] { debug_log 1 "mk_sct_driver $sct_controller $klass $name $tol" set catch_status [ catch { - MakeSICSObj $name SCT_OBJECT sicslist setatt $name klass $klass sicslist setatt $name long_name $name @@ -927,72 +926,3 @@ namespace eval ::scobj::[set vendor]_[set device] { namespace import ::scobj::[set vendor]_[set device]::* # add_lakeshore_370 "tc371" 127.0.0.1 7371 2.0 - -proc ::scobj::lakeshore_370::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::lakeshore_370::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::lakeshore_370::${debug_string}" - } - } catch_message ] -} - - -proc ::scobj::lakeshore_370::read_config {} { - set catch_status [ catch { - set ns "::scobj::lakeshore_370" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "lakeshore_370"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - add_lakeshore_370 ${name} "aqadapter" ${asyncqueue} - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::lakeshore_370::read_config -} else { - ::scobj::lakeshore_370::sics_log 5 "No config dict" -} diff --git a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl new file mode 100644 index 00000000..85f56563 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl @@ -0,0 +1,161 @@ +# Generated driver for lakeshore_m370 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::lakeshore_m370 { + set debug_threshold 5 +} + +proc ::scobj::lakeshore_m370::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/lakeshore_m370_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::lakeshore_m370::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::lakeshore_m370::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::lakeshore_m370::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::lakeshore_m370::mkDriver { sct_controller name tol } { + ::scobj::lakeshore_m370::sics_log 9 "::scobj::lakeshore_m370::mkDriver ${sct_controller} ${name} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_driver $sct_controller environment $name $tol +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::lakeshore_m370 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_lakeshore_m370 {name IP port tol} { + set catch_status [ catch { + ::scobj::lakeshore_m370::sics_log 9 "add_lakeshore_m370 ${name} ${IP} ${port} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::lakeshore_m370::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::lakeshore_m370::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::lakeshore_m370::sics_log 9 "[environment_simulation] => No sctcontroller for lakeshore_m370" + } + ::scobj::lakeshore_m370::sics_log 1 "::scobj::lakeshore_m370::mkDriver sct_${name} ${name} ${tol}" + ::scobj::lakeshore_m370::mkDriver sct_${name} ${name} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_lakeshore_m370.tcl" +::scobj::lakeshore_m370::sics_log 9 "file evaluation of sct_lakeshore_m370.tcl" + +proc ::scobj::lakeshore_m370::read_config {} { + set catch_status [ catch { + set ns "::scobj::lakeshore_m370" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "lakeshore_m370"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_lakeshore_m370 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_lakeshore_m370 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::lakeshore_m370::read_config +} else { + ::scobj::lakeshore_m370::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_ls336.tcl b/site_ansto/instrument/config/environment/temperature/sct_ls336.tcl new file mode 100644 index 00000000..8d4dc858 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_ls336.tcl @@ -0,0 +1,161 @@ +# Generated driver for ls336 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::ls336 { + set debug_threshold 5 +} + +proc ::scobj::ls336::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/ls336_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::ls336::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::ls336::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::ls336::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::ls336::mkDriver { sct_controller name id datype tol1 tol2 } { + ::scobj::ls336::sics_log 9 "::scobj::ls336::mkDriver ${sct_controller} ${name} ${id} ${datype} ${tol1} ${tol2}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + ::scobj::ls336::mk_sct_lakeshore_336 $sct_controller environment $name $id $datype $tol1 $tol2 0 +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::ls336 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_ls336 {name IP port id datype {tol1 1.0} {tol2 1.0}} { + set catch_status [ catch { + ::scobj::ls336::sics_log 9 "add_ls336 ${name} ${IP} ${port} ${id} ${datype} ${tol1} ${tol2}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::ls336::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::ls336::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::ls336::sics_log 9 "[environment_simulation] => No sctcontroller for ls336" + } + ::scobj::ls336::sics_log 1 "::scobj::ls336::mkDriver sct_${name} ${name} ${id} ${datype} ${tol1} ${tol2}" + ::scobj::ls336::mkDriver sct_${name} ${name} ${id} ${datype} ${tol1} ${tol2} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_ls336.tcl" +::scobj::ls336::sics_log 9 "file evaluation of sct_ls336.tcl" + +proc ::scobj::ls336::read_config {} { + set catch_status [ catch { + set ns "::scobj::ls336" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "ls336"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype tol1 tol2} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_ls336 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_ls336 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::ls336::read_config +} else { + ::scobj::ls336::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_ls340.tcl b/site_ansto/instrument/config/environment/temperature/sct_ls340.tcl new file mode 100644 index 00000000..bf33673a --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_ls340.tcl @@ -0,0 +1,161 @@ +# Generated driver for ls340 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::ls340 { + set debug_threshold 5 +} + +proc ::scobj::ls340::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/ls340_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::ls340::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::ls340::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::ls340::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::ls340::mkDriver { sct_controller name id datype tol1 tol2 } { + ::scobj::ls340::sics_log 9 "::scobj::ls340::mkDriver ${sct_controller} ${name} ${id} ${datype} ${tol1} ${tol2}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + ::scobj::ls340::mk_sct_lakeshore_340 $sct_controller environment $name $id $datype $tol1 $tol2 0 +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::ls340 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_ls340 {name IP port id datype {tol1 1.0} {tol2 1.0}} { + set catch_status [ catch { + ::scobj::ls340::sics_log 9 "add_ls340 ${name} ${IP} ${port} ${id} ${datype} ${tol1} ${tol2}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::ls340::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::ls340::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::ls340::sics_log 9 "[environment_simulation] => No sctcontroller for ls340" + } + ::scobj::ls340::sics_log 1 "::scobj::ls340::mkDriver sct_${name} ${name} ${id} ${datype} ${tol1} ${tol2}" + ::scobj::ls340::mkDriver sct_${name} ${name} ${id} ${datype} ${tol1} ${tol2} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_ls340.tcl" +::scobj::ls340::sics_log 9 "file evaluation of sct_ls340.tcl" + +proc ::scobj::ls340::read_config {} { + set catch_status [ catch { + set ns "::scobj::ls340" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "ls340"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype tol1 tol2} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_ls340 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_ls340 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::ls340::read_config +} else { + ::scobj::ls340::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl index ff9dacb7..4d9e5e7a 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl @@ -180,7 +180,7 @@ proc ::scobj::mercury_base::rdText {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -212,7 +212,7 @@ proc ::scobj::mercury_base::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -350,7 +350,6 @@ proc ::scobj::mercury_base::mkDriver { sct_controller name id tol } { ${sct_controller} poll ${scobj_hpath}/Loop1/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop1/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop1/setpoint - ansto_makesctdrive ${name}_Loop1_setpoint ${scobj_hpath}/Loop1/setpoint ${scobj_hpath}/Loop1/sensor ${sct_controller} } else { ::scobj::mercury_base::sics_log 9 "[environment_simulation] => No poll/write for mercury_base" } @@ -427,7 +426,6 @@ proc ::scobj::mercury_base::mkDriver { sct_controller name id tol } { ${sct_controller} poll ${scobj_hpath}/Loop2/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop2/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop2/setpoint - ansto_makesctdrive ${name}_Loop2_setpoint ${scobj_hpath}/Loop2/setpoint ${scobj_hpath}/Loop2/sensor ${sct_controller} } else { ::scobj::mercury_base::sics_log 9 "[environment_simulation] => No poll/write for mercury_base" } @@ -504,12 +502,16 @@ proc ::scobj::mercury_base::mkDriver { sct_controller name id tol } { ${sct_controller} poll ${scobj_hpath}/Loop3/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop3/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop3/setpoint - ansto_makesctdrive ${name}_Loop3_setpoint ${scobj_hpath}/Loop3/setpoint ${scobj_hpath}/Loop3/sensor ${sct_controller} } else { ::scobj::mercury_base::sics_log 9 "[environment_simulation] => No poll/write for mercury_base" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_Loop1_setpoint ${scobj_hpath}/Loop1/setpoint ${scobj_hpath}/Loop1/sensor ${sct_controller} + ansto_makesctdrive ${name}_Loop2_setpoint ${scobj_hpath}/Loop2/setpoint ${scobj_hpath}/Loop2/sensor ${sct_controller} + ansto_makesctdrive ${name}_Loop3_setpoint ${scobj_hpath}/Loop3/setpoint ${scobj_hpath}/Loop3/sensor ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -548,14 +550,17 @@ clientput "file evaluation of sct_mercury_base.tcl" proc ::scobj::mercury_base::read_config {} { set catch_status [ catch { set ns "::scobj::mercury_base" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -564,40 +569,52 @@ proc ::scobj::mercury_base::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "mercury_base"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id tol} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_mercury_base ${name} ${IP} ${PORT} {*}$arg_list + } else { add_mercury_base ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_mercury_level.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_level.tcl index ed0c4d4a..f4f8dcd9 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_level.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_level.tcl @@ -107,7 +107,7 @@ proc ::scobj::mercury_level::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -225,14 +225,17 @@ clientput "file evaluation of sct_mercury_level.tcl" proc ::scobj::mercury_level::read_config {} { set catch_status [ catch { set ns "::scobj::mercury_level" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -241,40 +244,52 @@ proc ::scobj::mercury_level::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "mercury_level"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_mercury_level ${name} ${IP} ${PORT} {*}$arg_list + } else { add_mercury_level ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_mercury_pres.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_pres.tcl index 36f16976..1d4d1211 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_pres.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_pres.tcl @@ -180,7 +180,7 @@ proc ::scobj::mercury_pres::rdText {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -212,7 +212,7 @@ proc ::scobj::mercury_pres::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -345,12 +345,14 @@ proc ::scobj::mercury_pres::mkDriver { sct_controller name id tol } { ${sct_controller} poll ${scobj_hpath}/Loop8/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop8/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop8/setpoint - ansto_makesctdrive ${name}_Loop8_setpoint ${scobj_hpath}/Loop8/setpoint ${scobj_hpath}/Loop8/sensor ${sct_controller} } else { ::scobj::mercury_pres::sics_log 9 "[environment_simulation] => No poll/write for mercury_pres" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_Loop8_setpoint ${scobj_hpath}/Loop8/setpoint ${scobj_hpath}/Loop8/sensor ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -389,14 +391,17 @@ clientput "file evaluation of sct_mercury_pres.tcl" proc ::scobj::mercury_pres::read_config {} { set catch_status [ catch { set ns "::scobj::mercury_pres" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -405,40 +410,52 @@ proc ::scobj::mercury_pres::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "mercury_pres"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id tol} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_mercury_pres ${name} ${IP} ${PORT} {*}$arg_list + } else { add_mercury_pres ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_mercury_scpi.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_scpi.tcl index d9b33c18..ca49ac1e 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_scpi.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_scpi.tcl @@ -180,7 +180,7 @@ proc ::scobj::mercury_scpi::rdText {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -212,7 +212,7 @@ proc ::scobj::mercury_scpi::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -421,7 +421,6 @@ proc ::scobj::mercury_scpi::mkDriver { sct_controller name id permlink tol valve ${sct_controller} poll ${scobj_hpath}/Loop1/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop1/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop1/setpoint - ansto_makesctdrive ${name}_Loop1_setpoint ${scobj_hpath}/Loop1/setpoint ${scobj_hpath}/Loop1/sensor ${sct_controller} } else { ::scobj::mercury_scpi::sics_log 9 "[environment_simulation] => No poll/write for mercury_scpi" } @@ -498,7 +497,6 @@ proc ::scobj::mercury_scpi::mkDriver { sct_controller name id permlink tol valve ${sct_controller} poll ${scobj_hpath}/Loop2/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop2/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop2/setpoint - ansto_makesctdrive ${name}_Loop2_setpoint ${scobj_hpath}/Loop2/setpoint ${scobj_hpath}/Loop2/sensor ${sct_controller} } else { ::scobj::mercury_scpi::sics_log 9 "[environment_simulation] => No poll/write for mercury_scpi" } @@ -575,7 +573,6 @@ proc ::scobj::mercury_scpi::mkDriver { sct_controller name id permlink tol valve ${sct_controller} poll ${scobj_hpath}/Loop3/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop3/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop3/setpoint - ansto_makesctdrive ${name}_Loop3_setpoint ${scobj_hpath}/Loop3/setpoint ${scobj_hpath}/Loop3/sensor ${sct_controller} } else { ::scobj::mercury_scpi::sics_log 9 "[environment_simulation] => No poll/write for mercury_scpi" } @@ -652,7 +649,6 @@ proc ::scobj::mercury_scpi::mkDriver { sct_controller name id permlink tol valve ${sct_controller} poll ${scobj_hpath}/Loop4/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop4/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop4/setpoint - ansto_makesctdrive ${name}_Loop4_setpoint ${scobj_hpath}/Loop4/setpoint ${scobj_hpath}/Loop4/sensor ${sct_controller} } else { ::scobj::mercury_scpi::sics_log 9 "[environment_simulation] => No poll/write for mercury_scpi" } @@ -700,12 +696,18 @@ proc ::scobj::mercury_scpi::mkDriver { sct_controller name id permlink tol valve if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { ${sct_controller} poll ${scobj_hpath}/Valve/sensor 5 ${sct_controller} write ${scobj_hpath}/Valve/setpoint - ansto_makesctdrive ${name}_Valve_setpoint ${scobj_hpath}/Valve/setpoint ${scobj_hpath}/Valve/sensor ${sct_controller} } else { ::scobj::mercury_scpi::sics_log 9 "[environment_simulation] => No poll/write for mercury_scpi" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_Loop1_setpoint ${scobj_hpath}/Loop1/setpoint ${scobj_hpath}/Loop1/sensor ${sct_controller} + ansto_makesctdrive ${name}_Loop2_setpoint ${scobj_hpath}/Loop2/setpoint ${scobj_hpath}/Loop2/sensor ${sct_controller} + ansto_makesctdrive ${name}_Loop3_setpoint ${scobj_hpath}/Loop3/setpoint ${scobj_hpath}/Loop3/sensor ${sct_controller} + ansto_makesctdrive ${name}_Loop4_setpoint ${scobj_hpath}/Loop4/setpoint ${scobj_hpath}/Loop4/sensor ${sct_controller} + ansto_makesctdrive ${name}_Valve_setpoint ${scobj_hpath}/Valve/setpoint ${scobj_hpath}/Valve/sensor ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -744,14 +746,17 @@ clientput "file evaluation of sct_mercury_scpi.tcl" proc ::scobj::mercury_scpi::read_config {} { set catch_status [ catch { set ns "::scobj::mercury_scpi" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -760,40 +765,52 @@ proc ::scobj::mercury_scpi::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "mercury_scpi"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id permlink tol valve_tol} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id permlink tol valve_tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_mercury_scpi ${name} ${IP} ${PORT} {*}$arg_list + } else { add_mercury_scpi ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_mercury_temp.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_temp.tcl index c2bacdd5..923e653d 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_temp.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_temp.tcl @@ -180,7 +180,7 @@ proc ::scobj::mercury_temp::rdText {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -212,7 +212,7 @@ proc ::scobj::mercury_temp::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -350,12 +350,14 @@ proc ::scobj::mercury_temp::mkDriver { sct_controller name id tol } { ${sct_controller} poll ${scobj_hpath}/Loop4/sensor 1 ${sct_controller} poll ${scobj_hpath}/Loop4/setpoint 5 ${sct_controller} write ${scobj_hpath}/Loop4/setpoint - ansto_makesctdrive ${name}_Loop4_setpoint ${scobj_hpath}/Loop4/setpoint ${scobj_hpath}/Loop4/sensor ${sct_controller} } else { ::scobj::mercury_temp::sics_log 9 "[environment_simulation] => No poll/write for mercury_temp" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_Loop4_setpoint ${scobj_hpath}/Loop4/setpoint ${scobj_hpath}/Loop4/sensor ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -394,14 +396,17 @@ clientput "file evaluation of sct_mercury_temp.tcl" proc ::scobj::mercury_temp::read_config {} { set catch_status [ catch { set ns "::scobj::mercury_temp" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -410,40 +415,52 @@ proc ::scobj::mercury_temp::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "mercury_temp"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id tol} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_mercury_temp ${name} ${IP} ${PORT} {*}$arg_list + } else { add_mercury_temp ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_mercury_valve.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_valve.tcl index bd4280b3..73944488 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_valve.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_valve.tcl @@ -180,7 +180,7 @@ proc ::scobj::mercury_valve::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -299,12 +299,14 @@ proc ::scobj::mercury_valve::mkDriver { sct_controller name id valve_tol } { if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { ${sct_controller} poll ${scobj_hpath}/Valve/sensor 5 ${sct_controller} write ${scobj_hpath}/Valve/setpoint - ansto_makesctdrive ${name}_Valve_setpoint ${scobj_hpath}/Valve/setpoint ${scobj_hpath}/Valve/sensor ${sct_controller} } else { ::scobj::mercury_valve::sics_log 9 "[environment_simulation] => No poll/write for mercury_valve" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_Valve_setpoint ${scobj_hpath}/Valve/setpoint ${scobj_hpath}/Valve/sensor ${sct_controller} + } # mkDriver hook code goes here } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -343,14 +345,17 @@ clientput "file evaluation of sct_mercury_valve.tcl" proc ::scobj::mercury_valve::read_config {} { set catch_status [ catch { set ns "::scobj::mercury_valve" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -359,40 +364,52 @@ proc ::scobj::mercury_valve::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "mercury_valve"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } - set arg_list [list] - foreach arg {id valve_tol} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" } + } + set arg_list [list] + set missing_list [list] + foreach arg {id valve_tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_mercury_valve ${name} ${IP} ${PORT} {*}$arg_list + } else { add_mercury_valve ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_nprvasm2.tcl b/site_ansto/instrument/config/environment/temperature/sct_nprvasm2.tcl new file mode 100644 index 00000000..a5d27553 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_nprvasm2.tcl @@ -0,0 +1,161 @@ +# Generated driver for nprvasm2 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::nprvasm2 { + set debug_threshold 5 +} + +proc ::scobj::nprvasm2::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/nprvasm2_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::nprvasm2::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::nprvasm2::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::nprvasm2::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::nprvasm2::mkDriver { sct_controller name tol } { + ::scobj::nprvasm2::sics_log 9 "::scobj::nprvasm2::mkDriver ${sct_controller} ${name} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_newport_rva sct_${name} environment $name $tol +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::nprvasm2 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_nprvasm2 {name IP port {tol 1.0}} { + set catch_status [ catch { + ::scobj::nprvasm2::sics_log 9 "add_nprvasm2 ${name} ${IP} ${port} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::nprvasm2::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::nprvasm2::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::nprvasm2::sics_log 9 "[environment_simulation] => No sctcontroller for nprvasm2" + } + ::scobj::nprvasm2::sics_log 1 "::scobj::nprvasm2::mkDriver sct_${name} ${name} ${tol}" + ::scobj::nprvasm2::mkDriver sct_${name} ${name} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_nprvasm2.tcl" +::scobj::nprvasm2::sics_log 9 "file evaluation of sct_nprvasm2.tcl" + +proc ::scobj::nprvasm2::read_config {} { + set catch_status [ catch { + set ns "::scobj::nprvasm2" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "nprvasm2"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_nprvasm2 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_nprvasm2 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::nprvasm2::read_config +} else { + ::scobj::nprvasm2::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl b/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl index ea5b211d..623d8fa5 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl @@ -60,7 +60,7 @@ proc ::scobj::pfeiffer_hg::ack_enq {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -197,19 +197,19 @@ proc ::scobj::pfeiffer_hg::noResponse {tc_root} { proc ::scobj::pfeiffer_hg::pid_pressure {tc_root sp pv} { set catch_status [ catch { debug_log ${tc_root} 1 "pid_pressure tc_root=${tc_root} sct=[sct] pv=${pv} sp=${sp}" - sct pid_error [expr ${sp} - ${pv}] - set p_value [expr [sct pid_pvalue] * [sct pid_error]] - set d_value [expr [sct pid_dvalue] * (${pv} - [sct oldval])] + sct pid_error [expr {${sp} - ${pv}}] + set p_value [expr {[sct pid_pvalue] * [sct pid_error]}] + set d_value [expr {[sct pid_dvalue] * (${pv} - [sct oldval])}] sct pid_deriv [sct pid_error] - sct pid_integ [expr [sct pid_integ] + [sct pid_error]] + sct pid_integ [expr {[sct pid_integ] + [sct pid_error]}] if { [sct pid_integ] > [sct pid_imax] } { sct pid_integ [sct pid_imax] } if { [sct pid_integ] < -[sct pid_imax] } { sct pid_integ -[sct pid_imax] } - set i_value [expr [sct pid_ivalue] * [sct pid_integ]] - set pid [expr ${p_value} + ${i_value} + ${d_value}] + set i_value [expr {[sct pid_ivalue] * [sct pid_integ]}] + set pid [expr {${p_value} + ${i_value} + ${d_value}}] # pid_pressure hook code starts if { [hpropexists [sct] pid_control] } { set co [hgetpropval [sct] pid_control] @@ -249,7 +249,7 @@ proc ::scobj::pfeiffer_hg::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -289,7 +289,7 @@ proc ::scobj::pfeiffer_hg::readPR1 {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -446,12 +446,14 @@ proc ::scobj::pfeiffer_hg::mkDriver { sct_controller name } { if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { ${sct_controller} poll ${scobj_hpath}/pressure/sensor 1 ${sct_controller} write ${scobj_hpath}/pressure/setpoint - ansto_makesctdrive ${name}_pressure_setpoint ${scobj_hpath}/pressure/setpoint ${scobj_hpath}/pressure/sensor ${sct_controller} } else { ::scobj::pfeiffer_hg::sics_log 9 "[environment_simulation] => No poll/write for pfeiffer_hg" } hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ansto_makesctdrive ${name}_pressure_setpoint ${scobj_hpath}/pressure/setpoint ${scobj_hpath}/pressure/sensor ${sct_controller} + } # mkDriver hook code starts hsetprop ${scobj_hpath}/pressure/sensor read ${ns}::sendPR1 ${scobj_hpath} ack_enq {PR1} hsetprop ${scobj_hpath}/pressure/sensor ack_enq ${ns}::ack_enq ${scobj_hpath} @@ -493,14 +495,17 @@ clientput "file evaluation of sct_pfeiffer_hg.tcl" proc ::scobj::pfeiffer_hg::read_config {} { set catch_status [ catch { set ns "::scobj::pfeiffer_hg" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -509,31 +514,37 @@ proc ::scobj::pfeiffer_hg::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "pfeiffer_hg"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_pfeiffer_hg ${name} ${IP} ${PORT} + } else { add_pfeiffer_hg ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/config/environment/temperature/sct_rvasm2.tcl b/site_ansto/instrument/config/environment/temperature/sct_rvasm2.tcl index e0b46e18..0ec95faa 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_rvasm2.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_rvasm2.tcl @@ -944,7 +944,6 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable\ set catch_status [ catch { set ns "[namespace current]" - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klass sicslist setatt $tempobj long_name $tempobj diff --git a/site_ansto/instrument/config/environment/temperature/sct_watlow_mpm.tcl b/site_ansto/instrument/config/environment/temperature/sct_watlow_mpm.tcl new file mode 100644 index 00000000..132762fd --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_watlow_mpm.tcl @@ -0,0 +1,161 @@ +# Generated driver for watlow_mpm +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::watlow_mpm { + set debug_threshold 5 +} + +proc ::scobj::watlow_mpm::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/watlow_mpm_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::watlow_mpm::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::watlow_mpm::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::watlow_mpm::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::watlow_mpm::mkDriver { sct_controller name id datype dev_id tol } { + ::scobj::watlow_mpm::sics_log 9 "::scobj::watlow_mpm::mkDriver ${sct_controller} ${name} ${id} ${datype} ${dev_id} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_watlow_pm $sct_controller environment $name $dev_id $tol $id $datype +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::watlow_mpm { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_watlow_mpm {name IP port id datype dev_id tol} { + set catch_status [ catch { + ::scobj::watlow_mpm::sics_log 9 "add_watlow_mpm ${name} ${IP} ${port} ${id} ${datype} ${dev_id} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::watlow_mpm::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::watlow_mpm::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::watlow_mpm::sics_log 9 "[environment_simulation] => No sctcontroller for watlow_mpm" + } + ::scobj::watlow_mpm::sics_log 1 "::scobj::watlow_mpm::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol}" + ::scobj::watlow_mpm::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_watlow_mpm.tcl" +::scobj::watlow_mpm::sics_log 9 "file evaluation of sct_watlow_mpm.tcl" + +proc ::scobj::watlow_mpm::read_config {} { + set catch_status [ catch { + set ns "::scobj::watlow_mpm" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "watlow_mpm"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype dev_id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_watlow_mpm ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_watlow_mpm ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::watlow_mpm::read_config +} else { + ::scobj::watlow_mpm::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_watlow_mrm.tcl b/site_ansto/instrument/config/environment/temperature/sct_watlow_mrm.tcl new file mode 100644 index 00000000..03ecb75c --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_watlow_mrm.tcl @@ -0,0 +1,161 @@ +# Generated driver for watlow_mrm +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::watlow_mrm { + set debug_threshold 5 +} + +proc ::scobj::watlow_mrm::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/watlow_mrm_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::watlow_mrm::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::watlow_mrm::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::watlow_mrm::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::watlow_mrm::mkDriver { sct_controller name id datype dev_id tol } { + ::scobj::watlow_mrm::sics_log 9 "::scobj::watlow_mrm::mkDriver ${sct_controller} ${name} ${id} ${datype} ${dev_id} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_watlow_rm $sct_controller environment $name $dev_id $tol $id $datype +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::watlow_mrm { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_watlow_mrm {name IP port id datype dev_id tol} { + set catch_status [ catch { + ::scobj::watlow_mrm::sics_log 9 "add_watlow_mrm ${name} ${IP} ${port} ${id} ${datype} ${dev_id} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::watlow_mrm::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::watlow_mrm::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::watlow_mrm::sics_log 9 "[environment_simulation] => No sctcontroller for watlow_mrm" + } + ::scobj::watlow_mrm::sics_log 1 "::scobj::watlow_mrm::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol}" + ::scobj::watlow_mrm::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_watlow_mrm.tcl" +::scobj::watlow_mrm::sics_log 9 "file evaluation of sct_watlow_mrm.tcl" + +proc ::scobj::watlow_mrm::read_config {} { + set catch_status [ catch { + set ns "::scobj::watlow_mrm" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "watlow_mrm"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype dev_id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_watlow_mrm ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_watlow_mrm ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::watlow_mrm::read_config +} else { + ::scobj::watlow_mrm::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_watlow_mst4.tcl b/site_ansto/instrument/config/environment/temperature/sct_watlow_mst4.tcl new file mode 100644 index 00000000..cfabdd2a --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_watlow_mst4.tcl @@ -0,0 +1,161 @@ +# Generated driver for watlow_mst4 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::watlow_mst4 { + set debug_threshold 5 +} + +proc ::scobj::watlow_mst4::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/watlow_mst4_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::watlow_mst4::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::watlow_mst4::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::watlow_mst4::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::watlow_mst4::mkDriver { sct_controller name id datype dev_id tol } { + ::scobj::watlow_mst4::sics_log 9 "::scobj::watlow_mst4::mkDriver ${sct_controller} ${name} ${id} ${datype} ${dev_id} ${tol}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT user float + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + mk_sct_watlow_st $sct_controller environment $name $dev_id $tol $id $datype +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::watlow_mst4 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_watlow_mst4 {name IP port id datype dev_id tol} { + set catch_status [ catch { + ::scobj::watlow_mst4::sics_log 9 "add_watlow_mst4 ${name} ${IP} ${port} ${id} ${datype} ${dev_id} ${tol}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::watlow_mst4::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::watlow_mst4::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::watlow_mst4::sics_log 9 "[environment_simulation] => No sctcontroller for watlow_mst4" + } + ::scobj::watlow_mst4::sics_log 1 "::scobj::watlow_mst4::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol}" + ::scobj::watlow_mst4::mkDriver sct_${name} ${name} ${id} ${datype} ${dev_id} ${tol} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_watlow_mst4.tcl" +::scobj::watlow_mst4::sics_log 9 "file evaluation of sct_watlow_mst4.tcl" + +proc ::scobj::watlow_mst4::read_config {} { + set catch_status [ catch { + set ns "::scobj::watlow_mst4" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "watlow_mst4"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {id datype dev_id tol} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_watlow_mst4 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_watlow_mst4 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::watlow_mst4::read_config +} else { + ::scobj::watlow_mst4::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_watlow_pm.tcl b/site_ansto/instrument/config/environment/temperature/sct_watlow_pm.tcl index 0661bc98..698e4d10 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_watlow_pm.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_watlow_pm.tcl @@ -403,7 +403,6 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable\ set catch_status [ catch { set ns "[namespace current]" - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klass sicslist setatt $tempobj long_name $tempobj @@ -540,87 +539,4 @@ set fd [open "../log/watlow_pm.log" w] puts $fd "file evaluation of sct_watlow_pm.tcl" close $fd -namespace eval ::scobj::watlow_pm { -set debug_threshold 5 -} -proc ::scobj::watlow_pm::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::watlow_pm::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::watlow_pm::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_watlow_pm.tcl" -::scobj::watlow_pm::sics_log 9 "file evaluation of sct_watlow_pm.tcl" - -proc ::scobj::watlow_pm::read_config {} { - set catch_status [ catch { - set ns "::scobj::watlow_pm" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "watlow_pm"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {devid tol id type} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_watlow_pm ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::watlow_pm::read_config -} else { - ::scobj::watlow_pm::sics_log 5 "No config dict" -} - namespace import ::scobj::watlow_pm::* diff --git a/site_ansto/instrument/config/environment/temperature/sct_watlow_rm.tcl b/site_ansto/instrument/config/environment/temperature/sct_watlow_rm.tcl index b94b82bf..7ee618c6 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_watlow_rm.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_watlow_rm.tcl @@ -411,7 +411,6 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable\ set catch_status [ catch { set ns "[namespace current]" - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klass sicslist setatt $tempobj long_name $tempobj @@ -570,87 +569,4 @@ set fd [open "../log/watlow_rm.log" w] puts $fd "file evaluation of sct_watlow_rm.tcl" close $fd -namespace eval ::scobj::watlow_rm { -set debug_threshold 5 -} -proc ::scobj::watlow_rm::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::watlow_rm::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::watlow_rm::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_watlow_rm.tcl" -::scobj::watlow_rm::sics_log 9 "file evaluation of sct_watlow_rm.tcl" - -proc ::scobj::watlow_rm::read_config {} { - set catch_status [ catch { - set ns "::scobj::watlow_rm" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "watlow_rm"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {devid tol id type} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_watlow_rm ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::watlow_rm::read_config -} else { - ::scobj::watlow_rm::sics_log 5 "No config dict" -} - namespace import ::scobj::watlow_rm::* diff --git a/site_ansto/instrument/config/environment/temperature/sct_watlow_st4.tcl b/site_ansto/instrument/config/environment/temperature/sct_watlow_st4.tcl index be23a751..d933b8d1 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_watlow_st4.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_watlow_st4.tcl @@ -597,7 +597,6 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable\ set catch_status [ catch { set ns "[namespace current]" - MakeSICSObj $tempobj SCT_OBJECT sicslist setatt $tempobj klass $klass sicslist setatt $tempobj long_name $tempobj @@ -781,89 +780,4 @@ set fd [open "../log/watlow_st.log" w] puts $fd "file evaluation of sct_watlow_st4.tcl" close $fd -namespace eval ::scobj::watlow_st4 { -set debug_threshold 5 -} -proc ::scobj::watlow_st4::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::watlow_st4::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::watlow_st4::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_watlow_st4.tcl" -::scobj::watlow_st4::sics_log 9 "file evaluation of sct_watlow_st4.tcl" - -proc ::scobj::watlow_st4::read_config {} { - set catch_status [ catch { - set ns "::scobj::watlow_st4" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "watlow_st4"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {devid tol id type} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_watlow_st4 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::watlow_st4::read_config -} else { - ::scobj::watlow_st4::sics_log 5 "No config dict" -} - - - namespace import ::scobj::watlow_st::* diff --git a/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl b/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl new file mode 100644 index 00000000..e65bc7a5 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl @@ -0,0 +1,161 @@ +# Generated driver for west4100 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::west4100 { + set debug_threshold 5 +} + +proc ::scobj::west4100::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/west4100_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::west4100::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::west4100::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::west4100::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::west4100::mkDriver { sct_controller name IP dev_id } { + ::scobj::west4100::sics_log 9 "::scobj::west4100::mkDriver ${sct_controller} ${name} ${IP} ${dev_id}" + set ns "[namespace current]" + set catch_status [ catch { + + MakeSICSObj ${name} SCT_OBJECT + + sicslist setatt ${name} klass environment + sicslist setatt ${name} long_name ${name} + + set scobj_hpath /sics/${name} + hsetprop ${scobj_hpath} klass environment + hsetprop ${scobj_hpath} debug_threshold 5 +# mkDriver hook code starts + ::environment::temperature::mkwest400 $name $IP $dev_id +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::west4100 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_west4100 {name IP port dev_id} { + set catch_status [ catch { + ::scobj::west4100::sics_log 9 "add_west4100 ${name} ${IP} ${port} ${IP} ${dev_id}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::west4100::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::west4100::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::west4100::sics_log 9 "[environment_simulation] => No sctcontroller for west4100" + } + ::scobj::west4100::sics_log 1 "::scobj::west4100::mkDriver sct_${name} ${name} ${IP} ${dev_id}" + ::scobj::west4100::mkDriver sct_${name} ${name} ${IP} ${dev_id} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_west4100.tcl" +::scobj::west4100::sics_log 9 "file evaluation of sct_west4100.tcl" + +proc ::scobj::west4100::read_config {} { + set catch_status [ catch { + set ns "::scobj::west4100" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "west4100"] } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { + set IP [dict get $v ip] + set PORT [dict get $v port] + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + set missing_list [list] + foreach arg {IP dev_id} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "$name is missing configuration values $missing_list" + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_west4100 ${name} ${IP} ${PORT} {*}$arg_list + } else { + add_west4100 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::west4100::read_config +} else { + ::scobj::west4100::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/config/environment/temperature/watlow_mpm.sct b/site_ansto/instrument/config/environment/temperature/watlow_mpm.sct new file mode 100644 index 00000000..bff68db1 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/watlow_mpm.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver watlow_mpm = { + protocol = std + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'id datype dev_id tol' + make_args = 'id datype dev_id tol' + code mkDriver = {%% + mk_sct_watlow_pm $sct_controller environment $name $dev_id $tol $id $datype + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/watlow_mrm.sct b/site_ansto/instrument/config/environment/temperature/watlow_mrm.sct new file mode 100644 index 00000000..c9b1dbf6 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/watlow_mrm.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver watlow_mrm = { + protocol = std + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'id datype dev_id tol' + make_args = 'id datype dev_id tol' + code mkDriver = {%% + mk_sct_watlow_rm $sct_controller environment $name $dev_id $tol $id $datype + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/watlow_mst4.sct b/site_ansto/instrument/config/environment/temperature/watlow_mst4.sct new file mode 100644 index 00000000..1beacb47 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/watlow_mst4.sct @@ -0,0 +1,12 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver watlow_mst4 = { + protocol = std + sobj_priv_type = 'user float' + class = environment + simulation_group = environment_simulation + add_args = 'id datype dev_id tol' + make_args = 'id datype dev_id tol' + code mkDriver = {%% + mk_sct_watlow_st $sct_controller environment $name $dev_id $tol $id $datype + %%} +} diff --git a/site_ansto/instrument/config/environment/temperature/west400.tcl b/site_ansto/instrument/config/environment/temperature/west400.tcl index 53223d0f..586247a3 100644 --- a/site_ansto/instrument/config/environment/temperature/west400.tcl +++ b/site_ansto/instrument/config/environment/temperature/west400.tcl @@ -48,86 +48,3 @@ proc ::environment::temperature::add_west4100 {IP ID} { #::environment::mkenvinfo tc1 {heateron {priv user} range {priv manager} } } - -namespace eval ::scobj::west4100 { -set debug_threshold 5 -} -proc ::scobj::west4100::sics_log {debug_level debug_string} { - set catch_status [ catch { - set debug_threshold ${::scobj::west4100::debug_threshold} - if {${debug_level} >= ${debug_threshold}} { - sicslog "::scobj::west4100::${debug_string}" - } - } catch_message ] -} - -clientput "file evaluation of sct_west4100.tcl" -::scobj::west4100::sics_log 9 "file evaluation of sct_west4100.tcl" - -proc ::scobj::west4100::read_config {} { - set catch_status [ catch { - set ns "::scobj::west4100" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { - continue - } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] - if { !([dict exists $::config_dict $implementation]) } { - continue - } - set v [dict get $::config_dict $implementation] - if { !([dict exists $v "driver"]) } { - continue - } - if { [string equal -nocase [dict get $v "driver"] "west4100"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue - set IP [dict get $v ip] - set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" - } - } - set arg_list [list] - foreach arg {id} { - if {[dict exists $v $arg]} { - lappend arg_list "[dict get $v $arg]" - } else { - ${ns}::sics_log 9 "Missing configuration value $arg" - error "Missing configuration value $arg" - } - } - add_west4100 ${name} "aqadapter" ${asyncqueue} {*}$arg_list - } - } - } - } - } catch_message ] - handle_exception ${catch_status} ${catch_message} -} - -if { [info exists ::config_dict] } { - ::scobj::west4100::read_config -} else { - ::scobj::west4100::sics_log 5 "No config dict" -} diff --git a/site_ansto/instrument/config/environment/temperature/west4100.sct b/site_ansto/instrument/config/environment/temperature/west4100.sct new file mode 100644 index 00000000..f3ea5279 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/west4100.sct @@ -0,0 +1,11 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver west4100 = { + protocol = std + class = environment + simulation_group = environment_simulation + add_args = 'dev_id' + make_args = 'IP dev_id' + code mkDriver = {%% + ::environment::temperature::mkwest400 $name $IP $dev_id + %%} +} diff --git a/site_ansto/instrument/config/source/sct_reactor_status.tcl b/site_ansto/instrument/config/source/sct_reactor_status.tcl index aa1558bb..62b4a7c4 100644 --- a/site_ansto/instrument/config/source/sct_reactor_status.tcl +++ b/site_ansto/instrument/config/source/sct_reactor_status.tcl @@ -136,7 +136,7 @@ proc ::scobj::reactor_status::rdAll {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -162,7 +162,7 @@ proc ::scobj::reactor_status::rdValue {tc_root} { sct oldval ${data} sct update ${data} sct utime readtime - } + } return ${nextState} } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -344,14 +344,17 @@ clientput "file evaluation of sct_reactor_status.tcl" proc ::scobj::reactor_status::read_config {} { set catch_status [ catch { set ns "::scobj::reactor_status" - dict for {k v} $::config_dict { - if { [dict exists $v "implementation"] } { - if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } { continue } - set name [dict get $v name] - set enabled [string tolower [dict get $v "enabled"]] - set implementation [dict get $v "implementation"] + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } @@ -360,31 +363,37 @@ proc ::scobj::reactor_status::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "reactor_status"] } { - if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } { - if { ![string equal -nocase [SplitReply [opal_simulation]] "false"] } { - set asyncqueue "null" - ${ns}::sics_log 9 "[opal_simulation] => using null asyncqueue" - } elseif { [dict exists $v "asyncqueue"] } { - set asyncqueue [dict get $v "asyncqueue"] - } else { - if { [dict exists $v "asyncprotocol"] } { - set asyncprotocol [dict get $v "asyncprotocol"] - } else { - set asyncprotocol ${name}_protocol - MakeAsyncProtocol ${asyncprotocol} - if { [dict exists $v "terminator"] } { - ${asyncprotocol} sendterminator "[dict get $v "terminator"]" - ${asyncprotocol} replyterminator "[dict get $v "terminator"]" - } - } - set asyncqueue ${name}_queue + if { ![string equal -nocase [SplitReply [opal_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[opal_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + if { [string equal -nocase ${asyncqueue} "sct"] } { set IP [dict get $v ip] set PORT [dict get $v port] - MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} - if { [dict exists $v "timeout"] } { - ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" } } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_reactor_status ${name} ${IP} ${PORT} + } else { add_reactor_status ${name} "aqadapter" ${asyncqueue} } } diff --git a/site_ansto/instrument/dingo/camtest_configuration.tcl b/site_ansto/instrument/dingo/camtest_configuration.tcl index b7107507..d7619acc 100644 --- a/site_ansto/instrument/dingo/camtest_configuration.tcl +++ b/site_ansto/instrument/dingo/camtest_configuration.tcl @@ -72,9 +72,9 @@ dummy_motor home 0 MakeDrive -MakeAsyncQueue cmserver CAMERA localhost 63300 +#MakeAsyncQueue cmserver CAMERA localhost 63300 +MakeAsyncQueue cmserver CAMERA [dict get $::CAMERA_HOSTPORT HOST] [dict get $::CAMERA_HOSTPORT PORT] #MakeAsyncQueue cmserver CAMERA 137.157.204.193 33000 -#MakeAsyncQueue cmserver CAMERA 137.157.236.122 33000 #MakeAsyncQueue cmserver CAMERA 192.168.56.1 33000 #MakeAsyncQueue cmserver CAMERA 192.168.1.2 33000 #MakeAsyncQueue cmserver CAMERA localhost 33000 diff --git a/site_ansto/instrument/dingo/config/counter/counter.tcl b/site_ansto/instrument/dingo/config/counter/counter.tcl index c03244a1..064cec02 100644 --- a/site_ansto/instrument/dingo/config/counter/counter.tcl +++ b/site_ansto/instrument/dingo/config/counter/counter.tcl @@ -19,9 +19,16 @@ proc ::counter::cm_initialize {} { variable isc_cm_address variable isc_cm_port - - MakeAsyncQueue cmserver CAMERA $isc_cm_address $isc_cm_port - MakeCounter cm1 anstocamera cmserver + # HACK: The ::montor::count command requires a bm in commands_common + MakeCounter bm SIM 0.0 + set sim_mode [SplitReply [counter_simulation]] + if {$sim_mode == "true"} { + MakeCounter cm1 SIM 0.0 + } else { + MakeAsyncQueue cmserver CAMERA $isc_cm_address $isc_cm_port + MakeCounter cm1 anstocamera cmserver + } + set isc_beam_monitor_list { cm1 } sicslist setatt cm1 privilege internal ::utility::macro::getset text cm1_mode {} { @@ -60,9 +67,6 @@ proc ::counter::cm_initialize {} { publish ::counter::cm_initialize user proc ::counter::isc_initialize {} { - if [SplitReply [counter_simulation]] { - return - } if [catch { variable isc_numchannels variable isc_monitor_address diff --git a/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl b/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl index 59d85d99..07129102 100644 --- a/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl +++ b/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl @@ -13,7 +13,7 @@ if {$sim_mode == "true"} { set motor_driver_type DMC2280 MakeAsyncQueue mc1 DMC2280 [dict get $::MOTOR_HOSTPORT MC1 HOST] [dict get $::MOTOR_HOSTPORT MC1 PORT] MakeAsyncQueue mc2 DMC2280 [dict get $::MOTOR_HOSTPORT MC2 HOST] [dict get $::MOTOR_HOSTPORT MC2 PORT] - MakeAsyncQueue mc3 DMC2280 [dict get $::MOTOR_HOSTPORT MC3 HOST] [dict get $::MOTOR_HOSTPORT MC3 PORT] + #MakeAsyncQueue mc3 DMC2280 [dict get $::MOTOR_HOSTPORT MC3 HOST] [dict get $::MOTOR_HOSTPORT MC3 PORT] } @@ -50,51 +50,58 @@ dummy_motor home 0 # All motors are at 25000steps/turn if no other specify set motorrate 25000.0 -# mc1: Sample rotation axis -# Gearbox 100:1, Gear ratio 356:1 -set stth_Home 0 -set stthStepRate [expr $motorrate*100.0*356.0/360.0] -Motor stth $motor_driver_type [params \ + +# mc1: Sample Z-translation sample stage +# Gearbox 20:1, pitch ? +set sz_Home 10993707 +set szStepRate [expr 4.8 * 25000] +Motor sz $motor_driver_type [params \ asyncqueue mc1\ host mc1-dingo\ port pmc1-dingo\ axis A\ - units degree\ - hardlowerlim 0\ - hardupperlim 360\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ - stepsPerX $stthStepRate\ + units mm\ + hardlowerlim -400\ + hardupperlim 0\ + maxSpeed 0.333333\ + maxAccel 0.333333\ + maxDecel 0.333333\ + stepsPerX $szStepRate\ absEnc 1\ - absEncHome $stth_Home\ - cntsPerX 4096] -stth part sample -stth long_name stth -stth softlowerlim 0 -stth softupperlim 360 -stth home 0 + absEncHome $sz_Home\ + cntsPerX [expr 4.8 * 4096] ] +sz speed 0.1 +sz accel 0.1 +sz decel 0.1 +sz part sample +sz long_name sz +sz softlowerlim -399 +sz softupperlim -70 +sz home 0 # mc1: Sample X-translation sample stage # Gearbox 20:1, pitch 5mm -set sx_Home 0 -set sxStepRate [expr $motorrate*20.0/5.0] +set sx_Home 8580919 +#set sxStepRate [expr -$motorrate*20.0/4.0] +set sxStepRate -100000 +#absEnc 1 Motor sx $motor_driver_type [params \ asyncqueue mc1\ host mc1-dingo\ port pmc1-dingo\ axis B\ units mm\ - hardlowerlim 0\ + hardlowerlim -300\ hardupperlim 500\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ + maxSpeed 1.2\ + maxAccel 1\ + maxDecel 1\ stepsPerX $sxStepRate\ - absEnc 1\ absEncHome $sx_Home\ - cntsPerX 4096] + absEnc 1\ + cntsPerX [expr 4096.0 / 5.0] ] +sx speed 0.3 sx part sample sx long_name sx sx softlowerlim -250 @@ -103,78 +110,94 @@ sx home 0 # mc1: Sample Y-translation sample stage # Gearbox 20:1, pitch 5mm -set sy_Home 0 -set syStepRate [expr $motorrate*20.0/5.0] +set sy_Home 8437458.000000 +#set syStepRate [expr -$motorrate*20.0/4.0] +set syStepRate -100000 Motor sy $motor_driver_type [params \ asyncqueue mc1\ host mc1-dingo\ port pmc1-dingo\ axis C\ units mm\ - hardlowerlim 0\ - hardupperlim 500\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ + hardlowerlim -70\ + hardupperlim 300\ + maxSpeed 1.2\ + maxAccel 1\ + maxDecel 1\ stepsPerX $syStepRate\ absEnc 1\ absEncHome $sy_Home\ - cntsPerX 4096] + cntsPerX [expr 4096.0 / 5.0] ] +sy speed 0.5 sy part sample sy long_name sy -sy softlowerlim -250 -sy softupperlim 250 +sy softlowerlim -50 +sy softupperlim 230 sy home 0 -# mc1: Sample Z-translation sample stage -# Gearbox 20:1, pitch ? -set sz_Home 0 -set szStepRate ? -Motor sz $motor_driver_type [params \ +# mc1: Sample rotation axis +# Gearbox 100:1, screw pitch 356:1 +# Encoder 2P17 +#set stth_Home 821487 +set stth_Home 0 +#set stthStepRate [expr -$motorrate*100.0] +set stthStepRate -2478000 +Motor stth $motor_driver_type [params \ asyncqueue mc1\ host mc1-dingo\ port pmc1-dingo\ axis D\ - units mm\ - hardlowerlim 0\ - hardupperlim 500\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ - stepsPerX $szStepRate\ + units degree\ + hardlowerlim -722\ + hardupperlim 722\ + maxSpeed 0.12\ + maxAccel 1\ + maxDecel 1\ + stepsPerX $stthStepRate\ absEnc 1\ - absEncHome $sz_Home\ - cntsPerX 4096] -sz part sample -sz long_name sz -sz softlowerlim -250 -sz softupperlim 250 -sz home 0 + absEncHome $stth_Home\ + nopowersave 1\ + cntsPerX 93206.75556 ] +stth speed 0.1 +stth accel 0.1 +stth decel 0.1 +stth part sample +stth long_name stth +stth softlowerlim 0.01 +stth softupperlim 359.99 +stth home 0 +#stth bias_bits 25 +#stth bias_bias -33432264 +stth rotary_bits 25 +stth creep_offset 0.05 -# mc1: End station Z-translation +# mc1: detection Z-stage Translation # Gearbox 5:1, Gear ratio 16:1, pitch 4mm -set dz_Home 0 +#set dz_Home 5041621 +set dz_Home 7617195 set dzStepRate [expr $motorrate*5.0*16.0/4.0] +# hardupperlim 8394505, hardlowerlim 5041249 Motor dz $motor_driver_type [params \ asyncqueue mc1\ host mc1-dingo\ port pmc1-dingo\ axis G\ units mm\ - hardlowerlim 0\ - hardupperlim 500\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ + hardlowerlim -0.02\ + hardupperlim 204.6\ + maxSpeed 0.3\ + maxAccel 0.2\ + maxDecel 0.2\ stepsPerX $dzStepRate\ absEnc 1\ absEncHome $dz_Home\ - cntsPerX 4096] + cntsPerX [expr -4 * 4096] ] +dz speed 0.1 dz part sample dz long_name dz -dz softlowerlim -125 -dz softupperlim 125 -sz home 0 +dz softlowerlim 0 +dz softupperlim 170 +dz home 0 ############################ @@ -185,28 +208,29 @@ sz home 0 # # mc2: Camera translation axis along beam -# Gearbox ?, Gear ratio ?, -set dy_Home 0 -set dyStepRate ? +# Gearbox ?, Gear ratio ?, +set dy_Home 8847069 +set dyStepRate [expr 25000.0/2.0] Motor dy $motor_driver_type [params \ asyncqueue mc2\ host mc2-dingo\ port pmc2-dingo\ axis A\ units mm\ - hardlowerlim 0\ - hardupperlim 500\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ + hardlowerlim -5\ + hardupperlim 296\ + maxSpeed 2\ + maxAccel 1\ + maxDecel 1\ stepsPerX $dyStepRate\ absEnc 1\ absEncHome $dy_Home\ - cntsPerX 4096] + cntsPerX [expr -4096/2] ] +dy speed 1 dy part instrument dy long_name dy -dy softlowerlim 0 -dy softupperlim 20 +dy softlowerlim -4.5 +dy softupperlim 295 dy home 0 ############################ @@ -218,27 +242,27 @@ dy home 0 # mc3: Selector Wheel Rotation Axis (attenuator) # Gearbox 50:1, Gear ratio 119:14 -set at_Home 0 -set atStepRate [expr $motorrate*50.0*119.0/14.0/360.0] -Motor at $motor_driver_type [params \ - asyncqueue mc3\ - host mc3-dingo\ - port pmc3-dingo\ - axis A\ - units degree\ - hardlowerlim 0\ - hardupperlim 500\ - maxSpeed [expr 400000.0/300000.0]\ - maxAccel [expr 150000.0/300000.0]\ - maxDecel [expr 150000.0/300000.0]\ - stepsPerX $atStepRate\ - absEnc 1\ - absEncHome $at_Home\ - cntsPerX 4096] -at part sample -at long_name at -at softlowerlim 0 -at softupperlim 20 +#set at_Home 0 +#set atStepRate [expr $motorrate*50.0*119.0/14.0/360.0] +#Motor at $motor_driver_type [params \ +# asyncqueue mc3\ +# host mc3-dingo\ +# port pmc3-dingo\ +# axis A\ +# units degree\ +# hardlowerlim 0\ +# hardupperlim 500\ +# maxSpeed [expr 400000.0/300000.0]\ +# maxAccel [expr 150000.0/300000.0]\ +# maxDecel [expr 150000.0/300000.0]\ +# stepsPerX $atStepRate\ +# absEnc 1\ +# absEncHome $at_Home\ +# cntsPerX 4096] +#at part sample +#at long_name at +#at softlowerlim 0 +#at softupperlim 20 proc motor_set_sobj_attributes {} { } diff --git a/site_ansto/instrument/dingo/config/plc/plc.tcl b/site_ansto/instrument/dingo/config/plc/plc.tcl index cc5b9296..1386c276 100644 --- a/site_ansto/instrument/dingo/config/plc/plc.tcl +++ b/site_ansto/instrument/dingo/config/plc/plc.tcl @@ -1,21 +1,97 @@ set sim_mode [SplitReply [plc_simulation]] + if {$sim_mode == "false"} { MakeAsyncQueue plc_chan SafetyPLC [dict get $::PLC_HOSTPORT HOST] [dict get $::PLC_HOSTPORT PORT] MakeSafetyPLC plc plc_chan 0 + } +makesctcontroller sct_shutter std 137.157.204.213:30000 + +# Configuration Note: +# +# A default setting has been set in safetyplc.c code. following configuration +# settings are only required when necessacy. +# +# fields Collimationgate, Detectorgate, Fastshutter, SecondTerShutter +# and IndTerShutter NOT belong to dafault fields and need to be configured +# based on particular instrument during deployment +# values: 1 -- will display in PLC List +# 0 -- wont show in PLC List +set bitstream "" +foreach {para paraval} { + Key 1 + Secondary 1 + Tertiary 1 + MotionControl 1 + Access 1 + DC 1 + Exit 1 + Trip 1 + Fault 1 + Operate 1 + Relay 1 + Ready 1 + Collimationgate 0 + Detectorgate 0 + Fastshutter 1 + SecondTerShutter 0 + IndTerShutter 0 +} { + append bitstream $paraval +} +plc setlist $bitstream proc shutter {args} { set cmd "set shutter=$args\r\n" - plc_chan send $cmd + sct_shutter transact $cmd } proc focuslight {args} { set cmd "set focuslight=$args\r\n" - plc_chan send $cmd + sct_shutter transact $cmd +} + +proc tertiary_shutter {args} { + set cmd "set tertiary shutter=$args\r\n" + sct_shutter transact $cmd } publish shutter user publish focuslight user +publish tertiary_shutter user source $cfPath(plc)/plc_common_1.tcl +set plc_t "plc" +MakeSICSObj $plc SCT_OBJECT +sicslist setatt $plc_t klass environment +sicslist setatt $plc_t long_name $plc_t + +set scobj_hpath /sics/$plc_t + +proc ::scobj::plc::getPlcValue {nextstate} { + + plc_chan transact "READ" + return $nextstate +} + +proc ::scobj::plc::rdPlcValue {} { + + set replyData [string trimright [sct result] " \r\n"] + + set d1 [clock format [clock seconds] -format %d%h%Y] + set fd [open "../log/plc.log" a] + + puts $fd "[clock format [clock seconds] -format "%D %T "] [string trim $replyData "{}"]" + close $fd + + return idle +} + +set ns ::::scobj::plc + +hsetprop $scobj_hpath read ${ns}::getPlcValue getPlcValueState +hsetprop $scobj_hpath getPlcValueState ${ns}::rdPlcValue + +plc_chan poll $scobj_hpath 5 + diff --git a/site_ansto/instrument/dingo/config/scan/scan.tcl b/site_ansto/instrument/dingo/config/scan/scan.tcl index afc325a4..f6035eeb 100644 --- a/site_ansto/instrument/dingo/config/scan/scan.tcl +++ b/site_ansto/instrument/dingo/config/scan/scan.tcl @@ -1,8 +1,152 @@ source $cfPath(scan)/scan_common_1.tcl proc ::scan::pre_hmm_scan_prepare {} {} +proc ::scan::cm_count {sobj uobj point mode preset} { + # send "clear meta" command to the camera server + clientput "sending clear meta" + set cmd "clear meta\r\n" + cm1 send $cmd + # send motor position + foreach m "[sicslist type motor]" { + if {$m == "motor" || $m == "dummy_motor"} { + # skipit + } else { + set cmd "set camera, " + append cmd "[$m]" + append cmd "\r\n" + cm1 send $cmd + } + } + cm1 count $preset +} + +proc ::scan::cm_scan_prepare {sobj uobj} { + + variable save_filetype + variable check_instrument_ready + variable force_scan + + # [::plc::inst_ready] + if {$force_scan || $check_instrument_ready} { + set force_scan false + if [catch { + ::scan::check_scanvar $sobj $uobj + ::scan::pre_hmm_scan_prepare + }] { + return -code error "ISCAN ABORTED: $::errorInfo" + } + + # send "shutter auto" command over + shutter auto + # send "focusflight off" command over + focuslight off + # send "clear meta" command to the camera server + clientput "sending clear meta" + set cmd "clear meta\r\n" + cm1 send $cmd + # send motor position + foreach m "[sicslist type motor]" { + if {$m == "motor" || $m == "dummy_motor"} { + # skipit + } else { + set cmd "set camera, " + append cmd "[$m]" + append cmd "\r\n" + cm1 send $cmd + } + } + + if [catch { + #TODO Parameterise varindex in some way + set varindex 0; + + set numpoints [SplitReply [$sobj np]] + set vlist [split [$sobj getvarpar $varindex] = ] + set scanstart [lindex $vlist 1] + set scanstep [lindex $vlist 2] + #::scan::camscan_cmd -set NP $numpoints + #::scan::camscan_cmd -set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]]; + #::scan::camscan_cmd -set scan_start $scanstart + #::scan::camscan_cmd -set scan_increment $scanstep + set scanvar_pts [SplitReply [$sobj getvardata $varindex]] + + #::scan::camscan_cmd -set feedback status BUSY + clientput "run_mode camscan" + run_mode "camscan" + + #::nexus::newfile BEAM_MONITOR $save_filetype + stdscan prepare $sobj $uobj; + clientput "Scan start: $scanstart, Scan step: $scanstep, Number of points: $numpoints" + }] { + run_mode "normal" + return -code error $::errorInfo + } + } else { + return -code error "ISCAN ABORTED: Instrument not ready" + } +} + +proc ::scan::cm_scan_collect {sobj uobj point} { + set vlist [split [$sobj getvarpar 0] = ]; + + set w(NP) $point + set sv [string trim [lindex [split [lindex $vlist 0] . ] 1]] + set header [format "%-4.4s %-9.9s %-14s %-7.7s" NP $sv Counts Time] + set varval [SplitReply [$sv]] + set counts [SplitReply [::histogram_memory::total_counts]] + set time [SplitReply [::histogram_memory::time]] + set data [format "%-4d %-9.3f %-14d %-7.2f" $point $varval $counts $time] + clientput $header + clientput $data + for {set bmn 1} {$bmn <= $::counter::isc_numchannels} {incr bmn} { + set bmon bm$bmn + clientput "Monitor $bmn [SplitReply [$bmon getcounts]]" + } +} + +publish ::scan::cm_count user +publish ::scan::cm_scan_prepare user +publish ::scan::cm_scan_collect user + proc ::scan::isc_initialize {} { - ::scan::ic_initialize + #::scan::ic_initialize + + if [ catch { + variable ic_runscanpar + variable ic_hmm_datatype + + set ic_hmm_datatype HISTOGRAM_XYT + + MakeScanCommand camscan cm1 $::cfPath(scan)/scan_common_1.hdd recover.bin + + camscan configure script + #camscan function writeheader ::scan::donothing + #camscan function writepoint ::scan:cm_writepoint + camscan function count ::scan::cm_count + #camscan function collect ::scan::cm_scan_collect + camscan function prepare ::scan::cm_scan_prepare + #camscan function finish ::scan::cm_scan_finish + + # TODO Use ic_runscanpar to create the ::scan::runscan command and + # to validate the "runscan" proc parameters. + array set ic_runscanpar [subst { + scanvar text=drivable + start float + stop float + numpoints int=0,inf + mode text=[join [concat [list time unlimited period count frame] $::counter::isc_beam_monitor_list ] , ] + preset float=0,inf + datatype text=[join [array names ::nexus::histmem_filetype_spec] , ] + savetype text=save,nosave + force boolean + }] + #scriptcallback connect hmscan SCANEND ::scan::hmscanend_event + #scriptcallback connect bmonscan SCANEND ::scan::bmonscanend_event + scriptcallback connect camscan SCANEND ::scan::cmscanend_event + } message ] { + if {$::errorCode=="NONE"} {return $message} + return -code error $message + } foreach {n v} { clock 1 diff --git a/site_ansto/instrument/dingo/dingo_configuration.tcl b/site_ansto/instrument/dingo/dingo_configuration.tcl index 29eb0d3e..d80c379f 100644 --- a/site_ansto/instrument/dingo/dingo_configuration.tcl +++ b/site_ansto/instrument/dingo/dingo_configuration.tcl @@ -15,31 +15,10 @@ MakeDrive ######################################## # INSTRUMENT SPECIFIC CONFIGURATION -Motor dummy_motor asim [params \ - asyncqueue mc1\ - host mc1-dingo\ - port pmc1-dingo\ - axis A\ - units mm\ - hardlowerlim -500\ - hardupperlim 500\ - maxSpeed 1\ - maxAccel 5\ - maxDecel 5\ - stepsPerX [expr 25000.0/5.0]\ - absEnc 1\ - absEncHome 0\ - cntsPerX [expr 8192.0/5.0]] -dummy_motor part instrument -dummy_motor long_name dummy_motor -dummy_motor softlowerlim -500 -dummy_motor softupperlim 500 -dummy_motor home 0 - source $cfPath(hipadaba)/hipadaba_configuration.tcl fileeval $cfPath(source)/source.tcl -#fileeval $cfPath(motors)/motor_configuration.tcl +fileeval $cfPath(motors)/motor_configuration.tcl #fileeval $cfPath(motors)/positmotor_configuration.tcl #fileeval $cfPath(motors)/extraconfig.tcl fileeval $cfPath(plc)/plc.tcl @@ -48,6 +27,8 @@ fileeval $cfPath(hmm)/hmm_configuration.tcl fileeval $cfPath(nexus)/nxscripts.tcl fileeval $cfPath(scan)/scan.tcl fileeval $cfPath(commands)/commands.tcl +fileeval $cfPath(commands)/pulser.tcl +fileeval $cfPath(commands)/hvcommands.tcl fileeval $cfPath(anticollider)/anticollider.tcl source gumxml.tcl @@ -56,13 +37,16 @@ source gumxml.tcl #::anticollider::protect_detector "true" # fix all motors -foreach m [sicslist type motor] { - if {$m == "motor" || $m == "dummy_motor"} { - # skipit - } else { - clientput fix $m position - $m fixed 1 - } +if {1} { + set motorlist "[sicslist type motor]" + puts $motorlist + foreach m $motorlist { + if {$m == "motor" || $m == "dummy_motor"} { + # skipit + } else { + $m fixed 1 + } + } } server_init diff --git a/site_ansto/instrument/dingo/hostport_config.tcl b/site_ansto/instrument/dingo/hostport_config.tcl index bbbf1ef7..47ab8117 100644 --- a/site_ansto/instrument/dingo/hostport_config.tcl +++ b/site_ansto/instrument/dingo/hostport_config.tcl @@ -17,8 +17,9 @@ foreach {host port} { } # Safety Interlock System +#137.157.204.214 foreach {host port} { - 137.157.204.213 30000 + 137.157.204.214 30000 } { dict set PLC_HOSTPORT HOST $host dict set PLC_HOSTPORT PORT $port diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 93dd91d3..b51987bf 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -1,3 +1,107 @@ +[12tmagnet_setup] +cascade = B1:12tmagnet_oxford,sample_stage:12tmagnet_sample_insert,T1:mercury_scpi_01 +enabled = False +[Autolab_setup] +cascade = sample_stage:normal_sample_stage,I1:protek_01,V1:protek_02 +enabled = False +[CF1] +cascade = T1:CF1_ls340,sample_stage:normal_sample_stage +enabled = False +[CF8] +cascade = T1:ls336_01,T2:ls340_11,sample_stage:normal_sample_stage +enabled = False +[Default] +cascade = sample_stage:normal_sample_stage +enabled = True +[B1] +datype = B +enabled = False +id = 1 +implementation = none +name = magnet1 +optype = magnetic_field +[Function_Generator] +datype = V +enabled = False +id = 1 +implementation = none +name = pulser +optype = function_generator +[I1] +datype = I +enabled = False +id = 1 +implementation = none +name = curr1 +optype = multimeter +[I2] +datype = I +enabled = False +id = 2 +implementation = none +name = curr2 +optype = multimeter +[T1] +datype = T +enabled = False +id = 1 +implementation = none +name = tc1 +optype = temperature +[T2] +datype = T +enabled = False +id = 2 +implementation = none +name = tc2 +optype = temperature +[T3] +datype = T +enabled = False +id = 3 +implementation = none +name = tc3 +optype = temperature +[T4] +datype = T +enabled = False +id = 4 +implementation = none +name = tc4 +optype = temperature +[T5] +datype = T +enabled = False +id = 5 +implementation = none +name = tc5 +optype = temperature +[T6] +datype = T +enabled = False +id = 6 +implementation = none +name = tc6 +optype = temperature +[V1] +datype = V +enabled = False +id = 1 +implementation = none +name = volts1 +optype = multimeter +[V2] +datype = V +enabled = False +id = 2 +implementation = none +name = volts2 +optype = multimeter +[sample_stage] +enabled = Always +implementation = normal_sample_stage +name = sample_stage +optype = motion_axis [12tmagnet_oxford] desc = "12 Tesla Oxford Magnet" driver = "oxford_labview" @@ -9,23 +113,9 @@ port = 55001 desc = "som will be redefined as the magnet sample insert rotation. Sample stage will be renamed to somss" imptype = motion_axis -[12tmagnet_setup] -cascade = B1:12tmagnet_oxford,sample_stage:12tmagnet_sample_insert,T1:mercury_scpi -enabled = False - -[B1] -enabled = False -implementation = 12tmagnet_oxford -name = magnet1 -optype = magnetic_field - -[CF1] -cascade = T1:CF1_ls340,sample_stage:normal_sample_stage -enabled = False - [CF1_ls340] desc = "cf1: Bottom loading cryofurnace" -driver = "lakeshore_340" +driver = "ls340" imptype = temperature ip = 10.157.205.43 port = 4001 @@ -33,63 +123,22 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 -[Default] -cascade = sample_stage:normal_sample_stage -enabled = True - -[I1] -datype = I -enabled = False -implementation = protek_01 -name = curr1 -optype = multimeter - -[I2] -datype = I -enabled = False -implementation = protek_02 -name = curr2 -optype = multimeter - -[T1] -enabled = False -implementation = mercury_scpi -name = tc1 -optype = temperature - -[T2] -enabled = False -implementation = ls336_02 -name = tc2 -optype = temperature - -[T3] -enabled = False -implementation = ls336_04 -name = tc3 -optype = temperature - -[V1] -datype = V -enabled = False -implementation = protek_01 -name = volts1 -optype = multimeter - -[V2] -datype = V -enabled = False -implementation = protek_02 -name = volts2 -optype = multimeter +[agilent_33220A] +asyncqueue = sct +desc = "Function Generator" +driver = agilent_33220A +imptype = function_generator +ip = 10.157.205.16 +port = 5025 [eularian_cradle] desc = "Load the Eulerian cradle configuration" imptype = motion_axis [ls336_01] -desc = "tc1: Lakeshore 336 temperature controller" -driver = "lakeshore_336" +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" imptype = temperature ip = 10.157.205.28 port = 7777 @@ -98,8 +147,9 @@ tol1 = 1.0 tol2 = 1.0 [ls336_02] -desc = "tc2: Lakeshore 336 temperature controller" -driver = "lakeshore_336" +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" imptype = temperature ip = 10.157.205.29 port = 7777 @@ -108,8 +158,9 @@ tol1 = 1.0 tol2 = 1.0 [ls336_04] -desc = "tc3: Lakeshore 336 temperature controller" -driver = "lakeshore_336" +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" imptype = temperature ip = 10.157.205.30 port = 7777 @@ -118,8 +169,9 @@ tol1 = 1.0 tol2 = 1.0 [ls336_05] -desc = "tc4: Lakeshore 336 temperature controller" -driver = "lakeshore_336" +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" imptype = temperature ip = 137.157.201.21 port = 7777 @@ -128,8 +180,9 @@ tol1 = 1.0 tol2 = 1.0 [ls336_06] -desc = "tc5: Lakeshore 336 temperature controller" -driver = "lakeshore_336" +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" imptype = temperature ip = 137.157.201.21 port = 7777 @@ -137,9 +190,20 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 +[ls336_11] +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 10.157.205.27 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + [ls336_12] -desc = "tc6: Lakeshore 336 temperature controller" -driver = "lakeshore_336" +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" imptype = temperature ip = 10.157.205.31 port = 7777 @@ -148,8 +212,9 @@ tol1 = 1.0 tol2 = 1.0 [ls340_01] -desc = "tc7: Lakeshore 340 temperature controller" -driver = "lakeshore_340" +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" imptype = temperature ip = 137.157.201.86 port = 4001 @@ -158,8 +223,9 @@ tol1 = 1.0 tol2 = 1.0 [ls340_02] -desc = "tc8: Lakeshore 340 temperature controller" -driver = "lakeshore_340" +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" imptype = temperature ip = 137.157.201.86 port = 4002 @@ -167,45 +233,65 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 -[mercury_scpi] -desc = "tc9: Oxford Mercury temperature controller in Mercury mode" +[ls340_11] +desc = "Lakeshore 340 temperature controller" +driver = "ls340" +imptype = temperature +ip = 137.157.201.86 +port = 4001 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[mercury_scpi_01] +desc = "Oxford Mercury temperature controller in Mercury mode" driver = "mercury_scpi" imptype = temperature ip = 10.157.205.5 +permlink = LT port = 7020 -terminator = \r -tol = 2.0 +terminator = \r\n +tol = 1.0 +valve_tol = 2 + +[mercury_scpi_02] +desc = "Oxford Mercury temperature controller in Mercury mode" +driver = "mercury_scpi" +imptype = temperature +ip = 10.157.205.47 +permlink = LT +port = 7020 +terminator = \r\n +tol = 1.0 +valve_tol = 2 [normal_sample_stage] desc = "This is the default sample stage configuration with xy translation and phi and chi tilt stages" imptype = motion_axis [protek_01] +asyncqueue = sct desc = "Protek Multimeter" -driver = "protek" +driver = "protekmm" imptype = multimeter ip = 10.157.205.36 port = 4001 [protek_02] +asyncqueue = sct desc = "Protek Multimeter" -driver = "protek" +driver = "protekmm" imptype = multimeter ip = 10.157.205.37 port = 4001 -[sample_stage] -enabled = Always -implementation = normal_sample_stage -name = sample_stage -optype = motion_axis - [small_omega] desc = "Load the small omega configuration" imptype = motion_axis [west4100] desc = "Blue furnace temperature controller" +dev_id = 1 driver = "west4100" imptype = temperature ip = 10.157.205.19 diff --git a/site_ansto/instrument/hipd/wombat_configuration.tcl b/site_ansto/instrument/hipd/wombat_configuration.tcl index cd29c804..87529b6f 100644 --- a/site_ansto/instrument/hipd/wombat_configuration.tcl +++ b/site_ansto/instrument/hipd/wombat_configuration.tcl @@ -25,16 +25,28 @@ fileeval $cfPath(source)/source.tcl fileeval $cfPath(motors)/positmotor_configuration.tcl fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(counter)/counter.tcl -fileeval $cfPath(environment)/sct_keithley_2700.tcl -fileeval $cfPath(environment)/sct_protek_common.tcl -#TODO Provide method for choosing environment controller +fileeval $cfPath(environment)/sct_agilent_33220A.tcl +fileeval $cfPath(environment)/sct_hiden_xcs.tcl +fileeval $cfPath(environment)/sct_huber_pilot.tcl +fileeval $cfPath(environment)/sct_isotech_ps.tcl fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl +fileeval $cfPath(environment)/temperature/sct_eurotherm_m2000.tcl +fileeval $cfPath(environment)/sct_keithley_2700.tcl +fileeval $cfPath(environment)/sct_keithley_m2700.tcl +fileeval $cfPath(environment)/sct_lakeshore_218.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl +fileeval $cfPath(environment)/temperature/sct_ls336.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl +fileeval $cfPath(environment)/temperature/sct_ls340.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_370.tcl +fileeval $cfPath(environment)/sct_lakeshore_m370.tcl +fileeval $cfPath(environment)/temperature/sct_mercury_scpi.tcl +fileeval $cfPath(environment)/sct_protek_common.tcl +fileeval $cfPath(environment)/sct_protekmm.tcl fileeval $cfPath(environment)/temperature/sct_julabo_lh45.tcl fileeval $cfPath(environment)/temperature/sct_qlink.tcl fileeval $cfPath(environment)/temperature/west400.tcl +fileeval $cfPath(environment)/temperature/sct_west4100.tcl fileeval $cfPath(environment)/temperature/sct_oxford_mercury.tcl fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl fileeval $cfPath(environment)/he3/sct_he3.tcl diff --git a/site_ansto/instrument/kookaburra/config/hmm/hmm_configuration.tcl b/site_ansto/instrument/kookaburra/config/hmm/hmm_configuration.tcl index cc1819ae..4b1e7e7f 100644 --- a/site_ansto/instrument/kookaburra/config/hmm/hmm_configuration.tcl +++ b/site_ansto/instrument/kookaburra/config/hmm/hmm_configuration.tcl @@ -44,6 +44,17 @@ return { } } +proc ::histogram_memory::init_FAT_TABLE {} { + FAT_TABLE -set COUNT_ROI_TYPE RECTANGULAR + FAT_TABLE -set COUNT_ROI_REGION INCLUSIVE + FAT_TABLE -set COUNT_ROI_XMIN 0 + FAT_TABLE -set COUNT_ROI_XMAX 4 + FAT_TABLE -set COUNT_ROI_YMIN 0 + FAT_TABLE -set COUNT_ROI_YMAX 1023 + FAT_TABLE -set COUNT_ROI_TMIN 0 + FAT_TABLE -set COUNT_ROI_TMAX 1e9 +} + proc ::histogram_memory::init_CAT_TABLE {} { CAT_TABLE -set MESYTEC_MPSD8_CHANNEL_GAINS { 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 @@ -107,6 +118,7 @@ proc ::histogram_memory::isc_initialize {} { # hmm configure FAT_SIMULATED_EVENT_X0 $x_bb0 # hmm configure FAT_SIMULATED_EVENT_X1 $xbbmax ::histogram_memory::init_OAT_TABLE + ::histogram_memory::init_FAT_TABLE # ::histogram_memory::init_SAT_TABLE # ::histogram_memory::init_CAT_TABLE ::histogram_memory::upload_config Filler_defaults diff --git a/site_ansto/instrument/kookaburra/config/motors/motor_configuration.tcl b/site_ansto/instrument/kookaburra/config/motors/motor_configuration.tcl index 511e2ef8..dafbb1ae 100644 --- a/site_ansto/instrument/kookaburra/config/motors/motor_configuration.tcl +++ b/site_ansto/instrument/kookaburra/config/motors/motor_configuration.tcl @@ -308,7 +308,7 @@ m1x home 0 # mc2: Slit system - 1 TOP Blade # Gearbox 55:1, pitch 0.5mm # Encoder 2p13 -set ss1u_Home 918407 +set ss1u_Home 754567 set ss1uSetRate [expr $motorrate*55.0/0.5] Motor ss1u $motor_driver_type [params \ asyncqueue mc2\ diff --git a/site_ansto/instrument/sans/config/environment/sct_antonparr_MCR500.tcl b/site_ansto/instrument/sans/config/environment/sct_antonparr_MCR500.tcl new file mode 100644 index 00000000..bd93bd8c --- /dev/null +++ b/site_ansto/instrument/sans/config/environment/sct_antonparr_MCR500.tcl @@ -0,0 +1,110 @@ +# Generated driver for antonparr_MCR500 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::antonparr_MCR500 { + set debug_threshold 5 +} + +proc ::scobj::antonparr_MCR500::debug_log {tc_root debug_level debug_string} { + set catch_status [ catch { + set debug_threshold [hgetpropval ${tc_root} debug_threshold] + if {${debug_level} >= ${debug_threshold}} { + set fd [open "../log/antonparr_MCR500_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::antonparr_MCR500::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::antonparr_MCR500::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::antonparr_MCR500::${debug_string}" + } + } catch_message ] +} + +proc ::scobj::antonparr_MCR500::mkDriver { speed_name torque_name tol settle } { + ::scobj::antonparr_MCR500::sics_log 9 "::scobj::antonparr_MCR500::mkDriver ${speed_name} ${torque_name} ${tol} ${settle}" + set ns "[namespace current]" + set catch_status [ catch { + +# mkDriver hook code starts + add_rheo $speed_name $tol $settle + add_rheo $torque_name $tol $settle +# mkDriver hook code ends + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::antonparr_MCR500 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_antonparr_MCR500 {speed_name torque_name tol settle} { + set catch_status [ catch { + ::scobj::antonparr_MCR500::sics_log 9 "add_antonparr_MCR500 ${speed_name} ${torque_name} ${tol} ${settle}" + ::scobj::antonparr_MCR500::sics_log 1 "::scobj::antonparr_MCR500::mkDriver ${speed_name} ${torque_name} ${tol} ${settle}" + ::scobj::antonparr_MCR500::mkDriver ${speed_name} ${torque_name} ${tol} ${settle} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +clientput "file evaluation of sct_antonparr_MCR500.tcl" +::scobj::antonparr_MCR500::sics_log 9 "file evaluation of sct_antonparr_MCR500.tcl" + +proc ::scobj::antonparr_MCR500::read_config {} { + set catch_status [ catch { + set ns "::scobj::antonparr_MCR500" + dict for {k u} $::config_dict { + if { [dict exists $u "implementation"] } { + if { ![dict exists $u "enabled"] } { + continue + } + set enabled [string tolower [dict get $u "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set implementation [dict get $u "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set v [dict get $::config_dict $implementation] + if { !([dict exists $v "driver"]) } { + continue + } + if { [string equal -nocase [dict get $v "driver"] "antonparr_MCR500"] } { + set arg_list [list] + set missing_list [list] + foreach arg {speed_name torque_name tol settle} { + if {[dict exists $u $arg]} { + lappend arg_list "[dict get $u $arg]" + } elseif {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + lappend missing_list $arg + } + } + if { [llength $missing_list] > 0 } { + error "Rheometer is missing configuration values $missing_list" + } + add_antonparr_MCR500 {*}$arg_list + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::antonparr_MCR500::read_config +} else { + ::scobj::antonparr_MCR500::sics_log 5 "No config dict" +} diff --git a/site_ansto/instrument/sans/config/environment/sct_rheometer.tcl b/site_ansto/instrument/sans/config/environment/sct_rheometer.tcl index a5f95478..7c2f49e7 100644 --- a/site_ansto/instrument/sans/config/environment/sct_rheometer.tcl +++ b/site_ansto/instrument/sans/config/environment/sct_rheometer.tcl @@ -86,8 +86,7 @@ proc rheometer_savehmmdata {rootPath} { publish rheometer_savehmmdata user -proc add_rheo {rhControl IP tol settle {PORT 4001}} { - MakeProtek $rhControl $IP $PORT 1.0 0.0 0.5 "rhCallBack /sics/$rhControl" +proc add_rheo {rhControl tol settle} { hfactory /sics/$rhControl/saveIndex plain user int hset /sics/$rhControl/saveIndex 0 hfactory /sics/$rhControl/triggerList plain user text diff --git a/site_ansto/instrument/sans/config/motors/positmotor_configuration.tcl b/site_ansto/instrument/sans/config/motors/positmotor_configuration.tcl index 2d4ac271..860d8b07 100644 --- a/site_ansto/instrument/sans/config/motors/positmotor_configuration.tcl +++ b/site_ansto/instrument/sans/config/motors/positmotor_configuration.tcl @@ -46,7 +46,20 @@ set 10sample_table { 9 -172.5996 10 -214.5996 } -mkPosit sct_mc1 sampleNum float samx sample $20sample_table + +if { [ info exists ::config_dict ] } { + if { [ dict exists $::config_dict sample_stage implementation ] } { + set implementation [ dict get $::config_dict sample_stage implementation ] + if {$implementation == "normal_sample_stage"} { + # Don't make posit motor + } elseif {$implementation == "10_pos_sample_stage"} { + mkPosit sct_mc1 sampleNum float samx sample $10sample_table + } elseif {$implementation == "20_pos_sample_stage"} { + mkPosit sct_mc1 sampleNum float samx sample $20sample_table + } + } +} + #diameter position set auto_ap_table { diff --git a/site_ansto/instrument/sans/quokka_configuration.tcl b/site_ansto/instrument/sans/quokka_configuration.tcl index 686d2307..6bdce7e5 100644 --- a/site_ansto/instrument/sans/quokka_configuration.tcl +++ b/site_ansto/instrument/sans/quokka_configuration.tcl @@ -26,8 +26,35 @@ fileeval $cfPath(parameters)/parameters.tcl fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(optics)/optics.tcl fileeval $cfPath(counter)/counter.tcl -fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl +fileeval $cfPath(environment)/sct_agilent_33220A.tcl +fileeval $cfPath(environment)/sct_hiden_xcs.tcl +fileeval $cfPath(environment)/sct_huber_pilot.tcl +fileeval $cfPath(environment)/sct_isotech_ps.tcl +fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl +fileeval $cfPath(environment)/temperature/sct_eurotherm_m2000.tcl +fileeval $cfPath(environment)/sct_keithley_2700.tcl +fileeval $cfPath(environment)/sct_keithley_m2700.tcl +fileeval $cfPath(environment)/sct_lakeshore_218.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl +fileeval $cfPath(environment)/temperature/sct_ls336.tcl +fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl +fileeval $cfPath(environment)/temperature/sct_ls340.tcl +fileeval $cfPath(environment)/temperature/sct_lakeshore_370.tcl +fileeval $cfPath(environment)/sct_lakeshore_m370.tcl +fileeval $cfPath(environment)/temperature/sct_mercury_scpi.tcl +fileeval $cfPath(environment)/sct_nhq_200.tcl +fileeval $cfPath(environment)/sct_omron_hldc.tcl +fileeval $cfPath(environment)/temperature/sct_pfeiffer_hg.tcl +fileeval $cfPath(environment)/sct_protek_common.tcl +fileeval $cfPath(environment)/sct_protekmm.tcl +fileeval $cfPath(environment)/temperature/sct_rvasm2.tcl +fileeval $cfPath(environment)/temperature/sct_nprvasm2.tcl +fileeval $cfPath(environment)/temperature/sct_watlow_pm.tcl +fileeval $cfPath(environment)/temperature/sct_watlow_mpm.tcl +fileeval $cfPath(environment)/temperature/sct_watlow_rm.tcl +fileeval $cfPath(environment)/temperature/sct_watlow_mrm.tcl +fileeval $cfPath(environment)/temperature/sct_watlow_st4.tcl +fileeval $cfPath(environment)/temperature/sct_watlow_mst4.tcl fileeval $cfPath(hmm)/hmm_configuration.tcl fileeval $cfPath(nexus)/nxscripts.tcl fileeval $cfPath(hmm)/detector.tcl @@ -36,19 +63,13 @@ fileeval $cfPath(commands)/commands.tcl fileeval $cfPath(anticollider)/anticollider.tcl fileeval $cfPath(environment)/temperature/sct_julabo_lh45.tcl fileeval $cfPath(environment)/temperature/sct_qlink.tcl -fileeval $cfPath(environment)/temperature/sct_watlow_st4.tcl -fileeval $cfPath(environment)/temperature/sct_watlow_rm.tcl -fileeval $cfPath(environment)/temperature/sct_rvasm2.tcl -#fileeval $cfPath(environment)/magneticField/sct_oxford_ips.tcl +fileeval $cfPath(environment)/magneticField/sct_tsi_smc.tcl fileeval $cfPath(environment)/temperature/sct_oxford_itc.tcl fileeval $cfPath(environment)/magneticField/oxford_labview.tcl fileeval $cfPath(environment)/magneticField/sct_bruker_BEC1.tcl fileeval $cfPath(environment)/environment.tcl fileeval $cfPath(environment)/sct_rheometer.tcl -fileeval $cfPath(environment)/sct_protek_common.tcl -fileeval $cfPath(environment)/sct_huber_pilot.tcl -fileeval $cfPath(environment)/sct_hiden_xcs.tcl -fileeval $cfPath(environment)/sct_isotech_ps.tcl +fileeval $cfPath(environment)/sct_antonparr_MCR500.tcl fileeval $cfPath(beamline)/spin_flipper.tcl fileeval $cfPath(commands)/pulser.tcl fileeval $cfPath(commands)/hvcommands.tcl diff --git a/site_ansto/instrument/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini new file mode 100644 index 00000000..8a3356b0 --- /dev/null +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -0,0 +1,392 @@ +[10_position_setup] +cascade = T1:watlow_rm,sample_stage:10_pos_sample_stage +enabled = False +[12Tmagnet_setup] +cascade = B1:12tmagnet_oxford,sample_stage:Oxford_12tmagnet_sample_insert,T1:mercury_scpi_01 +enabled = False +[20_position_setup] +cascade = T1:julabo_lh45,sample_stage:20_pos_sample_stage +enabled = False +[CF1] +cascade = T1:CF1_ls340,sample_stage:normal_sample_stage +enabled = False +[Default] +cascade = sample_stage:normal_sample_stage +enabled = True +[Differential_Scanning_Calorimetry] +cascade = DSC:protek_01,sample_stage:normal_sample_stage +enabled = False +[HV_control] +cascade = Function_Generator:agilent_33220A,High_Voltage:protek_01,sample_stage:normal_sample_stage +enabled = False +[Rheometer_APMCR500_setup] +cascade = rhSpeed:protek_01,rhTorque:protek_02,Rheometry:antonparr_MCR500 +enabled = False +[bruker_setup] +cascade = B1:bruker_bec1,sample_stage:normal_sample_stage,T1:julabo_lh45 +enabled = False +[rhqc_setup] +cascade = sample_stage:normal_sample_stage,T1:ls340_01,T2:ls340_02 +enabled = False +[B1] +datype = B +enabled = False +id = 1 +implementation = none +name = magnet1 +optype = magnetic_field +[DSC] +datype = V +enabled = False +id = 1 +implementation = none +name = dsc_val +optype = multimeter +[Function_Generator] +datype = V +enabled = False +id = 1 +implementation = none +name = pulser +optype = function_generator +[High_Voltage] +datype = V +enabled = False +id = 1 +implementation = none +name = hv_val +optype = multimeter +[I1] +datype = I +enabled = False +id = 1 +implementation = none +name = curr1 +optype = multimeter +[I2] +datype = I +enabled = False +id = 2 +implementation = none +name = curr2 +optype = multimeter +[Rheometry] +enabled = False +implementation = none +optype = rheometry +[T1] +datype = T +enabled = False +id = 1 +implementation = none +name = tc1 +optype = temperature +[T2] +datype = T +enabled = False +id = 2 +implementation = none +name = tc2 +optype = temperature +[T3] +datype = T +enabled = False +id = 3 +implementation = none +name = tc3 +optype = temperature +[T4] +datype = T +enabled = False +id = 4 +implementation = none +name = tc4 +optype = temperature +[T5] +datype = T +enabled = False +id = 5 +implementation = none +name = tc5 +optype = temperature +[T6] +datype = T +enabled = False +id = 6 +implementation = none +name = tc6 +optype = temperature +[V1] +datype = V +enabled = False +id = 1 +implementation = none +name = volts1 +optype = multimeter +[V2] +datype = V +enabled = False +id = 2 +implementation = none +name = volts2 +optype = multimeter +[Viscosity] +enabled = False +id = 1 +implementation = none +name = visc +optype = viscosity +[rhSpeed] +enabled = False +implementation = none +name = rhSpeed +optype = rheometry +[rhTorque] +enabled = False +implementation = none +name = rhTorque +optype = rheometry +[sample_stage] +enabled = Always +implementation = normal_sample_stage +name = sample_stage +optype = motion_axis +[10_pos_sample_stage] +desc = "Load the ten position sample changer configuration" +imptype = motion_axis + +[12tmagnet_oxford] +desc = "12 Tesla Oxford Magnet" +driver = "oxford_labview" +imptype = magnetic_field +ip = 10.157.205.3 +port = 55001 + +[20_pos_sample_stage] +desc = "Load the twenty position sample changer configuration" +imptype = motion_axis + +[5Tmagnet] +desc = "The New Zealand magnet" +driver = tsi_smc +imptype = magnetic_field +ip = 137.157.202.79 +port = 4004 +timeout = 2000 + +[CF1_ls340] +desc = "cf1: Bottom loading cryofurnace" +driver = "ls340" +imptype = temperature +ip = 10.157.205.43 +port = 4001 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[Oxford_12tmagnet_sample_insert] +desc = "som will be redefined as the magnet sample insert rotation. Sample stage will be renamed to somss" +imptype = motion_axis + +[agilent_33220A] +asyncqueue = sct +desc = "Function Generator" +driver = agilent_33220A +imptype = function_generator +ip = 10.157.205.16 +port = 5025 + +[antonparr_MCR500] +cbfunc = "rhCallback /sics/$rhControl" +desc = "Anton Parr MRC500 Rheometer" +driver = "antonparr_MCR500" +imptype = rheometry +ip = noip +port = noport +settle = 5.0 +speed_name = rhSpeed +tol = 0.01 +torque_name = rhTorque + +[bruker_bec1] +desc = "Bruker Magnet" +driver = "bruker_bec1" +imptype = magnetic_field +ip = 10.157.205.13 +port = 4444 +type = B + +[julabo_lh45] +ctrl_sensor = "bath" +desc = "Julabo temperature controller" +driver = "julabo_lh45" +imptype = temperature +ip = 10.157.205.39 +port = 4001 +tol = 5.0 +type = T + +[ls336_01] +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 10.157.205.28 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_02] +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 10.157.205.29 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_04] +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 10.157.205.30 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_05] +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 137.157.201.21 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_06] +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 137.157.201.21 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_12] +asyncqueue = sct +desc = "Lakeshore 336 temperature controller" +driver = "ls336" +imptype = temperature +ip = 10.157.205.31 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls340_01] +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" +imptype = temperature +ip = 137.157.201.86 +port = 4001 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls340_02] +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" +imptype = temperature +ip = 137.157.201.86 +port = 4002 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls340_11] +desc = "Lakeshore 340 temperature controller" +driver = "ls340" +imptype = temperature +ip = 137.157.201.86 +port = 4001 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[mercury_scpi_01] +desc = "Oxford Mercury temperature controller in Mercury mode" +driver = "mercury_scpi" +imptype = temperature +ip = 10.157.205.5 +permlink = LT +port = 7020 +terminator = \r\n +tol = 1.0 +valve_tol = 2 + +[mercury_scpi_02] +desc = "Oxford Mercury temperature controller in Mercury mode" +driver = "mercury_scpi" +imptype = temperature +ip = 10.157.205.47 +permlink = LT +port = 7020 +terminator = \r\n +tol = 1.0 +valve_tol = 2 + +[newport_rva] +desc = "Newport Rapid Visco-Analyser" +driver = "nprvasm2" +imptype = viscosity +ip = 137.157.202.91 +port = 4001 +tol = 1 + +[normal_sample_stage] +desc = "This is the default sample stage configuration xyz translation omega rotation but no tilt axes" +imptype = motion_axis + +[protek_01] +asyncqueue = sct +desc = "Protek Multimeter" +driver = "protekmm" +imptype = multimeter +ip = 10.157.205.36 +port = 4001 + +[protek_02] +asyncqueue = sct +desc = "Protek Multimeter" +driver = "protekmm" +imptype = multimeter +ip = 10.157.205.37 +port = 4001 + +[watlow_rm] +desc = "Watlow RM temperature controller" +driver = "watlow_mrm" +imptype = temperature +ip = 10.157.205.6 +terminator = \r\n +tol = 0.5 +type = T + +[west4100] +desc = "Blue furnace temperature controller" +dev_id = 1 +driver = "west4100" +imptype = temperature +ip = 10.157.205.19 + diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 484bc0dd..da6b6bfa 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -1,72 +1,261 @@ #!/usr/bin/env python +"""Provides a sics_config.ini file viewer and editor. +""" # vim: tabstop=8 softtabstop=4 shiftwidth=4 nocin si et ft=python # View Screen has 3 parts # (Instrument Configuration), (Configuration Options), (Option Implementation) -# Uses MVC implemented as InstConfigData, InstConfigView, ConfigEdit -# +# Uses MVC as InstConfigData, InstConfigView, InstConfigManager + # InstConfigData <>--- ConfigParser.SafeConfig # |--set_cfparse() -# ConfigEdit <>--- InstConfigData, PresentationData +# InstConfigManager <>--- InstConfigData, PresentationData # |--set_cfdata(), set_presdata() # |--set_xyz_data() call self.cfgdata.set_xyz() methods # -# urwid.Frame + +# urwid.Pile # ^ -# InstConfigView <>--- ConfigEdit, PresentationData +# | +# InstConfigView <>--- InstConfigManager, PresentationData # |--set_cfedit(), set_presdata() -# -# PresentationData -# |--set_cfdata() import os +import shutil import argparse import ConfigParser import urwid -import copy from collections import defaultdict +PALETTE = [ + ('body', 'dark cyan', '', 'standout'), + ('focus', 'dark red', '', 'standout'), + ('head', 'yellow', 'black'), +] -class InstConfigData: - msg_index = 4 - # configuration_dict: dict of instrument configurations as defined below, - # {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} } - configuration_dict = defaultdict(dict) - # opt_dict: dict of configuration options as defined below, - # {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}} - opt_dict = defaultdict(dict) +class RadioButtonListWalker(urwid.SimpleListWalker): - # imp_dict: dict of implementations indexed by optype, - # {optype: [impname] } - imp_dict = defaultdict(list) + """Extend urwid.SimpleListWalker to generate a radio button listwalker. - def __init__(self): + Attributes: + button_dict (dict): Maps radiobutton labels to an urwid.RadioButton. + """ + + def __init__(self, item_states, on_state_change=None, user_data=None): + """ + Args: + item_states (list of tuples): [(button name, state)]. + on_state_change: 'change' signal handler for each radiobutton. + user_data: data passed to signal handler. + """ + radio_grp = [] + mapped_rb_list = [] + self.button_dict = {} + for item, stateval in item_states: + _rb = urwid.RadioButton( radio_grp, item, state=stateval, + on_state_change=on_state_change, user_data=user_data ) + self.button_dict[item] = _rb + mapped_rb = urwid.AttrMap(_rb, 'body', 'focus') + mapped_rb_list.append(mapped_rb) + + super(RadioButtonListWalker, self).__init__(mapped_rb_list) + return + + def set_modified_callback(self, callback): + """This is an abstract method in SimpleListWalker. + The urwid doc says use connect_signal(lw, 'modified', callback) instead. + """ + slw = super(RadioButtonListWalker, self) + urwid.connect_signal(slw, 'modified', callback) return +class CheckBoxListWalker(urwid.SimpleListWalker): + + """Extend urwid.SimpleListWalker to generate a checkbox listwalker. + Attributes: + button_dict (dict): Maps checkbox labels to an urwid.CheckBox. + """ + + def __init__(self, item_states, on_state_change = None, user_data = None): + """ + Args: + item_states (list of tuples): [(button name, state)]. + on_state_change: 'change' signal handler for each radiobutton. + user_data: data passed to signal handler. + """ + mapped_cb_list = [] + self.button_dict = {} + for item, stateval in item_states: + _cb = urwid.CheckBox( item, state = stateval, + on_state_change = on_state_change, + user_data = user_data ) + self.button_dict[item] = _cb + mapped_cb = urwid.AttrMap(_cb, 'body', 'focus') + mapped_cb_list.append(mapped_cb) + + super(CheckBoxListWalker, self).__init__(mapped_cb_list) + return + + def set_modified_callback(self, callback): + """This is an abstract method in SimpleListWalker. + The urwid doc says use connect_signal(lw, 'modified', callback) instead. + """ + slw = super(CheckBoxListWalker, self) + urwid.connect_signal(slw, 'modified', callback) + return + + +class OptionListWalker(CheckBoxListWalker): + + """Extend CheckBoxListWalker to generate a listwalker from an + InstConfigData option description. + """ + + def __init__(self, opt_dict, statechange_cb): + """ + Args: + opt_dict: InstConfigData option description dictionary. + statechange_cb: 'change' signal handler for each checkbox. + """ + urwid.register_signal(OptionListWalker, ['focus_change']) + item_states = [(i, d['enabled']) for i, d in opt_dict.iteritems()] + item_states.sort() + + super(OptionListWalker, self).__init__(item_states, statechange_cb) + return + + def set_focus(self, pos): + """Emit 'focus_change' signal with position of button. + """ + urwid.emit_signal(self, 'focus_change', pos) + return super(OptionListWalker, self).set_focus(pos) + + +# ClosedListBox implements a ListBox which prevents selection outside of the +# list using the 'up' or 'down' keys +class ClosedListBox(urwid.ListBox): + + """Extend urwid.ListBox to prevent navigating outside of the listbox. + """ + + def keypress(self, size, key): + """Override keypress to limit navigation to within listbox. + """ + pos = self.get_focus()[1] + _ll = len(self.body) + if (pos <= 0 and key == 'up') or (pos >= _ll-1 and key == 'down'): + return + else: + return super(ClosedListBox, self).keypress(size, key) + + +# List of Checkboxes +class OptionListBox(ClosedListBox): + + """Extend ClosedListBox doesn't add anything but it may come in handy + someday when defining behaviour of configuration option lists. + """ + + def __init__(self, listwalker): + super(OptionListBox, self).__init__(listwalker) + return + + +# List of RadioButtons +class ImpListBox(ClosedListBox): + + """Extend ClosedListBox to allow updating implementation lists when + selecting a configuration option. + """ + + def __init__(self, listwalker): + super(ImpListBox, self).__init__(listwalker) + return + + def use_listwalker(self, listwalker): + """ Select the given listwalker for display. + """ + self.body.contents[:] = listwalker + return + + +class InstConfigData(object): + + """Handles reading and writing instrument configuration data and provides + methods to change the configuration. + Attributes: + config_dict: Instrument configurations by configuration name. + opt_dict: Configuration option descriptions indexed by option name. + imp_dict: Implementations for indexed by option type. + """ + + msg_index = 4 + + def __init__(self): + self.file_parser = ConfigParser.SafeConfigParser() + self.config_filename = 'sics_config.ini' + #config_dict: dict of instrument configurations as defined below, + # {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} } + self.config_dict = defaultdict(dict) + + #imp_dict: dict of implementations indexed by optype, + # {optype: []|[none:impname,...] } + self.imp_dict = defaultdict(list) + + #opt_dict: dict of configuration options as defined below, + # {optname:{'enabled':T/F/Always, 'imptype':optype,'selected_imp':dflt}} + self.opt_dict = defaultdict(dict) + + #imp_ip_dict: Maps each implementation to an ip and port if it has one. + # {imp, {ip:'q4.q3.q2.q1', port:'nnnn', ...} + self.imp_ip_dict = defaultdict(dict) + + #imp2opt_dict: Maps each implementation to an option or None, + # {imp: opt/None} + self.imp2opt_dict = {} + + #optypelist: list of (opt, optype) tuples + # [(opt, optype)] + self.optypelist = [] + def __get_configurations(self): - for s in self.file_parser.sections(): + """Parse instrument configuration definitions from INI file into + config_dict attribute of InstConfigData object + """ + for sect in self.file_parser.sections(): cascade_list = [] - if self.file_parser.has_option(s, 'cascade'): - enabled = self.file_parser.get(s, 'enabled') - for cascade_str in self.file_parser.get(s,'cascade').split(','): + if self.file_parser.has_option(sect, 'cascade'): + enabled = self.file_parser.get(sect, 'enabled') + # pylint: disable = E1103 + optimp_list = self.file_parser.get(sect, 'cascade').split(',') + # pylint: enable = E1103 + for cascade_str in optimp_list: cascade_list.append(tuple(cascade_str.split(':'))) - if enabled.lower() in ['true','always']: + # pylint: disable = E1103 + lower_enabled = enabled.lower() + # pylint: enable = E1103 + if lower_enabled in ['true', 'always']: stateval = True else: stateval = False - self.configuration_dict[s]['enabled'] = stateval - self.configuration_dict[s]['cascade_list'] = cascade_list + self.config_dict[sect]['enabled'] = stateval + self.config_dict[sect]['cascade_list'] = cascade_list def __get_options(self): - for s in self.file_parser.sections(): - if self.file_parser.has_option(s, 'implementation'): - selected_imp = self.file_parser.get(s, 'implementation') - imptype = self.file_parser.get(s, 'optype') - enabled = self.file_parser.get(s, 'enabled').lower() + """Parse configuration options from INI file into opt_dict attribute of + InstConfigData object. + """ + for sect in self.file_parser.sections(): + if self.file_parser.has_option(sect, 'implementation'): + selected_imp = self.file_parser.get(sect, 'implementation') + imptype = self.file_parser.get(sect, 'optype') + # pylint: disable = E1103 + enabled = self.file_parser.get(sect, 'enabled').lower() + # pylint: enable = E1103 if enabled == 'always': stateval = True permanent = True @@ -77,335 +266,451 @@ class InstConfigData: stateval = False permanent = False - self.opt_dict[s]['enabled'] = stateval - self.opt_dict[s]['permanent'] = permanent - self.opt_dict[s]['imptype'] = imptype - self.opt_dict[s]['selected_imp'] = selected_imp + if self.file_parser.has_option(sect, 'id'): + _id = self.file_parser.get(sect, 'id') + self.opt_dict[sect]['id'] = _id + + self.opt_dict[sect]['permanent'] = permanent + self.opt_dict[sect]['imptype'] = imptype + if stateval == True: + imp_unavailable = (selected_imp in self.imp2opt_dict) and ( + self.imp2opt_dict[selected_imp] != 'none' ) + if selected_imp == 'none' or imp_unavailable: + self.opt_dict[sect]['enabled'] = False + self.opt_dict[sect]['selected_imp'] = 'none' + else: + self.opt_dict[sect]['enabled'] = True + self.set_imp(sect, selected_imp) +# dbmsg = 'Add imp2opt_dict[{0}] = {1}' +# print dbmsg.format(selected_imp, sect) + else: + self.opt_dict[sect]['enabled'] = False + self.opt_dict[sect]['selected_imp'] = 'none' def __get_implementations(self): - for s in self.file_parser.sections(): - if self.file_parser.has_option(s, 'imptype'): - key = self.file_parser.get(s, 'imptype') - self.imp_dict[key].append(s) + """Parse implementation lists from INI file into imp_dict attribute of + InstConfigData object. + """ + for sect in self.file_parser.sections(): + if self.file_parser.has_option(sect, 'imptype'): + imptype = self.file_parser.get(sect, 'imptype') + self.imp_dict[imptype].append(sect) + if self.file_parser.has_option(sect, 'ip'): + ip_address = self.file_parser.get(sect, 'ip') + self.imp_ip_dict[sect]['ip'] = ip_address - def read_config_file(self, config_filename): - self.config_filename = config_filename - self.file_parser = ConfigParser.SafeConfigParser() - self.file_parser.read(config_filename) + if self.file_parser.has_option(sect, 'port'): + port = self.file_parser.get(sect, 'port') + self.imp_ip_dict[sect]['port'] = port + + if sect not in self.imp2opt_dict: + self.imp2opt_dict[sect] = 'none' +# print 'Add imp2opt_dict[{0}] = none'.format(sect) + + def consistency_check(self): + """Check that there is a one to one mapping between options and + implementations. + """ + for opt, opt_def in self.opt_dict.iteritems(): + selected_imp = opt_def['selected_imp'] + if selected_imp == 'none': + continue + else: + mapped_opt = self.imp2opt_dict[selected_imp] + + if mapped_opt != opt: + emsg = 'ERROR: imp2opt_dict fails to map {i} to {o}' + print emsg.format(i=selected_imp, o=opt) + + for imp, opt in self.imp2opt_dict.iteritems(): + if imp == 'none': + print 'ERROR: Found "none" as a keyword in imp2opt_dict' + continue + elif opt == 'none': + continue + else: + selected_imp = self.opt_dict[opt]['selected_imp'] + + if imp != selected_imp: + emsg = 'ERROR: imp2opt_dict fails to map {i} to {o}' + print emsg.format(i=selected_imp, o=opt) + + def read_config_file(self, **kwargs): + """ Load and parse a sics_config.ini file """ + if 'config_filename' in kwargs: + self.config_filename = kwargs['config_filename'] + self.file_parser.read(self.config_filename) self.__get_options() self.__get_implementations() self.__get_configurations() - return + self.consistency_check() + for opt, opt_desc in self.opt_dict.iteritems(): + self.optypelist.append((opt, opt_desc['imptype'])) + + for imptype in self.imp_dict.keys(): + if 'none' not in self.imp_dict[imptype]: + self.imp_dict[imptype].insert(0, 'none') def backup_files(self): + """ Backup configuration files """ for idx in range(8, 0, -1): if os.path.exists(self.config_filename + "." + str(idx)): os.rename(self.config_filename + "." + str(idx), - self.config_filename + "." + str(idx + 1)) + self.config_filename + "." + str(idx + 1)) + if os.path.exists(self.config_filename): - os.rename(self.config_filename, self.config_filename + ".1") + shutil.copy2(self.config_filename, self.config_filename + ".1") + + def write_section(self, fhandle, sect): + """Write a configuration section with sorted options""" + fhandle.write("[%s]\n" % sect) + for opt in sorted(self.file_parser.options(sect)): + fhandle.write('{0} = {1}\n'.format(opt, self.file_parser.get(sect, opt))) def write_config_file(self): - for item,dict in self.opt_dict.iteritems(): - if self.file_parser.get(item, 'enabled').lower() == 'always': + """ Write out InstConfigData values to the configuration file.""" + for opt, opt_desc in self.opt_dict.iteritems(): + if 'permanent' in opt_desc and opt_desc['permanent'] == True: enabled = 'Always' else: - enabled = dict['enabled'].__str__() - self.file_parser.set(item, 'enabled', enabled) - self.file_parser.set(item, 'implementation', dict['selected_imp']) - self.file_parser.set(item, 'optype', dict['imptype']) - for item,dict in self.configuration_dict.iteritems(): - enabled = dict['enabled'].__str__() - self.file_parser.set(item, 'enabled', enabled) - with open(self.config_filename,'w') as cfile: - for section in sorted(self.file_parser.sections()): - cfile.write("[%s]\n" % section) - for option in sorted(self.file_parser.options(section)): - cfile.write("%s = %s\n" % (option, self.file_parser.get(section, option))) + enabled = opt_desc['enabled'].__str__() + + self.file_parser.set(opt, 'enabled', enabled) + self.file_parser.set(opt, 'implementation', + opt_desc['selected_imp']) + self.file_parser.set(opt, 'optype', opt_desc['imptype']) + + for config, config_desc in self.config_dict.iteritems(): + enabled = config_desc['enabled'].__str__() + self.file_parser.set(config, 'enabled', enabled) + + scratch_file = self.config_filename + '.scratch' + with open(scratch_file, 'w') as cfile: + for config in sorted(self.config_dict.keys()): + self.write_section(cfile, config) + + for opt in sorted(self.opt_dict.keys()): + self.write_section(cfile, opt) + + for imp in sorted(self.imp2opt_dict.keys()): + self.write_section(cfile, imp) + cfile.write("\n") - #self.file_parser.write(cfile) - def cf_statechange(self, checkbox, new_state, udat=None): - cfg_id = checkbox.get_label() - self.configuration_dict[cfg_id]['enabled'] = new_state + os.rename(scratch_file, self.config_filename) - def opt_statechange(self, checkbox, new_state, udat=None): - opt = checkbox.get_label() - dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) + def set_imp(self, opt, new_imp): + """Keep option dictionaray and implementation -> option map in sync.""" + if 'selected_imp' in self.opt_dict[opt]: + old_imp = self.opt_dict[opt]['selected_imp'] + if old_imp != 'none': + self.imp2opt_dict[old_imp] = 'none' + + self.opt_dict[opt]['selected_imp'] = new_imp + if new_imp != 'none': + self.imp2opt_dict[new_imp] = opt + + def get_optypelist (self): + """Return a list of (option, optype) tuples.""" + return self.optypelist + + def iter_implementations(self, opt): + """Iterate over implementation names for the given option.""" + opt_desc = self.opt_dict[opt] + for imp in self.imp_dict[opt_desc['imptype']]: + yield imp + + def cf_statechange(self, cfg_id, new_state): + """Change the given instrument configuration state.""" + self.config_dict[cfg_id]['enabled'] = new_state + + def opt_statechange(self, opt, new_state): + """Change the given option state.""" self.opt_dict[opt]['enabled'] = new_state - def imp_statechange(self, button, new_state, opt): - selected_imp = button.get_label() - dbg.msg(self.msg_index, 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, new_state, opt)) + def imp_statechange(self, selected_imp, new_state, opt): + """Change the given implementation state.""" self.msg_index = (self.msg_index - 3) % 2 + 4 if new_state == True: self.opt_dict[opt]['selected_imp'] = selected_imp -## TODO Configuration Editor -## Configuration Viewer -Palette = [ - ('body', 'dark cyan', '', 'standout'), - ('focus', 'dark red', '', 'standout'), - ('head', 'light red', 'black'), -] +class InstConfigView(urwid.Frame): + + """Extend urwid.Pile to provide an instrument configuration viewer. + """ + + def __init__(self, cfg_lb, opt_lb, imp_lb): + """ + Args: + cfg_lb: Instrument configuration listbox + opt_lb: Configuration options listbox + imp_lb: Available implementations listbox + """ + option_listboxes = [ + cfg_lb, + opt_lb, + imp_lb] -#FIXME Replace the [(name,stateval)] list imp_states with list of item names -class RadioButtonListWalker(urwid.SimpleListWalker): - button_dict = {} - def __init__(self, item_states, on_state_change=None, user_data=None): - radio_grp = [] - mapped_rb_list = [] - for item,stateval in item_states: - rb = urwid.RadioButton(radio_grp, item, state=stateval, on_state_change=on_state_change, user_data=user_data) - self.button_dict[item] = rb - mapped_rb = urwid.AttrMap(rb, 'body', 'focus') - mapped_rb_list.append(mapped_rb) + self. main_loop = None + self.cfg_pile = urwid.Pile(option_listboxes) + self.help_str = 'Alt-Q (Quit), W (Write file)' + self.header_text = urwid.Text(u'') + self._msg_hdr('') + self.mapped_header = urwid.AttrMap(self.header_text, 'head') - super(RadioButtonListWalker, self).__init__(mapped_rb_list) + super(InstConfigView, self).__init__(header = self.mapped_header, body = self.cfg_pile) return + def _msg_hdr(self, msg): + """Display a message after the help string""" + hdr = self.help_str + msg + self.header_text.set_text(hdr) -class CheckBoxListWalker(urwid.SimpleListWalker): - button_dict = {} - def __init__(self, item_states, on_state_change = None, user_data = None): - mapped_cb_list = [] - for item,stateval in item_states: - cb = urwid.CheckBox(item, state = stateval, on_state_change = on_state_change, user_data = user_data) - self.button_dict[item] = cb - mapped_cb = urwid.AttrMap(cb, 'body', 'focus') - mapped_cb_list.append(mapped_cb) + def _msg_cb(self, main_loop, msg): + """Wrap the message function in an urwid main loop callback""" + self._msg_hdr(msg) - super(CheckBoxListWalker, self).__init__(mapped_cb_list) - return + def timed_msg(self, t_sec, msg): + """Display a transient message for the given time""" + self._msg_hdr(msg) + self.main_loop.set_alarm_in(t_sec, self._msg_cb, '') - -# Selects listwalker to display for ImpListBox on focus -class OptionListWalker(CheckBoxListWalker): - def __init__(self, opt_dict, statechange_cb): - urwid.register_signal(OptionListWalker, ['focus_change']) - item_states = [(i,d['enabled']) for i,d in opt_dict.iteritems()] - item_states.sort() - - super(OptionListWalker, self).__init__(item_states, statechange_cb) - return - - def set_focus(self, pos): - dbg.msg(0, 'OptionListWalker:set_focus({0}) -> emit focus_change'.format(pos)) - urwid.emit_signal(self, 'focus_change', pos) - return super(OptionListWalker, self).set_focus(pos) - - -# ClosedListBox implements a ListBox which prevents selection outside of the -# list using the 'up' or 'down' keys -class ClosedListBox(urwid.ListBox): - - def keypress(self, size, key): - """Prevents navigating outside of a ClosedListBox with the up and down arrow keys""" - pos = self.get_focus()[1] - ll = len(self.body) - if (pos <= 0 and key == 'up') or (pos >= ll-1 and key == 'down'): - return - else: - return super(ClosedListBox, self).keypress(size, key) - - -# List of Checkboxes -class OptionListBox(ClosedListBox): - def __init__(self, listwalker): - super(OptionListBox, self).__init__(listwalker) - return + def set_main(self, main_loop): + """Pass a reference to the main loop to InstConfigView""" + self.main_loop = main_loop # Contains OptionListWalker dict indexed by option # Contains ImpListBox # Connects OptionListWalker 'focus_change' signal to update_imp_lb handler # Tracks selected implementation for each option # and sets selection on ImpListBox -class InstConfigManager: - cf_msg_index = 8 - options = [] - imp_lw_dict = {} - def __init__(self, cfdat): - self.cfdat = cfdat +class InstConfigManager(object): + + """Provides controller which keeps data and viewer in sync.""" + + def __init__(self, cf_dat): + self.cf_dat = cf_dat urwid.register_signal(InstConfigManager, ['focus_change']) - for opt,dict in cfdat.opt_dict.iteritems(): - self.options.append((opt, dict['imptype'])) -# imp_items = [] -# for imp in cfdat.imp_dict[dict['imptype']]: -# if imp == dict['selected_imp']: -# imp_items.append((imp, True)) -# else: -# imp_items.append((imp, False)) - -# imp_items.sort() -# self.imp_lw_dict[opt] = RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) - - self.options.sort() -# imp_items.sort() - firstopt = self.options[0][0] + self.opt_optype_list = self.cf_dat.get_optypelist() + + self.opt_optype_list.sort() + firstopt = self.opt_optype_list[0][0] self.imp_lw = self.__gen_imp_listwalker(firstopt) -# self.imp_lw = RadioButtonListWalker([], on_state_change=self.imp_statechange, user_data=firstopt) - self.option_lw = OptionListWalker(cfdat.opt_dict, self.opt_statechange) - self.imp_lb = ImpListBox(self.imp_lw) - urwid.connect_signal(self.option_lw, 'focus_change', self.update_imp_lb) + self.opt_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange) + for label, button in self.opt_lw.button_dict.iteritems(): + button.set_label('{0}:{1}'.format( + label, self.cf_dat.opt_dict[label]['selected_imp']) ) - item_states = [(i,d['enabled']) for i,d in cf_dat.configuration_dict.iteritems()] + self.imp_lb = ImpListBox(self.imp_lw) + urwid.connect_signal(self.opt_lw, 'focus_change', self.update_imp_lb) + item_states = [(i, d['enabled']) for i, d in + cf_dat.config_dict.iteritems()] item_states.sort() - self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange) - self.config_lb = OptionListBox(self.cfg_lw) - self.opt_lb = OptionListBox(self.option_lw) + self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = + self.cf_statechange) + self.cfg_lb = OptionListBox(self.cfg_lw) + self.opt_lb = OptionListBox(self.opt_lw) self.opt_lb.set_focus(0) return + def __imp_unavailable(self, opt, imp, action): + """Return True if an implementation is unavailable because it is used + by an enabled option. + """ + if imp == 'none': + return False + + ckopt = self.cf_dat.imp2opt_dict[imp] + if ckopt == 'none': + return False + + opt_imp = self.cf_dat.opt_dict[opt]['selected_imp'] + if (action == 'focus'): + if opt_imp == imp: + return False + elif self.cf_dat.opt_dict[ckopt]['enabled']: + return True + else: + return False + elif (action == 'state_change'): + if self.cf_dat.opt_dict[ckopt]['enabled']: + return True + else: + return False + else: + return False + def __gen_imp_listwalker(self, opt): + """Generate the appropriate listwalker for the given option.""" imp_items = [] - dict = self.cfdat.opt_dict[opt] - for imp in self.cfdat.imp_dict[dict['imptype']]: - if imp == dict['selected_imp']: + for imp in self.cf_dat.iter_implementations(opt): + if self.__imp_unavailable(opt, imp, 'focus'): + continue + elif imp == 'none' and self.cf_dat.opt_dict[opt]['permanent']: + continue + + if imp == self.cf_dat.opt_dict[opt]['selected_imp']: imp_items.append((imp, True)) else: imp_items.append((imp, False)) - imp_items.sort() + imp_items = imp_items[:1] + sorted(imp_items[1:]) - return RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) + rb_lw = RadioButtonListWalker(imp_items, + on_state_change=self.imp_statechange, + user_data=opt) + for imp, button in rb_lw.button_dict.iteritems(): + if imp != 'none': + if 'ip' in self.cf_dat.imp_ip_dict[imp]: + address = self.cf_dat.imp_ip_dict[imp]['ip'] + if 'port' in self.cf_dat.imp_ip_dict[imp]: + port = self.cf_dat.imp_ip_dict[imp]['port'] + address += ':' + address += port - def cf_statechange(self, button, new_state, udat=None): - self.cfdat.cf_statechange(button, new_state, udat) - b = button.get_label() - cascade = self.cfdat.configuration_dict[b]['cascade_list'] + button.set_label('{0:20}{1}'.format(imp, address)) + else: + button.set_label('{0}'.format(imp)) + + return rb_lw + + def cf_statechange(self, button, new_state): + """Update option list when an instrument configuration is selected and + notify InstConfigData object. + """ + cfg_id = button.get_label() + self.cf_dat.cf_statechange(cfg_id, new_state) + cascade = self.cf_dat.config_dict[cfg_id]['cascade_list'] if new_state == True: - for opt in self.cfdat.opt_dict.keys(): - if self.cfdat.opt_dict[opt]['permanent'] == False: - self.option_lw.button_dict[opt].set_state(False) - for opt,imp in cascade: - self.option_lw.button_dict[opt].set_state(True) - imp_lw = self.__gen_imp_listwalker(opt) - imp_lw.button_dict[imp].set_state(True) - currpos = self.opt_lb.get_focus()[1] - self.opt_lb.set_focus(currpos) + for opt in self.cf_dat.opt_dict.keys(): + self.opt_lw.button_dict[opt].set_state(False) + + for opt, imp in cascade: + self.cf_dat.set_imp(opt, imp) + self.opt_lw.button_dict[opt].set_state(True) + + for opt in self.cf_dat.opt_dict.keys(): + if self.cf_dat.opt_dict[opt]['permanent'] == True: + self.opt_lw.button_dict[opt].set_state(True) + + if self.opt_lw.button_dict[opt].get_state() == False: + self.cf_dat.set_imp(opt, 'none') + self.opt_lw.button_dict[opt].set_label('{0}:none'.format(opt)) - dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(b, new_state, udat, cascade)) - self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8 return - def opt_statechange(self, button, new_state, udat=None): - self.cfdat.opt_statechange(button, new_state, udat) - return + def opt_statechange(self, button, new_state): + """Update option label when it changes state and notify InstConfigData + object. + """ + opt = button.get_label().split(':')[0] + imp = self.cf_dat.opt_dict[opt]['selected_imp'] + if new_state == True: + if self.__imp_unavailable(opt, imp, 'state_change'): + self.cf_dat.opt_dict[opt]['selected_imp'] = 'none' + imp_none_button = self.imp_lw.button_dict['none'] + imp_none_button.set_state(True) + opt_button = self.opt_lw.button_dict[opt] + opt_button.set_label('{0}:none'.format(opt)) + self.imp_lw = self.__gen_imp_listwalker(opt) + self.imp_lb.use_listwalker(self.imp_lw) + else: + opt_button = self.opt_lw.button_dict[opt] + opt_button.set_label('{0}:{1}'.format(opt, imp)) + self.cf_dat.set_imp(opt, imp) - def imp_statechange(self, button, new_state, udat=None): - self.cfdat.imp_statechange(button, new_state, udat) + self.cf_dat.opt_statechange(opt, new_state) + + def imp_statechange(self, button, new_state, opt): + """Update label on the configuration option when it's implementation is + changed. + """ + imp = button.get_label().split()[0] + if new_state == True: + self.cf_dat.set_imp(opt, imp) + opt_button = self.opt_lw.button_dict[opt] + opt_button.set_label('{0}:{1}'.format(opt, imp)) + + self.cf_dat.imp_statechange(imp, new_state, opt) return def update_imp_lb(self, pos): - optname = self.options[pos][0] - optype = self.options[pos][1] - mstr = 'InstConfigManager:update_imp_lb({0}) -> select {1}'.format(pos, optype) - dbg.msg(1, mstr) + """Update implementation list when an option gets focus.""" + optname = self.opt_optype_list[pos][0] self.imp_lw = self.__gen_imp_listwalker(optname) self.imp_lb.use_listwalker(self.imp_lw) return -# List of RadioButtons -class ImpListBox(ClosedListBox): - def __init__(self, listwalker): - super(ImpListBox, self).__init__(listwalker) - return - - def use_listwalker(self, liswalker): - self.body.contents[:] = liswalker - return - - -class InstConfigView(urwid.Pile): - - def __init__(self, cf_dat, cf_man, dbmsg): - self.cf_dat = cf_dat - self.cf_man = cf_man - option_ListBoxes = [ - self.cf_man.config_lb, - self.cf_man.opt_lb, - self.cf_man.imp_lb, - dbmsg] - super(InstConfigView, self).__init__(option_ListBoxes) - return - - def keyinput(self, key): +def gen_input_handler(cf_man, cf_dat, cf_viewer): + """Generate keyinput handler with references to the controller object, the + data object and the viewer object. + """ + def keyinput(key): + """Switch between lists, save data and quit on key input.""" if key == 'meta q': raise urwid.ExitMainLoop() elif key == 'w': - self.cf_dat.backup_files() - self.cf_dat.write_config_file() + cf_dat.backup_files() + cf_viewer.timed_msg(1, ': Saving file') + cf_dat.write_config_file() elif key in ['right', 'tab']: - if self.get_focus() == self.cf_man.config_lb: - self.set_focus(self.cf_man.opt_lb) - elif self.get_focus() == self.cf_man.opt_lb: - self.set_focus(self.cf_man.imp_lb) + if cf_viewer.cfg_pile.get_focus() == cf_man.cfg_lb: + cf_viewer.cfg_pile.set_focus(cf_man.opt_lb) + elif cf_viewer.cfg_pile.get_focus() == cf_man.opt_lb: + cf_viewer.cfg_pile.set_focus(cf_man.imp_lb) else: - self.set_focus(self.cf_man.config_lb) + cf_viewer.cfg_pile.set_focus(cf_man.cfg_lb) elif key in ['left', 'shift tab']: - if self.get_focus() == self.cf_man.config_lb: - self.set_focus(self.cf_man.imp_lb) - elif self.get_focus() == self.cf_man.opt_lb: - self.set_focus(self.cf_man.config_lb) + if cf_viewer.cfg_pile.get_focus() == cf_man.cfg_lb: + cf_viewer.cfg_pile.set_focus(cf_man.imp_lb) + elif cf_viewer.cfg_pile.get_focus() == cf_man.opt_lb: + cf_viewer.cfg_pile.set_focus(cf_man.cfg_lb) else: - self.set_focus(self.cf_man.opt_lb) - return + cf_viewer.cfg_pile.set_focus(cf_man.opt_lb) -import pdb -class DEBUG: - msgTextDict = {} - msglist = [] - msg_ids = [ 'm0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9' ] - def __init__(self, enabled=False): - self.enabled = enabled - if enabled: - for msgID in self.msg_ids: - msgText = urwid.Text(u'Space for message {0}'.format(msgID)) - self.msgTextDict[msgID] = msgText - self.msglist.append(urwid.AttrMap(msgText, 'body', 'focus')) - - mlw = urwid.SimpleListWalker(self.msglist) - self.mlb = urwid.ListBox(mlw) - return - - def msg(self, index, msg): - if self.enabled: - mid = self.msg_ids[index] - self.msgTextDict[mid].set_text(msg) - return + return keyinput -dbg = DEBUG(enabled=True) def main(config_ini): - global cf_dat, cf_man, cf_viewer + """Create configuration editor.""" +# global cf_dat, cf_man, cf_viewer + # Make configuration data cf_dat = InstConfigData() - cf_dat.read_config_file(config_ini) + cf_dat.read_config_file(config_filename = config_ini) # Make configuration editor cf_man = InstConfigManager(cf_dat) # Make configuration viewer - cf_viewer = InstConfigView(cf_dat, cf_man, dbg.mlb) - urwid.MainLoop(cf_viewer, Palette, unhandled_input=cf_viewer.keyinput).run() + cf_viewer = InstConfigView(cf_man.cfg_lb, cf_man.opt_lb, cf_man.imp_lb) + + keyinput = gen_input_handler(cf_man, cf_dat, cf_viewer) + main_loop = urwid.MainLoop(cf_viewer, PALETTE, unhandled_input=keyinput) + cf_viewer.set_main(main_loop) + main_loop.run() return if '__main__' == __name__: - default_ini = "/usr/local/sics/sics_config.ini" - parser = argparse.ArgumentParser(description = """ + DEFAULT_INI = "/usr/local/sics/sics_config.ini" + PARSER = argparse.ArgumentParser(description = """ Edit a configuration (*.ini) file using python urwid widget library. Options can be enabled or disabled with mouse or spacebar. Navigate with arrow keys. Press W to save. Press Alt-Q to quit. The default configuration filename is %s. - """ % default_ini) - parser.add_argument("-v", "--verbose", action="store_true", help="give more info in the footer") - parser.add_argument("path", nargs="?", default = default_ini, help="name of file to edit [%s]" % default_ini) - args = parser.parse_args() - default_ini = os.path.abspath(args.path) - main(default_ini) + """ % DEFAULT_INI) + PARSER.add_argument( + "-v", "--verbose", action="store_true", + help="give more info in the footer") + PARSER.add_argument( + "path", nargs="?", default = DEFAULT_INI, + help="name of file to edit [%s]" % DEFAULT_INI) + ARGS = PARSER.parse_args() + DEFAULT_INI = os.path.abspath(ARGS.path) + main(DEFAULT_INI) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 275b9df1..e6de8e13 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -86,6 +86,7 @@ reserved = { 'CODE' : 'CODE', 'ADD_ARGS' : 'ADD_ARGS', 'MAKE_ARGS' : 'MAKE_ARGS', + 'SOBJ_PRIV_TYPE' : 'SOBJ_PRIV_TYPE', 'PROTOCOL_ARGS' : 'PROTOCOL_ARGS', # Group keywords 'GROUP' : 'GROUP', @@ -314,6 +315,7 @@ def p_driver_assignment(p): | SIMULATION_GROUP EQUALS id_or_str | ADD_ARGS EQUALS text_string | MAKE_ARGS EQUALS text_string + | SOBJ_PRIV_TYPE EQUALS text_string | PROTOCOL_ARGS EQUALS text_string | DEBUG_THRESHOLD EQUALS value ''' @@ -365,9 +367,10 @@ def p_group_assignment(p): def p_variable(p): ''' variable : VAR id_or_str EQUALS LBRACE variable_statement_list RBRACE + | VAR id_or_str EQUALS LBRACE RBRACE | VAR id_or_str ''' - if len(p) > 3: + if len(p) > 6: p[0] = { 'Variable' : [{'name' : p[2]}] + p[5] } else: p[0] = { 'Variable' : [{'name' : p[2]}] } @@ -680,8 +683,8 @@ def build_variable(MyDriver, p): if 'permlink' in MyVar: device_type, node_type = MyVar['permlink'].split('.') if node_type not in MyDriver['Permlink']: - MyDriver['Permlink'][node_type] = []; - MyDriver['Permlink'][node_type] += [make_path(MyVar)]; + MyDriver['Permlink'][node_type] = [] + MyDriver['Permlink'][node_type] += [make_path(MyVar)] if Verbose: print '==>>MyVar:', MyVar return MyVar @@ -971,7 +974,7 @@ def put_read_function(MyDriver, func): txt += [' sct oldval ${data}'] txt += [' sct update ${data}'] txt += [' sct utime readtime'] - txt += [' }'] + txt += [' }'] txt += [' return ${nextState}'] txt += [' } catch_message ]'] txt += [' handle_exception ${catch_status} ${catch_message}'] @@ -1115,19 +1118,19 @@ def put_pid_function(MyDriver, func): txt += ['proc %s::%s {tc_root sp pv} {' % (MyDriver['namespace'], func)] txt += [' set catch_status [ catch {'] txt += [' debug_log ${tc_root} 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_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 += [' 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 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 += ['# %s hook code starts' % func] txt += MyDriver['Funcs'][func]['text'] @@ -1283,7 +1286,7 @@ def put_group(MyDriver, MyGroup): if MyVar['driveable']: # Generate __ at runtime for driveable driveable = '${name}_' + make_path(MyVar) - txt += [' ansto_makesctdrive %s ${scobj_hpath}/%s ${scobj_hpath}/%s ${sct_controller}' % (driveable, nodename, MyVar['driveable'])] + MyDriver['Deferred'] += ['ansto_makesctdrive %s ${scobj_hpath}/%s ${scobj_hpath}/%s ${sct_controller}' % (driveable, nodename, MyVar['driveable'])] txt += [' } else {'] txt += [' %s::sics_log 9 "[%s] => No poll/write for %s"' % (MyDriver['namespace'], MyDriver['simulation_group'], MyDriver['name'])] txt += [' }'] @@ -1312,7 +1315,12 @@ def put_mkDriver(MyDriver): else: txt += [' set permlink_device_number [format "%02d" [incr ::scobj::permlink_device_counter]]'] txt += [''] - txt += [' MakeSICSObj ${name} SCT_OBJECT'] + if 'sobj_priv_type' in MyDriver: + priv_type = MyDriver['sobj_priv_type'].split() + ms_line = ' MakeSICSObj ${name} SCT_OBJECT %s %s' % (priv_type[0], priv_type[1]) + else: + ms_line = ' MakeSICSObj ${name} SCT_OBJECT' + txt += [ms_line] txt += [''] txt += [' sicslist setatt ${name} klass %s' % MyDriver['class']] txt += [' sicslist setatt ${name} long_name ${name}'] @@ -1327,6 +1335,11 @@ def put_mkDriver(MyDriver): txt += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']] txt += [' hsetprop ${scobj_hpath} debug_threshold %s' % str(MyDriver['debug_threshold'])] + if len(MyDriver['Deferred']) > 0: + txt += [' if {[string equal -nocase [SplitReply [%s]] "false"]} {' % MyDriver['simulation_group']] + for line in MyDriver['Deferred']: + txt += [' ' + line] + txt += [' }'] func = 'mkDriver' if func in MyDriver['Funcs']: txt += ['# %s hook code starts' % func] @@ -1398,14 +1411,17 @@ def put_read_config(MyDriver): txt += ['proc %s::read_config {} {' % MyDriver['namespace']] txt += [' set catch_status [ catch {'] txt += [' set ns "%s"' % MyDriver['namespace']] - txt += [' dict for {k v} $::config_dict {'] - txt += [' if { [dict exists $v "implementation"] } {'] - txt += [' if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } {'] + txt += [' dict for {k u} $::config_dict {'] + txt += [' if { [dict exists $u "implementation"] } {'] + txt += [' if { !([dict exists $u "name"] && [dict exists $u "enabled"]) } {'] txt += [' continue'] txt += [' }'] - txt += [' set name [dict get $v name]'] - txt += [' set enabled [string tolower [dict get $v "enabled"]]'] - txt += [' set implementation [dict get $v "implementation"]'] + txt += [' set enabled [string tolower [dict get $u "enabled"]]'] + txt += [' if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } {'] + txt += [' continue'] + txt += [' }'] + txt += [' set name [dict get $u name]'] + txt += [' set implementation [dict get $u "implementation"]'] txt += [' if { !([dict exists $::config_dict $implementation]) } {'] txt += [' continue'] txt += [' }'] @@ -1414,45 +1430,61 @@ def put_read_config(MyDriver): txt += [' continue'] txt += [' }'] txt += [' if { [string equal -nocase [dict get $v "driver"] "%s"] } {' % MyDriver['name']] - txt += [' if { [string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"] } {'] - txt += [' if { ![string equal -nocase [SplitReply [%s]] "false"] } {' % MyDriver['simulation_group']] - txt += [' set asyncqueue "null"'] - txt += [' ${ns}::sics_log 9 "[%s] => using null asyncqueue"' % MyDriver['simulation_group']] - txt += [' } elseif { [dict exists $v "asyncqueue"] } {'] - txt += [' set asyncqueue [dict get $v "asyncqueue"]'] - txt += [' } else {'] - txt += [' if { [dict exists $v "asyncprotocol"] } {'] - txt += [' set asyncprotocol [dict get $v "asyncprotocol"]'] - txt += [' } else {'] - txt += [' set asyncprotocol ${name}_protocol'] - txt += [' MakeAsyncProtocol ${asyncprotocol}'] - txt += [' if { [dict exists $v "terminator"] } {'] - txt += [' ${asyncprotocol} sendterminator "[dict get $v "terminator"]"'] - txt += [' ${asyncprotocol} replyterminator "[dict get $v "terminator"]"'] - txt += [' }'] - txt += [' }'] - txt += [' set asyncqueue ${name}_queue'] + txt += [' if { ![string equal -nocase [SplitReply [%s]] "false"] } {' % MyDriver['simulation_group']] + txt += [' set asyncqueue "null"'] + txt += [' ${ns}::sics_log 9 "[%s] => using null asyncqueue"' % MyDriver['simulation_group']] + txt += [' } elseif { [dict exists $v "asyncqueue"] } {'] + txt += [' set asyncqueue [dict get $v "asyncqueue"]'] + txt += [' if { [string equal -nocase ${asyncqueue} "sct"] } {'] txt += [' set IP [dict get $v ip]'] txt += [' set PORT [dict get $v port]'] - txt += [' MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT}'] - txt += [' if { [dict exists $v "timeout"] } {'] - txt += [' ${asyncqueue} timeout "[dict get $v "timeout"]"'] + txt += [' }'] + txt += [' } else {'] + txt += [' if { [dict exists $v "asyncprotocol"] } {'] + txt += [' set asyncprotocol [dict get $v "asyncprotocol"]'] + txt += [' } else {'] + txt += [' set asyncprotocol ${name}_protocol'] + txt += [' MakeAsyncProtocol ${asyncprotocol}'] + txt += [' if { [dict exists $v "terminator"] } {'] + txt += [' ${asyncprotocol} sendterminator "[dict get $v "terminator"]"'] + txt += [' ${asyncprotocol} replyterminator "[dict get $v "terminator"]"'] txt += [' }'] txt += [' }'] - if 'make_args' in MyDriver: - txt += [' set arg_list [list]'] - txt += [' foreach arg {' + MyDriver['make_args'] + '} {'] - txt += [' if {[dict exists $v $arg]} {'] - txt += [' lappend arg_list "[dict get $v $arg]"'] - txt += [' } else {'] - txt += [' ${ns}::sics_log 9 "Missing configuration value $arg"'] - txt += [' error "Missing configuration value $arg"'] - txt += [' }'] - txt += [' }'] - txt += [' add_%s ${name} "aqadapter" ${asyncqueue} {*}$arg_list' % MyDriver['name']] - else: - txt += [' add_%s ${name} "aqadapter" ${asyncqueue}' % MyDriver['name']] + txt += [' set asyncqueue ${name}_queue'] + txt += [' set IP [dict get $v ip]'] + txt += [' set PORT [dict get $v port]'] + txt += [' MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT}'] + txt += [' if { [dict exists $v "timeout"] } {'] + txt += [' ${asyncqueue} timeout "[dict get $v "timeout"]"'] + txt += [' }'] txt += [' }'] + if 'make_args' in MyDriver: + txt += [' set arg_list [list]'] + txt += [' set missing_list [list]'] + txt += [' foreach arg {' + MyDriver['make_args'] + '} {'] + txt += [' if {[dict exists $u $arg]} {'] + txt += [' lappend arg_list "[dict get $u $arg]"'] + txt += [' } elseif {[dict exists $v $arg]} {'] + txt += [' lappend arg_list "[dict get $v $arg]"'] + txt += [' } else {'] + txt += [' ${ns}::sics_log 9 "Missing configuration value $arg"'] + txt += [' lappend missing_list $arg'] + txt += [' }'] + txt += [' }'] + txt += [' if { [llength $missing_list] > 0 } {'] + txt += [' error "$name is missing configuration values $missing_list"'] + txt += [' }'] + txt += [' if { [string equal -nocase ${asyncqueue} "sct"] } {'] + txt += [' add_%s ${name} ${IP} ${PORT} {*}$arg_list' % MyDriver['name']] + txt += [' } else {'] + txt += [' add_%s ${name} "aqadapter" ${asyncqueue} {*}$arg_list' % MyDriver['name']] + txt += [' }'] + else: + txt += [' if { [string equal -nocase ${asyncqueue} "sct"] } {'] + txt += [' add_%s ${name} ${IP} ${PORT}' % MyDriver['name']] + txt += [' } else {'] + txt += [' add_%s ${name} "aqadapter" ${asyncqueue}' % MyDriver['name']] + txt += [' }'] txt += [' }'] txt += [' }'] txt += [' }'] @@ -1478,23 +1510,23 @@ def put_standard_code(MyDriver): #if theFunc['reference_count'] == 0: # continue if theFunc['type'] == 'read_function': - put_read_function(MyDriver, func); + put_read_function(MyDriver, func) elif theFunc['type'] == 'write_function': - put_write_function(MyDriver, func); + put_write_function(MyDriver, func) elif theFunc['type'] == 'fetch_function': - put_fetch_function(MyDriver, func); + put_fetch_function(MyDriver, func) elif theFunc['type'] == 'check_function': - put_check_function(MyDriver, func); + put_check_function(MyDriver, func) elif theFunc['type'] == 'checkrange_function': - put_checkrange_function(MyDriver, func); + put_checkrange_function(MyDriver, func) elif theFunc['type'] == 'checklimits_function': - put_checklimits_function(MyDriver, func); + put_checklimits_function(MyDriver, func) elif theFunc['type'] == 'checkstatus_function': - put_checkstatus_function(MyDriver, func); + put_checkstatus_function(MyDriver, func) elif theFunc['type'] == 'halt_function': - put_halt_function(MyDriver, func); + put_halt_function(MyDriver, func) elif theFunc['type'] == 'pid_function': - put_pid_function(MyDriver, func); + put_pid_function(MyDriver, func) def generate_driver(MyDriver): global NumberOfLinesOut @@ -1529,6 +1561,7 @@ def process_drivers(TheDrivers): MyDriver['Groups'] = {} MyDriver['Funcs'] = {} MyDriver['Permlink'] = {} + MyDriver['Deferred'] = [] build_driver(MyDriver, TheDrivers[driver]) if Verbose: print "MyDriver:", MyDriver['name'], '=', MyDriver diff --git a/site_ansto/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index 4640a517..c6a4ee71 100644 --- a/site_ansto/motor_dmc2280.c +++ b/site_ansto/motor_dmc2280.c @@ -270,6 +270,7 @@ struct __MoDriv { int rotary_count; /**< count of rotations */ char ao_id[256]; bool legacy_fsm; /**< flag for legacy_fsm new code */ + bool status_valid; /**< flag for status has been set from controller */ bool doStats; /**< flag to request stats collection */ double S_x; double S_y; @@ -1639,6 +1640,20 @@ static int cmdOn(pDMC2280Driv self) { return DMC_SendReq(self, cmd); } +static int cmdZero(pDMC2280Driv self) { + char cmd[CMDLEN]; + if (self->abs_encoder == 0) { + SICSLogPrintf(eError, "motor=%s, Attempt to zero non-absolute motor", self->name); + snprintf(cmd, CMDLEN, "TD%c", self->axisLabel); + } else if (self->protocol == 3) { + SICSLogPrintf(eError, "motor=%s, Attempt to zero protocol 3 motor", self->name); + snprintf(cmd, CMDLEN, "TD%c", self->axisLabel); + } else { + snprintf(cmd, CMDLEN, "DP%c=0", self->axisLabel); + } + return DMC_SendReq(self, cmd); +} + static int cmdPosition(pDMC2280Driv self, int target) { char cmd[CMDLEN]; self->lastPosition = motPosit(self); @@ -1800,7 +1815,7 @@ static int rspStatus(pDMC2280Driv self, const char* text) { self->currSteps = iSteps; if (self->bias_bits > 0) iCounts = (iCounts + self->bias_bias) & ((1 << self->bias_bits) - 1); - if (self->rotary_bits > 0) { + if (self->rotary_bits > 0 && self->status_valid) { int shift = 2; int mask = (1 << shift) - 1; int old_bits = (self->currCounts >> (self->rotary_bits - shift)) & mask; @@ -1848,6 +1863,7 @@ static int rspStatus(pDMC2280Driv self, const char* text) { else self->stopCode = 1; } + self->status_valid = true; return 1; } @@ -2573,8 +2589,13 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) { change_state(self, DMCState_Idle); return; } - cmdOn(self); - self->subState = 1; + if (self->abs_encoder && self->rotary_bits > 0) { + cmdZero(self); + self->subState = 3; + } else { + cmdOn(self); + self->subState = 1; + } return; case eTimerEvent: cmdPoll(self); @@ -2623,6 +2644,25 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) { self->subState = 0; return; } + else if (self->subState == 3) { /* Zero */ + cmdStatus(self); + self->status_valid = false; + self->subState = 4; + return; + } + else if (self->subState == 4) { /* Status after Zero */ + int iRet; + iRet = rspStatus(self, pCmd->inp_buf); + if (iRet == 0) + break; + if (fabs(self->stepsPerX) < fabs(self->currSteps)) { + SICSLogPrintf(eError, "motor=%s, cmdZero failed %d", self->name, self->currSteps); + } + set_lastMotion(self, self->currSteps, self->currCounts); + cmdOn(self); + self->subState = 1; + return; + } } while (0); break; case eCommandEvent: