diff --git a/site_ansto/instrument/TEST_SICS/fakeNHQ/fakeNHQ.py b/site_ansto/instrument/TEST_SICS/fakeNHQ/fakeNHQ.py new file mode 100755 index 00000000..f9cbe42b --- /dev/null +++ b/site_ansto/instrument/TEST_SICS/fakeNHQ/fakeNHQ.py @@ -0,0 +1,219 @@ +#!/usr/bin/python +# vim: ft=python ts=8 sts=4 sw=4 et autoindent smartindent nocindent +# author: Douglas Clowes (douglas.clowes@ansto.gov.au) 2014 +# +from twisted.internet import reactor, protocol +from twisted.protocols.basic import LineReceiver +from twisted.python import log +from twisted.internet.task import LoopingCall + +import os +import sys +import curses +sys.path.insert(0, os.path.realpath(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]),"../../util")))) +from displayscreen import Screen + +devices = [] + +class Channel(object): + def __init__(self): + self.voltage = 0 + self.current = 0 + self.setpoint = 0 + self.ramp_speed = 255 + self.current_trip = 0 + self.voltage_limit = 100 + self.current_limit = 100 + self.status_word = "MAN" + self.module = 0 + self.auto_start = 8 + self.polarity = "+" + + def iterate(self): + if self.voltage < self.setpoint: + self.voltage += min(self.ramp_speed, self.setpoint - self.voltage) + elif self.voltage > self.setpoint: + self.voltage -= min(self.ramp_speed, self.voltage - self.setpoint) + + def set(self, data): + if data[0] == "D": + self.setpoint = int(data[3:]) + if data[0] == "V": + self.ramp_speed = int(data[3:]) + if data[0] == "L": + self.current_trip = int(data[3:]) + if data[0] == "A": + self.auto_start = int(data[3:]) + + def get(self, data): + if data[0] == "U": + return "%s%04d" % (self.polarity, self.voltage) + if data[0] == "I": + return "%04d-6" % self.current + if data[0] == "M": + return "%03d" % self.voltage_limit + if data[0] == "D": + return "%04d" % self.setpoint + if data[0] == "V": + return "%03d" % self.ramp_speed + if data[0] == "G": + return "S%s=%s" % (data[1], self.status_word) + if data[0] == "L": + return "%04d" % self.current_trip + if data[0] == "S": + return "%s" % self.status_word + if data[0] == "T": + return "%03d" % self.module + if data[0] == "A": + return "%d" % self.auto_start + +class NHQ_200(LineReceiver): + def __init__(self): + self.delimiter = '\r\n' + self.channels = {} + self.channels["1"] = Channel() + self.channels["2"] = Channel() + self.channels["2"].polarity = "-" + self.setRawMode() + self.line = "" + + def iterate(self): + for idx in self.channels.keys(): + self.channels[idx].iterate() + + def write(self, data): + sent = data + print "transmitted:", repr(sent) + self.transport.write(sent) + + def lineReceived(self, data): + print "lineReceived:", data + if data == "#": + self.write("123456;3.14;6000;1000uA"); + self.write(self.delimiter); + return + if data == "W": + self.write("000") + self.write(self.delimiter); + return + if data[1] not in self.channels: + return + if len(data) > 2 and data[2] == "=": + if data[0] in "DVLA": + self.channels[data[1]].set(data) + self.write(self.delimiter); + return + if data[0] in "UIMDVGLSTA": + result = self.channels[data[1]].get(data) + self.write(result) + self.write(self.delimiter); + return + + def rawDataReceived(self, data): + #print "rawDataReceived:", repr(data) + self.transport.write(data) + self.line += data + if self.line.endswith(self.delimiter): + self.line = self.line[:-len(self.delimiter)] + self.lineReceived(self.line) + self.line = "" + + def connectionMade(self): + print "connectionMade" + devices.append(self) + + def connectionLost(self, reason): + print "connectionLost" + devices.remove(self) + +def device_iterator(): + global devices + for dev in devices: + dev.iterate() + +def display_iterator(): + global screen, devices + + try: + rows, cols = screen.stdscr.getmaxyx() + screen.stdscr.clear() + col = 0 + for base in [0, 12]: + screen.stdscr.addstr(base + 1, 0, "Voltage : ") + screen.stdscr.addstr(base + 2, 0, "Current : ") + screen.stdscr.addstr(base + 3, 0, "Setpoint: ") + screen.stdscr.addstr(base + 4, 0, "Ramp : ") + for dev in devices: + col += 1 + screen.stdscr.addstr(0, 12 * col, "Top TODO") + for chan, base in [("1", 0), ("2", 12)]: + try: + if dev.channels[chan].polarity == "-": + voltage = - dev.channels[chan].voltage + else: + voltage = + dev.channels[chan].voltage + screen.stdscr.addstr(base + 1, 12 * col, "%6d" % voltage) + screen.stdscr.addstr(base + 2, 12 * col, "%6d" % dev.channels[chan].current) + screen.stdscr.addstr(base + 3, 12 * col, "%6d" % dev.channels[chan].setpoint) + screen.stdscr.addstr(base + 4, 12 * col, "%6d" % dev.channels[chan].ramp_speed) + except: + pass + except: + raise + finally: + try: + screen.stdscr.refresh() + except: + pass + +class MyScreen(Screen): + def __init__(self, stdscr): + Screen.__init__(self, stdscr) + + def sendLine(self, txt): + global devices + + def write(self, txt): + try: + newLine = self.lines[-1] + " => " + txt + del self.lines[-1] + self.addLine(newLine) + except: + pass + +def main(): + global screen + import argparse + parser = argparse.ArgumentParser(description="Fake NHQ-20x device") + parser.add_argument('instrument', help='The instrument name', nargs='*') + parser.add_argument('-p', '--port',\ + help='Port on which to listen',\ + type=int, default=60000) + parser.add_argument('-v', '--verbose',\ + help='Print lots of stuff',\ + action='store_true', default=False) + parser.add_argument('-w', '--window',\ + help='Create a display window',\ + action='store_true', default=False) + args = parser.parse_args() + log.startLogging(open(("/tmp/Fake_NHQ.log"), "w")) + if args.verbose: + print "Args:", args + Verbose = True + + if (args.window): + stdscr = curses.initscr() + screen = MyScreen(stdscr) + reactor.addReader(screen) + disp_iter = LoopingCall(display_iterator) + disp_iter.start(0.5) + + dev_iter = LoopingCall(device_iterator) + dev_iter.start(1.0) + factory = protocol.ServerFactory() + factory.protocol = NHQ_200 + reactor.listenTCP(args.port, factory) + reactor.run() + +if __name__ == "__main__": + main() diff --git a/site_ansto/instrument/config/environment/nhq_200.sct b/site_ansto/instrument/config/environment/nhq_200.sct new file mode 100644 index 00000000..b33d38eb --- /dev/null +++ b/site_ansto/instrument/config/environment/nhq_200.sct @@ -0,0 +1,65 @@ +# Simple driver generator for the Fast ComTech NHQ Power Supply +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent +# +driver nhq_200 = { + debug_threshold = 1; + vendor = FastComTech; device = NHQ; protocol = std; + class = environment; + simulation_group = environment_simulation; + + group = { + readable = 10; + var id = { type = text; read_command = '#'; } + var break = { type = int; read_command = 'W'; } + } + + group ch1 = { + readable = 5; + type = int; + var voltage = { type = int; read_command = 'U1'; read_function = rdVoltage; } + var current = { type = text; read_command = 'I1'; read_function = rdCurrent; } + var v_lim = { read_command = 'M1'; } + var i_lim = { read_command = 'N1'; } + var status = { type = text; read_command = 'S1'; } + var module = { read_command = 'T1'; } + writeable = 1; + var v_sp = { type = int; read_command = 'D1'; write_command = 'D1='; + driveable = ch1/voltage; lowerlimit = 0; upperlimit = 3000; tolerance = 5; + property settle_time = 10; } + var i_trip = { read_command = 'L1'; write_command = 'L1='; } + var v_ramp = { read_command = 'V1'; write_command = 'V1='; } + var auto_start = { read_command = 'A1'; write_command = 'A1='; } + readable = 0; + var go = { write_command = 'G1'; } + } + + group ch2 = { + readable = 5; + type = int; + var voltage = { type = int; read_command = 'U2'; read_function = rdVoltage; } + var current = { type = text; read_command = 'I2'; read_function = rdCurrent; } + var v_lim = { read_command = 'M2'; } + var i_lim = { read_command = 'N2'; } + var status = { type = text; read_command = 'S2'; } + var module = { read_command = 'T2'; } + writeable = 1; + var v_sp = { type = int; read_command = 'D2'; write_command = 'D2='; + driveable = ch2/voltage; lowerlimit = 0; upperlimit = 3000; tolerance = 5; + property settle_time = 10; } + var i_trip = { read_command = 'L2'; write_command = 'L2='; } + var v_ramp = { read_command = 'V2'; write_command = 'V2='; } + var auto_start = { read_command = 'A2'; write_command = 'A2='; } + readable = 0; + var go = { write_command = 'G2'; } + } + + code rdCurrent = {%% + + %%} + + code rdVoltage = {%% + # Strip the leading sign + set data [expr {abs(${data})}] + %%} + +} diff --git a/site_ansto/instrument/config/environment/sct_nhq_200.tcl b/site_ansto/instrument/config/environment/sct_nhq_200.tcl new file mode 100644 index 00000000..10cc5d54 --- /dev/null +++ b/site_ansto/instrument/config/environment/sct_nhq_200.tcl @@ -0,0 +1,750 @@ +# Generated driver for nhq_200 +# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent +# + +namespace eval ::scobj::nhq_200 { + set debug_threshold 1 +} + +proc ::scobj::nhq_200::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/nhq_200_[basename ${tc_root}].log" "a"] + set line "[clock format [clock seconds] -format "%T"] ${debug_string}" + puts ${fd} "${line}" + close ${fd} + } + } catch_message ] +} + +proc ::scobj::nhq_200::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::nhq_200::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::nhq_200::${debug_string}" + } + } catch_message ] +} + +# checklimits function for driveable interface +proc ::scobj::nhq_200::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::nhq_200::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::nhq_200::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::nhq_200::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::nhq_200::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::nhq_200::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::nhq_200::rdCurrent {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "rdCurrent 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]" + } +# rdCurrent hook code starts + +# rdCurrent 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::nhq_200::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 parse the read of a parameter on a device +proc ::scobj::nhq_200::rdVoltage {tc_root} { + set catch_status [ catch { + debug_log ${tc_root} 1 "rdVoltage 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]" + } +# rdVoltage hook code starts + # Strip the leading sign + set data [expr {abs(${data})}] +# rdVoltage 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::nhq_200::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::nhq_200::mkDriver { sct_controller name } { + ::scobj::nhq_200::sics_log 9 "::scobj::nhq_200::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} + + hfactory ${scobj_hpath}/break plain user int + hsetprop ${scobj_hpath}/break read ${ns}::getValue ${scobj_hpath} rdValue {W} + hsetprop ${scobj_hpath}/break rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/break control true + hsetprop ${scobj_hpath}/break data true + hsetprop ${scobj_hpath}/break mutable false + hsetprop ${scobj_hpath}/break nxsave true + hsetprop ${scobj_hpath}/break oldval 0 + hsetprop ${scobj_hpath}/break sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/break type "part" + hsetprop ${scobj_hpath}/break nxalias "${name}_break" + + hfactory ${scobj_hpath}/id plain user text + hsetprop ${scobj_hpath}/id read ${ns}::getValue ${scobj_hpath} rdValue {#} + hsetprop ${scobj_hpath}/id rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/id control true + hsetprop ${scobj_hpath}/id data true + hsetprop ${scobj_hpath}/id mutable false + hsetprop ${scobj_hpath}/id nxsave true + hsetprop ${scobj_hpath}/id oldval UNKNOWN + hsetprop ${scobj_hpath}/id sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/id type "part" + hsetprop ${scobj_hpath}/id nxalias "${name}_id" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/break 10 + ${sct_controller} poll ${scobj_hpath}/id 10 + } else { + ::scobj::nhq_200::sics_log 9 "[environment_simulation] => No poll/write for nhq_200" + } + + hfactory ${scobj_hpath}/ch1 plain spy none + + hfactory ${scobj_hpath}/ch1/auto_start plain user int + hsetprop ${scobj_hpath}/ch1/auto_start read ${ns}::getValue ${scobj_hpath} rdValue {A1} + hsetprop ${scobj_hpath}/ch1/auto_start rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/auto_start write ${ns}::setValue ${scobj_hpath} noResponse {A1=} + hsetprop ${scobj_hpath}/ch1/auto_start noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/auto_start check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/auto_start control true + hsetprop ${scobj_hpath}/ch1/auto_start data true + hsetprop ${scobj_hpath}/ch1/auto_start mutable false + hsetprop ${scobj_hpath}/ch1/auto_start nxsave true + hsetprop ${scobj_hpath}/ch1/auto_start oldval 0 + hsetprop ${scobj_hpath}/ch1/auto_start sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/auto_start type "part" + hsetprop ${scobj_hpath}/ch1/auto_start nxalias "${name}_ch1_auto_start" + + hfactory ${scobj_hpath}/ch1/current plain user text + hsetprop ${scobj_hpath}/ch1/current read ${ns}::getValue ${scobj_hpath} rdCurrent {I1} + hsetprop ${scobj_hpath}/ch1/current rdCurrent ${ns}::rdCurrent ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/current control true + hsetprop ${scobj_hpath}/ch1/current data true + hsetprop ${scobj_hpath}/ch1/current mutable false + hsetprop ${scobj_hpath}/ch1/current nxsave true + hsetprop ${scobj_hpath}/ch1/current oldval UNKNOWN + hsetprop ${scobj_hpath}/ch1/current sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/current type "part" + hsetprop ${scobj_hpath}/ch1/current nxalias "${name}_ch1_current" + + hfactory ${scobj_hpath}/ch1/go plain user int + hsetprop ${scobj_hpath}/ch1/go write ${ns}::setValue ${scobj_hpath} noResponse {G1} + hsetprop ${scobj_hpath}/ch1/go noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/go check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/go control true + hsetprop ${scobj_hpath}/ch1/go data true + hsetprop ${scobj_hpath}/ch1/go mutable false + hsetprop ${scobj_hpath}/ch1/go nxsave true + hsetprop ${scobj_hpath}/ch1/go oldval 0 + hsetprop ${scobj_hpath}/ch1/go sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/go type "part" + hsetprop ${scobj_hpath}/ch1/go nxalias "${name}_ch1_go" + + hfactory ${scobj_hpath}/ch1/i_lim plain user int + hsetprop ${scobj_hpath}/ch1/i_lim read ${ns}::getValue ${scobj_hpath} rdValue {N1} + hsetprop ${scobj_hpath}/ch1/i_lim rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/i_lim control true + hsetprop ${scobj_hpath}/ch1/i_lim data true + hsetprop ${scobj_hpath}/ch1/i_lim mutable false + hsetprop ${scobj_hpath}/ch1/i_lim nxsave true + hsetprop ${scobj_hpath}/ch1/i_lim oldval 0 + hsetprop ${scobj_hpath}/ch1/i_lim sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/i_lim type "part" + hsetprop ${scobj_hpath}/ch1/i_lim nxalias "${name}_ch1_i_lim" + + hfactory ${scobj_hpath}/ch1/i_trip plain user int + hsetprop ${scobj_hpath}/ch1/i_trip read ${ns}::getValue ${scobj_hpath} rdValue {L1} + hsetprop ${scobj_hpath}/ch1/i_trip rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/i_trip write ${ns}::setValue ${scobj_hpath} noResponse {L1=} + hsetprop ${scobj_hpath}/ch1/i_trip noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/i_trip check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/i_trip control true + hsetprop ${scobj_hpath}/ch1/i_trip data true + hsetprop ${scobj_hpath}/ch1/i_trip mutable false + hsetprop ${scobj_hpath}/ch1/i_trip nxsave true + hsetprop ${scobj_hpath}/ch1/i_trip oldval 0 + hsetprop ${scobj_hpath}/ch1/i_trip sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/i_trip type "part" + hsetprop ${scobj_hpath}/ch1/i_trip nxalias "${name}_ch1_i_trip" + + hfactory ${scobj_hpath}/ch1/module plain user int + hsetprop ${scobj_hpath}/ch1/module read ${ns}::getValue ${scobj_hpath} rdValue {T1} + hsetprop ${scobj_hpath}/ch1/module rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/module control true + hsetprop ${scobj_hpath}/ch1/module data true + hsetprop ${scobj_hpath}/ch1/module mutable false + hsetprop ${scobj_hpath}/ch1/module nxsave true + hsetprop ${scobj_hpath}/ch1/module oldval 0 + hsetprop ${scobj_hpath}/ch1/module sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/module type "part" + hsetprop ${scobj_hpath}/ch1/module nxalias "${name}_ch1_module" + + hfactory ${scobj_hpath}/ch1/status plain user text + hsetprop ${scobj_hpath}/ch1/status read ${ns}::getValue ${scobj_hpath} rdValue {S1} + hsetprop ${scobj_hpath}/ch1/status rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/status control true + hsetprop ${scobj_hpath}/ch1/status data true + hsetprop ${scobj_hpath}/ch1/status mutable false + hsetprop ${scobj_hpath}/ch1/status nxsave true + hsetprop ${scobj_hpath}/ch1/status oldval UNKNOWN + hsetprop ${scobj_hpath}/ch1/status sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/status type "part" + hsetprop ${scobj_hpath}/ch1/status nxalias "${name}_ch1_status" + + hfactory ${scobj_hpath}/ch1/v_lim plain user int + hsetprop ${scobj_hpath}/ch1/v_lim read ${ns}::getValue ${scobj_hpath} rdValue {M1} + hsetprop ${scobj_hpath}/ch1/v_lim rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_lim control true + hsetprop ${scobj_hpath}/ch1/v_lim data true + hsetprop ${scobj_hpath}/ch1/v_lim mutable false + hsetprop ${scobj_hpath}/ch1/v_lim nxsave true + hsetprop ${scobj_hpath}/ch1/v_lim oldval 0 + hsetprop ${scobj_hpath}/ch1/v_lim sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/v_lim type "part" + hsetprop ${scobj_hpath}/ch1/v_lim nxalias "${name}_ch1_v_lim" + + hfactory ${scobj_hpath}/ch1/v_ramp plain user int + hsetprop ${scobj_hpath}/ch1/v_ramp read ${ns}::getValue ${scobj_hpath} rdValue {V1} + hsetprop ${scobj_hpath}/ch1/v_ramp rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_ramp write ${ns}::setValue ${scobj_hpath} noResponse {V1=} + hsetprop ${scobj_hpath}/ch1/v_ramp noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_ramp check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_ramp control true + hsetprop ${scobj_hpath}/ch1/v_ramp data true + hsetprop ${scobj_hpath}/ch1/v_ramp mutable false + hsetprop ${scobj_hpath}/ch1/v_ramp nxsave true + hsetprop ${scobj_hpath}/ch1/v_ramp oldval 0 + hsetprop ${scobj_hpath}/ch1/v_ramp sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/v_ramp type "part" + hsetprop ${scobj_hpath}/ch1/v_ramp nxalias "${name}_ch1_v_ramp" + + hfactory ${scobj_hpath}/ch1/v_sp plain user int + hsetprop ${scobj_hpath}/ch1/v_sp read ${ns}::getValue ${scobj_hpath} rdValue {D1} + hsetprop ${scobj_hpath}/ch1/v_sp rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_sp write ${ns}::setValue ${scobj_hpath} noResponse {D1=} + hsetprop ${scobj_hpath}/ch1/v_sp noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_sp check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_sp driving 0 + hsetprop ${scobj_hpath}/ch1/v_sp checklimits ${ns}::checklimits ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_sp checkstatus ${ns}::checkstatus ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_sp halt ${ns}::halt ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/v_sp driveable ch1/voltage + hsetprop ${scobj_hpath}/ch1/v_sp control true + hsetprop ${scobj_hpath}/ch1/v_sp data true + hsetprop ${scobj_hpath}/ch1/v_sp mutable false + hsetprop ${scobj_hpath}/ch1/v_sp nxsave true + hsetprop ${scobj_hpath}/ch1/v_sp lowerlimit 0 + hsetprop ${scobj_hpath}/ch1/v_sp upperlimit 3000 + hsetprop ${scobj_hpath}/ch1/v_sp tolerance 5 + hsetprop ${scobj_hpath}/ch1/v_sp oldval 0 + hsetprop ${scobj_hpath}/ch1/v_sp sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/v_sp settle_time "10" + hsetprop ${scobj_hpath}/ch1/v_sp type "drivable" + hsetprop ${scobj_hpath}/ch1/v_sp nxalias "${name}_ch1_v_sp" + + hfactory ${scobj_hpath}/ch1/voltage plain user int + hsetprop ${scobj_hpath}/ch1/voltage read ${ns}::getValue ${scobj_hpath} rdVoltage {U1} + hsetprop ${scobj_hpath}/ch1/voltage rdVoltage ${ns}::rdVoltage ${scobj_hpath} + hsetprop ${scobj_hpath}/ch1/voltage control true + hsetprop ${scobj_hpath}/ch1/voltage data true + hsetprop ${scobj_hpath}/ch1/voltage mutable false + hsetprop ${scobj_hpath}/ch1/voltage nxsave true + hsetprop ${scobj_hpath}/ch1/voltage oldval 0 + hsetprop ${scobj_hpath}/ch1/voltage sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch1/voltage type "part" + hsetprop ${scobj_hpath}/ch1/voltage nxalias "${name}_ch1_voltage" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/ch1/auto_start 5 + ${sct_controller} poll ${scobj_hpath}/ch1/current 5 + ${sct_controller} poll ${scobj_hpath}/ch1/i_lim 5 + ${sct_controller} poll ${scobj_hpath}/ch1/i_trip 5 + ${sct_controller} poll ${scobj_hpath}/ch1/module 5 + ${sct_controller} poll ${scobj_hpath}/ch1/status 5 + ${sct_controller} poll ${scobj_hpath}/ch1/v_lim 5 + ${sct_controller} poll ${scobj_hpath}/ch1/v_ramp 5 + ${sct_controller} poll ${scobj_hpath}/ch1/v_sp 5 + ${sct_controller} poll ${scobj_hpath}/ch1/voltage 5 + ${sct_controller} write ${scobj_hpath}/ch1/auto_start + ${sct_controller} write ${scobj_hpath}/ch1/go + ${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" + } + + hfactory ${scobj_hpath}/ch2 plain spy none + + hfactory ${scobj_hpath}/ch2/auto_start plain user int + hsetprop ${scobj_hpath}/ch2/auto_start read ${ns}::getValue ${scobj_hpath} rdValue {A2} + hsetprop ${scobj_hpath}/ch2/auto_start rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/auto_start write ${ns}::setValue ${scobj_hpath} noResponse {A2=} + hsetprop ${scobj_hpath}/ch2/auto_start noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/auto_start check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/auto_start control true + hsetprop ${scobj_hpath}/ch2/auto_start data true + hsetprop ${scobj_hpath}/ch2/auto_start mutable false + hsetprop ${scobj_hpath}/ch2/auto_start nxsave true + hsetprop ${scobj_hpath}/ch2/auto_start oldval 0 + hsetprop ${scobj_hpath}/ch2/auto_start sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/auto_start type "part" + hsetprop ${scobj_hpath}/ch2/auto_start nxalias "${name}_ch2_auto_start" + + hfactory ${scobj_hpath}/ch2/current plain user text + hsetprop ${scobj_hpath}/ch2/current read ${ns}::getValue ${scobj_hpath} rdCurrent {I2} + hsetprop ${scobj_hpath}/ch2/current rdCurrent ${ns}::rdCurrent ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/current control true + hsetprop ${scobj_hpath}/ch2/current data true + hsetprop ${scobj_hpath}/ch2/current mutable false + hsetprop ${scobj_hpath}/ch2/current nxsave true + hsetprop ${scobj_hpath}/ch2/current oldval UNKNOWN + hsetprop ${scobj_hpath}/ch2/current sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/current type "part" + hsetprop ${scobj_hpath}/ch2/current nxalias "${name}_ch2_current" + + hfactory ${scobj_hpath}/ch2/go plain user int + hsetprop ${scobj_hpath}/ch2/go write ${ns}::setValue ${scobj_hpath} noResponse {G2} + hsetprop ${scobj_hpath}/ch2/go noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/go check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/go control true + hsetprop ${scobj_hpath}/ch2/go data true + hsetprop ${scobj_hpath}/ch2/go mutable false + hsetprop ${scobj_hpath}/ch2/go nxsave true + hsetprop ${scobj_hpath}/ch2/go oldval 0 + hsetprop ${scobj_hpath}/ch2/go sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/go type "part" + hsetprop ${scobj_hpath}/ch2/go nxalias "${name}_ch2_go" + + hfactory ${scobj_hpath}/ch2/i_lim plain user int + hsetprop ${scobj_hpath}/ch2/i_lim read ${ns}::getValue ${scobj_hpath} rdValue {N2} + hsetprop ${scobj_hpath}/ch2/i_lim rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/i_lim control true + hsetprop ${scobj_hpath}/ch2/i_lim data true + hsetprop ${scobj_hpath}/ch2/i_lim mutable false + hsetprop ${scobj_hpath}/ch2/i_lim nxsave true + hsetprop ${scobj_hpath}/ch2/i_lim oldval 0 + hsetprop ${scobj_hpath}/ch2/i_lim sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/i_lim type "part" + hsetprop ${scobj_hpath}/ch2/i_lim nxalias "${name}_ch2_i_lim" + + hfactory ${scobj_hpath}/ch2/i_trip plain user int + hsetprop ${scobj_hpath}/ch2/i_trip read ${ns}::getValue ${scobj_hpath} rdValue {L2} + hsetprop ${scobj_hpath}/ch2/i_trip rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/i_trip write ${ns}::setValue ${scobj_hpath} noResponse {L2=} + hsetprop ${scobj_hpath}/ch2/i_trip noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/i_trip check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/i_trip control true + hsetprop ${scobj_hpath}/ch2/i_trip data true + hsetprop ${scobj_hpath}/ch2/i_trip mutable false + hsetprop ${scobj_hpath}/ch2/i_trip nxsave true + hsetprop ${scobj_hpath}/ch2/i_trip oldval 0 + hsetprop ${scobj_hpath}/ch2/i_trip sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/i_trip type "part" + hsetprop ${scobj_hpath}/ch2/i_trip nxalias "${name}_ch2_i_trip" + + hfactory ${scobj_hpath}/ch2/module plain user int + hsetprop ${scobj_hpath}/ch2/module read ${ns}::getValue ${scobj_hpath} rdValue {T2} + hsetprop ${scobj_hpath}/ch2/module rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/module control true + hsetprop ${scobj_hpath}/ch2/module data true + hsetprop ${scobj_hpath}/ch2/module mutable false + hsetprop ${scobj_hpath}/ch2/module nxsave true + hsetprop ${scobj_hpath}/ch2/module oldval 0 + hsetprop ${scobj_hpath}/ch2/module sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/module type "part" + hsetprop ${scobj_hpath}/ch2/module nxalias "${name}_ch2_module" + + hfactory ${scobj_hpath}/ch2/status plain user text + hsetprop ${scobj_hpath}/ch2/status read ${ns}::getValue ${scobj_hpath} rdValue {S2} + hsetprop ${scobj_hpath}/ch2/status rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/status control true + hsetprop ${scobj_hpath}/ch2/status data true + hsetprop ${scobj_hpath}/ch2/status mutable false + hsetprop ${scobj_hpath}/ch2/status nxsave true + hsetprop ${scobj_hpath}/ch2/status oldval UNKNOWN + hsetprop ${scobj_hpath}/ch2/status sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/status type "part" + hsetprop ${scobj_hpath}/ch2/status nxalias "${name}_ch2_status" + + hfactory ${scobj_hpath}/ch2/v_lim plain user int + hsetprop ${scobj_hpath}/ch2/v_lim read ${ns}::getValue ${scobj_hpath} rdValue {M2} + hsetprop ${scobj_hpath}/ch2/v_lim rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_lim control true + hsetprop ${scobj_hpath}/ch2/v_lim data true + hsetprop ${scobj_hpath}/ch2/v_lim mutable false + hsetprop ${scobj_hpath}/ch2/v_lim nxsave true + hsetprop ${scobj_hpath}/ch2/v_lim oldval 0 + hsetprop ${scobj_hpath}/ch2/v_lim sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/v_lim type "part" + hsetprop ${scobj_hpath}/ch2/v_lim nxalias "${name}_ch2_v_lim" + + hfactory ${scobj_hpath}/ch2/v_ramp plain user int + hsetprop ${scobj_hpath}/ch2/v_ramp read ${ns}::getValue ${scobj_hpath} rdValue {V2} + hsetprop ${scobj_hpath}/ch2/v_ramp rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_ramp write ${ns}::setValue ${scobj_hpath} noResponse {V2=} + hsetprop ${scobj_hpath}/ch2/v_ramp noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_ramp check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_ramp control true + hsetprop ${scobj_hpath}/ch2/v_ramp data true + hsetprop ${scobj_hpath}/ch2/v_ramp mutable false + hsetprop ${scobj_hpath}/ch2/v_ramp nxsave true + hsetprop ${scobj_hpath}/ch2/v_ramp oldval 0 + hsetprop ${scobj_hpath}/ch2/v_ramp sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/v_ramp type "part" + hsetprop ${scobj_hpath}/ch2/v_ramp nxalias "${name}_ch2_v_ramp" + + hfactory ${scobj_hpath}/ch2/v_sp plain user int + hsetprop ${scobj_hpath}/ch2/v_sp read ${ns}::getValue ${scobj_hpath} rdValue {D2} + hsetprop ${scobj_hpath}/ch2/v_sp rdValue ${ns}::rdValue ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_sp write ${ns}::setValue ${scobj_hpath} noResponse {D2=} + hsetprop ${scobj_hpath}/ch2/v_sp noResponse ${ns}::noResponse ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_sp check ${ns}::checkrange ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_sp driving 0 + hsetprop ${scobj_hpath}/ch2/v_sp checklimits ${ns}::checklimits ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_sp checkstatus ${ns}::checkstatus ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_sp halt ${ns}::halt ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/v_sp driveable ch2/voltage + hsetprop ${scobj_hpath}/ch2/v_sp control true + hsetprop ${scobj_hpath}/ch2/v_sp data true + hsetprop ${scobj_hpath}/ch2/v_sp mutable false + hsetprop ${scobj_hpath}/ch2/v_sp nxsave true + hsetprop ${scobj_hpath}/ch2/v_sp lowerlimit 0 + hsetprop ${scobj_hpath}/ch2/v_sp upperlimit 3000 + hsetprop ${scobj_hpath}/ch2/v_sp tolerance 5 + hsetprop ${scobj_hpath}/ch2/v_sp oldval 0 + hsetprop ${scobj_hpath}/ch2/v_sp sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/v_sp settle_time "10" + hsetprop ${scobj_hpath}/ch2/v_sp type "drivable" + hsetprop ${scobj_hpath}/ch2/v_sp nxalias "${name}_ch2_v_sp" + + hfactory ${scobj_hpath}/ch2/voltage plain user int + hsetprop ${scobj_hpath}/ch2/voltage read ${ns}::getValue ${scobj_hpath} rdVoltage {U2} + hsetprop ${scobj_hpath}/ch2/voltage rdVoltage ${ns}::rdVoltage ${scobj_hpath} + hsetprop ${scobj_hpath}/ch2/voltage control true + hsetprop ${scobj_hpath}/ch2/voltage data true + hsetprop ${scobj_hpath}/ch2/voltage mutable false + hsetprop ${scobj_hpath}/ch2/voltage nxsave true + hsetprop ${scobj_hpath}/ch2/voltage oldval 0 + hsetprop ${scobj_hpath}/ch2/voltage sdsinfo "::nexus::scobj::sdsinfo" + hsetprop ${scobj_hpath}/ch2/voltage type "part" + hsetprop ${scobj_hpath}/ch2/voltage nxalias "${name}_ch2_voltage" + + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + ${sct_controller} poll ${scobj_hpath}/ch2/auto_start 5 + ${sct_controller} poll ${scobj_hpath}/ch2/current 5 + ${sct_controller} poll ${scobj_hpath}/ch2/i_lim 5 + ${sct_controller} poll ${scobj_hpath}/ch2/i_trip 5 + ${sct_controller} poll ${scobj_hpath}/ch2/module 5 + ${sct_controller} poll ${scobj_hpath}/ch2/status 5 + ${sct_controller} poll ${scobj_hpath}/ch2/v_lim 5 + ${sct_controller} poll ${scobj_hpath}/ch2/v_ramp 5 + ${sct_controller} poll ${scobj_hpath}/ch2/v_sp 5 + ${sct_controller} poll ${scobj_hpath}/ch2/voltage 5 + ${sct_controller} write ${scobj_hpath}/ch2/auto_start + ${sct_controller} write ${scobj_hpath}/ch2/go + ${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 +# mkDriver hook code goes here + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +namespace eval ::scobj::nhq_200 { + namespace export debug_threshold + namespace export debug_log + namespace export sics_log + namespace export mkDriver +} + +proc add_nhq_200 {name IP port} { + set catch_status [ catch { + ::scobj::nhq_200::sics_log 9 "add_nhq_200 ${name} ${IP} ${port}" + if {[string equal -nocase [SplitReply [environment_simulation]] "false"]} { + if {[string equal -nocase "aqadapter" "${IP}"]} { + ::scobj::nhq_200::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}" + makesctcontroller sct_${name} aqadapter ${port} + } else { + ::scobj::nhq_200::sics_log 9 "makesctcontroller sct_${name} std ${IP}:${port}" + makesctcontroller sct_${name} std ${IP}:${port} + } + } else { + ::scobj::nhq_200::sics_log 9 "[environment_simulation] => No sctcontroller for nhq_200" + } + ::scobj::nhq_200::sics_log 1 "::scobj::nhq_200::mkDriver sct_${name} ${name}" + ::scobj::nhq_200::mkDriver sct_${name} ${name} + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +puts stdout "file evaluation of sct_nhq_200.tcl" +::scobj::nhq_200::sics_log 9 "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 "driver"] } { + if { [dict get $v "driver"] == "nhq_200" } { + if { [dict get $v enabled] } { + set name [dict get $v name] + 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_nhq_200 ${name} "aqadapter" ${asyncqueue} + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::nhq_200::read_config +} else { + ::scobj::nhq_200::sics_log 5 "No config dict" +}