From a439601d7d131eda6edaad1d76f2af38bfb6c616 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 2 Jul 2014 14:39:36 +1000 Subject: [PATCH 01/72] Source mercury scpi driver for Wombat --- site_ansto/instrument/hipd/wombat_configuration.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/site_ansto/instrument/hipd/wombat_configuration.tcl b/site_ansto/instrument/hipd/wombat_configuration.tcl index cd29c804..2b814471 100644 --- a/site_ansto/instrument/hipd/wombat_configuration.tcl +++ b/site_ansto/instrument/hipd/wombat_configuration.tcl @@ -35,6 +35,7 @@ fileeval $cfPath(environment)/temperature/sct_lakeshore_370.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_mercury_scpi.tcl fileeval $cfPath(environment)/temperature/sct_oxford_mercury.tcl fileeval $cfPath(environment)/magneticField/sct_oxford_labview.tcl fileeval $cfPath(environment)/he3/sct_he3.tcl From 7a4ce1f234b083ee0a7cc11ad188e6392f502578 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 2 Jul 2014 14:40:22 +1000 Subject: [PATCH 02/72] Write option id into driver implementation section when saving the sics_config.ini --- .../instrument/hipd/util/sics_config.ini | 47 +++++++++++++++---- site_ansto/instrument/util/config_edit.py | 26 +++++++++- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 93dd91d3..05918e29 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -1,6 +1,7 @@ [12tmagnet_oxford] desc = "12 Tesla Oxford Magnet" driver = "oxford_labview" +id = 1 imptype = magnetic_field ip = 10.157.205.3 port = 55001 @@ -10,11 +11,12 @@ desc = "som will be redefined as the magnet sample insert rotation. Sample stage imptype = motion_axis [12tmagnet_setup] -cascade = B1:12tmagnet_oxford,sample_stage:12tmagnet_sample_insert,T1:mercury_scpi +cascade = B1:12tmagnet_oxford,sample_stage:12tmagnet_sample_insert,T1:mercury_scpi_01 enabled = False [B1] enabled = False +id = 1 implementation = 12tmagnet_oxford name = magnet1 optype = magnetic_field @@ -40,6 +42,7 @@ enabled = True [I1] datype = I enabled = False +id = 1 implementation = protek_01 name = curr1 optype = multimeter @@ -47,39 +50,45 @@ optype = multimeter [I2] datype = I enabled = False +id = 2 implementation = protek_02 name = curr2 optype = multimeter [T1] enabled = False -implementation = mercury_scpi +id = 1 +implementation = mercury_scpi_01 name = tc1 optype = temperature [T2] enabled = False -implementation = ls336_02 +id = 2 +implementation = ls340_01 name = tc2 optype = temperature [T3] enabled = False -implementation = ls336_04 +id = 3 +implementation = ls340_02 name = tc3 optype = temperature [V1] datype = V enabled = False -implementation = protek_01 +id = 1 +implementation = none name = volts1 optype = multimeter [V2] datype = V enabled = False -implementation = protek_02 +id = 2 +implementation = none name = volts2 optype = multimeter @@ -150,6 +159,7 @@ tol2 = 1.0 [ls340_01] desc = "tc7: Lakeshore 340 temperature controller" driver = "lakeshore_340" +id = 2 imptype = temperature ip = 137.157.201.86 port = 4001 @@ -160,6 +170,7 @@ tol2 = 1.0 [ls340_02] desc = "tc8: Lakeshore 340 temperature controller" driver = "lakeshore_340" +id = 3 imptype = temperature ip = 137.157.201.86 port = 4002 @@ -167,14 +178,28 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 -[mercury_scpi] -desc = "tc9: Oxford Mercury temperature controller in Mercury mode" +[mercury_scpi_01] +desc = "Oxford Mercury temperature controller in Mercury mode" driver = "mercury_scpi" +id = 1 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" @@ -183,6 +208,7 @@ imptype = motion_axis [protek_01] desc = "Protek Multimeter" driver = "protek" +id = 1 imptype = multimeter ip = 10.157.205.36 port = 4001 @@ -190,6 +216,7 @@ port = 4001 [protek_02] desc = "Protek Multimeter" driver = "protek" +id = 2 imptype = multimeter ip = 10.157.205.37 port = 4001 diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index e34f0eae..54b53ea6 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -43,6 +43,10 @@ class InstConfigData: # {optype: [impname] } imp_dict = defaultdict(list) + # imp2opt_dict: Maps each implementation to an option or None, + # {imp: opt/None} + imp2opt_dict = {} + def __init__(self): return @@ -77,16 +81,28 @@ class InstConfigData: stateval = False permanent = False + if self.file_parser.has_option(s, 'id'): + id = self.file_parser.get(s, 'id') + self.opt_dict[s]['id'] = id + 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 selected_imp in self.imp2opt_dict: + self.opt_dict[s]['selected_imp'] = "none" + else: + self.opt_dict[s]['selected_imp'] = selected_imp + print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp,s) + self.imp2opt_dict[selected_imp] = s 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) + if s not in self.imp2opt_dict: + print 'Add imp2opt_dict[{0}] = none'.format(s) + self.imp2opt_dict[s] = "none" def read_config_file(self, config_filename): self.config_filename = config_filename @@ -111,17 +127,25 @@ class InstConfigData: 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) + + for imp,opt in self.imp2opt_dict.iteritems(): + if imp != 'none' and 'id' in self.opt_dict[opt]: + self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) + 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))) + cfile.write("\n") #self.file_parser.write(cfile) From 294b6fa77605629d08fe98ea28d53136ca4790fa Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 3 Jul 2014 18:29:39 +1000 Subject: [PATCH 03/72] Make config_edit.py easier to browse by grouping order of class declarations. --- site_ansto/instrument/util/config_edit.py | 243 +++++++++++----------- 1 file changed, 122 insertions(+), 121 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 54b53ea6..c435d786 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -29,6 +29,128 @@ import copy from collections import defaultdict +## TODO Configuration Editor +## Configuration Viewer +Palette = [ + ('body', 'dark cyan', '', 'standout'), + ('focus', 'dark red', '', 'standout'), + ('head', 'light red', 'black'), +] + + +#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) + + super(RadioButtonListWalker, self).__init__(mapped_rb_list) + return + + +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) + + super(CheckBoxListWalker, self).__init__(mapped_cb_list) + return + + +# 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 + +# 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): + if key == 'meta q': + raise urwid.ExitMainLoop() + elif key == 'w': + self.cf_dat.backup_files() + self.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) + else: + self.set_focus(self.cf_man.config_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) + else: + self.set_focus(self.cf_man.opt_lb) + return + + class InstConfigData: msg_index = 4 # configuration_dict: dict of instrument configurations as defined below, @@ -166,81 +288,6 @@ class InstConfigData: 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'), -] - - -#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) - - super(RadioButtonListWalker, self).__init__(mapped_rb_list) - return - - -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) - - super(CheckBoxListWalker, self).__init__(mapped_cb_list) - return - - -# 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 - # Contains OptionListWalker dict indexed by option # Contains ImpListBox # Connects OptionListWalker 'focus_change' signal to update_imp_lb handler @@ -333,52 +380,6 @@ class InstConfigManager: 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): - if key == 'meta q': - raise urwid.ExitMainLoop() - elif key == 'w': - self.cf_dat.backup_files() - self.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) - else: - self.set_focus(self.cf_man.config_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) - else: - self.set_focus(self.cf_man.opt_lb) - return - import pdb class DEBUG: msgTextDict = {} From abcf19553b2d8ff480171fa2ccb3b35ea070e995 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 3 Jul 2014 23:36:43 +1000 Subject: [PATCH 04/72] Copy original file in backup_files method instead of renaming it in case write_config_file fails. Add a 'none' entry to the implementation list. --- site_ansto/instrument/util/config_edit.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index c435d786..6ea41714 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -22,6 +22,7 @@ import os +import shutil import argparse import ConfigParser import urwid @@ -221,11 +222,15 @@ class InstConfigData: for s in self.file_parser.sections(): if self.file_parser.has_option(s, 'imptype'): key = self.file_parser.get(s, 'imptype') + if 'none' not in self.imp_dict[key]: + self.imp_dict[key].append('none') + self.imp_dict[key].append(s) if s not in self.imp2opt_dict: print 'Add imp2opt_dict[{0}] = none'.format(s) self.imp2opt_dict[s] = "none" + def read_config_file(self, config_filename): self.config_filename = config_filename self.file_parser = ConfigParser.SafeConfigParser() @@ -241,11 +246,11 @@ class InstConfigData: os.rename(self.config_filename + "." + str(idx), self.config_filename + "." + str(idx + 1)) if os.path.exists(self.config_filename): - os.rename(self.config_filename, self.config_filename + ".1") + shutil.copy(self.config_filename, self.config_filename + ".1") def write_config_file(self): for item,dict in self.opt_dict.iteritems(): - if self.file_parser.get(item, 'enabled').lower() == 'always': + if 'permanent' in dict and dict['permanent'] == True: enabled = 'Always' else: enabled = dict['enabled'].__str__() @@ -259,7 +264,7 @@ class InstConfigData: self.file_parser.set(item, 'enabled', enabled) for imp,opt in self.imp2opt_dict.iteritems(): - if imp != 'none' and 'id' in self.opt_dict[opt]: + if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) with open(self.config_filename,'w') as cfile: @@ -338,7 +343,7 @@ class InstConfigManager: 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) From a802f98a2430794c64afc8c101f40253b84ac950 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 4 Jul 2014 13:46:47 +1000 Subject: [PATCH 05/72] Remove unavailable implementations from the impelementation list when an option is selected. --- site_ansto/instrument/util/config_edit.py | 83 +++++++++++++---------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 6ea41714..dae06dd9 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -3,18 +3,18 @@ # View Screen has 3 parts # (Instrument Configuration), (Configuration Options), (Option Implementation) -# Uses MVC implemented as InstConfigData, InstConfigView, ConfigEdit +# Uses MVC implemented 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 # ^ -# InstConfigView <>--- ConfigEdit, PresentationData +# InstConfigView <>--- InstConfigManager, PresentationData # |--set_cfedit(), set_presdata() # # PresentationData @@ -30,8 +30,6 @@ import copy from collections import defaultdict -## TODO Configuration Editor -## Configuration Viewer Palette = [ ('body', 'dark cyan', '', 'standout'), ('focus', 'dark red', '', 'standout'), @@ -69,7 +67,6 @@ class CheckBoxListWalker(urwid.SimpleListWalker): return -# Selects listwalker to display for ImpListBox on focus class OptionListWalker(CheckBoxListWalker): def __init__(self, opt_dict, statechange_cb): urwid.register_signal(OptionListWalker, ['focus_change']) @@ -212,11 +209,12 @@ class InstConfigData: self.opt_dict[s]['permanent'] = permanent self.opt_dict[s]['imptype'] = imptype if selected_imp in self.imp2opt_dict: - self.opt_dict[s]['selected_imp'] = "none" + self.opt_dict[s]['selected_imp'] = 'none' else: self.opt_dict[s]['selected_imp'] = selected_imp - print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp,s) - self.imp2opt_dict[selected_imp] = s + if selected_imp != 'none': + print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp,s) + self.imp2opt_dict[selected_imp] = s def __get_implementations(self): for s in self.file_parser.sections(): @@ -228,7 +226,7 @@ class InstConfigData: self.imp_dict[key].append(s) if s not in self.imp2opt_dict: print 'Add imp2opt_dict[{0}] = none'.format(s) - self.imp2opt_dict[s] = "none" + self.imp2opt_dict[s] = 'none' def read_config_file(self, config_filename): @@ -274,7 +272,6 @@ class InstConfigData: cfile.write("%s = %s\n" % (option, self.file_parser.get(section, option))) cfile.write("\n") - #self.file_parser.write(cfile) def cf_statechange(self, checkbox, new_state, udat=None): cfg_id = checkbox.get_label() @@ -302,30 +299,18 @@ class InstConfigManager: cf_msg_index = 8 options = [] imp_lw_dict = {} - def __init__(self, cfdat): - self.cfdat = cfdat + def __init__(self, cf_dat): + self.cf_dat = cf_dat urwid.register_signal(InstConfigManager, ['focus_change']) - for opt,dict in cfdat.opt_dict.iteritems(): + for opt,dict in cf_dat.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.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.option_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange) self.imp_lb = ImpListBox(self.imp_lw) urwid.connect_signal(self.option_lw, 'focus_change', self.update_imp_lb) - item_states = [(i,d['enabled']) for i,d in cf_dat.configuration_dict.iteritems()] item_states.sort() self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange) @@ -334,10 +319,24 @@ class InstConfigManager: self.opt_lb.set_focus(0) return + def __imp_unavailable(self, imp): + if imp == 'none': + return False + + ckopt = self.cf_dat.imp2opt_dict[imp] + if ckopt == 'none': + return False + elif self.cf_dat.opt_dict[ckopt]['enabled']: + return True + else: + return False + def __gen_imp_listwalker(self, opt): imp_items = [] - dict = self.cfdat.opt_dict[opt] - for imp in self.cfdat.imp_dict[dict['imptype']]: + dict = self.cf_dat.opt_dict[opt] + for imp in self.cf_dat.imp_dict[dict['imptype']]: + if self.__imp_unavailable(imp): + continue if imp == dict['selected_imp']: imp_items.append((imp, True)) else: @@ -349,12 +348,12 @@ class InstConfigManager: def cf_statechange(self, button, new_state, udat=None): - self.cfdat.cf_statechange(button, new_state, udat) + self.cf_dat.cf_statechange(button, new_state, udat) b = button.get_label() - cascade = self.cfdat.configuration_dict[b]['cascade_list'] + cascade = self.cf_dat.configuration_dict[b]['cascade_list'] if new_state == True: - for opt in self.cfdat.opt_dict.keys(): - if self.cfdat.opt_dict[opt]['permanent'] == False: + for opt in self.cf_dat.opt_dict.keys(): + if self.cf_dat.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) @@ -368,11 +367,23 @@ class InstConfigManager: return def opt_statechange(self, button, new_state, udat=None): - self.cfdat.opt_statechange(button, new_state, udat) + opt = button.get_label() + imp = self.cf_dat.opt_dict[opt]['selected_imp'] + if new_state == True: + if self.__imp_unavailable(imp): + self.cf_dat.opt_dict[opt]['selected_imp'] = 'none' + else: + self.cf_dat.imp2opt_dict[imp] = opt + + self.cf_dat.opt_statechange(button, new_state, udat) return - def imp_statechange(self, button, new_state, udat=None): - self.cfdat.imp_statechange(button, new_state, udat) + def imp_statechange(self, button, new_state, opt): + if new_state == True: + imp = button.get_label() + self.cf_dat.imp2opt_dict[imp] = opt + + self.cf_dat.imp_statechange(button, new_state, opt) return def update_imp_lb(self, pos): From 6625060fa07026d39600612b89341ee4045c7cf5 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 4 Jul 2014 17:19:36 +1000 Subject: [PATCH 06/72] Set opt:imp as the label on option checkboxes. Do this when selecting an implementation and when enabling an option. TODO: When an option is disabled insert its implementation into the implementation list. --- site_ansto/instrument/util/config_edit.py | 30 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index dae06dd9..2ee99b47 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -102,6 +102,7 @@ class OptionListBox(ClosedListBox): super(OptionListBox, self).__init__(listwalker) return + # List of RadioButtons class ImpListBox(ClosedListBox): def __init__(self, listwalker): @@ -278,7 +279,11 @@ class InstConfigData: self.configuration_dict[cfg_id]['enabled'] = new_state def opt_statechange(self, checkbox, new_state, udat=None): - opt = checkbox.get_label() + if SET_LABEL: + opt = checkbox.get_label().split(':')[0] + else: + opt = checkbox.get_label() + dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) self.opt_dict[opt]['enabled'] = new_state @@ -309,6 +314,10 @@ class InstConfigManager: firstopt = self.options[0][0] self.imp_lw = self.__gen_imp_listwalker(firstopt) self.option_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange) + if (SET_LABEL): + for label, button in self.option_lw.button_dict.iteritems(): + button.set_label('{0}:{1}'.format(label, self.cf_dat.opt_dict[label]['selected_imp'])) + self.imp_lb = ImpListBox(self.imp_lw) urwid.connect_signal(self.option_lw, 'focus_change', self.update_imp_lb) item_states = [(i,d['enabled']) for i,d in cf_dat.configuration_dict.iteritems()] @@ -346,7 +355,6 @@ class InstConfigManager: return RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) - def cf_statechange(self, button, new_state, udat=None): self.cf_dat.cf_statechange(button, new_state, udat) b = button.get_label() @@ -367,11 +375,21 @@ class InstConfigManager: return def opt_statechange(self, button, new_state, udat=None): - opt = button.get_label() + if (SET_LABEL): + opt = button.get_label().split(':')[0] + else: + opt = button.get_label() + imp = self.cf_dat.opt_dict[opt]['selected_imp'] if new_state == True: if self.__imp_unavailable(imp): self.cf_dat.opt_dict[opt]['selected_imp'] = 'none' + imp_button = self.imp_lw.button_dict['none'] + imp_button.set_state(True) + if SET_LABEL: + opt_button = self.option_lw.button_dict[opt] + opt_button.set_label('{0}:none'.format(opt)) +# FORCE DEDENT a blank line isn't enough in vim else: self.cf_dat.imp2opt_dict[imp] = opt @@ -382,6 +400,9 @@ class InstConfigManager: if new_state == True: imp = button.get_label() self.cf_dat.imp2opt_dict[imp] = opt + if SET_LABEL: + opt_button = self.option_lw.button_dict[opt] + opt_button.set_label('{0}:{1}'.format(opt, imp)) self.cf_dat.imp_statechange(button, new_state, opt) return @@ -422,7 +443,8 @@ class DEBUG: dbg = DEBUG(enabled=True) def main(config_ini): - global cf_dat, cf_man, cf_viewer + global cf_dat, cf_man, cf_viewer, SET_LABEL + SET_LABEL = True # Make configuration data cf_dat = InstConfigData() cf_dat.read_config_file(config_ini) From fb93daeb466ed6c493cf581d68254514abee62cf Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sat, 5 Jul 2014 19:37:23 +1000 Subject: [PATCH 07/72] Provide set_imp(opt,imp) method to keep opt and imp mappings in sync. Added convenience method iter_implementations(opt) to enable looping over an option's implementation list. Setting option labels now works properly when switching configurations. --- site_ansto/instrument/util/config_edit.py | 184 ++++++++++++---------- 1 file changed, 100 insertions(+), 84 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 2ee99b47..a6b9cea6 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -29,7 +29,6 @@ import urwid import copy from collections import defaultdict - Palette = [ ('body', 'dark cyan', '', 'standout'), ('focus', 'dark red', '', 'standout'), @@ -37,12 +36,11 @@ Palette = [ ] -#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 = [] + 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 @@ -54,9 +52,9 @@ class RadioButtonListWalker(urwid.SimpleListWalker): class CheckBoxListWalker(urwid.SimpleListWalker): - button_dict = {} def __init__(self, item_states, on_state_change = None, user_data = None): 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 @@ -114,62 +112,28 @@ class ImpListBox(ClosedListBox): 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): - if key == 'meta q': - raise urwid.ExitMainLoop() - elif key == 'w': - self.cf_dat.backup_files() - self.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) - else: - self.set_focus(self.cf_man.config_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) - else: - self.set_focus(self.cf_man.opt_lb) - return - - 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) - # imp_dict: dict of implementations indexed by optype, # {optype: [impname] } imp_dict = defaultdict(list) + # opt_dict: dict of configuration options as defined below, + # {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}} + opt_dict = defaultdict(dict) + # imp2opt_dict: Maps each implementation to an option or None, # {imp: opt/None} imp2opt_dict = {} - def __init__(self): - return + # optypelist: list of (opt, optype) tuples + # [(opt, optype)] + optypelist = [] + def __get_configurations(self): for s in self.file_parser.sections(): @@ -187,6 +151,14 @@ class InstConfigData: self.configuration_dict[s]['cascade_list'] = cascade_list def __get_options(self): + # opt_dict: dict of configuration options as defined below, + # {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}} + opt_dict = defaultdict(dict) + + # imp2opt_dict: Maps each implementation to an option or None, + # {imp: opt/None} + imp2opt_dict = {} + for s in self.file_parser.sections(): if self.file_parser.has_option(s, 'implementation'): selected_imp = self.file_parser.get(s, 'implementation') @@ -229,6 +201,19 @@ class InstConfigData: print 'Add imp2opt_dict[{0}] = none'.format(s) self.imp2opt_dict[s] = 'none' + def set_imp(self, opt, new_imp): + old_imp =self.opt_dict[opt]['selected_imp'] + self.imp2opt_dict[old_imp] = 'none' + self.opt_dict[opt]['selected_imp'] = new_imp + self.imp2opt_dict[new_imp] = opt + + def get_optypelist (self): + return self.optypelist + + def iter_implementations(self, opt): + dict = self.opt_dict[opt] + for imp in self.imp_dict[dict['imptype']]: + yield imp def read_config_file(self, config_filename): self.config_filename = config_filename @@ -237,6 +222,9 @@ class InstConfigData: self.__get_options() self.__get_implementations() self.__get_configurations() + for opt,dict in self.opt_dict.iteritems(): + self.optypelist.append((opt, dict['imptype'])) + return def backup_files(self): @@ -279,11 +267,7 @@ class InstConfigData: self.configuration_dict[cfg_id]['enabled'] = new_state def opt_statechange(self, checkbox, new_state, udat=None): - if SET_LABEL: - opt = checkbox.get_label().split(':')[0] - else: - opt = checkbox.get_label() - + opt = checkbox.get_label().split(':')[0] dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) self.opt_dict[opt]['enabled'] = new_state @@ -295,6 +279,42 @@ class InstConfigData: self.opt_dict[opt]['selected_imp'] = selected_imp +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): + if key == 'meta q': + raise urwid.ExitMainLoop() + elif key == 'w': + self.cf_dat.backup_files() + self.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) + else: + self.set_focus(self.cf_man.config_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) + else: + self.set_focus(self.cf_man.opt_lb) + return + + # Contains OptionListWalker dict indexed by option # Contains ImpListBox # Connects OptionListWalker 'focus_change' signal to update_imp_lb handler @@ -302,29 +322,26 @@ class InstConfigData: # and sets selection on ImpListBox class InstConfigManager: cf_msg_index = 8 - options = [] imp_lw_dict = {} def __init__(self, cf_dat): self.cf_dat = cf_dat urwid.register_signal(InstConfigManager, ['focus_change']) - for opt,dict in cf_dat.opt_dict.iteritems(): - self.options.append((opt, dict['imptype'])) + self.options = self.cf_dat.get_optypelist() self.options.sort() firstopt = self.options[0][0] self.imp_lw = self.__gen_imp_listwalker(firstopt) - self.option_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange) - if (SET_LABEL): - for label, button in self.option_lw.button_dict.iteritems(): - button.set_label('{0}:{1}'.format(label, self.cf_dat.opt_dict[label]['selected_imp'])) + 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'])) self.imp_lb = ImpListBox(self.imp_lw) - urwid.connect_signal(self.option_lw, 'focus_change', self.update_imp_lb) + urwid.connect_signal(self.opt_lw, 'focus_change', self.update_imp_lb) item_states = [(i,d['enabled']) for i,d in cf_dat.configuration_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.opt_lb = OptionListBox(self.opt_lw) self.opt_lb.set_focus(0) return @@ -342,11 +359,10 @@ class InstConfigManager: def __gen_imp_listwalker(self, opt): imp_items = [] - dict = self.cf_dat.opt_dict[opt] - for imp in self.cf_dat.imp_dict[dict['imptype']]: + for imp in self.cf_dat.iter_implementations(opt): if self.__imp_unavailable(imp): continue - if imp == dict['selected_imp']: + if imp == self.cf_dat.opt_dict[opt]['selected_imp']: imp_items.append((imp, True)) else: imp_items.append((imp, False)) @@ -359,39 +375,40 @@ class InstConfigManager: self.cf_dat.cf_statechange(button, new_state, udat) b = button.get_label() cascade = self.cf_dat.configuration_dict[b]['cascade_list'] + if new_state == True: for opt in self.cf_dat.opt_dict.keys(): +# self.cf_dat.set_imp(opt, 'none') + self.opt_lw.button_dict[opt].set_state(False) if self.cf_dat.opt_dict[opt]['permanent'] == False: - self.option_lw.button_dict[opt].set_state(False) + self.opt_lw.button_dict[opt].set_state(False) for opt,imp in cascade: - self.option_lw.button_dict[opt].set_state(True) + self.cf_dat.set_imp(opt, imp) + self.opt_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) +# imp_lw.button_dict[imp].set_state(True) + +# currpos = self.opt_lb.get_focus()[1] +# self.opt_lb.set_focus(currpos) 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): - if (SET_LABEL): - opt = button.get_label().split(':')[0] - else: - opt = button.get_label() - + opt = button.get_label().split(':')[0] imp = self.cf_dat.opt_dict[opt]['selected_imp'] if new_state == True: if self.__imp_unavailable(imp): self.cf_dat.opt_dict[opt]['selected_imp'] = 'none' imp_button = self.imp_lw.button_dict['none'] imp_button.set_state(True) - if SET_LABEL: - opt_button = self.option_lw.button_dict[opt] - opt_button.set_label('{0}:none'.format(opt)) -# FORCE DEDENT a blank line isn't enough in vim + opt_button = self.opt_lw.button_dict[opt] + opt_button.set_label('{0}:none'.format(opt)) else: - self.cf_dat.imp2opt_dict[imp] = opt + opt_button = self.opt_lw.button_dict[opt] + opt_button.set_label('{0}:{1}'.format(opt,imp)) + self.cf_dat.set_imp(opt, imp) self.cf_dat.opt_statechange(button, new_state, udat) return @@ -399,10 +416,9 @@ class InstConfigManager: def imp_statechange(self, button, new_state, opt): if new_state == True: imp = button.get_label() - self.cf_dat.imp2opt_dict[imp] = opt - if SET_LABEL: - opt_button = self.option_lw.button_dict[opt] - opt_button.set_label('{0}:{1}'.format(opt, imp)) + 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(button, new_state, opt) return @@ -443,8 +459,8 @@ class DEBUG: dbg = DEBUG(enabled=True) def main(config_ini): - global cf_dat, cf_man, cf_viewer, SET_LABEL - SET_LABEL = True + global cf_dat, cf_man, cf_viewer + # Make configuration data cf_dat = InstConfigData() cf_dat.read_config_file(config_ini) From 30791324ac9937960d4f9bda895038f73db3a01e Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sat, 5 Jul 2014 20:09:47 +1000 Subject: [PATCH 08/72] Always enable permanent options when changing instrument configuration. --- site_ansto/instrument/util/config_edit.py | 94 +++++++++-------------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index a6b9cea6..a23df917 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -151,14 +151,6 @@ class InstConfigData: self.configuration_dict[s]['cascade_list'] = cascade_list def __get_options(self): - # opt_dict: dict of configuration options as defined below, - # {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}} - opt_dict = defaultdict(dict) - - # imp2opt_dict: Maps each implementation to an option or None, - # {imp: opt/None} - imp2opt_dict = {} - for s in self.file_parser.sections(): if self.file_parser.has_option(s, 'implementation'): selected_imp = self.file_parser.get(s, 'implementation') @@ -201,20 +193,6 @@ class InstConfigData: print 'Add imp2opt_dict[{0}] = none'.format(s) self.imp2opt_dict[s] = 'none' - def set_imp(self, opt, new_imp): - old_imp =self.opt_dict[opt]['selected_imp'] - self.imp2opt_dict[old_imp] = 'none' - self.opt_dict[opt]['selected_imp'] = new_imp - self.imp2opt_dict[new_imp] = opt - - def get_optypelist (self): - return self.optypelist - - def iter_implementations(self, opt): - dict = self.opt_dict[opt] - for imp in self.imp_dict[dict['imptype']]: - yield imp - def read_config_file(self, config_filename): self.config_filename = config_filename self.file_parser = ConfigParser.SafeConfigParser() @@ -225,13 +203,12 @@ class InstConfigData: for opt,dict in self.opt_dict.iteritems(): self.optypelist.append((opt, dict['imptype'])) - return - def backup_files(self): 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)) + if os.path.exists(self.config_filename): shutil.copy(self.config_filename, self.config_filename + ".1") @@ -262,17 +239,28 @@ class InstConfigData: cfile.write("\n") - def cf_statechange(self, checkbox, new_state, udat=None): - cfg_id = checkbox.get_label() + def set_imp(self, opt, new_imp): + old_imp =self.opt_dict[opt]['selected_imp'] + self.imp2opt_dict[old_imp] = 'none' + self.opt_dict[opt]['selected_imp'] = new_imp + self.imp2opt_dict[new_imp] = opt + + def get_optypelist (self): + return self.optypelist + + def iter_implementations(self, opt): + dict = self.opt_dict[opt] + for imp in self.imp_dict[dict['imptype']]: + yield imp + + def cf_statechange(self, cfg_id, new_state, udat=None): self.configuration_dict[cfg_id]['enabled'] = new_state - def opt_statechange(self, checkbox, new_state, udat=None): - opt = checkbox.get_label().split(':')[0] + def opt_statechange(self, opt, new_state, udat=None): dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) self.opt_dict[opt]['enabled'] = new_state - def imp_statechange(self, button, new_state, opt): - selected_imp = button.get_label() + def imp_statechange(self, selected_imp, new_state, opt): dbg.msg(self.msg_index, 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, new_state, opt)) self.msg_index = (self.msg_index - 3) % 2 + 4 if new_state == True: @@ -289,6 +277,7 @@ class InstConfigView(urwid.Pile): self.cf_man.opt_lb, self.cf_man.imp_lb, dbmsg] + super(InstConfigView, self).__init__(option_ListBoxes) return @@ -312,7 +301,6 @@ class InstConfigView(urwid.Pile): self.set_focus(self.cf_man.config_lb) else: self.set_focus(self.cf_man.opt_lb) - return # Contains OptionListWalker dict indexed by option @@ -326,10 +314,10 @@ class InstConfigManager: def __init__(self, cf_dat): self.cf_dat = cf_dat urwid.register_signal(InstConfigManager, ['focus_change']) - self.options = self.cf_dat.get_optypelist() + self.opt_optype_list = self.cf_dat.get_optypelist() - self.options.sort() - firstopt = self.options[0][0] + self.opt_optype_list.sort() + firstopt = self.opt_optype_list[0][0] self.imp_lw = self.__gen_imp_listwalker(firstopt) self.opt_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange) for label, button in self.opt_lw.button_dict.iteritems(): @@ -369,29 +357,27 @@ class InstConfigManager: 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) + return rb_lw def cf_statechange(self, button, new_state, udat=None): - self.cf_dat.cf_statechange(button, new_state, udat) - b = button.get_label() - cascade = self.cf_dat.configuration_dict[b]['cascade_list'] - + cfg_id = button.get_label() + self.cf_dat.cf_statechange(cfg_id, new_state, udat) + cascade = self.cf_dat.configuration_dict[cfg_id]['cascade_list'] if new_state == True: for opt in self.cf_dat.opt_dict.keys(): -# self.cf_dat.set_imp(opt, 'none') self.opt_lw.button_dict[opt].set_state(False) - if self.cf_dat.opt_dict[opt]['permanent'] == False: - 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) 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(): + if self.cf_dat.opt_dict[opt]['permanent'] == True: + self.opt_lw.button_dict[opt].set_state(True) - dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(b, new_state, udat, cascade)) + dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(cfg_id, new_state, udat, cascade)) self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8 return @@ -401,8 +387,8 @@ class InstConfigManager: if new_state == True: if self.__imp_unavailable(imp): self.cf_dat.opt_dict[opt]['selected_imp'] = 'none' - imp_button = self.imp_lw.button_dict['none'] - imp_button.set_state(True) + 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)) else: @@ -410,8 +396,7 @@ class InstConfigManager: opt_button.set_label('{0}:{1}'.format(opt,imp)) self.cf_dat.set_imp(opt, imp) - self.cf_dat.opt_statechange(button, new_state, udat) - return + self.cf_dat.opt_statechange(opt, new_state, udat) def imp_statechange(self, button, new_state, opt): if new_state == True: @@ -420,12 +405,12 @@ class InstConfigManager: opt_button = self.opt_lw.button_dict[opt] opt_button.set_label('{0}:{1}'.format(opt, imp)) - self.cf_dat.imp_statechange(button, new_state, opt) + 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] + optname = self.opt_optype_list[pos][0] + optype = self.opt_optype_list[pos][1] mstr = 'InstConfigManager:update_imp_lb({0}) -> select {1}'.format(pos, optype) dbg.msg(1, mstr) self.imp_lw = self.__gen_imp_listwalker(optname) @@ -448,14 +433,11 @@ class DEBUG: 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 - dbg = DEBUG(enabled=True) def main(config_ini): From a0465541b3cb156844321e5fc1eb1edeb116a78a Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sat, 5 Jul 2014 20:16:09 +1000 Subject: [PATCH 09/72] set indent to four spaces. --- site_ansto/instrument/util/config_edit.py | 678 +++++++++++----------- 1 file changed, 339 insertions(+), 339 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index a23df917..ba31b523 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# vim: tabstop=8 softtabstop=2 shiftwidth=2 nocin si et ft=python +# vim: tabstop=8 softtabstop=4 shiftwidth=4 nocin si et ft=python # View Screen has 3 parts # (Instrument Configuration), (Configuration Options), (Option Implementation) @@ -30,277 +30,277 @@ import copy from collections import defaultdict Palette = [ - ('body', 'dark cyan', '', 'standout'), - ('focus', 'dark red', '', 'standout'), - ('head', 'light red', 'black'), + ('body', 'dark cyan', '', 'standout'), + ('focus', 'dark red', '', 'standout'), + ('head', 'light red', 'black'), ] class RadioButtonListWalker(urwid.SimpleListWalker): - def __init__(self, item_states, on_state_change=None, user_data=None): - 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) + def __init__(self, item_states, on_state_change=None, user_data=None): + 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 + super(RadioButtonListWalker, self).__init__(mapped_rb_list) + return class CheckBoxListWalker(urwid.SimpleListWalker): - def __init__(self, item_states, on_state_change = None, user_data = None): - 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) + def __init__(self, item_states, on_state_change = None, user_data = None): + 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 + super(CheckBoxListWalker, self).__init__(mapped_cb_list) + return 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() + 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 + 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) + 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) + 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 __init__(self, listwalker): + super(OptionListBox, self).__init__(listwalker) + return # List of RadioButtons class ImpListBox(ClosedListBox): - def __init__(self, listwalker): - super(ImpListBox, self).__init__(listwalker) - return + def __init__(self, listwalker): + super(ImpListBox, self).__init__(listwalker) + return - def use_listwalker(self, liswalker): - self.body.contents[:] = liswalker - return + def use_listwalker(self, liswalker): + self.body.contents[:] = liswalker + return 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) + 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) - # imp_dict: dict of implementations indexed by optype, - # {optype: [impname] } - imp_dict = defaultdict(list) + # imp_dict: dict of implementations indexed by optype, + # {optype: [impname] } + imp_dict = defaultdict(list) - # opt_dict: dict of configuration options as defined below, - # {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}} - opt_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) - # imp2opt_dict: Maps each implementation to an option or None, - # {imp: opt/None} - imp2opt_dict = {} + # imp2opt_dict: Maps each implementation to an option or None, + # {imp: opt/None} + imp2opt_dict = {} - # optypelist: list of (opt, optype) tuples - # [(opt, optype)] - optypelist = [] + # optypelist: list of (opt, optype) tuples + # [(opt, optype)] + optypelist = [] - def __get_configurations(self): - for s 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(','): - cascade_list.append(tuple(cascade_str.split(':'))) - if enabled.lower() in ['true','always']: - stateval = True - else: - stateval = False + def __get_configurations(self): + for s 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(','): + cascade_list.append(tuple(cascade_str.split(':'))) + if enabled.lower() in ['true','always']: + stateval = True + else: + stateval = False - self.configuration_dict[s]['enabled'] = stateval - self.configuration_dict[s]['cascade_list'] = cascade_list + self.configuration_dict[s]['enabled'] = stateval + self.configuration_dict[s]['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() - if enabled == 'always': - stateval = True - permanent = True - elif enabled == 'true': - stateval = True - permanent = False - else: - stateval = False - permanent = False + 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() + if enabled == 'always': + stateval = True + permanent = True + elif enabled == 'true': + stateval = True + permanent = False + else: + stateval = False + permanent = False - if self.file_parser.has_option(s, 'id'): - id = self.file_parser.get(s, 'id') - self.opt_dict[s]['id'] = id + if self.file_parser.has_option(s, 'id'): + id = self.file_parser.get(s, 'id') + self.opt_dict[s]['id'] = id - self.opt_dict[s]['enabled'] = stateval - self.opt_dict[s]['permanent'] = permanent - self.opt_dict[s]['imptype'] = imptype - if selected_imp in self.imp2opt_dict: - self.opt_dict[s]['selected_imp'] = 'none' - else: - self.opt_dict[s]['selected_imp'] = selected_imp - if selected_imp != 'none': - print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp,s) - self.imp2opt_dict[selected_imp] = s + self.opt_dict[s]['enabled'] = stateval + self.opt_dict[s]['permanent'] = permanent + self.opt_dict[s]['imptype'] = imptype + if selected_imp in self.imp2opt_dict: + self.opt_dict[s]['selected_imp'] = 'none' + else: + self.opt_dict[s]['selected_imp'] = selected_imp + if selected_imp != 'none': + print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp,s) + self.imp2opt_dict[selected_imp] = s - 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') - if 'none' not in self.imp_dict[key]: - self.imp_dict[key].append('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') + if 'none' not in self.imp_dict[key]: + self.imp_dict[key].append('none') - self.imp_dict[key].append(s) - if s not in self.imp2opt_dict: - print 'Add imp2opt_dict[{0}] = none'.format(s) - self.imp2opt_dict[s] = 'none' + self.imp_dict[key].append(s) + if s not in self.imp2opt_dict: + print 'Add imp2opt_dict[{0}] = none'.format(s) + self.imp2opt_dict[s] = 'none' - def read_config_file(self, config_filename): - self.config_filename = config_filename - self.file_parser = ConfigParser.SafeConfigParser() - self.file_parser.read(config_filename) - self.__get_options() - self.__get_implementations() - self.__get_configurations() - for opt,dict in self.opt_dict.iteritems(): - self.optypelist.append((opt, dict['imptype'])) + def read_config_file(self, config_filename): + self.config_filename = config_filename + self.file_parser = ConfigParser.SafeConfigParser() + self.file_parser.read(config_filename) + self.__get_options() + self.__get_implementations() + self.__get_configurations() + for opt,dict in self.opt_dict.iteritems(): + self.optypelist.append((opt, dict['imptype'])) - def backup_files(self): - 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)) + def backup_files(self): + 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)) - if os.path.exists(self.config_filename): - shutil.copy(self.config_filename, self.config_filename + ".1") + if os.path.exists(self.config_filename): + shutil.copy(self.config_filename, self.config_filename + ".1") - def write_config_file(self): - for item,dict in self.opt_dict.iteritems(): - if 'permanent' in dict and dict['permanent'] == True: - enabled = 'Always' - else: - enabled = dict['enabled'].__str__() + def write_config_file(self): + for item,dict in self.opt_dict.iteritems(): + if 'permanent' in dict and dict['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']) + 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) + for item,dict in self.configuration_dict.iteritems(): + enabled = dict['enabled'].__str__() + self.file_parser.set(item, 'enabled', enabled) - for imp,opt in self.imp2opt_dict.iteritems(): - if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: - self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) + for imp,opt in self.imp2opt_dict.iteritems(): + if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: + self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) - 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))) + 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))) - cfile.write("\n") + cfile.write("\n") - def set_imp(self, opt, new_imp): - old_imp =self.opt_dict[opt]['selected_imp'] - self.imp2opt_dict[old_imp] = 'none' - self.opt_dict[opt]['selected_imp'] = new_imp - self.imp2opt_dict[new_imp] = opt + def set_imp(self, opt, new_imp): + old_imp =self.opt_dict[opt]['selected_imp'] + self.imp2opt_dict[old_imp] = 'none' + self.opt_dict[opt]['selected_imp'] = new_imp + self.imp2opt_dict[new_imp] = opt - def get_optypelist (self): - return self.optypelist + def get_optypelist (self): + return self.optypelist - def iter_implementations(self, opt): - dict = self.opt_dict[opt] - for imp in self.imp_dict[dict['imptype']]: - yield imp + def iter_implementations(self, opt): + dict = self.opt_dict[opt] + for imp in self.imp_dict[dict['imptype']]: + yield imp - def cf_statechange(self, cfg_id, new_state, udat=None): - self.configuration_dict[cfg_id]['enabled'] = new_state + def cf_statechange(self, cfg_id, new_state, udat=None): + self.configuration_dict[cfg_id]['enabled'] = new_state - def opt_statechange(self, opt, new_state, udat=None): - dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) - self.opt_dict[opt]['enabled'] = new_state + def opt_statechange(self, opt, new_state, udat=None): + dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) + self.opt_dict[opt]['enabled'] = new_state - def imp_statechange(self, selected_imp, new_state, opt): - dbg.msg(self.msg_index, 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, new_state, opt)) - self.msg_index = (self.msg_index - 3) % 2 + 4 - if new_state == True: - self.opt_dict[opt]['selected_imp'] = selected_imp + def imp_statechange(self, selected_imp, new_state, opt): + dbg.msg(self.msg_index, 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, new_state, opt)) + self.msg_index = (self.msg_index - 3) % 2 + 4 + if new_state == True: + self.opt_dict[opt]['selected_imp'] = selected_imp 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] + 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 + super(InstConfigView, self).__init__(option_ListBoxes) + return - def keyinput(self, key): - if key == 'meta q': - raise urwid.ExitMainLoop() - elif key == 'w': - self.cf_dat.backup_files() - self.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) - else: - self.set_focus(self.cf_man.config_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) - else: - self.set_focus(self.cf_man.opt_lb) + def keyinput(self, key): + if key == 'meta q': + raise urwid.ExitMainLoop() + elif key == 'w': + self.cf_dat.backup_files() + self.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) + else: + self.set_focus(self.cf_man.config_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) + else: + self.set_focus(self.cf_man.opt_lb) # Contains OptionListWalker dict indexed by option @@ -309,164 +309,164 @@ class InstConfigView(urwid.Pile): # Tracks selected implementation for each option # and sets selection on ImpListBox class InstConfigManager: - cf_msg_index = 8 - imp_lw_dict = {} - def __init__(self, cf_dat): - self.cf_dat = cf_dat - urwid.register_signal(InstConfigManager, ['focus_change']) - 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.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'])) + cf_msg_index = 8 + imp_lw_dict = {} + def __init__(self, cf_dat): + self.cf_dat = cf_dat + urwid.register_signal(InstConfigManager, ['focus_change']) + 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.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'])) - 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.configuration_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.opt_lw) - self.opt_lb.set_focus(0) - return + 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.configuration_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.opt_lw) + self.opt_lb.set_focus(0) + return - def __imp_unavailable(self, imp): - if imp == 'none': - return False + def __imp_unavailable(self, imp): + if imp == 'none': + return False - ckopt = self.cf_dat.imp2opt_dict[imp] - if ckopt == 'none': - return False - elif self.cf_dat.opt_dict[ckopt]['enabled']: - return True - else: - return False + ckopt = self.cf_dat.imp2opt_dict[imp] + if ckopt == 'none': + return False + elif self.cf_dat.opt_dict[ckopt]['enabled']: + return True + else: + return False - def __gen_imp_listwalker(self, opt): - imp_items = [] - for imp in self.cf_dat.iter_implementations(opt): - if self.__imp_unavailable(imp): - continue - if imp == self.cf_dat.opt_dict[opt]['selected_imp']: - imp_items.append((imp, True)) - else: - imp_items.append((imp, False)) + def __gen_imp_listwalker(self, opt): + imp_items = [] + for imp in self.cf_dat.iter_implementations(opt): + if self.__imp_unavailable(imp): + continue + if imp == self.cf_dat.opt_dict[opt]['selected_imp']: + imp_items.append((imp, True)) + else: + imp_items.append((imp, False)) - imp_items = imp_items[:1] + sorted(imp_items[1:]) + imp_items = imp_items[:1] + sorted(imp_items[1:]) - rb_lw = RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) - return rb_lw + rb_lw = RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) + return rb_lw - def cf_statechange(self, button, new_state, udat=None): - cfg_id = button.get_label() - self.cf_dat.cf_statechange(cfg_id, new_state, udat) - cascade = self.cf_dat.configuration_dict[cfg_id]['cascade_list'] - if new_state == True: - for opt in self.cf_dat.opt_dict.keys(): - self.opt_lw.button_dict[opt].set_state(False) + def cf_statechange(self, button, new_state, udat=None): + cfg_id = button.get_label() + self.cf_dat.cf_statechange(cfg_id, new_state, udat) + cascade = self.cf_dat.configuration_dict[cfg_id]['cascade_list'] + if new_state == True: + 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) - imp_lw = self.__gen_imp_listwalker(opt) + for opt,imp in cascade: + self.cf_dat.set_imp(opt, imp) + self.opt_lw.button_dict[opt].set_state(True) + imp_lw = self.__gen_imp_listwalker(opt) - 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) + 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) - dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(cfg_id, new_state, udat, cascade)) - self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8 - return + dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(cfg_id, 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): - opt = button.get_label().split(':')[0] - imp = self.cf_dat.opt_dict[opt]['selected_imp'] - if new_state == True: - if self.__imp_unavailable(imp): - 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)) - 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 opt_statechange(self, button, new_state, udat=None): + opt = button.get_label().split(':')[0] + imp = self.cf_dat.opt_dict[opt]['selected_imp'] + if new_state == True: + if self.__imp_unavailable(imp): + 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)) + 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) - self.cf_dat.opt_statechange(opt, new_state, udat) + self.cf_dat.opt_statechange(opt, new_state, udat) - def imp_statechange(self, button, new_state, opt): - if new_state == True: - imp = button.get_label() - self.cf_dat.set_imp(opt, imp) - opt_button = self.opt_lw.button_dict[opt] - opt_button.set_label('{0}:{1}'.format(opt, imp)) + def imp_statechange(self, button, new_state, opt): + if new_state == True: + imp = button.get_label() + 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 + self.cf_dat.imp_statechange(imp, new_state, opt) + return - def update_imp_lb(self, pos): - optname = self.opt_optype_list[pos][0] - optype = self.opt_optype_list[pos][1] - mstr = 'InstConfigManager:update_imp_lb({0}) -> select {1}'.format(pos, optype) - dbg.msg(1, mstr) - self.imp_lw = self.__gen_imp_listwalker(optname) - self.imp_lb.use_listwalker(self.imp_lw) - return + def update_imp_lb(self, pos): + optname = self.opt_optype_list[pos][0] + optype = self.opt_optype_list[pos][1] + mstr = 'InstConfigManager:update_imp_lb({0}) -> select {1}'.format(pos, optype) + dbg.msg(1, mstr) + self.imp_lw = self.__gen_imp_listwalker(optname) + self.imp_lb.use_listwalker(self.imp_lw) + return 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')) + 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) + mlw = urwid.SimpleListWalker(self.msglist) + self.mlb = urwid.ListBox(mlw) - def msg(self, index, msg): - if self.enabled: - mid = self.msg_ids[index] - self.msgTextDict[mid].set_text(msg) + def msg(self, index, msg): + if self.enabled: + mid = self.msg_ids[index] + self.msgTextDict[mid].set_text(msg) dbg = DEBUG(enabled=True) def main(config_ini): - global cf_dat, cf_man, cf_viewer + global cf_dat, cf_man, cf_viewer - # Make configuration data - cf_dat = InstConfigData() - cf_dat.read_config_file(config_ini) + # Make configuration data + cf_dat = InstConfigData() + cf_dat.read_config_file(config_ini) - # Make configuration editor - cf_man = InstConfigManager(cf_dat) + # 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() - return + # Make configuration viewer + cf_viewer = InstConfigView(cf_dat, cf_man, dbg.mlb) + urwid.MainLoop(cf_viewer, Palette, unhandled_input=cf_viewer.keyinput).run() + return if '__main__' == __name__: - 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 = "/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) From 37e75ab5b41b4ec7f5eadafce6fce45083f6a9b1 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sat, 5 Jul 2014 22:32:34 +1000 Subject: [PATCH 10/72] Make harmless changes to reduce pylint noise. Work out what to do about warnings and apparent errors later. --- site_ansto/instrument/util/config_edit.py | 258 ++++++++++++++++------ 1 file changed, 196 insertions(+), 62 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index ba31b523..d57c4b66 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -1,9 +1,11 @@ #!/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, InstConfigManager +# Uses MVC as InstConfigData, InstConfigView, InstConfigManager # # InstConfigData <>--- ConfigParser.SafeConfig # |--set_cfparse() @@ -26,10 +28,9 @@ import shutil import argparse import ConfigParser import urwid -import copy from collections import defaultdict -Palette = [ +PALETTE = [ ('body', 'dark cyan', '', 'standout'), ('focus', 'dark red', '', 'standout'), ('head', 'light red', 'black'), @@ -37,12 +38,26 @@ Palette = [ class RadioButtonListWalker(urwid.SimpleListWalker): + + """Extend urwid.SimpleListWalker to generate a radio button listwalker. + + 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) + 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) @@ -52,11 +67,25 @@ class RadioButtonListWalker(urwid.SimpleListWalker): 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) + 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) @@ -66,16 +95,29 @@ class CheckBoxListWalker(urwid.SimpleListWalker): 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 = [(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)) + """Emit 'focus_change' signal with position of button. + """ + 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) @@ -84,8 +126,12 @@ class OptionListWalker(CheckBoxListWalker): # 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): - """Prevents navigating outside of a ClosedListBox with the up and down arrow keys""" + """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'): @@ -96,6 +142,11 @@ class ClosedListBox(urwid.ListBox): # 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 @@ -103,46 +154,67 @@ class OptionListBox(ClosedListBox): # 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, liswalker): - self.body.contents[:] = liswalker + def use_listwalker(self, listwalker): + """ Select the given listwalker for display. + """ + self.body.contents[:] = listwalker return class InstConfigData: + + """Handles reading and writing instrument configuration data and provides + methods to change the configuration. + Attributes: + configuration_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 - # configuration_dict: dict of instrument configurations as defined below, - # {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} } - configuration_dict = defaultdict(dict) - # imp_dict: dict of implementations indexed by optype, - # {optype: [impname] } - imp_dict = defaultdict(list) + def __init__(self): + #configuration_dict: dict of instrument configurations as defined below, + # {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} } + self.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) + #imp_dict: dict of implementations indexed by optype, + # {optype: [impname] } + self.imp_dict = defaultdict(list) - # imp2opt_dict: Maps each implementation to an option or None, - # {imp: opt/None} - imp2opt_dict = {} + #opt_dict: dict of configuration options as defined below, + # {optname:{'enabled':T/F/Always, 'imptype':optype,'selected_imp':dflt}} + self.opt_dict = defaultdict(dict) - # optypelist: list of (opt, optype) tuples - # [(opt, optype)] - optypelist = [] + #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): + """Parse instrument configuration definitions from INI file into + configuration_dict attribute of InstConfigData object + """ for s 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(','): + for cascade_str in self.file_parser.get(s, + 'cascade').split(','): cascade_list.append(tuple(cascade_str.split(':'))) - if enabled.lower() in ['true','always']: + if enabled.lower() in ['true', 'always']: stateval = True else: stateval = False @@ -151,6 +223,9 @@ class InstConfigData: self.configuration_dict[s]['cascade_list'] = cascade_list def __get_options(self): + """Parse configuration options from INI file into opt_dict attribute of + InstConfigData object. + """ for s in self.file_parser.sections(): if self.file_parser.has_option(s, 'implementation'): selected_imp = self.file_parser.get(s, 'implementation') @@ -178,10 +253,14 @@ class InstConfigData: else: self.opt_dict[s]['selected_imp'] = selected_imp if selected_imp != 'none': - print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp,s) + print 'Add imp2opt_dict[{0}]={1}'.format( + selected_imp, s) self.imp2opt_dict[selected_imp] = s def __get_implementations(self): + """Parse implementation lists from INI file into imp_dict attribute of + InstConfigData object. + """ for s in self.file_parser.sections(): if self.file_parser.has_option(s, 'imptype'): key = self.file_parser.get(s, 'imptype') @@ -194,16 +273,18 @@ class InstConfigData: self.imp2opt_dict[s] = 'none' def read_config_file(self, config_filename): + """ Load and parse a sics_config.ini file """ self.config_filename = config_filename self.file_parser = ConfigParser.SafeConfigParser() self.file_parser.read(config_filename) self.__get_options() self.__get_implementations() self.__get_configurations() - for opt,dict in self.opt_dict.iteritems(): + for opt, dict in self.opt_dict.iteritems(): self.optypelist.append((opt, dict['imptype'])) 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), @@ -213,7 +294,8 @@ class InstConfigData: shutil.copy(self.config_filename, self.config_filename + ".1") def write_config_file(self): - for item,dict in self.opt_dict.iteritems(): + """ Write out InstConfigData values to the configuration file.""" + for item, dict in self.opt_dict.iteritems(): if 'permanent' in dict and dict['permanent'] == True: enabled = 'Always' else: @@ -223,45 +305,58 @@ class InstConfigData: 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(): + for item, dict in self.configuration_dict.iteritems(): enabled = dict['enabled'].__str__() self.file_parser.set(item, 'enabled', enabled) - for imp,opt in self.imp2opt_dict.iteritems(): + for imp, opt in self.imp2opt_dict.iteritems(): if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) - with open(self.config_filename,'w') as cfile: + 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))) + cfile.write( + '{0} = {1}\n'.format(option, + self.file_parser.get(section, + option))) cfile.write("\n") def set_imp(self, opt, new_imp): - old_imp =self.opt_dict[opt]['selected_imp'] + """Keep option dictionaray and implementation -> option map in sync.""" + old_imp = self.opt_dict[opt]['selected_imp'] self.imp2opt_dict[old_imp] = 'none' self.opt_dict[opt]['selected_imp'] = new_imp 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.""" dict = self.opt_dict[opt] for imp in self.imp_dict[dict['imptype']]: yield imp def cf_statechange(self, cfg_id, new_state, udat=None): + """Change the given instrument configuration state.""" self.configuration_dict[cfg_id]['enabled'] = new_state def opt_statechange(self, opt, new_state, udat=None): - dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat)) + """Change the given option state.""" + DBG.msg(3, + 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, + new_state, udat)) self.opt_dict[opt]['enabled'] = new_state def imp_statechange(self, selected_imp, new_state, opt): - dbg.msg(self.msg_index, 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, new_state, opt)) + """Change the given implementation state.""" + DBG.msg(self.msg_index, + 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, + new_state, opt)) self.msg_index = (self.msg_index - 3) % 2 + 4 if new_state == True: self.opt_dict[opt]['selected_imp'] = selected_imp @@ -269,7 +364,15 @@ class InstConfigData: class InstConfigView(urwid.Pile): + """Extend urwid.Pile to provide an instrument configuration viewer. + """ + def __init__(self, cf_dat, cf_man, dbmsg): + """ + Args: + cf_dat: InstConfigData object. + cf_man: InstConfigManager object. + """ self.cf_dat = cf_dat self.cf_man = cf_man option_ListBoxes = [ @@ -282,6 +385,7 @@ class InstConfigView(urwid.Pile): return def keyinput(self, key): + """Switch between lists, save data and quit on key input.""" if key == 'meta q': raise urwid.ExitMainLoop() elif key == 'w': @@ -309,8 +413,11 @@ class InstConfigView(urwid.Pile): # Tracks selected implementation for each option # and sets selection on ImpListBox class InstConfigManager: + + """Provides controller which keeps data and viewer in sync. + """ + cf_msg_index = 8 - imp_lw_dict = {} def __init__(self, cf_dat): self.cf_dat = cf_dat urwid.register_signal(InstConfigManager, ['focus_change']) @@ -321,19 +428,25 @@ class InstConfigManager: self.imp_lw = self.__gen_imp_listwalker(firstopt) 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'])) + button.set_label('{0}:{1}'.format( + label, self.cf_dat.opt_dict[label]['selected_imp']) ) 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.configuration_dict.iteritems()] + item_states = [(i, d['enabled']) for i, d in + cf_dat.configuration_dict.iteritems()] item_states.sort() - self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange) + self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = + self.cf_statechange) self.config_lb = OptionListBox(self.cfg_lw) self.opt_lb = OptionListBox(self.opt_lw) self.opt_lb.set_focus(0) return def __imp_unavailable(self, imp): + """Return True if an implementation is unavailable because it is used + by an enabled option. + """ if imp == 'none': return False @@ -346,6 +459,7 @@ class InstConfigManager: return False def __gen_imp_listwalker(self, opt): + """Generate the appropriate listwalker for the given option.""" imp_items = [] for imp in self.cf_dat.iter_implementations(opt): if self.__imp_unavailable(imp): @@ -357,10 +471,15 @@ class InstConfigManager: imp_items = imp_items[:1] + sorted(imp_items[1:]) - rb_lw = 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) return rb_lw def cf_statechange(self, button, new_state, udat=None): + """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, udat) cascade = self.cf_dat.configuration_dict[cfg_id]['cascade_list'] @@ -368,7 +487,7 @@ class InstConfigManager: for opt in self.cf_dat.opt_dict.keys(): self.opt_lw.button_dict[opt].set_state(False) - for opt,imp in cascade: + for opt, imp in cascade: self.cf_dat.set_imp(opt, imp) self.opt_lw.button_dict[opt].set_state(True) imp_lw = self.__gen_imp_listwalker(opt) @@ -377,11 +496,16 @@ class InstConfigManager: if self.cf_dat.opt_dict[opt]['permanent'] == True: self.opt_lw.button_dict[opt].set_state(True) - dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(cfg_id, new_state, udat, cascade)) + DBG.msg(self.cf_msg_index, + 'InstConfigManager:cf_statechange({0},{1},{2}),cascade={3}'.format( + cfg_id, 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): + """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: @@ -393,12 +517,15 @@ class InstConfigManager: opt_button.set_label('{0}:none'.format(opt)) else: opt_button = self.opt_lw.button_dict[opt] - opt_button.set_label('{0}:{1}'.format(opt,imp)) + opt_button.set_label('{0}:{1}'.format(opt, imp)) self.cf_dat.set_imp(opt, imp) self.cf_dat.opt_statechange(opt, new_state, udat) def imp_statechange(self, button, new_state, opt): + """Update label on the configuration option when it's implementation is + changed. + """ if new_state == True: imp = button.get_label() self.cf_dat.set_imp(opt, imp) @@ -409,17 +536,19 @@ class InstConfigManager: return def update_imp_lb(self, pos): + """Update implementation list when an option gets focus.""" optname = self.opt_optype_list[pos][0] optype = self.opt_optype_list[pos][1] - mstr = 'InstConfigManager:update_imp_lb({0}) -> select {1}'.format(pos, optype) - dbg.msg(1, mstr) + mstr = 'InstConfigManager:update_imp_lb({0})->select{1}'.format(pos, + optype) + DBG.msg(1, mstr) self.imp_lw = self.__gen_imp_listwalker(optname) self.imp_lb.use_listwalker(self.imp_lw) return -import pdb class DEBUG: + """DEBUG class""" msgTextDict = {} msglist = [] msg_ids = [ 'm0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9' ] @@ -435,13 +564,14 @@ class DEBUG: self.mlb = urwid.ListBox(mlw) def msg(self, index, msg): + """Debug message.""" if self.enabled: mid = self.msg_ids[index] self.msgTextDict[mid].set_text(msg) -dbg = DEBUG(enabled=True) +DBG = DEBUG(enabled=True) def main(config_ini): - global cf_dat, cf_man, cf_viewer + """Create configuration editor.""" # Make configuration data cf_dat = InstConfigData() @@ -451,22 +581,26 @@ def main(config_ini): 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_dat, cf_man, DBG.mlb) + urwid.MainLoop(cf_viewer, PALETTE, unhandled_input=cf_viewer.keyinput).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) From 7eaa8242bd93241b5d5b9daebf92f7db3f4e3018 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 09:40:37 +1000 Subject: [PATCH 11/72] Always show selected_imp in the implementation list for an option. Fix imp_statechange bug (imp undefined for disabled options). --- site_ansto/instrument/util/config_edit.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index d57c4b66..1d978748 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -443,7 +443,7 @@ class InstConfigManager: self.opt_lb.set_focus(0) return - def __imp_unavailable(self, imp): + def __imp_unavailable(self, opt, imp): """Return True if an implementation is unavailable because it is used by an enabled option. """ @@ -453,6 +453,10 @@ class InstConfigManager: ckopt = self.cf_dat.imp2opt_dict[imp] if ckopt == 'none': return False + + opt_imp = self.cf_dat.opt_dict[opt]['selected_imp'] + if opt_imp == imp: + return False elif self.cf_dat.opt_dict[ckopt]['enabled']: return True else: @@ -462,7 +466,7 @@ class InstConfigManager: """Generate the appropriate listwalker for the given option.""" imp_items = [] for imp in self.cf_dat.iter_implementations(opt): - if self.__imp_unavailable(imp): + if self.__imp_unavailable(opt, imp): continue if imp == self.cf_dat.opt_dict[opt]['selected_imp']: imp_items.append((imp, True)) @@ -509,7 +513,7 @@ class InstConfigManager: opt = button.get_label().split(':')[0] imp = self.cf_dat.opt_dict[opt]['selected_imp'] if new_state == True: - if self.__imp_unavailable(imp): + if self.__imp_unavailable(opt, imp): self.cf_dat.opt_dict[opt]['selected_imp'] = 'none' imp_none_button = self.imp_lw.button_dict['none'] imp_none_button.set_state(True) @@ -526,8 +530,8 @@ class InstConfigManager: """Update label on the configuration option when it's implementation is changed. """ + imp = button.get_label() if new_state == True: - imp = button.get_label() self.cf_dat.set_imp(opt, imp) opt_button = self.opt_lw.button_dict[opt] opt_button.set_label('{0}:{1}'.format(opt, imp)) From 13c837d9b5295bb9b3f7bf0f0e88a4767b514b61 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 10:13:40 +1000 Subject: [PATCH 12/72] Reduce pylint noise and remove unused variable imp_lw --- site_ansto/instrument/util/config_edit.py | 85 +++++++++++------------ 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 1d978748..0e4ea080 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -56,10 +56,10 @@ class RadioButtonListWalker(urwid.SimpleListWalker): mapped_rb_list = [] self.button_dict = {} for item, stateval in item_states: - rb = urwid.RadioButton( radio_grp, item, state=stateval, + _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') + 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) @@ -83,11 +83,11 @@ class CheckBoxListWalker(urwid.SimpleListWalker): mapped_cb_list = [] self.button_dict = {} for item, stateval in item_states: - cb = urwid.CheckBox( item, state = stateval, + _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') + 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) @@ -133,8 +133,8 @@ class ClosedListBox(urwid.ListBox): """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'): + _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) @@ -207,11 +207,11 @@ class InstConfigData: """Parse instrument configuration definitions from INI file into configuration_dict attribute of InstConfigData object """ - for s in self.file_parser.sections(): + 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, + if self.file_parser.has_option(sect, 'cascade'): + enabled = self.file_parser.get(sect, 'enabled') + for cascade_str in self.file_parser.get(sect, 'cascade').split(','): cascade_list.append(tuple(cascade_str.split(':'))) if enabled.lower() in ['true', 'always']: @@ -219,18 +219,18 @@ class InstConfigData: else: stateval = False - self.configuration_dict[s]['enabled'] = stateval - self.configuration_dict[s]['cascade_list'] = cascade_list + self.configuration_dict[sect]['enabled'] = stateval + self.configuration_dict[sect]['cascade_list'] = cascade_list def __get_options(self): """Parse configuration options from INI file into opt_dict attribute of InstConfigData object. """ - 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() + 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') + enabled = self.file_parser.get(sect, 'enabled').lower() if enabled == 'always': stateval = True permanent = True @@ -241,36 +241,36 @@ class InstConfigData: stateval = False permanent = False - if self.file_parser.has_option(s, 'id'): - id = self.file_parser.get(s, 'id') - self.opt_dict[s]['id'] = id + if self.file_parser.has_option(sect, 'id'): + _id = self.file_parser.get(sect, 'id') + self.opt_dict[sect]['id'] = _id - self.opt_dict[s]['enabled'] = stateval - self.opt_dict[s]['permanent'] = permanent - self.opt_dict[s]['imptype'] = imptype + self.opt_dict[sect]['enabled'] = stateval + self.opt_dict[sect]['permanent'] = permanent + self.opt_dict[sect]['imptype'] = imptype if selected_imp in self.imp2opt_dict: - self.opt_dict[s]['selected_imp'] = 'none' + self.opt_dict[sect]['selected_imp'] = 'none' else: - self.opt_dict[s]['selected_imp'] = selected_imp + self.opt_dict[sect]['selected_imp'] = selected_imp if selected_imp != 'none': print 'Add imp2opt_dict[{0}]={1}'.format( - selected_imp, s) - self.imp2opt_dict[selected_imp] = s + selected_imp, sect) + self.imp2opt_dict[selected_imp] = sect def __get_implementations(self): """Parse implementation lists from INI file into imp_dict attribute of InstConfigData object. """ - for s in self.file_parser.sections(): - if self.file_parser.has_option(s, 'imptype'): - key = self.file_parser.get(s, 'imptype') + for sect in self.file_parser.sections(): + if self.file_parser.has_option(sect, 'imptype'): + key = self.file_parser.get(sect, 'imptype') if 'none' not in self.imp_dict[key]: self.imp_dict[key].append('none') - self.imp_dict[key].append(s) - if s not in self.imp2opt_dict: - print 'Add imp2opt_dict[{0}] = none'.format(s) - self.imp2opt_dict[s] = 'none' + self.imp_dict[key].append(sect) + if sect not in self.imp2opt_dict: + print 'Add imp2opt_dict[{0}] = none'.format(sect) + self.imp2opt_dict[sect] = 'none' def read_config_file(self, config_filename): """ Load and parse a sics_config.ini file """ @@ -375,13 +375,13 @@ class InstConfigView(urwid.Pile): """ self.cf_dat = cf_dat self.cf_man = cf_man - option_ListBoxes = [ + option_listboxes = [ self.cf_man.config_lb, self.cf_man.opt_lb, self.cf_man.imp_lb, dbmsg] - super(InstConfigView, self).__init__(option_ListBoxes) + super(InstConfigView, self).__init__(option_listboxes) return def keyinput(self, key): @@ -494,7 +494,6 @@ class InstConfigManager: for opt, imp in cascade: self.cf_dat.set_imp(opt, imp) self.opt_lw.button_dict[opt].set_state(True) - imp_lw = self.__gen_imp_listwalker(opt) for opt in self.cf_dat.opt_dict.keys(): if self.cf_dat.opt_dict[opt]['permanent'] == True: @@ -559,10 +558,10 @@ class DEBUG: 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')) + for msg_id in self.msg_ids: + msg_text = urwid.Text(u'Space for message {0}'.format(msg_id)) + self.msgTextDict[msg_id] = msg_text + self.msglist.append(urwid.AttrMap(msg_text, 'body', 'focus')) mlw = urwid.SimpleListWalker(self.msglist) self.mlb = urwid.ListBox(mlw) From 8a6004e12d1571d1a6a2d4b9319e72f6ab10b56b Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 11:14:36 +1000 Subject: [PATCH 13/72] Stop pylint complaining about unimplemented abstract methods. But instantiating an apparently abstract class didn't bother Python??? --- site_ansto/instrument/util/config_edit.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 0e4ea080..2a5ac7f9 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -65,6 +65,13 @@ class RadioButtonListWalker(urwid.SimpleListWalker): 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): @@ -93,6 +100,14 @@ class CheckBoxListWalker(urwid.SimpleListWalker): 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): From a5ea730343adedad7b13b107ad39cfa071da387a Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 11:47:23 +1000 Subject: [PATCH 14/72] Don't redefine the 'dict' builtin. (Caught by pylint) Also improve variable name consistency. --- site_ansto/instrument/util/config_edit.py | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 2a5ac7f9..a988e392 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -295,8 +295,8 @@ class InstConfigData: self.__get_options() self.__get_implementations() self.__get_configurations() - for opt, dict in self.opt_dict.iteritems(): - self.optypelist.append((opt, dict['imptype'])) + for opt, opt_desc in self.opt_dict.iteritems(): + self.optypelist.append((opt, opt_desc['imptype'])) def backup_files(self): """ Backup configuration files """ @@ -310,19 +310,19 @@ class InstConfigData: def write_config_file(self): """ Write out InstConfigData values to the configuration file.""" - for item, dict in self.opt_dict.iteritems(): - if 'permanent' in dict and dict['permanent'] == True: + 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__() + enabled = opt_desc['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']) + 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 item, dict in self.configuration_dict.iteritems(): - enabled = dict['enabled'].__str__() - self.file_parser.set(item, 'enabled', enabled) + for config, config_desc in self.configuration_dict.iteritems(): + enabled = config_desc['enabled'].__str__() + self.file_parser.set(config, 'enabled', enabled) for imp, opt in self.imp2opt_dict.iteritems(): if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: @@ -352,8 +352,8 @@ class InstConfigData: def iter_implementations(self, opt): """Iterate over implementation names for the given option.""" - dict = self.opt_dict[opt] - for imp in self.imp_dict[dict['imptype']]: + 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, udat=None): From 82268ecc2e41b7784acf747773e66d4dbb578abe Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 12:03:19 +1000 Subject: [PATCH 15/72] Make sure all instance attributes are defined in __init__ methods. Also play with named arguments that don't define a default value (**kwargs) --- site_ansto/instrument/util/config_edit.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index a988e392..7cf77579 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -198,6 +198,8 @@ class InstConfigData: msg_index = 4 def __init__(self): + self.file_parser = ConfigParser.SafeConfigParser() + self.config_filename = 'sics_config.ini' #configuration_dict: dict of instrument configurations as defined below, # {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} } self.configuration_dict = defaultdict(dict) @@ -287,11 +289,11 @@ class InstConfigData: print 'Add imp2opt_dict[{0}] = none'.format(sect) self.imp2opt_dict[sect] = 'none' - def read_config_file(self, config_filename): + def read_config_file(self, **kwargs): """ Load and parse a sics_config.ini file """ - self.config_filename = config_filename - self.file_parser = ConfigParser.SafeConfigParser() - self.file_parser.read(config_filename) + 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() @@ -317,7 +319,8 @@ class InstConfigData: 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, 'implementation', + opt_desc['selected_imp']) self.file_parser.set(opt, 'optype', opt_desc['imptype']) for config, config_desc in self.configuration_dict.iteritems(): @@ -593,7 +596,7 @@ def main(config_ini): # 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) From 9228dd2c0c8bbb8f5f51f22c607a8a3602c5a565 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 12:15:13 +1000 Subject: [PATCH 16/72] Remove unused variable. --- site_ansto/instrument/util/config_edit.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 7cf77579..bdb974a2 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -359,7 +359,7 @@ class InstConfigData: for imp in self.imp_dict[opt_desc['imptype']]: yield imp - def cf_statechange(self, cfg_id, new_state, udat=None): + def cf_statechange(self, cfg_id, new_state): """Change the given instrument configuration state.""" self.configuration_dict[cfg_id]['enabled'] = new_state @@ -498,12 +498,12 @@ class InstConfigManager: user_data=opt) return rb_lw - def cf_statechange(self, button, new_state, udat=None): + 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, udat) + self.cf_dat.cf_statechange(cfg_id, new_state) cascade = self.cf_dat.configuration_dict[cfg_id]['cascade_list'] if new_state == True: for opt in self.cf_dat.opt_dict.keys(): @@ -518,8 +518,8 @@ class InstConfigManager: self.opt_lw.button_dict[opt].set_state(True) DBG.msg(self.cf_msg_index, - 'InstConfigManager:cf_statechange({0},{1},{2}),cascade={3}'.format( - cfg_id, new_state, udat, cascade)) + 'InstConfigManager:cf_statechange({0},{1}):cascade={2}'.format( + cfg_id, new_state, cascade)) self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8 return From 80cc3350c53e74abef508d0d73cae73fa066bfc9 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 15:08:03 +1000 Subject: [PATCH 17/72] Experiment with "pylint: disable" to eliminate false positives from pylint. --- site_ansto/instrument/util/config_edit.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index bdb974a2..a4df0594 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -228,10 +228,15 @@ class InstConfigData: cascade_list = [] if self.file_parser.has_option(sect, 'cascade'): enabled = self.file_parser.get(sect, 'enabled') - for cascade_str in self.file_parser.get(sect, - 'cascade').split(','): + # 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 @@ -247,7 +252,9 @@ class InstConfigData: 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 From f1b13aa7c6a15a9413d1970547d9df15cbfdd0ff Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 18:27:45 +1000 Subject: [PATCH 18/72] Remove dependency of viewer on data and manager objects. It just requires listboxes for the layout. Also use new style class definition for InstConfigData and InstConfigManager. --- site_ansto/instrument/util/config_edit.py | 77 +++++++++++++---------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index a4df0594..44402e82 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -185,7 +185,7 @@ class ImpListBox(ClosedListBox): return -class InstConfigData: +class InstConfigData(object): """Handles reading and writing instrument configuration data and provides methods to change the configuration. @@ -392,52 +392,29 @@ class InstConfigView(urwid.Pile): """Extend urwid.Pile to provide an instrument configuration viewer. """ - def __init__(self, cf_dat, cf_man, dbmsg): + def __init__(self, config_lb, opt_lb, imp_lb, dbmsg): """ Args: - cf_dat: InstConfigData object. - cf_man: InstConfigManager object. + config_lb: Instrument configuration listbox + opt_lb: Configuration options listbox + imp_lb: Available implementations listbox """ - 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, + config_lb, + opt_lb, + imp_lb, dbmsg] super(InstConfigView, self).__init__(option_listboxes) return - def keyinput(self, 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() - 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) - else: - self.set_focus(self.cf_man.config_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) - else: - self.set_focus(self.cf_man.opt_lb) - # 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: +class InstConfigManager(object): """Provides controller which keeps data and viewer in sync. """ @@ -575,6 +552,35 @@ class InstConfigManager: return +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': + cf_dat.backup_files() + cf_dat.write_config_file() + elif key in ['right', 'tab']: + if cf_viewer.get_focus() == cf_man.config_lb: + cf_viewer.set_focus(cf_man.opt_lb) + elif cf_viewer.get_focus() == cf_man.opt_lb: + cf_viewer.set_focus(cf_man.imp_lb) + else: + cf_viewer.set_focus(cf_man.config_lb) + elif key in ['left', 'shift tab']: + if cf_viewer.get_focus() == cf_man.config_lb: + cf_viewer.set_focus(cf_man.imp_lb) + elif cf_viewer.get_focus() == cf_man.opt_lb: + cf_viewer.set_focus(cf_man.config_lb) + else: + cf_viewer.set_focus(cf_man.opt_lb) + + return keyinput + + class DEBUG: """DEBUG class""" msgTextDict = {} @@ -609,8 +615,11 @@ def main(config_ini): 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.config_lb, cf_man.opt_lb, cf_man.imp_lb, + DBG.mlb) + + keyinput = gen_input_handler(cf_man, cf_dat, cf_viewer) + urwid.MainLoop(cf_viewer, PALETTE, unhandled_input=keyinput).run() return if '__main__' == __name__: From 46b0e1a9a30bfe37d5b6a2012bdecd6193e0dc8e Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 20:09:15 +1000 Subject: [PATCH 19/72] Provide navigation context for __imp_unavailable method. --- site_ansto/instrument/util/config_edit.py | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 44402e82..f7b1c92e 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -445,7 +445,7 @@ class InstConfigManager(object): self.opt_lb.set_focus(0) return - def __imp_unavailable(self, opt, imp): + def __imp_unavailable(self, opt, imp, action): """Return True if an implementation is unavailable because it is used by an enabled option. """ @@ -457,10 +457,18 @@ class InstConfigManager(object): return False opt_imp = self.cf_dat.opt_dict[opt]['selected_imp'] - if opt_imp == imp: - return False - elif self.cf_dat.opt_dict[ckopt]['enabled']: - return True + 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 @@ -468,7 +476,7 @@ class InstConfigManager(object): """Generate the appropriate listwalker for the given option.""" imp_items = [] for imp in self.cf_dat.iter_implementations(opt): - if self.__imp_unavailable(opt, imp): + if self.__imp_unavailable(opt, imp, 'focus'): continue if imp == self.cf_dat.opt_dict[opt]['selected_imp']: imp_items.append((imp, True)) @@ -514,12 +522,14 @@ class InstConfigManager(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): + 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)) @@ -605,6 +615,7 @@ class DEBUG: DBG = DEBUG(enabled=True) def main(config_ini): + global cf_dat, cf_man, cf_viewer """Create configuration editor.""" # Make configuration data From 3ce563696f0aef305e7e18f61d1e40f4a91dffa0 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sun, 6 Jul 2014 20:15:41 +1000 Subject: [PATCH 20/72] Remove debug output and cleanup a bit. --- site_ansto/instrument/util/config_edit.py | 75 +++++------------------ 1 file changed, 16 insertions(+), 59 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index f7b1c92e..a051d82b 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -6,7 +6,7 @@ # View Screen has 3 parts # (Instrument Configuration), (Configuration Options), (Option Implementation) # Uses MVC as InstConfigData, InstConfigView, InstConfigManager -# + # InstConfigData <>--- ConfigParser.SafeConfig # |--set_cfparse() @@ -14,13 +14,12 @@ # |--set_cfdata(), set_presdata() # |--set_xyz_data() call self.cfgdata.set_xyz() methods # -# urwid.Frame + +# urwid.Pile # ^ +# | # InstConfigView <>--- InstConfigManager, PresentationData # |--set_cfedit(), set_presdata() -# -# PresentationData -# |--set_cfdata() import os @@ -131,8 +130,6 @@ class OptionListWalker(CheckBoxListWalker): def set_focus(self, pos): """Emit 'focus_change' signal with position of button. """ - 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) @@ -370,18 +367,12 @@ class InstConfigData(object): """Change the given instrument configuration state.""" self.configuration_dict[cfg_id]['enabled'] = new_state - def opt_statechange(self, opt, new_state, udat=None): + def opt_statechange(self, opt, new_state): """Change the given option state.""" - DBG.msg(3, - 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, - new_state, udat)) self.opt_dict[opt]['enabled'] = new_state def imp_statechange(self, selected_imp, new_state, opt): """Change the given implementation state.""" - DBG.msg(self.msg_index, - 'InstConfigData:imp_statechange({0},{1},{2})'.format(selected_imp, - new_state, opt)) self.msg_index = (self.msg_index - 3) % 2 + 4 if new_state == True: self.opt_dict[opt]['selected_imp'] = selected_imp @@ -392,18 +383,17 @@ class InstConfigView(urwid.Pile): """Extend urwid.Pile to provide an instrument configuration viewer. """ - def __init__(self, config_lb, opt_lb, imp_lb, dbmsg): + def __init__(self, cfg_lb, opt_lb, imp_lb): """ Args: - config_lb: Instrument configuration listbox + cfg_lb: Instrument configuration listbox opt_lb: Configuration options listbox imp_lb: Available implementations listbox """ option_listboxes = [ - config_lb, + cfg_lb, opt_lb, - imp_lb, - dbmsg] + imp_lb] super(InstConfigView, self).__init__(option_listboxes) return @@ -419,7 +409,6 @@ class InstConfigManager(object): """Provides controller which keeps data and viewer in sync. """ - cf_msg_index = 8 def __init__(self, cf_dat): self.cf_dat = cf_dat urwid.register_signal(InstConfigManager, ['focus_change']) @@ -440,7 +429,7 @@ class InstConfigManager(object): item_states.sort() self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange) - self.config_lb = OptionListBox(self.cfg_lw) + self.cfg_lb = OptionListBox(self.cfg_lw) self.opt_lb = OptionListBox(self.opt_lw) self.opt_lb.set_focus(0) return @@ -509,10 +498,6 @@ class InstConfigManager(object): if self.cf_dat.opt_dict[opt]['permanent'] == True: self.opt_lw.button_dict[opt].set_state(True) - DBG.msg(self.cf_msg_index, - 'InstConfigManager:cf_statechange({0},{1}):cascade={2}'.format( - cfg_id, new_state, cascade)) - self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8 return def opt_statechange(self, button, new_state, udat=None): @@ -535,7 +520,7 @@ class InstConfigManager(object): opt_button.set_label('{0}:{1}'.format(opt, imp)) self.cf_dat.set_imp(opt, imp) - self.cf_dat.opt_statechange(opt, 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 @@ -554,9 +539,6 @@ class InstConfigManager(object): """Update implementation list when an option gets focus.""" optname = self.opt_optype_list[pos][0] optype = self.opt_optype_list[pos][1] - mstr = 'InstConfigManager:update_imp_lb({0})->select{1}'.format(pos, - optype) - DBG.msg(1, mstr) self.imp_lw = self.__gen_imp_listwalker(optname) self.imp_lb.use_listwalker(self.imp_lw) return @@ -574,48 +556,24 @@ def gen_input_handler(cf_man, cf_dat, cf_viewer): cf_dat.backup_files() cf_dat.write_config_file() elif key in ['right', 'tab']: - if cf_viewer.get_focus() == cf_man.config_lb: + if cf_viewer.get_focus() == cf_man.cfg_lb: cf_viewer.set_focus(cf_man.opt_lb) elif cf_viewer.get_focus() == cf_man.opt_lb: cf_viewer.set_focus(cf_man.imp_lb) else: - cf_viewer.set_focus(cf_man.config_lb) + cf_viewer.set_focus(cf_man.cfg_lb) elif key in ['left', 'shift tab']: - if cf_viewer.get_focus() == cf_man.config_lb: + if cf_viewer.get_focus() == cf_man.cfg_lb: cf_viewer.set_focus(cf_man.imp_lb) elif cf_viewer.get_focus() == cf_man.opt_lb: - cf_viewer.set_focus(cf_man.config_lb) + cf_viewer.set_focus(cf_man.cfg_lb) else: cf_viewer.set_focus(cf_man.opt_lb) return keyinput -class DEBUG: - """DEBUG class""" - 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 msg_id in self.msg_ids: - msg_text = urwid.Text(u'Space for message {0}'.format(msg_id)) - self.msgTextDict[msg_id] = msg_text - self.msglist.append(urwid.AttrMap(msg_text, 'body', 'focus')) - - mlw = urwid.SimpleListWalker(self.msglist) - self.mlb = urwid.ListBox(mlw) - - def msg(self, index, msg): - """Debug message.""" - if self.enabled: - mid = self.msg_ids[index] - self.msgTextDict[mid].set_text(msg) - -DBG = DEBUG(enabled=True) def main(config_ini): - global cf_dat, cf_man, cf_viewer """Create configuration editor.""" # Make configuration data @@ -626,8 +584,7 @@ def main(config_ini): cf_man = InstConfigManager(cf_dat) # Make configuration viewer - cf_viewer = InstConfigView(cf_man.config_lb, cf_man.opt_lb, cf_man.imp_lb, - DBG.mlb) + 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) urwid.MainLoop(cf_viewer, PALETTE, unhandled_input=keyinput).run() From cc39cc08fe2c4d8c7e5b9b4571cc8e6225eecccf Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Mon, 7 Jul 2014 09:15:54 +1000 Subject: [PATCH 21/72] Select sample changer from sics_config.ini --- .../config/motors/positmotor_configuration.tcl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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 { From 8a8a08e57fe1e350dcd34a965a8d264e712266b8 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Mon, 7 Jul 2014 10:22:06 +1000 Subject: [PATCH 22/72] Add sics_config.ini to quokka. --- .../instrument/sans/util/sics_config.ini | 295 ++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 site_ansto/instrument/sans/util/sics_config.ini 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..989f44b1 --- /dev/null +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -0,0 +1,295 @@ +[sample_stage] +enabled = Always +implementation = normal_sample_stage +name = sample_stage +optype = motion_axis + +[12tmagnet_oxford] +desc = "12 Tesla Oxford Magnet" +driver = "oxford_labview" +imptype = magnetic_field +ip = 10.157.205.3 +port = 55001 + +[bruker_bec1] +desc = "Bruker Magnet" +driver = "bruker_bec1" +type = B +imptype = magnetic_field +ip = XXXX +port = XXXX + +[rhqc_setup] +cascade = sample_stage:normal_sample_stage,T1:ls340_01,T2:ls340_02 +enabled = False + +[bruker_setup] +cascade = B1:bruker_bec1,sample_stage:normal_sample_stage,T1:julabo_lh45 +enabled = False + +[12Tmagnet_setup] +cascade = B1:12tmagnet_oxford,sample_stage:Oxford_12tmagnet_sample_insert,T1:mercury_scpi_01 +enabled = False + +[10_position_setup] +cascade = T1:watlow_rm,sample_stage:10_pos_sample_stage +enabled = False + +[20_position_setup] +cascade = T1:julabo_lh45,sample_stage:20_pos_sample_stage +enabled = False + +[B1] +enabled = False +id = 1 +implementation = none +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" +imptype = temperature +ip = 10.157.205.43 +port = 4001 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[Default] +cascade = sample_stage:normal_sample_stage +enabled = True + +[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 + +[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 + +[T1] +enabled = False +id = 1 +implementation = none +name = tc1 +optype = temperature + +[T2] +enabled = False +id = 2 +implementation = none +name = tc2 +optype = temperature + +[T3] +enabled = False +id = 3 +implementation = none +name = tc3 +optype = temperature + +[T4] +enabled = False +id = 4 +implementation = none +name = tc4 +optype = temperature + +[T5] +enabled = False +id = 5 +implementation = none +name = tc5 +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 + +[ls336_01] +desc = "tc1: Lakeshore 336 temperature controller" +driver = "lakeshore_336" +imptype = temperature +ip = 10.157.205.28 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_02] +desc = "tc2: Lakeshore 336 temperature controller" +driver = "lakeshore_336" +imptype = temperature +ip = 10.157.205.29 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_04] +desc = "tc3: Lakeshore 336 temperature controller" +driver = "lakeshore_336" +imptype = temperature +ip = 10.157.205.30 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_05] +desc = "tc4: Lakeshore 336 temperature controller" +driver = "lakeshore_336" +imptype = temperature +ip = 137.157.201.21 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_06] +desc = "tc5: Lakeshore 336 temperature controller" +driver = "lakeshore_336" +imptype = temperature +ip = 137.157.201.21 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls336_12] +desc = "tc6: Lakeshore 336 temperature controller" +driver = "lakeshore_336" +imptype = temperature +ip = 10.157.205.31 +port = 7777 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls340_01] +desc = "tc7: Lakeshore 340 temperature controller" +driver = "lakeshore_340" +id = 2 +imptype = temperature +ip = 137.157.201.86 +port = 4001 +terminator = \r\n +tol1 = 1.0 +tol2 = 1.0 + +[ls340_02] +desc = "tc8: Lakeshore 340 temperature controller" +driver = "lakeshore_340" +imptype = temperature +ip = 137.157.201.86 +port = 4002 +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 + +[normal_sample_stage] +desc = "This is the default sample stage configuration xyz translation omega rotation but no tilt axes" +imptype = motion_axis + +[10_pos_sample_stage] +desc = "Load the ten position sample changer configuration" +imptype = motion_axis + +[20_pos_sample_stage] +desc = "Load the twenty position sample changer configuration" +imptype = motion_axis + +[protek_01] +desc = "Protek Multimeter" +driver = "protek" +imptype = multimeter +ip = 10.157.205.36 +port = 4001 + +[protek_02] +desc = "Protek Multimeter" +driver = "protek" +imptype = multimeter +ip = 10.157.205.37 +port = 4001 + +[sample_stage] +enabled = Always +implementation = normal_sample_stage +name = sample_stage +optype = motion_axis + +[west4100] +desc = "Blue furnace temperature controller" +driver = "west4100" +imptype = temperature +ip = 10.157.205.19 + +[julabo_lh45] +desc = "Julabo temperature controller" +driver = "julabo_lh45" +imptype = temperature +ip = ca4-quokka +port = 4003 +terminator = \r\n +tol = 0.5 + +[watlow_rm] +desc = "Watlow RM temperature controller" +driver = "watlow_rm" +imptype = temperature +ip = 10.157.205.6 +terminator = \r\n +tol = 0.5 +type = T From 71931299564b85211772d7f399be7ef394b87bd2 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Mon, 7 Jul 2014 10:25:09 +1000 Subject: [PATCH 23/72] Set bruker IP address and port --- site_ansto/instrument/sans/util/sics_config.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site_ansto/instrument/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini index 989f44b1..a83b0624 100644 --- a/site_ansto/instrument/sans/util/sics_config.ini +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -16,8 +16,8 @@ desc = "Bruker Magnet" driver = "bruker_bec1" type = B imptype = magnetic_field -ip = XXXX -port = XXXX +ip = 10.157.205.13 +port = 4444 [rhqc_setup] cascade = sample_stage:normal_sample_stage,T1:ls340_01,T2:ls340_02 From 47d5604e1ecd03ab4c1a95c2db7b6bd21131d775 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 7 Jul 2014 13:58:08 +1000 Subject: [PATCH 24/72] Make the Julabo work for asyncqueue adapters --- .../environment/temperature/sct_julabo_lh45.tcl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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..5c21a3e6 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" { @@ -518,4 +524,3 @@ if { [info exists ::config_dict] } { } -namespace import ::scobj::lh45::* From 737e56670b4e5d7df6d07cd47f570ea180e6e15e Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 7 Jul 2014 13:59:03 +1000 Subject: [PATCH 25/72] Use shutil.copy2 to preserve file dates --- site_ansto/instrument/util/config_edit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index a051d82b..c94e7d9a 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -312,7 +312,7 @@ class InstConfigData(object): self.config_filename + "." + str(idx + 1)) if os.path.exists(self.config_filename): - shutil.copy(self.config_filename, self.config_filename + ".1") + shutil.copy2(self.config_filename, self.config_filename + ".1") def write_config_file(self): """ Write out InstConfigData values to the configuration file.""" From 852f87f13136b98847600e4411358f9cd83a4c13 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 7 Jul 2014 13:59:41 +1000 Subject: [PATCH 26/72] Sort and massage Quokka's sics_config.ini --- .../instrument/sans/util/sics_config.ini | 102 +++++++++--------- 1 file changed, 49 insertions(+), 53 deletions(-) diff --git a/site_ansto/instrument/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini index a83b0624..e4712f48 100644 --- a/site_ansto/instrument/sans/util/sics_config.ini +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -1,8 +1,14 @@ -[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 + +[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 [12tmagnet_oxford] desc = "12 Tesla Oxford Magnet" @@ -11,29 +17,9 @@ imptype = magnetic_field ip = 10.157.205.3 port = 55001 -[bruker_bec1] -desc = "Bruker Magnet" -driver = "bruker_bec1" -type = B -imptype = magnetic_field -ip = 10.157.205.13 -port = 4444 - -[rhqc_setup] -cascade = sample_stage:normal_sample_stage,T1:ls340_01,T2:ls340_02 -enabled = False - -[bruker_setup] -cascade = B1:bruker_bec1,sample_stage:normal_sample_stage,T1:julabo_lh45 -enabled = False - -[12Tmagnet_setup] -cascade = B1:12tmagnet_oxford,sample_stage:Oxford_12tmagnet_sample_insert,T1:mercury_scpi_01 -enabled = False - -[10_position_setup] -cascade = T1:watlow_rm,sample_stage:10_pos_sample_stage -enabled = False +[20_pos_sample_stage] +desc = "Load the twenty position sample changer configuration" +imptype = motion_axis [20_position_setup] cascade = T1:julabo_lh45,sample_stage:20_pos_sample_stage @@ -135,6 +121,28 @@ implementation = none name = volts2 optype = multimeter +[bruker_bec1] +desc = "Bruker Magnet" +driver = "bruker_bec1" +imptype = magnetic_field +ip = 10.157.205.13 +port = 4444 +type = B + +[bruker_setup] +cascade = B1:bruker_bec1,sample_stage:normal_sample_stage,T1:julabo_lh45 +enabled = False + +[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] desc = "tc1: Lakeshore 336 temperature controller" driver = "lakeshore_336" @@ -242,49 +250,30 @@ valve_tol = 2 desc = "This is the default sample stage configuration xyz translation omega rotation but no tilt axes" imptype = motion_axis -[10_pos_sample_stage] -desc = "Load the ten position sample changer configuration" -imptype = motion_axis - -[20_pos_sample_stage] -desc = "Load the twenty position sample changer configuration" -imptype = motion_axis - [protek_01] desc = "Protek Multimeter" -driver = "protek" +driver = "protekmm" imptype = multimeter ip = 10.157.205.36 port = 4001 [protek_02] desc = "Protek Multimeter" -driver = "protek" +driver = "protekmm" imptype = multimeter ip = 10.157.205.37 port = 4001 +[rhqc_setup] +cascade = sample_stage:normal_sample_stage,T1:ls340_01,T2:ls340_02 +enabled = False + [sample_stage] enabled = Always implementation = normal_sample_stage name = sample_stage optype = motion_axis -[west4100] -desc = "Blue furnace temperature controller" -driver = "west4100" -imptype = temperature -ip = 10.157.205.19 - -[julabo_lh45] -desc = "Julabo temperature controller" -driver = "julabo_lh45" -imptype = temperature -ip = ca4-quokka -port = 4003 -terminator = \r\n -tol = 0.5 - [watlow_rm] desc = "Watlow RM temperature controller" driver = "watlow_rm" @@ -293,3 +282,10 @@ ip = 10.157.205.6 terminator = \r\n tol = 0.5 type = T + +[west4100] +desc = "Blue furnace temperature controller" +driver = "west4100" +imptype = temperature +ip = 10.157.205.19 + From cc5400c5958a7a2b6e76cb6a12903932dd524ce0 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 7 Jul 2014 14:48:12 +1000 Subject: [PATCH 27/72] Pull back changes in Kookaburra config --- .../kookaburra/config/hmm/hmm_configuration.tcl | 12 ++++++++++++ .../kookaburra/config/motors/motor_configuration.tcl | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) 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\ From f6dfc76ada72f2a922b1e32dfb62f8372f2f4613 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Wed, 9 Jul 2014 15:01:21 +1000 Subject: [PATCH 28/72] Pull back changes from Dingo --- .../dingo/camtest_configuration.tcl | 4 +- .../dingo/config/counter/counter.tcl | 16 +- .../config/motors/motor_configuration.tcl | 223 ++++++++++-------- .../instrument/dingo/config/plc/plc.tcl | 80 ++++++- .../instrument/dingo/config/scan/scan.tcl | 146 +++++++++++- .../instrument/dingo/dingo_configuration.tcl | 42 +--- .../instrument/dingo/hostport_config.tcl | 3 +- 7 files changed, 373 insertions(+), 141 deletions(-) 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..21cd1ba9 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,93 @@ 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 0.01\ + hardupperlim 359.99\ + 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 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 +207,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 +241,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 From f05bf2e7db8268f67c120200447be72470da013c Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Wed, 9 Jul 2014 15:02:24 +1000 Subject: [PATCH 29/72] Change Dingo stth for multi-turn rotary encoder --- .../dingo/config/motors/motor_configuration.tcl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl b/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl index 21cd1ba9..07129102 100644 --- a/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl +++ b/site_ansto/instrument/dingo/config/motors/motor_configuration.tcl @@ -148,8 +148,8 @@ Motor stth $motor_driver_type [params \ port pmc1-dingo\ axis D\ units degree\ - hardlowerlim 0.01\ - hardupperlim 359.99\ + hardlowerlim -722\ + hardupperlim 722\ maxSpeed 0.12\ maxAccel 1\ maxDecel 1\ @@ -166,8 +166,9 @@ stth long_name stth stth softlowerlim 0.01 stth softupperlim 359.99 stth home 0 -stth bias_bits 25 -stth bias_bias -33432264 +#stth bias_bits 25 +#stth bias_bias -33432264 +stth rotary_bits 25 stth creep_offset 0.05 # mc1: detection Z-stage Translation From cd80f567fe37eeb8f142ce842d97b636a611a9fb Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Thu, 10 Jul 2014 13:13:57 +1000 Subject: [PATCH 30/72] Only do the rotary_bits if the previous counts is valid This saves decrementing it the first time through because it is in the fourth quadrant and the initial value (zero) is in the first. --- site_ansto/motor_dmc2280.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/site_ansto/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index 4640a517..08db73c6 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; @@ -1800,7 +1801,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 +1849,7 @@ static int rspStatus(pDMC2280Driv self, const char* text) { else self->stopCode = 1; } + self->status_valid = true; return 1; } From cc6634abe9bf80d4a503c67249f29ef895dcc0c7 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 8 Jul 2014 17:57:45 +1000 Subject: [PATCH 31/72] The implementation field is set only if an option is enabled in the config file. All other options should be shown as disabled with 'none' as the implementation. Conflicts between enabled options are resolved in favour of the first option returned by the ConfigParser which isn't necessarily the first enabled option in the file. Only enabled options are mapped in the imp2opt_dict dictionary. --- site_ansto/instrument/util/config_edit.py | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index c94e7d9a..98f5b96d 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -266,17 +266,20 @@ class InstConfigData(object): _id = self.file_parser.get(sect, 'id') self.opt_dict[sect]['id'] = _id - self.opt_dict[sect]['enabled'] = stateval self.opt_dict[sect]['permanent'] = permanent self.opt_dict[sect]['imptype'] = imptype - if selected_imp in self.imp2opt_dict: - self.opt_dict[sect]['selected_imp'] = 'none' - else: - self.opt_dict[sect]['selected_imp'] = selected_imp - if selected_imp != 'none': - print 'Add imp2opt_dict[{0}]={1}'.format( - selected_imp, sect) + if stateval == True: + if selected_imp == 'none' or (selected_imp in self.imp2opt_dict): + self.opt_dict[sect]['enabled'] = False + self.opt_dict[sect]['selected_imp'] = 'none' + else: + self.opt_dict[sect]['enabled'] = True + self.opt_dict[sect]['selected_imp'] = selected_imp self.imp2opt_dict[selected_imp] = sect + print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp, sect) + else: + self.opt_dict[sect]['enabled'] = False + self.opt_dict[sect]['selected_imp'] = 'none' def __get_implementations(self): """Parse implementation lists from INI file into imp_dict attribute of @@ -285,13 +288,13 @@ class InstConfigData(object): for sect in self.file_parser.sections(): if self.file_parser.has_option(sect, 'imptype'): key = self.file_parser.get(sect, 'imptype') - if 'none' not in self.imp_dict[key]: - self.imp_dict[key].append('none') - self.imp_dict[key].append(sect) + if 'none' not in self.imp_dict[key]: + self.imp_dict[key].insert(0, 'none') + if sect not in self.imp2opt_dict: - print 'Add imp2opt_dict[{0}] = none'.format(sect) self.imp2opt_dict[sect] = 'none' + print 'Add imp2opt_dict[{0}] = none'.format(sect) def read_config_file(self, **kwargs): """ Load and parse a sics_config.ini file """ From dee4b0430e250c5df3be3180df153160632fa08d Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 8 Jul 2014 18:36:15 +1000 Subject: [PATCH 32/72] The order that __get_options() and __get_implementations() are called in shouldn't matter. --- site_ansto/instrument/util/config_edit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 98f5b96d..0ab6a1fe 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -269,7 +269,7 @@ class InstConfigData(object): self.opt_dict[sect]['permanent'] = permanent self.opt_dict[sect]['imptype'] = imptype if stateval == True: - if selected_imp == 'none' or (selected_imp in self.imp2opt_dict): + if selected_imp == 'none' or (selected_imp in self.imp2opt_dict) and self.imp2opt_dict[selected_imp] != 'none': self.opt_dict[sect]['enabled'] = False self.opt_dict[sect]['selected_imp'] = 'none' else: From a294d50a1d1528c0ce737990a7fd2397740c552b Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 8 Jul 2014 19:33:29 +1000 Subject: [PATCH 33/72] A bit of refactoring, a bit of housekeeping. Make Pylint happy. Mmmmm nice. --- site_ansto/instrument/util/config_edit.py | 41 +++++++++++++---------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 0ab6a1fe..5a6a8d8d 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -187,7 +187,7 @@ class InstConfigData(object): """Handles reading and writing instrument configuration data and provides methods to change the configuration. Attributes: - configuration_dict: Instrument configurations by configuration name. + config_dict: Instrument configurations by configuration name. opt_dict: Configuration option descriptions indexed by option name. imp_dict: Implementations for indexed by option type. """ @@ -197,9 +197,9 @@ class InstConfigData(object): def __init__(self): self.file_parser = ConfigParser.SafeConfigParser() self.config_filename = 'sics_config.ini' - #configuration_dict: dict of instrument configurations as defined below, + #config_dict: dict of instrument configurations as defined below, # {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} } - self.configuration_dict = defaultdict(dict) + self.config_dict = defaultdict(dict) #imp_dict: dict of implementations indexed by optype, # {optype: [impname] } @@ -219,7 +219,7 @@ class InstConfigData(object): def __get_configurations(self): """Parse instrument configuration definitions from INI file into - configuration_dict attribute of InstConfigData object + config_dict attribute of InstConfigData object """ for sect in self.file_parser.sections(): cascade_list = [] @@ -238,8 +238,8 @@ class InstConfigData(object): else: stateval = False - self.configuration_dict[sect]['enabled'] = stateval - self.configuration_dict[sect]['cascade_list'] = cascade_list + self.config_dict[sect]['enabled'] = stateval + self.config_dict[sect]['cascade_list'] = cascade_list def __get_options(self): """Parse configuration options from INI file into opt_dict attribute of @@ -269,14 +269,17 @@ class InstConfigData(object): self.opt_dict[sect]['permanent'] = permanent self.opt_dict[sect]['imptype'] = imptype if stateval == True: - if selected_imp == 'none' or (selected_imp in self.imp2opt_dict) and self.imp2opt_dict[selected_imp] != 'none': + 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.opt_dict[sect]['selected_imp'] = selected_imp self.imp2opt_dict[selected_imp] = sect - print 'Add imp2opt_dict[{0}] = {1}'.format(selected_imp, sect) + 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' @@ -287,10 +290,8 @@ class InstConfigData(object): """ for sect in self.file_parser.sections(): if self.file_parser.has_option(sect, 'imptype'): - key = self.file_parser.get(sect, 'imptype') - self.imp_dict[key].append(sect) - if 'none' not in self.imp_dict[key]: - self.imp_dict[key].insert(0, 'none') + imptype = self.file_parser.get(sect, 'imptype') + self.imp_dict[imptype].append(sect) if sect not in self.imp2opt_dict: self.imp2opt_dict[sect] = 'none' @@ -307,6 +308,10 @@ class InstConfigData(object): 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): @@ -330,7 +335,7 @@ class InstConfigData(object): opt_desc['selected_imp']) self.file_parser.set(opt, 'optype', opt_desc['imptype']) - for config, config_desc in self.configuration_dict.iteritems(): + for config, config_desc in self.config_dict.iteritems(): enabled = config_desc['enabled'].__str__() self.file_parser.set(config, 'enabled', enabled) @@ -368,7 +373,7 @@ class InstConfigData(object): def cf_statechange(self, cfg_id, new_state): """Change the given instrument configuration state.""" - self.configuration_dict[cfg_id]['enabled'] = new_state + self.config_dict[cfg_id]['enabled'] = new_state def opt_statechange(self, opt, new_state): """Change the given option state.""" @@ -428,7 +433,7 @@ class InstConfigManager(object): 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.configuration_dict.iteritems()] + cf_dat.config_dict.iteritems()] item_states.sort() self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange) @@ -488,7 +493,7 @@ class InstConfigManager(object): """ cfg_id = button.get_label() self.cf_dat.cf_statechange(cfg_id, new_state) - cascade = self.cf_dat.configuration_dict[cfg_id]['cascade_list'] + cascade = self.cf_dat.config_dict[cfg_id]['cascade_list'] if new_state == True: for opt in self.cf_dat.opt_dict.keys(): self.opt_lw.button_dict[opt].set_state(False) @@ -503,7 +508,7 @@ class InstConfigManager(object): return - def opt_statechange(self, button, new_state, udat=None): + def opt_statechange(self, button, new_state): """Update option label when it changes state and notify InstConfigData object. """ @@ -541,7 +546,6 @@ class InstConfigManager(object): def update_imp_lb(self, pos): """Update implementation list when an option gets focus.""" optname = self.opt_optype_list[pos][0] - optype = self.opt_optype_list[pos][1] self.imp_lw = self.__gen_imp_listwalker(optname) self.imp_lb.use_listwalker(self.imp_lw) return @@ -578,6 +582,7 @@ def gen_input_handler(cf_man, cf_dat, cf_viewer): def main(config_ini): """Create configuration editor.""" +# global cf_dat, cf_man, cf_viewer # Make configuration data cf_dat = InstConfigData() From b5d3b745c312523b7ca0474a7e69420d132f3c03 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 8 Jul 2014 20:23:18 +1000 Subject: [PATCH 34/72] Don't allow the implementation of permanent options to be set to 'none'. --- site_ansto/instrument/util/config_edit.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 5a6a8d8d..dee80282 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -475,6 +475,9 @@ class InstConfigManager(object): 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: From 1b4cca9390aca13df31b6ca5474e734ffab02ffa Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 9 Jul 2014 09:41:09 +1000 Subject: [PATCH 35/72] Options not in the cascade list should have their implementation set to 'none' --- site_ansto/instrument/util/config_edit.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index dee80282..a011619c 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -509,6 +509,10 @@ class InstConfigManager(object): 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)) + return def opt_statechange(self, button, new_state): From 9be5cc4cec67a5225a151d86db588bdd1dd9f446 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 10 Jul 2014 04:34:26 +1000 Subject: [PATCH 36/72] set_imp now works in initialisation code and makes sure that 'none' is not used as a key in imp2opt_dict. Also provide consistency_check() method to check that there is a one to one mapping between options and implementations. --- site_ansto/instrument/util/config_edit.py | 42 ++++++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index a011619c..8df2c32f 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -276,8 +276,7 @@ class InstConfigData(object): self.opt_dict[sect]['selected_imp'] = 'none' else: self.opt_dict[sect]['enabled'] = True - self.opt_dict[sect]['selected_imp'] = selected_imp - self.imp2opt_dict[selected_imp] = sect + self.set_imp(sect, selected_imp) dbmsg = 'Add imp2opt_dict[{0}] = {1}' print dbmsg.format(selected_imp, sect) else: @@ -297,6 +296,34 @@ class InstConfigData(object): 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 opt == 'none': + continue + elif imp == 'none': + print 'ERROR: Found "none" as a keyword in imp2opt_dict' + 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: @@ -305,6 +332,7 @@ class InstConfigData(object): self.__get_options() self.__get_implementations() self.__get_configurations() + self.consistency_check() for opt, opt_desc in self.opt_dict.iteritems(): self.optypelist.append((opt, opt_desc['imptype'])) @@ -356,10 +384,13 @@ class InstConfigData(object): def set_imp(self, opt, new_imp): """Keep option dictionaray and implementation -> option map in sync.""" - old_imp = self.opt_dict[opt]['selected_imp'] - self.imp2opt_dict[old_imp] = 'none' + if 'selected_imp' in self.opt_dict[opt]: + old_imp = self.opt_dict[opt]['selected_imp'] + self.imp2opt_dict[old_imp] = 'none' + self.opt_dict[opt]['selected_imp'] = new_imp - self.imp2opt_dict[new_imp] = opt + if new_imp != 'none': + self.imp2opt_dict[new_imp] = opt def get_optypelist (self): """Return a list of (option, optype) tuples.""" @@ -488,6 +519,7 @@ class InstConfigManager(object): rb_lw = RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) + return rb_lw def cf_statechange(self, button, new_state): From 8953273dacfe5ac83bc596c571b1c264e98b8997 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 10 Jul 2014 05:35:41 +1000 Subject: [PATCH 37/72] Show IP address and PORT number for implmentations that have them. --- site_ansto/instrument/util/config_edit.py | 28 +++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 8df2c32f..0f830c62 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -202,13 +202,17 @@ class InstConfigData(object): self.config_dict = defaultdict(dict) #imp_dict: dict of implementations indexed by optype, - # {optype: [impname] } + # {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 = {} @@ -291,6 +295,13 @@ class InstConfigData(object): 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 + + 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' @@ -520,6 +531,19 @@ class InstConfigManager(object): 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 + + 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): @@ -573,7 +597,7 @@ class InstConfigManager(object): """Update label on the configuration option when it's implementation is changed. """ - imp = button.get_label() + 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] From d79865edb4707394ad640119cd044145502954aa Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 10 Jul 2014 06:42:43 +1000 Subject: [PATCH 38/72] Write sections to the configuration file in the same order as the screen layout. --- site_ansto/instrument/util/config_edit.py | 35 +++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 0f830c62..856af673 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -323,11 +323,11 @@ class InstConfigData(object): print emsg.format(i=selected_imp, o=opt) for imp, opt in self.imp2opt_dict.iteritems(): - if opt == 'none': - continue - elif imp == 'none': + 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'] @@ -361,6 +361,12 @@ class InstConfigData(object): if os.path.exists(self.config_filename): 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): """ Write out InstConfigData values to the configuration file.""" for opt, opt_desc in self.opt_dict.iteritems(): @@ -382,22 +388,27 @@ class InstConfigData(object): if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) - 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( - '{0} = {1}\n'.format(option, - self.file_parser.get(section, - option))) + 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") + os.rename(scratch_file, self.config_filename) + 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'] - self.imp2opt_dict[old_imp] = 'none' + if old_imp != 'none': + self.imp2opt_dict[old_imp] = 'none' self.opt_dict[opt]['selected_imp'] = new_imp if new_imp != 'none': From 6aa229ee75f5621bb1856e051abb77892ca850ed Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Thu, 10 Jul 2014 09:56:09 +1000 Subject: [PATCH 39/72] Driver changes made on ics1-wombat-test. --- .../magneticField/sct_oxford_labview.tcl | 11 +- .../config/environment/sct_protek_common.tcl | 10 +- .../temperature/sct_lakeshore_336.tcl | 257 +++++++++--------- .../temperature/sct_lakeshore_340.tcl | 13 +- .../instrument/hipd/util/sics_config.ini | 166 +++++------ 5 files changed, 243 insertions(+), 214 deletions(-) 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/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index 23ec88d8..08a23bfb 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -197,6 +197,9 @@ proc ::scobj::add_protekmm::read_config {} { set name [dict get $v name] set enabled [string tolower [dict get $v "enabled"]] set implementation [dict get $v "implementation"] + if [dict exists $v "datype"] { + set datype [dict get $v "datype"] + } if { !([dict exists $::config_dict $implementation]) } { continue } @@ -205,6 +208,8 @@ proc ::scobj::add_protekmm::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "protekmm"] } { + 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" @@ -216,6 +221,7 @@ proc ::scobj::add_protekmm::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"]" @@ -225,13 +231,14 @@ proc ::scobj::add_protekmm::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"]" } } set arg_list [list] - foreach arg {name ip port datype id scale offset interval} { + foreach arg {id} { if {[dict exists $v $arg]} { lappend arg_list "[dict get $v $arg]" } else { @@ -239,6 +246,7 @@ proc ::scobj::add_protekmm::read_config {} { error "Missing configuration value $arg" } } + ${ns}:sics_log 9 "add_protekmm ${name} aqadapter ${asyncqueue} {*}$arg_list" add_protekmm ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } 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..872cf795 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 ]} { @@ -1628,84 +1628,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 +1896,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 @@ -1945,6 +1945,8 @@ proc ::scobj::lakeshore_336::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "lakeshore_336"] } { + 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" @@ -1956,6 +1958,7 @@ proc ::scobj::lakeshore_336::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"]" @@ -1965,6 +1968,7 @@ proc ::scobj::lakeshore_336::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"]" @@ -1979,6 +1983,7 @@ proc ::scobj::lakeshore_336::read_config {} { error "Missing configuration value $arg" } } + ${ns}::sics_log 9 "add_lakeshore_336 ${name} aqadapter ${asyncqueue} {*}$arg_list" add_lakeshore_336 ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } 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..a72830b1 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl @@ -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 @@ -2127,8 +2127,8 @@ proc ::scobj::lakeshore_340::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_lakeshore_340.tcl" +::scobj::lakeshore_340::sics_log 9 "file evaluation of sct_lakeshore_340.tcl" proc ::scobj::lakeshore_340::read_config {} { set catch_status [ catch { @@ -2149,6 +2149,8 @@ proc ::scobj::lakeshore_340::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "lakeshore_340"] } { + 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" @@ -2160,6 +2162,7 @@ proc ::scobj::lakeshore_340::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"]" @@ -2169,6 +2172,7 @@ proc ::scobj::lakeshore_340::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"]" @@ -2183,6 +2187,7 @@ proc ::scobj::lakeshore_340::read_config {} { error "Missing configuration value $arg" } } + ${ns}::sics_log 9 "add_lakeshore_340 ${name} aqadapter ${asyncqueue} {*}$arg_list" add_lakeshore_340 ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 05918e29..73948379 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -1,3 +1,87 @@ +[12tmagnet_setup] +cascade = B1:12tmagnet_oxford,sample_stage:12tmagnet_sample_insert,T1:mercury_scpi_01 +enabled = False +[CF1] +cascade = T1:CF1_ls340,sample_stage:normal_sample_stage +enabled = False +[Default] +cascade = sample_stage:normal_sample_stage +enabled = True +[B1] +enabled = False +id = 1 +implementation = none +name = magnet1 +optype = magnetic_field +[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] +enabled = False +id = 1 +implementation = none +name = tc1 +optype = temperature +[T2] +enabled = False +id = 2 +implementation = none +name = tc2 +optype = temperature +[T3] +enabled = False +id = 3 +implementation = none +name = tc3 +optype = temperature +[T4] +enabled = False +id = 4 +implementation = none +name = tc4 +optype = temperature +[T5] +enabled = False +id = 5 +implementation = none +name = tc5 +optype = temperature +[T6] +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" @@ -10,21 +94,6 @@ 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_01 -enabled = False - -[B1] -enabled = False -id = 1 -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" @@ -35,63 +104,6 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 -[Default] -cascade = sample_stage:normal_sample_stage -enabled = True - -[I1] -datype = I -enabled = False -id = 1 -implementation = protek_01 -name = curr1 -optype = multimeter - -[I2] -datype = I -enabled = False -id = 2 -implementation = protek_02 -name = curr2 -optype = multimeter - -[T1] -enabled = False -id = 1 -implementation = mercury_scpi_01 -name = tc1 -optype = temperature - -[T2] -enabled = False -id = 2 -implementation = ls340_01 -name = tc2 -optype = temperature - -[T3] -enabled = False -id = 3 -implementation = ls340_02 -name = tc3 -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 - [eularian_cradle] desc = "Load the Eulerian cradle configuration" imptype = motion_axis @@ -207,7 +219,7 @@ imptype = motion_axis [protek_01] desc = "Protek Multimeter" -driver = "protek" +driver = "protekmm" id = 1 imptype = multimeter ip = 10.157.205.36 @@ -215,18 +227,12 @@ port = 4001 [protek_02] desc = "Protek Multimeter" -driver = "protek" +driver = "protekmm" id = 2 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 From 679651bd28f05d28ceadbc1f73faf1348232e610 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 11 Jul 2014 08:41:10 +1000 Subject: [PATCH 40/72] Add some help and feedback when saving a file. --- site_ansto/instrument/util/config_edit.py | 58 ++++++++++++++++------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 856af673..18738412 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -32,7 +32,7 @@ from collections import defaultdict PALETTE = [ ('body', 'dark cyan', '', 'standout'), ('focus', 'dark red', '', 'standout'), - ('head', 'light red', 'black'), + ('head', 'yellow', 'black'), ] @@ -281,8 +281,8 @@ class InstConfigData(object): 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) +# 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' @@ -305,7 +305,7 @@ class InstConfigData(object): if sect not in self.imp2opt_dict: self.imp2opt_dict[sect] = 'none' - print 'Add imp2opt_dict[{0}] = none'.format(sect) +# print 'Add imp2opt_dict[{0}] = none'.format(sect) def consistency_check(self): """Check that there is a one to one mapping between options and @@ -439,7 +439,7 @@ class InstConfigData(object): self.opt_dict[opt]['selected_imp'] = selected_imp -class InstConfigView(urwid.Pile): +class InstConfigView(urwid.Frame): """Extend urwid.Pile to provide an instrument configuration viewer. """ @@ -456,9 +456,30 @@ class InstConfigView(urwid.Pile): opt_lb, imp_lb] - super(InstConfigView, self).__init__(option_listboxes) + + 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(InstConfigView, self).__init__(header = self.mapped_header, body = self.cfg_pile) return + def _msg_hdr(self, msg): + hdr = self.help_str + msg + self.header_text.set_text(hdr) + + def _msg_cb(self, ml, msg): + self._msg_hdr(msg) + + def _timed_msg(self, t_sec, msg): + self._msg_hdr(msg) + self.main_loop.set_alarm_in(t_sec, self._msg_cb, '') + + def set_main(self, m): + self.main_loop = m # Contains OptionListWalker dict indexed by option # Contains ImpListBox @@ -635,21 +656,22 @@ def gen_input_handler(cf_man, cf_dat, cf_viewer): raise urwid.ExitMainLoop() elif key == 'w': cf_dat.backup_files() + cf_viewer._timed_msg(1, ': Saving file') cf_dat.write_config_file() elif key in ['right', 'tab']: - if cf_viewer.get_focus() == cf_man.cfg_lb: - cf_viewer.set_focus(cf_man.opt_lb) - elif cf_viewer.get_focus() == cf_man.opt_lb: - cf_viewer.set_focus(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: - cf_viewer.set_focus(cf_man.cfg_lb) + cf_viewer.cfg_pile.set_focus(cf_man.cfg_lb) elif key in ['left', 'shift tab']: - if cf_viewer.get_focus() == cf_man.cfg_lb: - cf_viewer.set_focus(cf_man.imp_lb) - elif cf_viewer.get_focus() == cf_man.opt_lb: - cf_viewer.set_focus(cf_man.cfg_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: - cf_viewer.set_focus(cf_man.opt_lb) + cf_viewer.cfg_pile.set_focus(cf_man.opt_lb) return keyinput @@ -669,7 +691,9 @@ def main(config_ini): 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) - urwid.MainLoop(cf_viewer, PALETTE, unhandled_input=keyinput).run() + main_loop = urwid.MainLoop(cf_viewer, PALETTE, unhandled_input=keyinput) + cf_viewer.set_main(main_loop) + main_loop.run() return if '__main__' == __name__: From 16b228dc0e0ac53cdd1c7765d8a65842b28e0193 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 11 Jul 2014 09:30:59 +1000 Subject: [PATCH 41/72] Sort and save the the Quokka sics_config.ini file in its default configuration. --- .../instrument/sans/util/sics_config.ini | 192 ++++++++---------- 1 file changed, 87 insertions(+), 105 deletions(-) diff --git a/site_ansto/instrument/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini index e4712f48..76189b90 100644 --- a/site_ansto/instrument/sans/util/sics_config.ini +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -1,14 +1,96 @@ -[10_pos_sample_stage] -desc = "Load the ten position sample changer configuration" -imptype = motion_axis - [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 +[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] +enabled = False +id = 1 +implementation = none +name = magnet1 +optype = magnetic_field +[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] +enabled = False +id = 1 +implementation = none +name = tc1 +optype = temperature +[T2] +enabled = False +id = 2 +implementation = none +name = tc2 +optype = temperature +[T3] +enabled = False +id = 3 +implementation = none +name = tc3 +optype = temperature +[T4] +enabled = False +id = 4 +implementation = none +name = tc4 +optype = temperature +[T5] +enabled = False +id = 5 +implementation = none +name = tc5 +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 +[10_pos_sample_stage] +desc = "Load the ten position sample changer configuration" +imptype = motion_axis [12tmagnet_oxford] desc = "12 Tesla Oxford Magnet" @@ -21,21 +103,6 @@ port = 55001 desc = "Load the twenty position sample changer configuration" imptype = motion_axis -[20_position_setup] -cascade = T1:julabo_lh45,sample_stage:20_pos_sample_stage -enabled = False - -[B1] -enabled = False -id = 1 -implementation = none -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" @@ -46,81 +113,10 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 -[Default] -cascade = sample_stage:normal_sample_stage -enabled = True - -[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 - [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 -[T1] -enabled = False -id = 1 -implementation = none -name = tc1 -optype = temperature - -[T2] -enabled = False -id = 2 -implementation = none -name = tc2 -optype = temperature - -[T3] -enabled = False -id = 3 -implementation = none -name = tc3 -optype = temperature - -[T4] -enabled = False -id = 4 -implementation = none -name = tc4 -optype = temperature - -[T5] -enabled = False -id = 5 -implementation = none -name = tc5 -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 - [bruker_bec1] desc = "Bruker Magnet" driver = "bruker_bec1" @@ -129,10 +125,6 @@ ip = 10.157.205.13 port = 4444 type = B -[bruker_setup] -cascade = B1:bruker_bec1,sample_stage:normal_sample_stage,T1:julabo_lh45 -enabled = False - [julabo_lh45] ctrl_sensor = "bath" desc = "Julabo temperature controller" @@ -264,16 +256,6 @@ imptype = multimeter ip = 10.157.205.37 port = 4001 -[rhqc_setup] -cascade = sample_stage:normal_sample_stage,T1:ls340_01,T2:ls340_02 -enabled = False - -[sample_stage] -enabled = Always -implementation = normal_sample_stage -name = sample_stage -optype = motion_axis - [watlow_rm] desc = "Watlow RM temperature controller" driver = "watlow_rm" From a9e4c80a8735322d0b917a38f7433afdf0d88a61 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 11 Jul 2014 13:37:02 +1000 Subject: [PATCH 42/72] Reindent gen_sct.py to 4 spaces --- site_ansto/instrument/util/gen_sct.py | 2398 ++++++++++++------------- 1 file changed, 1199 insertions(+), 1199 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 85ecb308..275b9df1 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Script Context Driver Generator # Author: Douglas Clowes (douglas.clowes@ansto.gov.au) Jan/Feb 2014 -# vim: ft=python ts=8 sts=2 sw=2 expandtab autoindent smartindent +# vim: ft=python ts=8 sts=4 sw=4 expandtab autoindent smartindent # # This program generates Script Context Driver TCL files. # @@ -166,28 +166,28 @@ t_RBRACE = r'}' t_SLASH = r'/' def t_TCL_BEG(t): - r'{%%' - if Verbose: - print 'TCL_BEG' - t.lexer.begin('tcl') - return t + r'{%%' + if Verbose: + print 'TCL_BEG' + t.lexer.begin('tcl') + return t def t_tcl_TCL_END(t): - r'.*%%}' - if Verbose: - print 'TCL_END' - t.lexer.begin('INITIAL') - return t + r'.*%%}' + if Verbose: + print 'TCL_END' + t.lexer.begin('INITIAL') + return t t_tcl_ignore = "" def t_tcl_CODE_STRING(t): - r'.+' - if t.value[0] == '@': - t.value = t.value[1:] - if Verbose: - print 'TCL:', t.value - return t + r'.+' + if t.value[0] == '@': + t.value = t.value[1:] + if Verbose: + print 'TCL:', t.value + return t def t_tcl_newline(t): r'\n+' @@ -198,51 +198,51 @@ def t_tcl_error(t): t.lexer.skip(1) def t_TEXT_STRING1(t): - r'\'[^\']+\'' - t.value = t.value[1:-1] - return t + r'\'[^\']+\'' + t.value = t.value[1:-1] + return t def t_TEXT_STRING2(t): - r"\"[^\"]+\"" - t.value = t.value[1:-1] - return t + r"\"[^\"]+\"" + t.value = t.value[1:-1] + return t def t_CODE_STRING(t): - r'\@.*' - t.value = t.value[1:] - return t + r'\@.*' + t.value = t.value[1:] + return t def t_COMMENT(t): - r'\#.*' - pass - # No Return Value. Token discarded + r'\#.*' + pass + # No Return Value. Token discarded def t_FLOATER(t): - r'-?\d+\.\d*([eE]\d+)?' - try: - t.value = float(t.value) - except ValueError: - print "Floating value invalid:", t.value - t.value = 0.0 - return t + r'-?\d+\.\d*([eE]\d+)?' + try: + t.value = float(t.value) + except ValueError: + print "Floating value invalid:", t.value + t.value = 0.0 + return t def t_INTEGER(t): - r'-?\d+' - try: - t.value = int(t.value) - except ValueError: - print "Integer value too large:", t.value - t.value = 0 - return t + r'-?\d+' + try: + t.value = int(t.value) + except ValueError: + print "Integer value too large:", t.value + t.value = 0 + return t def t_ID(t): - r'[a-zA-Z_][a-zA-Z_0-9]*' - t.type = reserved.get(t.value.upper(), 'ID') # Check for reserved words - # Force reserved words to lower case for map lookup and comparisson - if t.value.upper() in reserved: - t.type = reserved[t.value.upper()] - t.value = t.value.lower() - return t + r'[a-zA-Z_][a-zA-Z_0-9]*' + t.type = reserved.get(t.value.upper(), 'ID') # Check for reserved words + # Force reserved words to lower case for map lookup and comparisson + if t.value.upper() in reserved: + t.type = reserved[t.value.upper()] + t.value = t.value.lower() + return t # Ignored characters t_ignore = " \t;" @@ -276,293 +276,293 @@ precedence = ( # The head token - it all reduces to this # def p_driver(p): - 'driver : DRIVER id_or_str EQUALS driver_block' - p[0] = [{ 'Driver' : {p[2] : p[4]}}] - if Verbose: - print "Driver:", p[0] - global PathName - global TheDrivers - TheDrivers[p[2]] = p[4] + [{'PathName':PathName}] + 'driver : DRIVER id_or_str EQUALS driver_block' + p[0] = [{ 'Driver' : {p[2] : p[4]}}] + if Verbose: + print "Driver:", p[0] + global PathName + global TheDrivers + TheDrivers[p[2]] = p[4] + [{'PathName':PathName}] def p_driver_block(p): - 'driver_block : LBRACE driver_statement_list RBRACE' - p[0] = p[2] + 'driver_block : LBRACE driver_statement_list RBRACE' + p[0] = p[2] def p_driver_statement_list(p): - '''driver_statement_list : driver_statement - | driver_statement_list driver_statement - ''' - if len(p) == 2: - p[0] = [p[1]] - else: - p[0] = p[1] + [p[2]] + '''driver_statement_list : driver_statement + | driver_statement_list driver_statement + ''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = p[1] + [p[2]] def p_driver_statement(p): - '''driver_statement : driver_assignment - | group - | code - | driver_property - ''' - p[0] = p[1] + '''driver_statement : driver_assignment + | group + | code + | driver_property + ''' + p[0] = p[1] def p_driver_assignment(p): - ''' - driver_assignment : VENDOR EQUALS id_or_str - | DEVICE EQUALS id_or_str - | PROTOCOL EQUALS id_or_str - | CLASS EQUALS id_or_str - | SIMULATION_GROUP EQUALS id_or_str - | ADD_ARGS EQUALS text_string - | MAKE_ARGS EQUALS text_string - | PROTOCOL_ARGS EQUALS text_string - | DEBUG_THRESHOLD EQUALS value - ''' - p[0] = { p[1] : p[3] } + ''' + driver_assignment : VENDOR EQUALS id_or_str + | DEVICE EQUALS id_or_str + | PROTOCOL EQUALS id_or_str + | CLASS EQUALS id_or_str + | SIMULATION_GROUP EQUALS id_or_str + | ADD_ARGS EQUALS text_string + | MAKE_ARGS EQUALS text_string + | PROTOCOL_ARGS EQUALS text_string + | DEBUG_THRESHOLD EQUALS value + ''' + p[0] = { p[1] : p[3] } # # The GROUP block # def p_group(p): - ''' - group : GROUP group_id EQUALS LBRACE group_statement_list RBRACE - ''' - p[0] = { 'Group' : [{'name': p[2]}] + p[5] } + ''' + group : GROUP group_id EQUALS LBRACE group_statement_list RBRACE + ''' + p[0] = { 'Group' : [{'name': p[2]}] + p[5] } def p_group_id(p): - ''' - group_id : id_or_str - | empty - ''' - p[0] = p[1] + ''' + group_id : id_or_str + | empty + ''' + p[0] = p[1] def p_group_statement_list(p): - ''' - group_statement_list : group_statement - | group_statement_list group_statement - ''' - if len(p) == 2: - p[0] = [p[1]] - else: - p[0] = p[1] + [p[2]] + ''' + group_statement_list : group_statement + | group_statement_list group_statement + ''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = p[1] + [p[2]] def p_group_statement(p): - '''group_statement : group_assignment - | variable - | group - ''' - p[0] = p[1] + '''group_statement : group_assignment + | variable + | group + ''' + p[0] = p[1] def p_group_assignment(p): - '''group_assignment : group_property - | var_typ_ass - | property - ''' - p[0] = p[1] + '''group_assignment : group_property + | var_typ_ass + | property + ''' + p[0] = p[1] # # The VAR block # def p_variable(p): - ''' - variable : VAR id_or_str EQUALS LBRACE variable_statement_list RBRACE - | VAR id_or_str - ''' - if len(p) > 3: - p[0] = { 'Variable' : [{'name' : p[2]}] + p[5] } - else: - p[0] = { 'Variable' : [{'name' : p[2]}] } + ''' + variable : VAR id_or_str EQUALS LBRACE variable_statement_list RBRACE + | VAR id_or_str + ''' + if len(p) > 3: + p[0] = { 'Variable' : [{'name' : p[2]}] + p[5] } + else: + p[0] = { 'Variable' : [{'name' : p[2]}] } def p_variable_statement_list(p): - '''variable_statement_list : variable_statement - | variable_statement_list variable_statement - ''' - if len(p) == 2: - p[0] = [p[1]] - else: - p[0] = p[1] + [p[2]] + '''variable_statement_list : variable_statement + | variable_statement_list variable_statement + ''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = p[1] + [p[2]] def p_variable_statement(p): - '''variable_statement : var_typ_ass - | var_val_ass - | property - ''' - p[0] = p[1] + '''variable_statement : var_typ_ass + | var_val_ass + | property + ''' + p[0] = p[1] def p_var_typ_ass(p): - ''' - var_typ_ass : READABLE EQUALS INTEGER - | WRITEABLE EQUALS INTEGER - | READ_COMMAND EQUALS text_string - | READ_FUNCTION EQUALS id_or_str - | FETCH_FUNCTION EQUALS id_or_str - | WRITE_COMMAND EQUALS text_string - | WRITE_FUNCTION EQUALS id_or_str - | CHECK_FUNCTION EQUALS id_or_str - | PID_FUNCTION EQUALS id_or_str - | CHECKRANGE_FUNCTION EQUALS id_or_str - | CHECKLIMITS_FUNCTION EQUALS id_or_str - | CHECKSTATUS_FUNCTION EQUALS id_or_str - | HALT_FUNCTION EQUALS id_or_str - | TYPE EQUALS type_code - | PRIV EQUALS priv_code - | CONTROL EQUALS true_false - | DATA EQUALS true_false - | NXSAVE EQUALS true_false - | MUTABLE EQUALS true_false - ''' - p[0] = { p[1] : p[3] } + ''' + var_typ_ass : READABLE EQUALS INTEGER + | WRITEABLE EQUALS INTEGER + | READ_COMMAND EQUALS text_string + | READ_FUNCTION EQUALS id_or_str + | FETCH_FUNCTION EQUALS id_or_str + | WRITE_COMMAND EQUALS text_string + | WRITE_FUNCTION EQUALS id_or_str + | CHECK_FUNCTION EQUALS id_or_str + | PID_FUNCTION EQUALS id_or_str + | CHECKRANGE_FUNCTION EQUALS id_or_str + | CHECKLIMITS_FUNCTION EQUALS id_or_str + | CHECKSTATUS_FUNCTION EQUALS id_or_str + | HALT_FUNCTION EQUALS id_or_str + | TYPE EQUALS type_code + | PRIV EQUALS priv_code + | CONTROL EQUALS true_false + | DATA EQUALS true_false + | NXSAVE EQUALS true_false + | MUTABLE EQUALS true_false + ''' + p[0] = { p[1] : p[3] } def p_var_path(p): - ''' - var_path : id_or_str - | var_path SLASH id_or_str - ''' - if len(p) == 2: - p[0] = p[1] - else: - p[0] = p[1] + '/' + p[3] + ''' + var_path : id_or_str + | var_path SLASH id_or_str + ''' + if len(p) == 2: + p[0] = p[1] + else: + p[0] = p[1] + '/' + p[3] def p_var_val_ass(p): - ''' - var_val_ass : VALUE EQUALS FLOATER - | VALUE EQUALS text_string - | VALUE EQUALS INTEGER - | ALLOWED EQUALS text_string - | UNITS EQUALS text_string - | LOWERLIMIT EQUALS value - | UPPERLIMIT EQUALS value - | TOLERANCE EQUALS value - | PERMLINK EQUALS text_string - | DRIVEABLE EQUALS var_path - ''' - p[0] = { p[1] : p[3] } + ''' + var_val_ass : VALUE EQUALS FLOATER + | VALUE EQUALS text_string + | VALUE EQUALS INTEGER + | ALLOWED EQUALS text_string + | UNITS EQUALS text_string + | LOWERLIMIT EQUALS value + | UPPERLIMIT EQUALS value + | TOLERANCE EQUALS value + | PERMLINK EQUALS text_string + | DRIVEABLE EQUALS var_path + ''' + p[0] = { p[1] : p[3] } def p_driver_property(p): - ''' - driver_property : DRIVER_PROPERTY id_or_str EQUALS value - ''' - p[0] = { 'DriverProperty' : ( p[2], p[4] ) } + ''' + driver_property : DRIVER_PROPERTY id_or_str EQUALS value + ''' + p[0] = { 'DriverProperty' : ( p[2], p[4] ) } def p_group_property(p): - ''' - group_property : GROUP_PROPERTY id_or_str EQUALS value - ''' - p[0] = { 'GroupProperty' : ( p[2], p[4] ) } + ''' + group_property : GROUP_PROPERTY id_or_str EQUALS value + ''' + p[0] = { 'GroupProperty' : ( p[2], p[4] ) } def p_property(p): - ''' - property : PROPERTY id_or_str EQUALS value - ''' - p[0] = { 'Property' : ( p[2], p[4] ) } + ''' + property : PROPERTY id_or_str EQUALS value + ''' + p[0] = { 'Property' : ( p[2], p[4] ) } def p_value(p): - ''' - value : number - | id_or_str - | true_false - ''' - p[0] = p[1] + ''' + value : number + | id_or_str + | true_false + ''' + p[0] = p[1] def p_number(p): - ''' - number : INTEGER - | FLOATER - ''' - p[0] = p[1] + ''' + number : INTEGER + | FLOATER + ''' + p[0] = p[1] def p_type_code(p): - ''' - type_code : FLOAT - | INT - | TEXT - | NONE - ''' - p[0] = p[1] + ''' + type_code : FLOAT + | INT + | TEXT + | NONE + ''' + p[0] = p[1] def p_priv_code(p): - ''' - priv_code : SPY - | USER - | MANAGER - | READONLY - | INTERNAL - ''' - p[0] = p[1] + ''' + priv_code : SPY + | USER + | MANAGER + | READONLY + | INTERNAL + ''' + p[0] = p[1] def p_true_false(p): - ''' - true_false : TRUE - | FALSE - ''' - p[0] = p[1] + ''' + true_false : TRUE + | FALSE + ''' + p[0] = p[1] # # The CODE block # def p_code(p): - ''' - code : CODE code_type id_or_str EQUALS LBRACE code_block RBRACE - | CODE code_type id_or_str EQUALS TCL_BEG code_block TCL_END - ''' - p[0] = { 'Code' : { 'name' : p[3], 'type' : p[2], 'text' : p[6] }} + ''' + code : CODE code_type id_or_str EQUALS LBRACE code_block RBRACE + | CODE code_type id_or_str EQUALS TCL_BEG code_block TCL_END + ''' + p[0] = { 'Code' : { 'name' : p[3], 'type' : p[2], 'text' : p[6] }} def p_code_type(p): - ''' - code_type : READ_FUNCTION - | FETCH_FUNCTION - | WRITE_FUNCTION - | CHECK_FUNCTION - | PID_FUNCTION - | CHECKRANGE_FUNCTION - | CHECKLIMITS_FUNCTION - | CHECKSTATUS_FUNCTION - | HALT_FUNCTION - | empty - ''' - p[0] = p[1] + ''' + code_type : READ_FUNCTION + | FETCH_FUNCTION + | WRITE_FUNCTION + | CHECK_FUNCTION + | PID_FUNCTION + | CHECKRANGE_FUNCTION + | CHECKLIMITS_FUNCTION + | CHECKSTATUS_FUNCTION + | HALT_FUNCTION + | empty + ''' + p[0] = p[1] def p_code_block(p): - '''code_block : empty - | code_block CODE_STRING - ''' - if len(p) == 2: - p[0] = [] - else: - p[0] = p[1] + [p[2]] + '''code_block : empty + | code_block CODE_STRING + ''' + if len(p) == 2: + p[0] = [] + else: + p[0] = p[1] + [p[2]] def p_id_or_str(p): - ''' - id_or_str : ID - | text_string - ''' - p[0] = p[1] + ''' + id_or_str : ID + | text_string + ''' + p[0] = p[1] def p_text_string(p): - ''' - text_string : TEXT_STRING1 - | TEXT_STRING2 - ''' - p[0] = p[1] + ''' + text_string : TEXT_STRING1 + | TEXT_STRING2 + ''' + p[0] = p[1] def p_empty(p): - ''' - empty : - ''' - pass + ''' + empty : + ''' + pass def p_error(t): - print("Syntax error at '%s'" % t.value), t + print("Syntax error at '%s'" % t.value), t # # Utility functions # def make_path(MyVar): - path = MyVar['path'] - if len(path) > 0: - path = path.replace('/', '_') - path += '_' - path += MyVar['name'] - return path + path = MyVar['path'] + if len(path) > 0: + path = path.replace('/', '_') + path += '_' + path += MyVar['name'] + return path # # This section handles building a driver tree from the Abstract Syntax Tree @@ -570,1037 +570,1037 @@ def make_path(MyVar): # cascading context explicitly stated to make the code generation simpler. # def init_context(): - global ContextStack, ContextIndex - ContextStack = [{}] - ContextIndex = 0 - ContextStack[ContextIndex]['type'] = 'none' - ContextStack[ContextIndex]['priv'] = 'user' - ContextStack[ContextIndex]['readable'] = 0 - ContextStack[ContextIndex]['writeable'] = 0 - ContextStack[ContextIndex]['driveable'] = None - ContextStack[ContextIndex]['control'] = 'true' - ContextStack[ContextIndex]['data'] = 'true' - ContextStack[ContextIndex]['mutable'] = 'false' - ContextStack[ContextIndex]['nxsave'] = 'true' - ContextStack[ContextIndex]['read_function'] = 'rdValue' - ContextStack[ContextIndex]['write_function'] = 'setValue' - ContextStack[ContextIndex]['fetch_function'] = 'getValue' - ContextStack[ContextIndex]['check_function'] = 'noResponse' - ContextStack[ContextIndex]['checkrange_function'] = 'checkrange' - ContextStack[ContextIndex]['path'] = '' + global ContextStack, ContextIndex + ContextStack = [{}] + ContextIndex = 0 + ContextStack[ContextIndex]['type'] = 'none' + ContextStack[ContextIndex]['priv'] = 'user' + ContextStack[ContextIndex]['readable'] = 0 + ContextStack[ContextIndex]['writeable'] = 0 + ContextStack[ContextIndex]['driveable'] = None + ContextStack[ContextIndex]['control'] = 'true' + ContextStack[ContextIndex]['data'] = 'true' + ContextStack[ContextIndex]['mutable'] = 'false' + ContextStack[ContextIndex]['nxsave'] = 'true' + ContextStack[ContextIndex]['read_function'] = 'rdValue' + ContextStack[ContextIndex]['write_function'] = 'setValue' + ContextStack[ContextIndex]['fetch_function'] = 'getValue' + ContextStack[ContextIndex]['check_function'] = 'noResponse' + ContextStack[ContextIndex]['checkrange_function'] = 'checkrange' + ContextStack[ContextIndex]['path'] = '' def push_context(): - global ContextStack, ContextIndex - ContextIndex = ContextIndex + 1 - if len(ContextStack) <= ContextIndex: - ContextStack.append({}) - ContextStack[ContextIndex] = {} - for k in ContextStack[ContextIndex - 1].keys(): - ContextStack[ContextIndex][k] = ContextStack[ContextIndex - 1][k] + global ContextStack, ContextIndex + ContextIndex = ContextIndex + 1 + if len(ContextStack) <= ContextIndex: + ContextStack.append({}) + ContextStack[ContextIndex] = {} + for k in ContextStack[ContextIndex - 1].keys(): + ContextStack[ContextIndex][k] = ContextStack[ContextIndex - 1][k] def pop_context(): - global ContextStack, ContextIndex - ContextIndex = ContextIndex - 1 + global ContextStack, ContextIndex + ContextIndex = ContextIndex - 1 def build_code(MyDriver, p): - if Verbose: - print 'Code:', p - print "Function:", p['name'] - MyCode = {} - MyCode['name'] = p['name'] - MyCode['reference_count'] = 0 - if 'type' in p: - MyCode['type'] = p['type'] - MyCode['text'] = p['text'] - if Verbose: - for line in p['text']: - print " Line:", line - return MyCode + if Verbose: + print 'Code:', p + print "Function:", p['name'] + MyCode = {} + MyCode['name'] = p['name'] + MyCode['reference_count'] = 0 + if 'type' in p: + MyCode['type'] = p['type'] + MyCode['text'] = p['text'] + if Verbose: + for line in p['text']: + print " Line:", line + return MyCode def build_variable(MyDriver, p): - global FunctionTypes - global DriveableFunctionTypes - if Verbose: - print 'Variable:', p - MyVar = {} - MyVar['Property'] = {} - # Copy items for this variable - for item in p: + global FunctionTypes + global DriveableFunctionTypes if Verbose: - print "Variable Item:", item - for key in item.keys(): - if key == 'Property': - MyVar['Property'][item[key][0]] = item[key][1] - else: - MyVar[key] = item[key] - # copy the defaults for missing items - for key in ContextStack[ContextIndex]: - if key == 'Property': - for key2 in ContextStack[ContextIndex][key]: - if key2 not in MyVar['Property']: - MyVar['Property'][key2] = ContextStack[ContextIndex][key][key2] - elif not key in MyVar: - MyVar[key] = ContextStack[ContextIndex][key] - if 'sdsinfo' not in MyVar['Property']: - MyVar['Property']['sdsinfo'] = '::nexus::scobj::sdsinfo' - # set the type if not explicitly set - if 'type' not in MyVar['Property']: - if 'driveable' in MyVar and MyVar['driveable']: - MyVar['Property']['type'] = 'drivable' - else: - MyVar['Property']['type'] = 'part' - # if this variable is driveable - if 'driveable' in MyVar and MyVar['driveable']: - # insert defaults for missing driveable functions - if 'checklimits_function' not in MyVar: - MyVar['checklimits_function'] = 'checklimits' - if 'checkstatus_function' not in MyVar: - MyVar['checkstatus_function'] = 'checkstatus' - if 'halt_function' not in MyVar: - MyVar['halt_function'] = 'halt' - - for func in FunctionTypes + DriveableFunctionTypes: - if func in MyVar and MyVar[func] != 'none': - if Verbose: - print 'Var:', MyVar['name'], 'Func:', func, '=', MyVar[func] - if MyVar[func] not in MyDriver['Funcs']: - MyDriver['Funcs'][MyVar[func]] = { 'type' : func, 'text' : [], 'reference_count' : 0 } + print 'Variable:', p + MyVar = {} + MyVar['Property'] = {} + # Copy items for this variable + for item in p: if Verbose: - print MyVar['name'], 'Add func ' + MyVar[func], MyDriver['Funcs'][MyVar[func]] - elif not MyDriver['Funcs'][MyVar[func]]['type'] == func: - # allow override of type none else error message - if not MyDriver['Funcs'][MyVar[func]]['type']: - if Verbose: - print MyVar['name'], 'Mod func type:', MyDriver['Funcs'][MyVar[func]], '= ' + func - MyDriver['Funcs'][MyVar[func]]['type'] = func + print "Variable Item:", item + for key in item.keys(): + if key == 'Property': + MyVar['Property'][item[key][0]] = item[key][1] + else: + MyVar[key] = item[key] + # copy the defaults for missing items + for key in ContextStack[ContextIndex]: + if key == 'Property': + for key2 in ContextStack[ContextIndex][key]: + if key2 not in MyVar['Property']: + MyVar['Property'][key2] = ContextStack[ContextIndex][key][key2] + elif not key in MyVar: + MyVar[key] = ContextStack[ContextIndex][key] + if 'sdsinfo' not in MyVar['Property']: + MyVar['Property']['sdsinfo'] = '::nexus::scobj::sdsinfo' + # set the type if not explicitly set + if 'type' not in MyVar['Property']: + if 'driveable' in MyVar and MyVar['driveable']: + MyVar['Property']['type'] = 'drivable' else: - # TODO FIXME error message - print 'Error: Function type mismatch: var = ' + str(MyVar) + ', code = ' + str(MyDriver['Funcs'][MyVar[func]]) + ', func = ' + str(func) - MyDriver['Funcs'][MyVar[func]]['reference_count'] += 1 - 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)]; - if Verbose: - print '==>>MyVar:', MyVar - return MyVar + MyVar['Property']['type'] = 'part' + # if this variable is driveable + if 'driveable' in MyVar and MyVar['driveable']: + # insert defaults for missing driveable functions + if 'checklimits_function' not in MyVar: + MyVar['checklimits_function'] = 'checklimits' + if 'checkstatus_function' not in MyVar: + MyVar['checkstatus_function'] = 'checkstatus' + if 'halt_function' not in MyVar: + MyVar['halt_function'] = 'halt' + + for func in FunctionTypes + DriveableFunctionTypes: + if func in MyVar and MyVar[func] != 'none': + if Verbose: + print 'Var:', MyVar['name'], 'Func:', func, '=', MyVar[func] + if MyVar[func] not in MyDriver['Funcs']: + MyDriver['Funcs'][MyVar[func]] = { 'type' : func, 'text' : [], 'reference_count' : 0 } + if Verbose: + print MyVar['name'], 'Add func ' + MyVar[func], MyDriver['Funcs'][MyVar[func]] + elif not MyDriver['Funcs'][MyVar[func]]['type'] == func: + # allow override of type none else error message + if not MyDriver['Funcs'][MyVar[func]]['type']: + if Verbose: + print MyVar['name'], 'Mod func type:', MyDriver['Funcs'][MyVar[func]], '= ' + func + MyDriver['Funcs'][MyVar[func]]['type'] = func + else: + # TODO FIXME error message + print 'Error: Function type mismatch: var = ' + str(MyVar) + ', code = ' + str(MyDriver['Funcs'][MyVar[func]]) + ', func = ' + str(func) + MyDriver['Funcs'][MyVar[func]]['reference_count'] += 1 + 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)]; + if Verbose: + print '==>>MyVar:', MyVar + return MyVar def build_group(MyDriver, p): - if Verbose: - print 'Group:', p[0]['name'], p - push_context() - MyGroup = {} - MyGroup['Groups'] = {} - MyGroup['Vars'] = {} - # the sequence of both variables and non-variables is significant - # Therefore, they have to be processed in a single sequence - if p[0]['name']: - if len(ContextStack[ContextIndex]['path']) > 0: - ContextStack[ContextIndex]['path'] += '/' - ContextStack[ContextIndex]['path'] += p[0]['name'] - MyGroup['path'] = ContextStack[ContextIndex]['path'] - for item in p: - if 'Variable' in item: - MyVar = build_variable(MyDriver, item['Variable']) - MyGroup['Vars'][MyVar['name']] = MyVar - elif 'Group' in item: - MySubGroup = build_group(MyDriver, item['Group']) - MyGroup['Groups'][MySubGroup['name']] = MySubGroup - else: - if Verbose: - print "Group Item:", item - if 'GroupProperty' in item: - if 'GroupProperty' not in MyGroup: - MyGroup['GroupProperty'] = {} - MyGroup['GroupProperty'][item['GroupProperty'][0]] = item['GroupProperty'][1] - elif 'Property' in item: - if 'Property' not in MyGroup: - MyGroup['Property'] = {} - MyGroup['Property'][item['Property'][0]] = item['Property'][1] - if 'Property' not in ContextStack[ContextIndex]: - ContextStack[ContextIndex]['Property'] = {} - ContextStack[ContextIndex]['Property'][item['Property'][0]] = item['Property'][1] - else: - for key in item: - MyGroup[key] = item[key] - if key in ContextStack[ContextIndex]: - ContextStack[ContextIndex][key] = item[key] - pop_context() - return MyGroup + if Verbose: + print 'Group:', p[0]['name'], p + push_context() + MyGroup = {} + MyGroup['Groups'] = {} + MyGroup['Vars'] = {} + # the sequence of both variables and non-variables is significant + # Therefore, they have to be processed in a single sequence + if p[0]['name']: + if len(ContextStack[ContextIndex]['path']) > 0: + ContextStack[ContextIndex]['path'] += '/' + ContextStack[ContextIndex]['path'] += p[0]['name'] + MyGroup['path'] = ContextStack[ContextIndex]['path'] + for item in p: + if 'Variable' in item: + MyVar = build_variable(MyDriver, item['Variable']) + MyGroup['Vars'][MyVar['name']] = MyVar + elif 'Group' in item: + MySubGroup = build_group(MyDriver, item['Group']) + MyGroup['Groups'][MySubGroup['name']] = MySubGroup + else: + if Verbose: + print "Group Item:", item + if 'GroupProperty' in item: + if 'GroupProperty' not in MyGroup: + MyGroup['GroupProperty'] = {} + MyGroup['GroupProperty'][item['GroupProperty'][0]] = item['GroupProperty'][1] + elif 'Property' in item: + if 'Property' not in MyGroup: + MyGroup['Property'] = {} + MyGroup['Property'][item['Property'][0]] = item['Property'][1] + if 'Property' not in ContextStack[ContextIndex]: + ContextStack[ContextIndex]['Property'] = {} + ContextStack[ContextIndex]['Property'][item['Property'][0]] = item['Property'][1] + else: + for key in item: + MyGroup[key] = item[key] + if key in ContextStack[ContextIndex]: + ContextStack[ContextIndex][key] = item[key] + pop_context() + return MyGroup def build_driver(MyDriver, TheTree): - if Verbose: - print "TheTree:", TheTree - init_context() - for item in [x for x in TheTree if 'Code' in x]: - MyCode = build_code(MyDriver, item['Code']) - MyDriver['Funcs'][MyCode['name']] = MyCode - for item in [x for x in TheTree if 'Group' in x]: - MyGroup = build_group(MyDriver, item['Group']) - MyDriver['Groups'][MyGroup['name']] = MyGroup - for item in TheTree: if Verbose: - print "Driver Item:", item - if 'Group' in item: - continue - elif 'Code' in item: - continue - else: - if 'DriverProperty' in item: - if 'DriverProperty' not in MyDriver: - MyDriver['DriverProperty'] = {} - MyDriver['DriverProperty'][item['DriverProperty'][0]] = item['DriverProperty'][1] - continue - for key in item: - MyDriver[key] = item[key] - for item in MyDriver['Permlink']: - if len(MyDriver['Permlink'][item]) > 1: - print 'Error: duplicate permlink entries for "%s"' % item, MyDriver['Permlink'][item] - if Verbose: - print "MyDriver:", MyDriver + print "TheTree:", TheTree + init_context() + for item in [x for x in TheTree if 'Code' in x]: + MyCode = build_code(MyDriver, item['Code']) + MyDriver['Funcs'][MyCode['name']] = MyCode + for item in [x for x in TheTree if 'Group' in x]: + MyGroup = build_group(MyDriver, item['Group']) + MyDriver['Groups'][MyGroup['name']] = MyGroup + for item in TheTree: + if Verbose: + print "Driver Item:", item + if 'Group' in item: + continue + elif 'Code' in item: + continue + else: + if 'DriverProperty' in item: + if 'DriverProperty' not in MyDriver: + MyDriver['DriverProperty'] = {} + MyDriver['DriverProperty'][item['DriverProperty'][0]] = item['DriverProperty'][1] + continue + for key in item: + MyDriver[key] = item[key] + for item in MyDriver['Permlink']: + if len(MyDriver['Permlink'][item]) > 1: + print 'Error: duplicate permlink entries for "%s"' % item, MyDriver['Permlink'][item] + if Verbose: + print "MyDriver:", MyDriver # # Driver Dump Functions # def dump_driver_vars(vars, indent): - global FunctionTypes - global DriveableFunctionTypes - for item in sorted(vars): - print indent + ' VAR %s = {' % item - for subitem in sorted([i for i in vars[item] if i not in FunctionTypes + DriveableFunctionTypes]): - print indent + ' %s =' % subitem, vars[item][subitem] - for subitem in sorted([i for i in vars[item] if i in FunctionTypes]): - print indent + ' %s =' % subitem, vars[item][subitem] - for subitem in sorted([i for i in vars[item] if i in DriveableFunctionTypes]): - print indent + ' %s =' % subitem, vars[item][subitem] - print indent + ' }' + global FunctionTypes + global DriveableFunctionTypes + for item in sorted(vars): + print indent + ' VAR %s = {' % item + for subitem in sorted([i for i in vars[item] if i not in FunctionTypes + DriveableFunctionTypes]): + print indent + ' %s =' % subitem, vars[item][subitem] + for subitem in sorted([i for i in vars[item] if i in FunctionTypes]): + print indent + ' %s =' % subitem, vars[item][subitem] + for subitem in sorted([i for i in vars[item] if i in DriveableFunctionTypes]): + print indent + ' %s =' % subitem, vars[item][subitem] + print indent + ' }' def dump_driver_groups(groups, indent): - for item in sorted(groups): - if item: - print indent + 'GROUP ' + item + ' = {' - else: - print indent + 'GROUP = {' - for subitem in sorted([x for x in groups[item] if not x in ['Groups', 'Vars']]): - print indent + ' ', subitem, '=', groups[item][subitem] - dump_driver_vars(groups[item]['Vars'], indent) - dump_driver_groups(groups[item]['Groups'], indent + ' ') - print indent + '}' + for item in sorted(groups): + if item: + print indent + 'GROUP ' + item + ' = {' + else: + print indent + 'GROUP = {' + for subitem in sorted([x for x in groups[item] if not x in ['Groups', 'Vars']]): + print indent + ' ', subitem, '=', groups[item][subitem] + dump_driver_vars(groups[item]['Vars'], indent) + dump_driver_groups(groups[item]['Groups'], indent + ' ') + print indent + '}' def dump_driver_funcs(funcs): - for item in sorted(funcs): - if 'type' in funcs[item] and funcs[item]['type']: - print ' CODE ' + funcs[item]['type'] + ' ' + item + ' = {' - else: - print ' CODE ' + item + ' = {' - for line in funcs[item]['text']: - print ' @%s' % line - print ' }' + for item in sorted(funcs): + if 'type' in funcs[item] and funcs[item]['type']: + print ' CODE ' + funcs[item]['type'] + ' ' + item + ' = {' + else: + print ' CODE ' + item + ' = {' + for line in funcs[item]['text']: + print ' @%s' % line + print ' }' def dump_driver(MyDriver): - print 'DRIVER ' + MyDriver['name'] + ' = {' - for item in sorted([x for x in MyDriver if x not in ['Groups', 'Funcs']]): - print ' ' + item + ' =', MyDriver[item] - #print 'Groups:', MyDriver['Groups'] - dump_driver_groups(MyDriver['Groups'], ' ') - #print 'Funcs:', MyDriver['Funcs'] - dump_driver_funcs(MyDriver['Funcs']) - print '}' + print 'DRIVER ' + MyDriver['name'] + ' = {' + for item in sorted([x for x in MyDriver if x not in ['Groups', 'Funcs']]): + print ' ' + item + ' =', MyDriver[item] + #print 'Groups:', MyDriver['Groups'] + dump_driver_groups(MyDriver['Groups'], ' ') + #print 'Funcs:', MyDriver['Funcs'] + dump_driver_funcs(MyDriver['Funcs']) + print '}' # # Code Generation Functions # def emit(txt): - global NumberOfLinesOut - NumberOfLinesOut += len(txt) - for line in txt: - fdo.write(line) - if not line.endswith('\n'): - fdo.write('\n') + global NumberOfLinesOut + NumberOfLinesOut += len(txt) + for line in txt: + fdo.write(line) + if not line.endswith('\n'): + fdo.write('\n') def put_preamble(MyDriver): - txt = [] - txt += ['# Generated driver for %s' % MyDriver['name']] - txt += ['# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent'] - txt += ['#'] - txt += [''] - txt += ['namespace eval %s {' % MyDriver['namespace']] - txt += [' set debug_threshold %s' % str( MyDriver['debug_threshold'])] - if len(MyDriver['Permlink']) > 0: - if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): - pass - else: - txt += [' if { ![info exists ::scobj::permlink_device_counter]} {'] - txt += [' set ::scobj::permlink_device_counter 0'] - txt += [' }'] - txt += ['}'] - txt += [''] - txt += ['proc %s::debug_log {tc_root debug_level debug_string} {' % MyDriver['namespace']] - txt += [' set catch_status [ catch {'] - txt += [' set debug_threshold [hgetpropval ${tc_root} debug_threshold]'] - txt += [' if {${debug_level} >= ${debug_threshold}} {'] - txt += [' set fd [open "../log/%s_[basename ${tc_root}].log" "a"]' % MyDriver['name']] - txt += [' set line "[clock format [clock seconds] -format "%T"] ${debug_string}"'] - txt += [' puts ${fd} "${line}"'] - txt += [' close ${fd}'] - txt += [' }'] - txt += [' } catch_message ]'] - txt += ['}'] - txt += [''] - txt += ['proc %s::sics_log {debug_level debug_string} {' % MyDriver['namespace']] - txt += [' set catch_status [ catch {'] - txt += [' set debug_threshold ${%s::debug_threshold}' % MyDriver['namespace']] - txt += [' if {${debug_level} >= ${debug_threshold}} {'] - txt += [' sicslog "%s::${debug_string}"' % MyDriver['namespace']] - txt += [' }'] - txt += [' } catch_message ]'] - txt += ['}'] - emit(txt) + txt = [] + txt += ['# Generated driver for %s' % MyDriver['name']] + txt += ['# vim: ft=tcl tabstop=8 softtabstop=2 shiftwidth=2 nocindent smartindent'] + txt += ['#'] + txt += [''] + txt += ['namespace eval %s {' % MyDriver['namespace']] + txt += [' set debug_threshold %s' % str( MyDriver['debug_threshold'])] + if len(MyDriver['Permlink']) > 0: + if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): + pass + else: + txt += [' if { ![info exists ::scobj::permlink_device_counter]} {'] + txt += [' set ::scobj::permlink_device_counter 0'] + txt += [' }'] + txt += ['}'] + txt += [''] + txt += ['proc %s::debug_log {tc_root debug_level debug_string} {' % MyDriver['namespace']] + txt += [' set catch_status [ catch {'] + txt += [' set debug_threshold [hgetpropval ${tc_root} debug_threshold]'] + txt += [' if {${debug_level} >= ${debug_threshold}} {'] + txt += [' set fd [open "../log/%s_[basename ${tc_root}].log" "a"]' % MyDriver['name']] + txt += [' set line "[clock format [clock seconds] -format "%T"] ${debug_string}"'] + txt += [' puts ${fd} "${line}"'] + txt += [' close ${fd}'] + txt += [' }'] + txt += [' } catch_message ]'] + txt += ['}'] + txt += [''] + txt += ['proc %s::sics_log {debug_level debug_string} {' % MyDriver['namespace']] + txt += [' set catch_status [ catch {'] + txt += [' set debug_threshold ${%s::debug_threshold}' % MyDriver['namespace']] + txt += [' if {${debug_level} >= ${debug_threshold}} {'] + txt += [' sicslog "%s::${debug_string}"' % MyDriver['namespace']] + txt += [' }'] + txt += [' } catch_message ]'] + txt += ['}'] + emit(txt) def put_write_function(MyDriver, func): - txt = [''] - txt += ['# function to write a parameter value on a device'] - txt += ['proc %s::%s {tc_root nextState cmd_str} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' hdelprop [sct] geterror'] - txt += [' }'] - txt += [' set par [sct target]'] - txt += [' set cmd "${cmd_str}${par}"'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] + txt = [''] + txt += ['# function to write a parameter value on a device'] + txt += ['proc %s::%s {tc_root nextState cmd_str} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' debug_log ${tc_root} 9 "[sct] error: [sct geterror]"'] - txt += [' error "[sct geterror]"'] + txt += [' hdelprop [sct] geterror'] txt += [' }'] - else: - txt += ['# %s hook code goes here' % func] - txt += [' if { [hpropexists [sct] driving] } {'] - txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {'] - txt += [' sct driving 1'] - txt += [' }'] - txt += [' }'] - txt += [' debug_log ${tc_root} 1 "%s sct send ${cmd}"' % func] - txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] - txt += [' sct send "${cmd}"'] - txt += [' }'] - txt += [' return ${nextState}'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt += [' set par [sct target]'] + txt += [' set cmd "${cmd_str}${par}"'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' debug_log ${tc_root} 9 "[sct] error: [sct geterror]"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] + else: + txt += ['# %s hook code goes here' % func] + txt += [' if { [hpropexists [sct] driving] } {'] + txt += [' if { [hpropexists [sct] writestatus] && [sct writestatus] == "start" } {'] + txt += [' sct driving 1'] + txt += [' }'] + txt += [' }'] + txt += [' debug_log ${tc_root} 1 "%s sct send ${cmd}"' % func] + txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] + txt += [' sct send "${cmd}"'] + txt += [' }'] + txt += [' return ${nextState}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_check_function(MyDriver, func): - txt = [''] - txt += ['# function to check the write parameter on a device'] - txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] resp=[sct result]"' % func] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' return "idle"'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['# function to check the write parameter on a device'] + txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] resp=[sct result]"' % func] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' return "idle"'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_fetch_function(MyDriver, func): - txt = [''] - txt += ['# function to request the read of a parameter on a device'] - txt += ['proc %s::%s {tc_root nextState cmd_str} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' hdelprop [sct] geterror'] - txt += [' }'] - txt += [' set cmd "${cmd_str}"'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] + txt = [''] + txt += ['# function to request the read of a parameter on a device'] + txt += ['proc %s::%s {tc_root nextState cmd_str} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] cmd=${cmd_str}"' % func] txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' debug_log ${tc_root} 9 "[sct] error: [sct geterror]"'] - txt += [' error "[sct geterror]"'] + txt += [' hdelprop [sct] geterror'] txt += [' }'] - else: - txt += ['# %s hook code goes here' % func] - txt += [' debug_log ${tc_root} 1 "%s sct send ${cmd}"' % func] - txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] - txt += [' sct send "${cmd}"'] - txt += [' }'] - txt += [' return ${nextState}'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt += [' set cmd "${cmd_str}"'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' debug_log ${tc_root} 9 "[sct] error: [sct geterror]"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] + else: + txt += ['# %s hook code goes here' % func] + txt += [' debug_log ${tc_root} 1 "%s sct send ${cmd}"' % func] + txt += [' if {![string equal -nocase -length 10 ${cmd} "@@NOSEND@@"]} {'] + txt += [' sct send "${cmd}"'] + txt += [' }'] + txt += [' return ${nextState}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_read_function(MyDriver, func): - txt = [''] - txt += ['# function to parse the read of a parameter on a device'] - txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] result=[sct result]"' % func] - txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' hdelprop [sct] geterror'] - txt += [' }'] - txt += [' set data [sct result]'] - txt += [' set nextState "idle"'] - txt += [' if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {'] - txt += [' # the protocol driver has reported an error'] - txt += [' sct geterror "${data}"'] - txt += [' error "[sct geterror]"'] - txt += [' }'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] + txt = [''] + txt += ['# function to parse the read of a parameter on a device'] + txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] result=[sct result]"' % func] txt += [' if { [hpropexists [sct] geterror] } {'] - txt += [' debug_log ${tc_root} 9 "[sct] error: [sct geterror]"'] + txt += [' hdelprop [sct] geterror'] + txt += [' }'] + txt += [' set data [sct result]'] + txt += [' set nextState "idle"'] + txt += [' if {[string equal -nocase -length 7 ${data} "ASCERR:"]} {'] + txt += [' # the protocol driver has reported an error'] + txt += [' sct geterror "${data}"'] txt += [' error "[sct geterror]"'] txt += [' }'] - else: - txt += ['# %s hook code goes here' % func] - txt += [' if { ${data} != [sct oldval] } {'] - txt += [' debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"'] - txt += [' sct oldval ${data}'] - txt += [' sct update ${data}'] - txt += [' sct utime readtime'] - txt += [' }'] - txt += [' return ${nextState}'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + txt += [' if { [hpropexists [sct] geterror] } {'] + txt += [' debug_log ${tc_root} 9 "[sct] error: [sct geterror]"'] + txt += [' error "[sct geterror]"'] + txt += [' }'] + else: + txt += ['# %s hook code goes here' % func] + txt += [' if { ${data} != [sct oldval] } {'] + txt += [' debug_log ${tc_root} 1 "[sct] changed to new:${data}, from old:[sct oldval]"'] + txt += [' sct oldval ${data}'] + txt += [' sct update ${data}'] + txt += [' sct utime readtime'] + txt += [' }'] + txt += [' return ${nextState}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_checkrange_function(MyDriver, func): - txt = [''] - txt += ['# check function for hset change'] - txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] - txt += [' set setpoint [sct target]'] - txt += [' if { [hpropexists [sct] lowerlimit] } {'] - txt += [' set lolimit [sct lowerlimit]'] - txt += [' } else {'] - txt += [' # lowerlimit not set, use target'] - txt += [' set lolimit [sct target]'] - txt += [' }'] - txt += [' if { [hpropexists [sct] upperlimit] } {'] - txt += [' set hilimit [sct upperlimit]'] - txt += [' } else {'] - txt += [' # upperlimit not set, use target'] - txt += [' set hilimit [sct target]'] - txt += [' }'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] - txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] - txt += [' }'] - txt += [' return OK'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['# check function for hset change'] + txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] + txt += [' set setpoint [sct target]'] + txt += [' if { [hpropexists [sct] lowerlimit] } {'] + txt += [' set lolimit [sct lowerlimit]'] + txt += [' } else {'] + txt += [' # lowerlimit not set, use target'] + txt += [' set lolimit [sct target]'] + txt += [' }'] + txt += [' if { [hpropexists [sct] upperlimit] } {'] + txt += [' set hilimit [sct upperlimit]'] + txt += [' } else {'] + txt += [' # upperlimit not set, use target'] + txt += [' set hilimit [sct target]'] + txt += [' }'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] + txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] + txt += [' }'] + txt += [' return OK'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_checklimits_function(MyDriver, func): - txt = [''] - txt += ['# checklimits function for driveable interface'] - txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] - txt += [' set setpoint [sct target]'] - txt += [' if { [hpropexists [sct] lowerlimit] } {'] - txt += [' set lolimit [sct lowerlimit]'] - txt += [' } else {'] - txt += [' # lowerlimit not set, use target'] - txt += [' set lolimit [sct target]'] - txt += [' }'] - txt += [' if { [hpropexists [sct] upperlimit] } {'] - txt += [' set hilimit [sct upperlimit]'] - txt += [' } else {'] - txt += [' # upperlimit not set, use target'] - txt += [' set hilimit [sct target]'] - txt += [' }'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] - txt += [' sct driving 0'] - txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] - txt += [' }'] - txt += [' return OK'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['# checklimits function for driveable interface'] + txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] target=[sct target]"' % func] + txt += [' set setpoint [sct target]'] + txt += [' if { [hpropexists [sct] lowerlimit] } {'] + txt += [' set lolimit [sct lowerlimit]'] + txt += [' } else {'] + txt += [' # lowerlimit not set, use target'] + txt += [' set lolimit [sct target]'] + txt += [' }'] + txt += [' if { [hpropexists [sct] upperlimit] } {'] + txt += [' set hilimit [sct upperlimit]'] + txt += [' } else {'] + txt += [' # upperlimit not set, use target'] + txt += [' set hilimit [sct target]'] + txt += [' }'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' if { ${setpoint} < ${lolimit} || ${setpoint} > ${hilimit} } {'] + txt += [' sct driving 0'] + txt += [' error "setpoint ${setpoint} violates limits (${lolimit}..${hilimit}) on [sct]"'] + txt += [' }'] + txt += [' return OK'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_checkstatus_function(MyDriver, func): - txt = [''] - txt += ['# checkstatus function for driveable interface'] - txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' if {[sct driving]} {'] - txt += [' set sp "[sct target]"'] - txt += [' set pv "[hval ${tc_root}/[sct driveable]]"'] - txt += [' if { abs(${pv} - ${sp}) <= [sct tolerance] } {'] - txt += [' if { [hpropexists [sct] settle_time] } {'] - txt += [' if { [hpropexists [sct] settle_time_start] } {'] - txt += [' if { [sct utime] - [sct settle_time_start] >= [sct settle_time]} {'] - txt += [' sct driving 0'] - txt += [' return "idle"'] - txt += [' }'] - txt += [' return "busy"'] - txt += [' } else {'] - txt += [' sct utime settle_time_start'] - txt += [' return "busy"'] - txt += [' }'] - txt += [' }'] - txt += [' sct driving 0'] - txt += [' return "idle"'] - txt += [' }'] - txt += [' if { [hpropexists [sct] settle_time_start] } {'] - txt += [' hdelprop [sct] settle_time_start'] - txt += [' }'] - txt += [' return "busy"'] - txt += [' } else {'] - txt += [' return "idle"'] - txt += [' }'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['# checkstatus function for driveable interface'] + txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' if {[sct driving]} {'] + txt += [' set sp "[sct target]"'] + txt += [' set pv "[hval ${tc_root}/[sct driveable]]"'] + txt += [' if { abs(${pv} - ${sp}) <= [sct tolerance] } {'] + txt += [' if { [hpropexists [sct] settle_time] } {'] + txt += [' if { [hpropexists [sct] settle_time_start] } {'] + txt += [' if { [sct utime] - [sct settle_time_start] >= [sct settle_time]} {'] + txt += [' sct driving 0'] + txt += [' return "idle"'] + txt += [' }'] + txt += [' return "busy"'] + txt += [' } else {'] + txt += [' sct utime settle_time_start'] + txt += [' return "busy"'] + txt += [' }'] + txt += [' }'] + txt += [' sct driving 0'] + txt += [' return "idle"'] + txt += [' }'] + txt += [' if { [hpropexists [sct] settle_time_start] } {'] + txt += [' hdelprop [sct] settle_time_start'] + txt += [' }'] + txt += [' return "busy"'] + txt += [' } else {'] + txt += [' return "idle"'] + txt += [' }'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_halt_function(MyDriver, func): - txt = [''] - txt += ['# halt function for driveable interface'] - txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] - txt += [' set catch_status [ catch {'] - txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] driving=[sct driving]"' % func] - txt += [' ### TODO hset [sct] [hval [sct]]'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' sct driving 0'] - txt += [' return "idle"'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['# halt function for driveable interface'] + txt += ['proc %s::%s {tc_root} {' % (MyDriver['namespace'], func)] + txt += [' set catch_status [ catch {'] + txt += [' debug_log ${tc_root} 1 "%s tc_root=${tc_root} sct=[sct] driving=[sct driving]"' % func] + txt += [' ### TODO hset [sct] [hval [sct]]'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' sct driving 0'] + txt += [' return "idle"'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_pid_function(MyDriver, func): - txt = [''] - txt += ['# pid function for PID control'] - 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_deriv [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}]'] - if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' sct pid_output ${pid}'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += [' return ${pid}'] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['# pid function for PID control'] + 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_deriv [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}]'] + if func in MyDriver['Funcs'] and len(MyDriver['Funcs'][func]['text']) > 0: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' sct pid_output ${pid}'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += [' return ${pid}'] + txt += ['}'] + emit(txt) def put_group(MyDriver, MyGroup): - readable_or_writeable = False - txt = [] - if MyGroup['name']: - txt += [''] - txt += [' hfactory ${scobj_hpath}/%s plain spy none' % MyGroup['path']] - if 'GroupProperty' in MyGroup: - for key in sorted(MyGroup['GroupProperty']): - txt += [' hsetprop ${scobj_hpath}/%s %s "%s"' % (MyGroup['path'], key, MyGroup['GroupProperty'][key])] - groupname = MyGroup['path'] + '/' - else: - groupname = '' - for var in sorted(MyGroup['Vars']): - txt += [''] - MyVar = MyGroup['Vars'][var] - nodename = groupname + MyVar['name'] - # Check driveable attributes are present if required - if 'driveable' in MyVar and MyVar['driveable']: - for attr in ('lowerlimit', 'upperlimit', 'tolerance'): - if attr not in MyVar: - msg = 'Driveable: %s does not have required attribute: %s' % (nodename, attr) - print 'Warning:', msg - txt += [' # Warning: ' + msg] - # Check PID attributes are present if required - if 'pid_function' in MyVar: - for attr in ('pid_pvalue', - 'pid_ivalue', - 'pid_dvalue', - 'pid_imax', - 'pid_error', - 'pid_deriv', - 'pid_integ', - ): - if attr not in MyVar['Property']: - msg = 'PID: %s does not have required attribute: %s' % (nodename, attr) - print 'Warning:', msg - txt += [' # Warning: ' + msg] - txt += [' hfactory ${scobj_hpath}/%s plain %s %s' % (nodename, MyVar['priv'], MyVar['type'])] - if MyVar['readable'] > 0: - readable_or_writeable = True - fetch_func = MyVar['fetch_function'] - if fetch_func == 'none': - fetch_func = 'getValue' - read_func = MyVar['read_function'] - read_command = MyVar['read_command'] - txt += [' hsetprop ${scobj_hpath}/%s read ${ns}::%s ${scobj_hpath} %s {%s}' % (nodename, fetch_func, read_func, read_command)] - txt += [' hsetprop ${scobj_hpath}/%s %s ${ns}::%s ${scobj_hpath}' % (nodename, read_func, read_func)] - if MyVar['writeable'] > 0 or MyVar['driveable']: - readable_or_writeable = True - check_func = MyVar['check_function'] - checkrange_func = MyVar['checkrange_function'] - write_func = MyVar['write_function'] - if 'write_command' in MyVar: - write_command = MyVar['write_command'] - else: - write_command = '' - txt += [' hsetprop ${scobj_hpath}/%s write ${ns}::%s ${scobj_hpath} %s {%s}' % (nodename, write_func, check_func, write_command)] - txt += [' hsetprop ${scobj_hpath}/%s %s ${ns}::%s ${scobj_hpath}' % (nodename, check_func, check_func)] - txt += [' hsetprop ${scobj_hpath}/%s check ${ns}::%s ${scobj_hpath}' % (nodename, checkrange_func)] - if MyVar['driveable']: - halt_func = MyVar['halt_function'] - checklimits_func = MyVar['checklimits_function'] - checkstatus_func = MyVar['checkstatus_function'] - txt += [' hsetprop ${scobj_hpath}/%s driving 0' % nodename] - txt += [' hsetprop ${scobj_hpath}/%s checklimits ${ns}::%s ${scobj_hpath}' % (nodename, checklimits_func)] - txt += [' hsetprop ${scobj_hpath}/%s checkstatus ${ns}::%s ${scobj_hpath}' % (nodename, checkstatus_func)] - txt += [' hsetprop ${scobj_hpath}/%s halt ${ns}::%s ${scobj_hpath}' % (nodename, halt_func)] - txt += [' hsetprop ${scobj_hpath}/%s driveable %s' % (nodename, MyVar['driveable'])] - if 'control' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s control %s' % (nodename, MyVar['control'])] - if 'data' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s data %s' % (nodename, MyVar['data'])] - if 'mutable' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s mutable %s' % (nodename, MyVar['mutable'])] - if 'nxsave' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s nxsave %s' % (nodename, MyVar['nxsave'])] - if 'lowerlimit' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s lowerlimit %s' % (nodename, MyVar['lowerlimit'])] - if 'upperlimit' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s upperlimit %s' % (nodename, MyVar['upperlimit'])] - if 'tolerance' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s tolerance %s' % (nodename, MyVar['tolerance'])] - if 'units' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s units %s' % (nodename, MyVar['units'])] - if 'allowed' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s values %s' % (nodename, MyVar['allowed'])] - if 'permlink' in MyVar: - device_type, node_type = MyVar['permlink'].split('.') - if device_type.startswith("#"): - if 'make_args' in MyDriver and 'permlink' in MyDriver['make_args'].split(): - idx = int(device_type[1:]) - device_type = '[string index ${permlink} %d]' % idx - else: - print 'Error: permlink required in make_ags' - if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): - permlink = device_type + '[format "%02d" ${id}]' + node_type - else: - permlink = device_type + '${permlink_device_number}' + node_type - txt += [' hsetprop ${scobj_hpath}/%s permlink data_set "%s"' % (nodename, permlink)] - txt += [' hsetprop ${scobj_hpath}/%s @description "%s"' % (nodename, permlink)] - if 'value' in MyVar: - txt += [' hsetprop ${scobj_hpath}/%s oldval %s' % (nodename, MyVar['value'])] - txt += [' hset ${scobj_hpath}/%s %s' % (nodename, MyVar['value'])] + readable_or_writeable = False + txt = [] + if MyGroup['name']: + txt += [''] + txt += [' hfactory ${scobj_hpath}/%s plain spy none' % MyGroup['path']] + if 'GroupProperty' in MyGroup: + for key in sorted(MyGroup['GroupProperty']): + txt += [' hsetprop ${scobj_hpath}/%s %s "%s"' % (MyGroup['path'], key, MyGroup['GroupProperty'][key])] + groupname = MyGroup['path'] + '/' else: - if MyVar['type'] == 'none': - pass - elif MyVar['type'] == 'int': - txt += [' hsetprop ${scobj_hpath}/%s oldval 0' % nodename] - elif MyVar['type'] == 'float': - txt += [' hsetprop ${scobj_hpath}/%s oldval 0.0' % nodename] - else: - txt += [' hsetprop ${scobj_hpath}/%s oldval UNKNOWN' % nodename] - for key in sorted(MyVar['Property']): - txt += [' hsetprop ${scobj_hpath}/%s %s "%s"' % (nodename, key, MyVar['Property'][key])] - # Generate __ at runtime for nxalias - if 'nxalias' not in MyVar['Property']: - nxalias = '${name}_' + make_path(MyVar) - txt += [' hsetprop ${scobj_hpath}/%s nxalias "%s"' % (nodename, nxalias)] - if not MyGroup['name']: - if 'GroupProperty' in MyGroup: - txt += [''] - for key in sorted(MyGroup['GroupProperty']): - txt += [' hsetprop ${scobj_hpath} %s "%s"' % (key, MyGroup['GroupProperty'][key])] - if readable_or_writeable: - txt += [''] - txt += [' if {[string equal -nocase [SplitReply [%s]] "false"]} {' % MyDriver['simulation_group']] + groupname = '' for var in sorted(MyGroup['Vars']): - MyVar = MyGroup['Vars'][var] - nodename = groupname + MyVar['name'] - if MyVar['readable'] > 0: - poll_period = MyVar['readable'] - if poll_period < 1 or poll_period > 300: - poll_period = 5 - txt += [' ${sct_controller} poll ${scobj_hpath}/%s %s' % (nodename, poll_period)] - for var in sorted(MyGroup['Vars']): - MyVar = MyGroup['Vars'][var] - nodename = groupname + MyVar['name'] - if MyVar['writeable'] > 0 or MyVar['driveable']: - txt += [' ${sct_controller} write ${scobj_hpath}/%s' % nodename] - 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'])] - txt += [' } else {'] - txt += [' %s::sics_log 9 "[%s] => No poll/write for %s"' % (MyDriver['namespace'], MyDriver['simulation_group'], MyDriver['name'])] - txt += [' }'] - for grp in sorted(MyGroup['Groups']): - txt += put_group(MyDriver, MyGroup['Groups'][grp]) - return txt + txt += [''] + MyVar = MyGroup['Vars'][var] + nodename = groupname + MyVar['name'] + # Check driveable attributes are present if required + if 'driveable' in MyVar and MyVar['driveable']: + for attr in ('lowerlimit', 'upperlimit', 'tolerance'): + if attr not in MyVar: + msg = 'Driveable: %s does not have required attribute: %s' % (nodename, attr) + print 'Warning:', msg + txt += [' # Warning: ' + msg] + # Check PID attributes are present if required + if 'pid_function' in MyVar: + for attr in ('pid_pvalue', + 'pid_ivalue', + 'pid_dvalue', + 'pid_imax', + 'pid_error', + 'pid_deriv', + 'pid_integ', + ): + if attr not in MyVar['Property']: + msg = 'PID: %s does not have required attribute: %s' % (nodename, attr) + print 'Warning:', msg + txt += [' # Warning: ' + msg] + txt += [' hfactory ${scobj_hpath}/%s plain %s %s' % (nodename, MyVar['priv'], MyVar['type'])] + if MyVar['readable'] > 0: + readable_or_writeable = True + fetch_func = MyVar['fetch_function'] + if fetch_func == 'none': + fetch_func = 'getValue' + read_func = MyVar['read_function'] + read_command = MyVar['read_command'] + txt += [' hsetprop ${scobj_hpath}/%s read ${ns}::%s ${scobj_hpath} %s {%s}' % (nodename, fetch_func, read_func, read_command)] + txt += [' hsetprop ${scobj_hpath}/%s %s ${ns}::%s ${scobj_hpath}' % (nodename, read_func, read_func)] + if MyVar['writeable'] > 0 or MyVar['driveable']: + readable_or_writeable = True + check_func = MyVar['check_function'] + checkrange_func = MyVar['checkrange_function'] + write_func = MyVar['write_function'] + if 'write_command' in MyVar: + write_command = MyVar['write_command'] + else: + write_command = '' + txt += [' hsetprop ${scobj_hpath}/%s write ${ns}::%s ${scobj_hpath} %s {%s}' % (nodename, write_func, check_func, write_command)] + txt += [' hsetprop ${scobj_hpath}/%s %s ${ns}::%s ${scobj_hpath}' % (nodename, check_func, check_func)] + txt += [' hsetprop ${scobj_hpath}/%s check ${ns}::%s ${scobj_hpath}' % (nodename, checkrange_func)] + if MyVar['driveable']: + halt_func = MyVar['halt_function'] + checklimits_func = MyVar['checklimits_function'] + checkstatus_func = MyVar['checkstatus_function'] + txt += [' hsetprop ${scobj_hpath}/%s driving 0' % nodename] + txt += [' hsetprop ${scobj_hpath}/%s checklimits ${ns}::%s ${scobj_hpath}' % (nodename, checklimits_func)] + txt += [' hsetprop ${scobj_hpath}/%s checkstatus ${ns}::%s ${scobj_hpath}' % (nodename, checkstatus_func)] + txt += [' hsetprop ${scobj_hpath}/%s halt ${ns}::%s ${scobj_hpath}' % (nodename, halt_func)] + txt += [' hsetprop ${scobj_hpath}/%s driveable %s' % (nodename, MyVar['driveable'])] + if 'control' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s control %s' % (nodename, MyVar['control'])] + if 'data' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s data %s' % (nodename, MyVar['data'])] + if 'mutable' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s mutable %s' % (nodename, MyVar['mutable'])] + if 'nxsave' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s nxsave %s' % (nodename, MyVar['nxsave'])] + if 'lowerlimit' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s lowerlimit %s' % (nodename, MyVar['lowerlimit'])] + if 'upperlimit' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s upperlimit %s' % (nodename, MyVar['upperlimit'])] + if 'tolerance' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s tolerance %s' % (nodename, MyVar['tolerance'])] + if 'units' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s units %s' % (nodename, MyVar['units'])] + if 'allowed' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s values %s' % (nodename, MyVar['allowed'])] + if 'permlink' in MyVar: + device_type, node_type = MyVar['permlink'].split('.') + if device_type.startswith("#"): + if 'make_args' in MyDriver and 'permlink' in MyDriver['make_args'].split(): + idx = int(device_type[1:]) + device_type = '[string index ${permlink} %d]' % idx + else: + print 'Error: permlink required in make_ags' + if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): + permlink = device_type + '[format "%02d" ${id}]' + node_type + else: + permlink = device_type + '${permlink_device_number}' + node_type + txt += [' hsetprop ${scobj_hpath}/%s permlink data_set "%s"' % (nodename, permlink)] + txt += [' hsetprop ${scobj_hpath}/%s @description "%s"' % (nodename, permlink)] + if 'value' in MyVar: + txt += [' hsetprop ${scobj_hpath}/%s oldval %s' % (nodename, MyVar['value'])] + txt += [' hset ${scobj_hpath}/%s %s' % (nodename, MyVar['value'])] + else: + if MyVar['type'] == 'none': + pass + elif MyVar['type'] == 'int': + txt += [' hsetprop ${scobj_hpath}/%s oldval 0' % nodename] + elif MyVar['type'] == 'float': + txt += [' hsetprop ${scobj_hpath}/%s oldval 0.0' % nodename] + else: + txt += [' hsetprop ${scobj_hpath}/%s oldval UNKNOWN' % nodename] + for key in sorted(MyVar['Property']): + txt += [' hsetprop ${scobj_hpath}/%s %s "%s"' % (nodename, key, MyVar['Property'][key])] + # Generate __ at runtime for nxalias + if 'nxalias' not in MyVar['Property']: + nxalias = '${name}_' + make_path(MyVar) + txt += [' hsetprop ${scobj_hpath}/%s nxalias "%s"' % (nodename, nxalias)] + if not MyGroup['name']: + if 'GroupProperty' in MyGroup: + txt += [''] + for key in sorted(MyGroup['GroupProperty']): + txt += [' hsetprop ${scobj_hpath} %s "%s"' % (key, MyGroup['GroupProperty'][key])] + if readable_or_writeable: + txt += [''] + txt += [' if {[string equal -nocase [SplitReply [%s]] "false"]} {' % MyDriver['simulation_group']] + for var in sorted(MyGroup['Vars']): + MyVar = MyGroup['Vars'][var] + nodename = groupname + MyVar['name'] + if MyVar['readable'] > 0: + poll_period = MyVar['readable'] + if poll_period < 1 or poll_period > 300: + poll_period = 5 + txt += [' ${sct_controller} poll ${scobj_hpath}/%s %s' % (nodename, poll_period)] + for var in sorted(MyGroup['Vars']): + MyVar = MyGroup['Vars'][var] + nodename = groupname + MyVar['name'] + if MyVar['writeable'] > 0 or MyVar['driveable']: + txt += [' ${sct_controller} write ${scobj_hpath}/%s' % nodename] + 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'])] + txt += [' } else {'] + txt += [' %s::sics_log 9 "[%s] => No poll/write for %s"' % (MyDriver['namespace'], MyDriver['simulation_group'], MyDriver['name'])] + txt += [' }'] + for grp in sorted(MyGroup['Groups']): + txt += put_group(MyDriver, MyGroup['Groups'][grp]) + return txt def put_mkDriver(MyDriver): - txt = [''] - if 'make_args' in MyDriver: - line = 'proc %s::mkDriver { sct_controller name %s } {' % (MyDriver['namespace'], MyDriver['make_args']) - else: - line = 'proc %s::mkDriver { sct_controller name } {' % (MyDriver['namespace']) - txt += [line] - if 'make_args' in MyDriver: - make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) - txt += [' %s::sics_log 9 "%s::mkDriver ${sct_controller} ${name} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)] - else: - txt += [' %s::sics_log 9 "%s::mkDriver for ${name}"' % (MyDriver['namespace'], MyDriver['namespace'])] - txt += [' set ns "[namespace current]"'] - txt += [' set catch_status [ catch {'] - txt += [''] - if len(MyDriver['Permlink']) > 0: - if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): - pass + txt = [''] + if 'make_args' in MyDriver: + line = 'proc %s::mkDriver { sct_controller name %s } {' % (MyDriver['namespace'], MyDriver['make_args']) else: - txt += [' set permlink_device_number [format "%02d" [incr ::scobj::permlink_device_counter]]'] - txt += [''] - txt += [' MakeSICSObj ${name} SCT_OBJECT'] - txt += [''] - txt += [' sicslist setatt ${name} klass %s' % MyDriver['class']] - txt += [' sicslist setatt ${name} long_name ${name}'] - if 'DriverProperty' in MyDriver: - for key in MyDriver['DriverProperty']: - txt += [' sicslist setatt ${name} %s "%s"' % (key, MyDriver['DriverProperty'][key])] - txt += [''] - txt += [' set scobj_hpath /sics/${name}'] + line = 'proc %s::mkDriver { sct_controller name } {' % (MyDriver['namespace']) + txt += [line] + if 'make_args' in MyDriver: + make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) + txt += [' %s::sics_log 9 "%s::mkDriver ${sct_controller} ${name} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)] + else: + txt += [' %s::sics_log 9 "%s::mkDriver for ${name}"' % (MyDriver['namespace'], MyDriver['namespace'])] + txt += [' set ns "[namespace current]"'] + txt += [' set catch_status [ catch {'] + txt += [''] + if len(MyDriver['Permlink']) > 0: + if 'make_args' in MyDriver and 'id' in MyDriver['make_args'].split(): + pass + else: + txt += [' set permlink_device_number [format "%02d" [incr ::scobj::permlink_device_counter]]'] + txt += [''] + txt += [' MakeSICSObj ${name} SCT_OBJECT'] + txt += [''] + txt += [' sicslist setatt ${name} klass %s' % MyDriver['class']] + txt += [' sicslist setatt ${name} long_name ${name}'] + if 'DriverProperty' in MyDriver: + for key in MyDriver['DriverProperty']: + txt += [' sicslist setatt ${name} %s "%s"' % (key, MyDriver['DriverProperty'][key])] + txt += [''] + txt += [' set scobj_hpath /sics/${name}'] - for group in sorted(MyDriver['Groups']): - txt += put_group(MyDriver, MyDriver['Groups'][group]) + for group in sorted(MyDriver['Groups']): + txt += put_group(MyDriver, MyDriver['Groups'][group]) - txt += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']] - txt += [' hsetprop ${scobj_hpath} debug_threshold %s' % str(MyDriver['debug_threshold'])] - func = 'mkDriver' - if func in MyDriver['Funcs']: - txt += ['# %s hook code starts' % func] - txt += MyDriver['Funcs'][func]['text'] - txt += ['# %s hook code ends' % func] - else: - txt += ['# %s hook code goes here' % func] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(txt) + txt += [' hsetprop ${scobj_hpath} klass %s' % MyDriver['class']] + txt += [' hsetprop ${scobj_hpath} debug_threshold %s' % str(MyDriver['debug_threshold'])] + func = 'mkDriver' + if func in MyDriver['Funcs']: + txt += ['# %s hook code starts' % func] + txt += MyDriver['Funcs'][func]['text'] + txt += ['# %s hook code ends' % func] + else: + txt += ['# %s hook code goes here' % func] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_postamble(MyDriver): - txt = [''] - txt += ['namespace eval %s {' % MyDriver['namespace']] - txt += [' namespace export debug_threshold'] - txt += [' namespace export debug_log'] - txt += [' namespace export sics_log'] - txt += [' namespace export mkDriver'] - txt += ['}'] - txt += [''] - if 'add_args' in MyDriver: - line = 'proc add_%s {name IP port %s} {' % (MyDriver['name'], MyDriver['add_args']) - else: - line = 'proc add_%s {name IP port} {' % MyDriver['name'] - txt += [line] - txt += [' set catch_status [ catch {'] - if 'make_args' in MyDriver: - make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) - txt += [' %s::sics_log 9 "add_%s ${name} ${IP} ${port} %s"' % (MyDriver['namespace'], MyDriver['name'], make_args)] - else: - txt += [' %s::sics_log 9 "add_%s ${name} ${IP} ${port}"' % (MyDriver['namespace'], MyDriver['name'])] - txt += [' if {[string equal -nocase [SplitReply [%s]] "false"]} {' % MyDriver['simulation_group']] - txt += [' if {[string equal -nocase "aqadapter" "${IP}"]} {'] - txt += [' %s::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}"' % MyDriver['namespace']] - txt += [' makesctcontroller sct_${name} aqadapter ${port}'] - txt += [' } else {'] - if 'protocol_args' in MyDriver: - protocol_args = MyDriver['protocol_args'].replace('\\', '\\\\').replace('"', '\\"') - txt += [' %s::sics_log 9 "makesctcontroller sct_${name} %s ${IP}:${port} %s"' % (MyDriver['namespace'], MyDriver['protocol'], protocol_args)] - txt += [' makesctcontroller sct_${name} %s ${IP}:${port} %s' % (MyDriver['protocol'], MyDriver['protocol_args'])] - else: - txt += [' %s::sics_log 9 "makesctcontroller sct_${name} %s ${IP}:${port}"' % (MyDriver['namespace'], MyDriver['protocol'])] - txt += [' makesctcontroller sct_${name} %s ${IP}:${port}' % MyDriver['protocol']] - txt += [' }'] - txt += [' } else {'] - txt += [' %s::sics_log 9 "[%s] => No sctcontroller for %s"' % (MyDriver['namespace'], MyDriver['simulation_group'], MyDriver['name'])] - txt += [' }'] - if 'make_args' in MyDriver: - make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) - txt += [' %s::sics_log 1 "%s::mkDriver sct_${name} ${name} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)] - txt += [' %s::mkDriver sct_${name} ${name} %s' % (MyDriver['namespace'], make_args)] - else: - txt += [' %s::sics_log 1 "%s::mkDriver sct_${name} ${name}"' % (MyDriver['namespace'], MyDriver['namespace'])] - txt += [' %s::mkDriver sct_${name} ${name}' % (MyDriver['namespace'])] + txt = [''] + txt += ['namespace eval %s {' % MyDriver['namespace']] + txt += [' namespace export debug_threshold'] + txt += [' namespace export debug_log'] + txt += [' namespace export sics_log'] + txt += [' namespace export mkDriver'] + txt += ['}'] + txt += [''] + if 'add_args' in MyDriver: + line = 'proc add_%s {name IP port %s} {' % (MyDriver['name'], MyDriver['add_args']) + else: + line = 'proc add_%s {name IP port} {' % MyDriver['name'] + txt += [line] + txt += [' set catch_status [ catch {'] + if 'make_args' in MyDriver: + make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) + txt += [' %s::sics_log 9 "add_%s ${name} ${IP} ${port} %s"' % (MyDriver['namespace'], MyDriver['name'], make_args)] + else: + txt += [' %s::sics_log 9 "add_%s ${name} ${IP} ${port}"' % (MyDriver['namespace'], MyDriver['name'])] + txt += [' if {[string equal -nocase [SplitReply [%s]] "false"]} {' % MyDriver['simulation_group']] + txt += [' if {[string equal -nocase "aqadapter" "${IP}"]} {'] + txt += [' %s::sics_log 9 "makesctcontroller sct_${name} aqadapter ${port}"' % MyDriver['namespace']] + txt += [' makesctcontroller sct_${name} aqadapter ${port}'] + txt += [' } else {'] + if 'protocol_args' in MyDriver: + protocol_args = MyDriver['protocol_args'].replace('\\', '\\\\').replace('"', '\\"') + txt += [' %s::sics_log 9 "makesctcontroller sct_${name} %s ${IP}:${port} %s"' % (MyDriver['namespace'], MyDriver['protocol'], protocol_args)] + txt += [' makesctcontroller sct_${name} %s ${IP}:${port} %s' % (MyDriver['protocol'], MyDriver['protocol_args'])] + else: + txt += [' %s::sics_log 9 "makesctcontroller sct_${name} %s ${IP}:${port}"' % (MyDriver['namespace'], MyDriver['protocol'])] + txt += [' makesctcontroller sct_${name} %s ${IP}:${port}' % MyDriver['protocol']] + txt += [' }'] + txt += [' } else {'] + txt += [' %s::sics_log 9 "[%s] => No sctcontroller for %s"' % (MyDriver['namespace'], MyDriver['simulation_group'], MyDriver['name'])] + txt += [' }'] + if 'make_args' in MyDriver: + make_args = ' '.join(["${%s}"%arg for arg in MyDriver['make_args'].split()]) + txt += [' %s::sics_log 1 "%s::mkDriver sct_${name} ${name} %s"' % (MyDriver['namespace'], MyDriver['namespace'], make_args)] + txt += [' %s::mkDriver sct_${name} ${name} %s' % (MyDriver['namespace'], make_args)] + else: + txt += [' %s::sics_log 1 "%s::mkDriver sct_${name} ${name}"' % (MyDriver['namespace'], MyDriver['namespace'])] + txt += [' %s::mkDriver sct_${name} ${name}' % (MyDriver['namespace'])] # TODO #txt += [' %s::sics_log "makesctemon ${name} /sics/${name}/emon/monmode /sics/${name}/emon/isintol /sics/${name}/emon/errhandler"' % (MyDriver['namespace'])] # txt += [' makesctemon ${name} /sics/${name}/emon/monmode /sics/${name}/emon/isintol /sics/${name}/emon/errhandler'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - txt += [''] - txt += ['clientput "file evaluation of sct_%s.tcl"' % MyDriver['name']] - txt += ['%s::sics_log 9 "file evaluation of sct_%s.tcl"' % (MyDriver['namespace'], MyDriver['name'])] - emit(txt) + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + txt += [''] + txt += ['clientput "file evaluation of sct_%s.tcl"' % MyDriver['name']] + txt += ['%s::sics_log 9 "file evaluation of sct_%s.tcl"' % (MyDriver['namespace'], MyDriver['name'])] + emit(txt) def put_read_config(MyDriver): - txt = [''] - 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 += [' 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 += [' if { !([dict exists $::config_dict $implementation]) } {'] - txt += [' continue'] - txt += [' }'] - txt += [' set v [dict get $::config_dict $implementation]'] - txt += [' if { !([dict exists $v "driver"]) } {'] - 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 += [' 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 += [' foreach arg {' + MyDriver['make_args'] + '} {'] - txt += [' if {[dict exists $v $arg]} {'] - txt += [' lappend arg_list "[dict get $v $arg]"'] + txt = [''] + 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 += [' 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 += [' if { !([dict exists $::config_dict $implementation]) } {'] + txt += [' continue'] + txt += [' }'] + txt += [' set v [dict get $::config_dict $implementation]'] + txt += [' if { !([dict exists $v "driver"]) } {'] + 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 += [' ${ns}::sics_log 9 "Missing configuration value $arg"'] - txt += [' error "Missing configuration value $arg"'] + 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 += [' 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 += [' }'] - txt += [' add_%s ${name} "aqadapter" ${asyncqueue} {*}$arg_list' % MyDriver['name']] - else: - txt += [' add_%s ${name} "aqadapter" ${asyncqueue}' % MyDriver['name']] - txt += [' }'] - txt += [' }'] - txt += [' }'] - txt += [' }'] - txt += [' } catch_message ]'] - txt += [' handle_exception ${catch_status} ${catch_message}'] - txt += ['}'] - emit(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 += [' }'] + txt += [' }'] + txt += [' }'] + txt += [' }'] + txt += [' } catch_message ]'] + txt += [' handle_exception ${catch_status} ${catch_message}'] + txt += ['}'] + emit(txt) def put_check_config(MyDriver): - txt = [''] - txt += ['if { [info exists ::config_dict] } {'] - txt += [' %s::read_config' % MyDriver['namespace']] - txt += ['} else {'] - txt += [' %s::sics_log 5 "No config dict"' % MyDriver['namespace']] - txt += ['}'] - emit(txt) + txt = [''] + txt += ['if { [info exists ::config_dict] } {'] + txt += [' %s::read_config' % MyDriver['namespace']] + txt += ['} else {'] + txt += [' %s::sics_log 5 "No config dict"' % MyDriver['namespace']] + txt += ['}'] + emit(txt) def put_standard_code(MyDriver): - # emit all of the functions in Funcs - for func in sorted(MyDriver['Funcs']): - theFunc = MyDriver['Funcs'][func] - # Don't generate functions which are not referenced - #if theFunc['reference_count'] == 0: - # continue - if theFunc['type'] == 'read_function': - put_read_function(MyDriver, func); - elif theFunc['type'] == 'write_function': - put_write_function(MyDriver, func); - elif theFunc['type'] == 'fetch_function': - put_fetch_function(MyDriver, func); - elif theFunc['type'] == 'check_function': - put_check_function(MyDriver, func); - elif theFunc['type'] == 'checkrange_function': - put_checkrange_function(MyDriver, func); - elif theFunc['type'] == 'checklimits_function': - put_checklimits_function(MyDriver, func); - elif theFunc['type'] == 'checkstatus_function': - put_checkstatus_function(MyDriver, func); - elif theFunc['type'] == 'halt_function': - put_halt_function(MyDriver, func); - elif theFunc['type'] == 'pid_function': - put_pid_function(MyDriver, func); + # emit all of the functions in Funcs + for func in sorted(MyDriver['Funcs']): + theFunc = MyDriver['Funcs'][func] + # Don't generate functions which are not referenced + #if theFunc['reference_count'] == 0: + # continue + if theFunc['type'] == 'read_function': + put_read_function(MyDriver, func); + elif theFunc['type'] == 'write_function': + put_write_function(MyDriver, func); + elif theFunc['type'] == 'fetch_function': + put_fetch_function(MyDriver, func); + elif theFunc['type'] == 'check_function': + put_check_function(MyDriver, func); + elif theFunc['type'] == 'checkrange_function': + put_checkrange_function(MyDriver, func); + elif theFunc['type'] == 'checklimits_function': + put_checklimits_function(MyDriver, func); + elif theFunc['type'] == 'checkstatus_function': + put_checkstatus_function(MyDriver, func); + elif theFunc['type'] == 'halt_function': + put_halt_function(MyDriver, func); + elif theFunc['type'] == 'pid_function': + put_pid_function(MyDriver, func); def generate_driver(MyDriver): - global NumberOfLinesOut - global fdo - NumberOfLinesOut = 0 - full_filename = filename = "sct_%s.tcl" % MyDriver['name'] - if 'PathName' in MyDriver: - full_filename = os.path.join(MyDriver['PathName'], filename) - fdo = open(full_filename, 'w') - put_preamble(MyDriver) - put_standard_code(MyDriver) - put_mkDriver(MyDriver) - put_postamble(MyDriver) - put_read_config(MyDriver) - put_check_config(MyDriver) - fdo.close() - if CodeDump or Verbose: - print "Code Fragments:", MyDriver['Funcs'] - for f in sorted(MyDriver['Funcs'].keys()): - print "Function:", f, "Type:", MyDriver['Funcs'][f]['type'], '#Uses:', MyDriver['Funcs'][f]['reference_count'] - for l in MyDriver['Funcs'][f]['text']: - print " ", l - print "Produced file %s with %d lines." % (filename, NumberOfLinesOut) + global NumberOfLinesOut + global fdo + NumberOfLinesOut = 0 + full_filename = filename = "sct_%s.tcl" % MyDriver['name'] + if 'PathName' in MyDriver: + full_filename = os.path.join(MyDriver['PathName'], filename) + fdo = open(full_filename, 'w') + put_preamble(MyDriver) + put_standard_code(MyDriver) + put_mkDriver(MyDriver) + put_postamble(MyDriver) + put_read_config(MyDriver) + put_check_config(MyDriver) + fdo.close() + if CodeDump or Verbose: + print "Code Fragments:", MyDriver['Funcs'] + for f in sorted(MyDriver['Funcs'].keys()): + print "Function:", f, "Type:", MyDriver['Funcs'][f]['type'], '#Uses:', MyDriver['Funcs'][f]['reference_count'] + for l in MyDriver['Funcs'][f]['text']: + print " ", l + print "Produced file %s with %d lines." % (filename, NumberOfLinesOut) def process_drivers(TheDrivers): - if Verbose: - print "TheDrivers:", TheDrivers - for driver in TheDrivers: - MyDriver = {'name':driver} - MyDriver['namespace'] = '::scobj::%s' % driver - MyDriver['debug_threshold'] = '5' - MyDriver['Groups'] = {} - MyDriver['Funcs'] = {} - MyDriver['Permlink'] = {} - build_driver(MyDriver, TheDrivers[driver]) if Verbose: - print "MyDriver:", MyDriver['name'], '=', MyDriver - if DriverDump or Verbose: - dump_driver(MyDriver) - generate_driver(MyDriver) + print "TheDrivers:", TheDrivers + for driver in TheDrivers: + MyDriver = {'name':driver} + MyDriver['namespace'] = '::scobj::%s' % driver + MyDriver['debug_threshold'] = '5' + MyDriver['Groups'] = {} + MyDriver['Funcs'] = {} + MyDriver['Permlink'] = {} + build_driver(MyDriver, TheDrivers[driver]) + if Verbose: + print "MyDriver:", MyDriver['name'], '=', MyDriver + if DriverDump or Verbose: + dump_driver(MyDriver) + generate_driver(MyDriver) def process_source(source_files): - global PathName - global TheDrivers - global NumberOfLinesIn + global PathName + global TheDrivers + global NumberOfLinesIn - TheDrivers = {} + TheDrivers = {} - # - # Build the lexer - # - lexer = lex.lex() + # + # Build the lexer + # + lexer = lex.lex() - # - # Build the parser - # - #yaccer = yacc.yacc(tabmodule="gen_sct",outputdir="/tmp",write_tables=0,debug=0) - yaccer = yacc.yacc() + # + # Build the parser + # + #yaccer = yacc.yacc(tabmodule="gen_sct",outputdir="/tmp",write_tables=0,debug=0) + yaccer = yacc.yacc() - for source_file in source_files: - PathName = os.path.realpath(os.path.abspath(os.path.dirname(source_file))) - fd = open(source_file, 'r') - data = fd.read() - fd.close() - NumberOfLinesIn = data.count('\n') - start_line = lexer.lineno - yaccer.parse(data) - stop_line = lexer.lineno - print 'Consumed file %s with %d lines (%d, %d)' % (source_file, - NumberOfLinesIn, start_line, stop_line - 1) - lexer.lineno = 1 + for source_file in source_files: + PathName = os.path.realpath(os.path.abspath(os.path.dirname(source_file))) + fd = open(source_file, 'r') + data = fd.read() + fd.close() + NumberOfLinesIn = data.count('\n') + start_line = lexer.lineno + yaccer.parse(data) + stop_line = lexer.lineno + print 'Consumed file %s with %d lines (%d, %d)' % (source_file, + NumberOfLinesIn, start_line, stop_line - 1) + lexer.lineno = 1 - process_drivers(TheDrivers) + process_drivers(TheDrivers) def main(): - global Verbose - global DriverDump - global CodeDump - import argparse + global Verbose + global DriverDump + global CodeDump + import argparse - parser = argparse.ArgumentParser() - parser.add_argument("-c", "--code", help="dump code", - action="store_true") - parser.add_argument("-d", "--driver", help="dump driver", - action="store_true") - parser.add_argument("-v", "--verbose", help="verbose output", - action="store_true") - parser.add_argument("driver_source", help="driver source file", nargs="*") - args = parser.parse_args() - print args - if args.code: - CodeDump = True - else: - CodeDump = False - if args.driver: - DriverDump = True - else: - DriverDump = False - if args.verbose: - Verbose = True - else: - Verbose = False - source_files = args.driver_source - if source_files: - process_source(source_files) + parser = argparse.ArgumentParser() + parser.add_argument("-c", "--code", help="dump code", + action="store_true") + parser.add_argument("-d", "--driver", help="dump driver", + action="store_true") + parser.add_argument("-v", "--verbose", help="verbose output", + action="store_true") + parser.add_argument("driver_source", help="driver source file", nargs="*") + args = parser.parse_args() + print args + if args.code: + CodeDump = True + else: + CodeDump = False + if args.driver: + DriverDump = True + else: + DriverDump = False + if args.verbose: + Verbose = True + else: + Verbose = False + source_files = args.driver_source + if source_files: + process_source(source_files) if __name__ == "__main__": - main() + main() From 35067c3673e42c1191c65df2b47b3b5c0560e287 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 4 Jul 2014 16:27:44 +1000 Subject: [PATCH 43/72] Clean up Nagelfar warnings in generated drivers --- site_ansto/instrument/util/gen_sct.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 275b9df1..7332b890 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -971,7 +971,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 +1115,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'] From 0dbe7bd53e6791d61ab37ed6ce905c9ed3eaabad Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 11 Jul 2014 10:07:05 +1000 Subject: [PATCH 44/72] Allow empty braces on sct vars and remove semicolons from python code --- site_ansto/instrument/util/gen_sct.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 7332b890..bca5dc3d 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -365,9 +365,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 +681,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 @@ -1478,23 +1479,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 From 5ee7e6719fbdb43f85a0dd4377eb64d5ace956f3 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 11 Jul 2014 10:11:27 +1000 Subject: [PATCH 45/72] Defer makesctdrive to end of mkDriver to avoid possible forward references. --- site_ansto/instrument/util/gen_sct.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index bca5dc3d..7c94502b 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -1284,7 +1284,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 += [' }'] @@ -1328,6 +1328,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] @@ -1530,6 +1535,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 From 4f72bcaaf576b602f4538632d5cb09d3d8a7be79 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 11 Jul 2014 13:18:38 +1000 Subject: [PATCH 46/72] allow legacy sct controllers in generated drivers --- site_ansto/instrument/util/gen_sct.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 7c94502b..162c5caf 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -1426,6 +1426,10 @@ def put_read_config(MyDriver): 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 += [' }'] txt += [' } else {'] txt += [' if { [dict exists $v "asyncprotocol"] } {'] txt += [' set asyncprotocol [dict get $v "asyncprotocol"]'] @@ -1455,9 +1459,17 @@ def put_read_config(MyDriver): txt += [' error "Missing configuration value $arg"'] txt += [' }'] txt += [' }'] - txt += [' add_%s ${name} "aqadapter" ${asyncqueue} {*}$arg_list' % MyDriver['name']] + 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 += [' add_%s ${name} "aqadapter" ${asyncqueue}' % MyDriver['name']] + 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 += [' }'] From 867c6c8eaa2a07e8915035bc4bf0f49d4e7a49a7 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 11 Jul 2014 13:52:37 +1000 Subject: [PATCH 47/72] Generate a wrapper for the old protek driver from a protekmm.sct template. --- .../config/environment/protekmm.sct | 9 ++ .../config/environment/sct_protek_common.tcl | 116 ++------------ .../config/environment/sct_protekmm.tcl | 145 ++++++++++++++++++ .../instrument/hipd/util/sics_config.ini | 2 + .../instrument/hipd/wombat_configuration.tcl | 1 + 5 files changed, 168 insertions(+), 105 deletions(-) create mode 100644 site_ansto/instrument/config/environment/protekmm.sct create mode 100644 site_ansto/instrument/config/environment/sct_protekmm.tcl diff --git a/site_ansto/instrument/config/environment/protekmm.sct b/site_ansto/instrument/config/environment/protekmm.sct new file mode 100644 index 00000000..e8316a8e --- /dev/null +++ b/site_ansto/instrument/config/environment/protekmm.sct @@ -0,0 +1,9 @@ +# vim: ts=8 sts=2 sw=2 expandtab autoindent smartindent nocindent +driver protekmm = { + protocol = protek608 + class = environment + simulation_group = environment_simulation + code mkDriver = {%% + MakeProtek $name $sct_controller + %%} +} diff --git a/site_ansto/instrument/config/environment/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index 08a23bfb..7558835d 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,7 +122,7 @@ 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 {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "return idle"}} { set catch_status [ catch { set sctName "sct_$name" set sobjName "$name" @@ -149,9 +149,6 @@ 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 } @@ -162,102 +159,11 @@ proc MakeProtek {name IP PORT {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "r } -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 $v "datype"] { - set datype [dict get $v "datype"] - } - 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"] } { - 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" - ${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 - ${ns}::sics_log 9 "${name}:${driver}: MakeAsyncProtocol ${asyncprotocol}" - 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] - ${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"]" - } - } - 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" - } - } - ${ns}:sics_log 9 "add_protekmm ${name} aqadapter ${asyncqueue} {*}$arg_list" - 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..f473265d --- /dev/null +++ b/site_ansto/instrument/config/environment/sct_protekmm.tcl @@ -0,0 +1,145 @@ +# 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 } { + ::scobj::protekmm::sics_log 9 "::scobj::protekmm::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 + MakeProtek $name $sct_controller +# 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} { + set catch_status [ catch { + ::scobj::protekmm::sics_log 9 "add_protekmm ${name} ${IP} ${port}" + 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}" + ::scobj::protekmm::mkDriver sct_${name} ${name} + } 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 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"] + 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_protekmm ${name} ${IP} ${PORT} + } else { + add_protekmm ${name} "aqadapter" ${asyncqueue} + } + } + } + } + } + } 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/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 73948379..887f1d2b 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -218,6 +218,7 @@ desc = "This is the default sample stage configuration with xy translation and p imptype = motion_axis [protek_01] +asyncqueue = sct desc = "Protek Multimeter" driver = "protekmm" id = 1 @@ -226,6 +227,7 @@ ip = 10.157.205.36 port = 4001 [protek_02] +asyncqueue = sct desc = "Protek Multimeter" driver = "protekmm" id = 2 diff --git a/site_ansto/instrument/hipd/wombat_configuration.tcl b/site_ansto/instrument/hipd/wombat_configuration.tcl index 2b814471..ae63569d 100644 --- a/site_ansto/instrument/hipd/wombat_configuration.tcl +++ b/site_ansto/instrument/hipd/wombat_configuration.tcl @@ -27,6 +27,7 @@ fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(counter)/counter.tcl fileeval $cfPath(environment)/sct_keithley_2700.tcl fileeval $cfPath(environment)/sct_protek_common.tcl +fileeval $cfPath(environment)/sct_protekmm.tcl #TODO Provide method for choosing environment controller fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl From 47fbb1979ecc9d5f779f0b4b0d62eac09ea3ceb5 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 11 Jul 2014 17:14:08 +1000 Subject: [PATCH 48/72] You can now set the privilege and type for MakeSICSObj in an sct template. --- site_ansto/instrument/config/environment/protekmm.sct | 1 + .../instrument/config/environment/sct_protek_common.tcl | 1 - .../instrument/config/environment/sct_protekmm.tcl | 2 +- site_ansto/instrument/util/gen_sct.py | 9 ++++++++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/site_ansto/instrument/config/environment/protekmm.sct b/site_ansto/instrument/config/environment/protekmm.sct index e8316a8e..68924230 100644 --- a/site_ansto/instrument/config/environment/protekmm.sct +++ b/site_ansto/instrument/config/environment/protekmm.sct @@ -1,6 +1,7 @@ # 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 code mkDriver = {%% diff --git a/site_ansto/instrument/config/environment/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index 7558835d..04621577 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -129,7 +129,6 @@ proc MakeProtek {name sctName {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "r set soState "so_state_$name" clientput "MakeSICSObj $sobjName 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 diff --git a/site_ansto/instrument/config/environment/sct_protekmm.tcl b/site_ansto/instrument/config/environment/sct_protekmm.tcl index f473265d..b7acc976 100644 --- a/site_ansto/instrument/config/environment/sct_protekmm.tcl +++ b/site_ansto/instrument/config/environment/sct_protekmm.tcl @@ -32,7 +32,7 @@ proc ::scobj::protekmm::mkDriver { sct_controller name } { set ns "[namespace current]" set catch_status [ catch { - MakeSICSObj ${name} SCT_OBJECT + MakeSICSObj ${name} SCT_OBJECT user float sicslist setatt ${name} klass environment sicslist setatt ${name} long_name ${name} diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 162c5caf..87d168ca 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 ''' @@ -1313,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}'] From f916462be6022f60da6d37fb98f6c132691d9a95 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 11 Jul 2014 18:28:31 +1000 Subject: [PATCH 49/72] Updated julabo SCT template --- .../environment/temperature/julabo_lh45.sct | 165 ++-- .../temperature/sct_julabo_lh45_gen.tcl | 717 ++++++++++++++++++ 2 files changed, 817 insertions(+), 65 deletions(-) create mode 100644 site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl diff --git a/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct b/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct index 9c3ad69f..1f623c04 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}\r\nversion" + %%} + + code Write_function setValue = {%% + # Put a space between command and param + set cmd "${cmd_str} ${par}" + # Hack to get a response + set cmd "${cmd}\r\nversion" + %%} # # 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 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/sct_julabo_lh45_gen.tcl b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl new file mode 100644 index 00000000..1a0f42a8 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl @@ -0,0 +1,717 @@ +# 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}\r\nversion" +# 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}\r\nversion" +# 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 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_gen"] } { + 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"] + 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] + foreach arg {id ctrl_sensor 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" + } + } + 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" +} From d010e76076c81a560abbed46fde8fbf807d90c15 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 14 Jul 2014 13:18:26 +1000 Subject: [PATCH 50/72] SICS-759 Make asyncprotocol look for the list command in the correct place. --- asyncprotocol.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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); } From 9305d6da53a8bca35fae0855da6494aaa317422f Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Sat, 12 Jul 2014 16:53:13 +1000 Subject: [PATCH 51/72] Don't fetch an implementation if an option is disabled. --- site_ansto/instrument/util/gen_sct.py | 87 ++++++++++++++------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 87d168ca..de3f7457 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -1416,8 +1416,11 @@ def put_read_config(MyDriver): txt += [' if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } {'] txt += [' continue'] txt += [' }'] - txt += [' set name [dict get $v name]'] txt += [' set enabled [string tolower [dict get $v "enabled"]]'] + txt += [' if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } {'] + txt += [' continue'] + txt += [' }'] + txt += [' set name [dict get $v name]'] txt += [' set implementation [dict get $v "implementation"]'] txt += [' if { !([dict exists $::config_dict $implementation]) } {'] txt += [' continue'] @@ -1427,57 +1430,55 @@ 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 += [' if { [string equal -nocase ${asyncqueue} "sct"] } {'] - txt += [' set IP [dict get $v ip]'] - txt += [' set PORT [dict get $v port]'] - 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 += [' }'] - 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 += [' }'] + 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 += [' 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 += [' if { [string equal -nocase ${asyncqueue} "sct"] } {'] - txt += [' add_%s ${name} ${IP} ${PORT} {*}$arg_list' % MyDriver['name']] + txt += [' foreach arg {' + MyDriver['make_args'] + '} {'] + txt += [' if {[dict exists $v $arg]} {'] + txt += [' lappend arg_list "[dict get $v $arg]"'] txt += [' } else {'] - txt += [' add_%s ${name} "aqadapter" ${asyncqueue} {*}$arg_list' % MyDriver['name']] + txt += [' ${ns}::sics_log 9 "Missing configuration value $arg"'] + txt += [' error "Missing configuration value $arg"'] txt += [' }'] + 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 += [' 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 += [' }'] From deb6716f9b3fac3b6954f456891b1cafcf1cd9bc Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Mon, 14 Jul 2014 14:22:17 +1000 Subject: [PATCH 52/72] make_args can now be set in the option section of a sics_config.ini --- site_ansto/instrument/util/gen_sct.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index de3f7457..e6de8e13 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -1411,17 +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 enabled [string tolower [dict get $v "enabled"]]'] + 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 $v name]'] - txt += [' set implementation [dict get $v "implementation"]'] + txt += [' set name [dict get $u name]'] + txt += [' set implementation [dict get $u "implementation"]'] txt += [' if { !([dict exists $::config_dict $implementation]) } {'] txt += [' continue'] txt += [' }'] @@ -1459,15 +1459,21 @@ def put_read_config(MyDriver): txt += [' }'] txt += [' }'] if 'make_args' in MyDriver: - txt += [' set arg_list [list]'] + txt += [' set arg_list [list]'] + txt += [' set missing_list [list]'] txt += [' foreach arg {' + MyDriver['make_args'] + '} {'] - txt += [' if {[dict exists $v $arg]} {'] + 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 += [' error "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 {'] From 6112c8afa0ed6ca2e811ca071f42a17adc7cc9ed Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Mon, 14 Jul 2014 14:27:47 +1000 Subject: [PATCH 53/72] Don't copy 'id' from the option section into the implementation section. The read_config procs should fetch arguments from both the option and implemention sections. --- site_ansto/instrument/util/config_edit.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 18738412..da6b6bfa 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -384,10 +384,6 @@ class InstConfigData(object): enabled = config_desc['enabled'].__str__() self.file_parser.set(config, 'enabled', enabled) - for imp, opt in self.imp2opt_dict.iteritems(): - if imp != 'none' and opt != 'none' and 'id' in self.opt_dict[opt]: - self.file_parser.set(imp, 'id', self.opt_dict[opt]['id']) - scratch_file = self.config_filename + '.scratch' with open(scratch_file, 'w') as cfile: for config in sorted(self.config_dict.keys()): @@ -468,18 +464,22 @@ class InstConfigView(urwid.Frame): return def _msg_hdr(self, msg): + """Display a message after the help string""" hdr = self.help_str + msg self.header_text.set_text(hdr) - def _msg_cb(self, ml, msg): + def _msg_cb(self, main_loop, msg): + """Wrap the message function in an urwid main loop callback""" self._msg_hdr(msg) - def _timed_msg(self, t_sec, msg): + 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, '') - def set_main(self, m): - self.main_loop = m + 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 @@ -488,8 +488,7 @@ class InstConfigView(urwid.Frame): # and sets selection on ImpListBox class InstConfigManager(object): - """Provides controller which keeps data and viewer in sync. - """ + """Provides controller which keeps data and viewer in sync.""" def __init__(self, cf_dat): self.cf_dat = cf_dat @@ -656,7 +655,7 @@ def gen_input_handler(cf_man, cf_dat, cf_viewer): raise urwid.ExitMainLoop() elif key == 'w': cf_dat.backup_files() - cf_viewer._timed_msg(1, ': Saving file') + cf_viewer.timed_msg(1, ': Saving file') cf_dat.write_config_file() elif key in ['right', 'tab']: if cf_viewer.cfg_pile.get_focus() == cf_man.cfg_lb: From 67b8576f356b248b8eb03c682fe51e778006f7ed Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 00:30:17 +1000 Subject: [PATCH 54/72] Modify legacy drivers so that they can be called by sct wrappers and define wrapper templates. --- .../config/environment/agilent_33220A.sct | 9 ++ .../config/environment/keithley_m2700.sct | 12 +++ .../config/environment/protekmm.sct | 4 +- .../config/environment/sct_keithley_2700.tcl | 85 ----------------- .../config/environment/sct_protek_common.tcl | 5 +- .../temperature/eurotherm_m2000.sct | 12 +++ .../temperature/lakeshore_m370.sct | 12 +++ .../config/environment/temperature/ls336.sct | 11 +++ .../config/environment/temperature/ls340.sct | 11 +++ .../environment/temperature/nprvasm2.sct | 11 +++ .../temperature/sct_eurotherm_2000.tcl | 85 ----------------- .../temperature/sct_lakeshore_336.tcl | 94 ------------------- .../temperature/sct_lakeshore_340.tcl | 93 +----------------- .../temperature/sct_lakeshore_370.tcl | 70 -------------- .../environment/temperature/sct_rvasm2.tcl | 1 - .../environment/temperature/sct_watlow_pm.tcl | 84 ----------------- .../environment/temperature/sct_watlow_rm.tcl | 84 ----------------- .../temperature/sct_watlow_st4.tcl | 86 ----------------- .../environment/temperature/watlow_mpm.sct | 12 +++ .../environment/temperature/watlow_mrm.sct | 12 +++ .../environment/temperature/watlow_mst4.sct | 12 +++ .../environment/temperature/west400.tcl | 83 ---------------- .../environment/temperature/west4100.sct | 11 +++ .../sans/config/environment/sct_rheometer.tcl | 3 +- 24 files changed, 134 insertions(+), 768 deletions(-) create mode 100644 site_ansto/instrument/config/environment/agilent_33220A.sct create mode 100644 site_ansto/instrument/config/environment/keithley_m2700.sct create mode 100644 site_ansto/instrument/config/environment/temperature/eurotherm_m2000.sct create mode 100644 site_ansto/instrument/config/environment/temperature/lakeshore_m370.sct create mode 100644 site_ansto/instrument/config/environment/temperature/ls336.sct create mode 100644 site_ansto/instrument/config/environment/temperature/ls340.sct create mode 100644 site_ansto/instrument/config/environment/temperature/nprvasm2.sct create mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mpm.sct create mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mrm.sct create mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mst4.sct create mode 100644 site_ansto/instrument/config/environment/temperature/west4100.sct 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/protekmm.sct b/site_ansto/instrument/config/environment/protekmm.sct index 68924230..e5e3e2f6 100644 --- a/site_ansto/instrument/config/environment/protekmm.sct +++ b/site_ansto/instrument/config/environment/protekmm.sct @@ -4,7 +4,9 @@ driver protekmm = { 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 + MakeProtek $name $sct_controller $id $datype %%} } 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_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index 04621577..0560674c 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -122,12 +122,12 @@ 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 sctName {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 sicslist setatt $sobjName long_name $sobjName @@ -135,6 +135,7 @@ proc MakeProtek {name sctName {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "r 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 read rqVal "reportVal" hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState callBack hsetprop /sics/$sobjName callBack $cbFunc 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/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_lakeshore_336.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl index 872cf795..08bb5196 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl @@ -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 @@ -1910,96 +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"] } { - 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" - ${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 - ${ns}::sics_log 9 "${name}:${driver}: MakeAsyncProtocol ${asyncprotocol}" - 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] - ${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"]" - } - } - 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" - } - } - ${ns}::sics_log 9 "add_lakeshore_336 ${name} aqadapter ${asyncqueue} {*}$arg_list" - 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 a72830b1..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 @@ -2114,92 +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_340.tcl" -::scobj::lakeshore_340::sics_log 9 "file evaluation of sct_lakeshore_340.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"] } { - 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" - ${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 - ${ns}::sics_log 9 "${name}:${driver}: MakeAsyncProtocol ${asyncprotocol}" - 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] - ${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"]" - } - } - 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" - } - } - ${ns}::sics_log 9 "add_lakeshore_340 ${name} aqadapter ${asyncqueue} {*}$arg_list" - 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_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_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/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/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 From 58a64da71265f39bd7cf3c640ea01dd9478d2fb2 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 00:32:18 +1000 Subject: [PATCH 55/72] Wrapper code for legacy drivers. --- .../config/environment/sct_agilent_33220A.tcl | 146 ++++++++++++++++ .../config/environment/sct_keithley_m2700.tcl | 161 ++++++++++++++++++ .../config/environment/sct_protekmm.tcl | 100 ++++++----- .../temperature/sct_eurotherm_m2000.tcl | 161 ++++++++++++++++++ .../temperature/sct_lakeshore_m370.tcl | 156 +++++++++++++++++ .../environment/temperature/sct_ls336.tcl | 161 ++++++++++++++++++ .../environment/temperature/sct_ls340.tcl | 161 ++++++++++++++++++ .../environment/temperature/sct_nprvasm2.tcl | 161 ++++++++++++++++++ .../temperature/sct_watlow_mpm.tcl | 161 ++++++++++++++++++ .../temperature/sct_watlow_mrm.tcl | 161 ++++++++++++++++++ .../temperature/sct_watlow_mst4.tcl | 161 ++++++++++++++++++ .../environment/temperature/sct_west4100.tcl | 156 +++++++++++++++++ .../environment/sct_antonparr_MCR500.tcl | 110 ++++++++++++ 13 files changed, 1914 insertions(+), 42 deletions(-) create mode 100644 site_ansto/instrument/config/environment/sct_agilent_33220A.tcl create mode 100644 site_ansto/instrument/config/environment/sct_keithley_m2700.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_eurotherm_m2000.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_ls336.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_ls340.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_nprvasm2.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_watlow_mpm.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_watlow_mrm.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_watlow_mst4.tcl create mode 100644 site_ansto/instrument/config/environment/temperature/sct_west4100.tcl create mode 100644 site_ansto/instrument/sans/config/environment/sct_antonparr_MCR500.tcl 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_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_protekmm.tcl b/site_ansto/instrument/config/environment/sct_protekmm.tcl index b7acc976..9c8581cb 100644 --- a/site_ansto/instrument/config/environment/sct_protekmm.tcl +++ b/site_ansto/instrument/config/environment/sct_protekmm.tcl @@ -27,8 +27,8 @@ proc ::scobj::protekmm::sics_log {debug_level debug_string} { } catch_message ] } -proc ::scobj::protekmm::mkDriver { sct_controller name } { - ::scobj::protekmm::sics_log 9 "::scobj::protekmm::mkDriver for ${name}" +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 { @@ -41,7 +41,7 @@ proc ::scobj::protekmm::mkDriver { sct_controller name } { hsetprop ${scobj_hpath} klass environment hsetprop ${scobj_hpath} debug_threshold 5 # mkDriver hook code starts - MakeProtek $name $sct_controller + MakeProtek $name $sct_controller $id $datype # mkDriver hook code ends } catch_message ] handle_exception ${catch_status} ${catch_message} @@ -54,9 +54,9 @@ namespace eval ::scobj::protekmm { namespace export mkDriver } -proc add_protekmm {name IP port} { +proc add_protekmm {name IP port id datype} { set catch_status [ catch { - ::scobj::protekmm::sics_log 9 "add_protekmm ${name} ${IP} ${port}" + ::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}" @@ -68,8 +68,8 @@ proc add_protekmm {name 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}" - ::scobj::protekmm::mkDriver sct_${name} ${name} + ::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} } @@ -80,14 +80,17 @@ clientput "file evaluation of sct_protekmm.tcl" proc ::scobj::protekmm::read_config {} { set catch_status [ catch { set ns "::scobj::protekmm" - 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 } @@ -96,41 +99,54 @@ proc ::scobj::protekmm::read_config {} { 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"] - 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 + 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"]" } } - if { [string equal -nocase ${asyncqueue} "sct"] } { - add_protekmm ${name} ${IP} ${PORT} - } else { - add_protekmm ${name} "aqadapter" ${asyncqueue} + 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 + } } } } 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_lakeshore_m370.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl new file mode 100644 index 00000000..f9fd6a91 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl @@ -0,0 +1,156 @@ +# 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 v} $::config_dict { + if { [dict exists $v "implementation"] } { + if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + continue + } + set enabled [string tolower [dict get $v "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $v name] + set implementation [dict get $v "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set arg_list [list] + 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] + foreach arg {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" + } + } + 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_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_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_west4100.tcl b/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl new file mode 100644 index 00000000..0933f6cf --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl @@ -0,0 +1,156 @@ +# 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 v} $::config_dict { + if { [dict exists $v "implementation"] } { + if { !([dict exists $v "name"] && [dict exists $v "enabled"]) } { + continue + } + set enabled [string tolower [dict get $v "enabled"]] + if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { + continue + } + set name [dict get $v name] + set implementation [dict get $v "implementation"] + if { !([dict exists $::config_dict $implementation]) } { + continue + } + set arg_list [list] + 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] + foreach arg {IP dev_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" + } + } + 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/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" +} From ee539a53413cc1837b03c0bb7aca4e6dd623c662 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 00:33:14 +1000 Subject: [PATCH 56/72] Load wrapper code for legacy drivers. --- .../instrument/hipd/wombat_configuration.tcl | 22 ++++++++--- .../instrument/sans/quokka_configuration.tcl | 37 +++++++++++++++---- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/site_ansto/instrument/hipd/wombat_configuration.tcl b/site_ansto/instrument/hipd/wombat_configuration.tcl index ae63569d..87529b6f 100644 --- a/site_ansto/instrument/hipd/wombat_configuration.tcl +++ b/site_ansto/instrument/hipd/wombat_configuration.tcl @@ -25,18 +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_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 -#TODO Provide method for choosing environment controller -fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl -fileeval $cfPath(environment)/temperature/sct_lakeshore_336.tcl -fileeval $cfPath(environment)/temperature/sct_lakeshore_340.tcl -fileeval $cfPath(environment)/temperature/sct_lakeshore_370.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_mercury_scpi.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/sans/quokka_configuration.tcl b/site_ansto/instrument/sans/quokka_configuration.tcl index 686d2307..9b69af8e 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)/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 From c83e5d681c1e2fe9313783b412c391184aedb79e Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 00:34:38 +1000 Subject: [PATCH 57/72] Update sics_config.ini files for Wombat and Quokka. --- .../instrument/hipd/util/sics_config.ini | 97 +++++++++--- .../instrument/sans/util/sics_config.ini | 149 +++++++++++++++--- 2 files changed, 201 insertions(+), 45 deletions(-) diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 887f1d2b..1fc5f2ab 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -4,15 +4,26 @@ 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 @@ -28,36 +39,42 @@ 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 @@ -85,7 +102,6 @@ optype = motion_axis [12tmagnet_oxford] desc = "12 Tesla Oxford Magnet" driver = "oxford_labview" -id = 1 imptype = magnetic_field ip = 10.157.205.3 port = 55001 @@ -96,7 +112,7 @@ imptype = motion_axis [CF1_ls340] desc = "cf1: Bottom loading cryofurnace" -driver = "lakeshore_340" +driver = "ls340" imptype = temperature ip = 10.157.205.43 port = 4001 @@ -104,13 +120,22 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 +[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 @@ -119,8 +144,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 @@ -129,8 +155,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 @@ -139,8 +166,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 @@ -149,8 +177,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 @@ -158,9 +187,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 @@ -169,9 +209,9 @@ tol1 = 1.0 tol2 = 1.0 [ls340_01] -desc = "tc7: Lakeshore 340 temperature controller" -driver = "lakeshore_340" -id = 2 +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" imptype = temperature ip = 137.157.201.86 port = 4001 @@ -180,9 +220,9 @@ tol1 = 1.0 tol2 = 1.0 [ls340_02] -desc = "tc8: Lakeshore 340 temperature controller" -driver = "lakeshore_340" -id = 3 +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" imptype = temperature ip = 137.157.201.86 port = 4002 @@ -190,24 +230,30 @@ 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" -id = 1 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 @@ -221,7 +267,6 @@ imptype = motion_axis asyncqueue = sct desc = "Protek Multimeter" driver = "protekmm" -id = 1 imptype = multimeter ip = 10.157.205.36 port = 4001 @@ -230,7 +275,6 @@ port = 4001 asyncqueue = sct desc = "Protek Multimeter" driver = "protekmm" -id = 2 imptype = multimeter ip = 10.157.205.37 port = 4001 @@ -241,6 +285,7 @@ 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/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini index 76189b90..84691877 100644 --- a/site_ansto/instrument/sans/util/sics_config.ini +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -13,6 +13,15 @@ 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 @@ -20,11 +29,33 @@ enabled = False 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 @@ -39,36 +70,52 @@ 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 @@ -83,6 +130,22 @@ 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 @@ -105,7 +168,7 @@ imptype = motion_axis [CF1_ls340] desc = "cf1: Bottom loading cryofurnace" -driver = "lakeshore_340" +driver = "ls340" imptype = temperature ip = 10.157.205.43 port = 4001 @@ -117,6 +180,26 @@ tol2 = 1.0 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 +speed_name = rhSpeed +torque_name = rhTorque +tol = 0.01 +settle = 5.0 + [bruker_bec1] desc = "Bruker Magnet" driver = "bruker_bec1" @@ -136,8 +219,9 @@ tol = 5.0 type = T [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 @@ -146,8 +230,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 @@ -156,8 +241,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 @@ -166,8 +252,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 @@ -176,8 +263,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 @@ -186,8 +274,9 @@ 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 @@ -196,9 +285,9 @@ tol1 = 1.0 tol2 = 1.0 [ls340_01] -desc = "tc7: Lakeshore 340 temperature controller" -driver = "lakeshore_340" -id = 2 +asyncqueue = sct +desc = "Lakeshore 340 temperature controller" +driver = "ls340" imptype = temperature ip = 137.157.201.86 port = 4001 @@ -207,8 +296,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 @@ -216,6 +306,16 @@ 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" @@ -238,11 +338,20 @@ 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 @@ -250,6 +359,7 @@ ip = 10.157.205.36 port = 4001 [protek_02] +asyncqueue = sct desc = "Protek Multimeter" driver = "protekmm" imptype = multimeter @@ -258,7 +368,7 @@ port = 4001 [watlow_rm] desc = "Watlow RM temperature controller" -driver = "watlow_rm" +driver = "watlow_mrm" imptype = temperature ip = 10.157.205.6 terminator = \r\n @@ -267,6 +377,7 @@ type = T [west4100] desc = "Blue furnace temperature controller" +dev_id = 1 driver = "west4100" imptype = temperature ip = 10.157.205.19 From ac136f342615b4afb1f08929e0001e8fa40a57c6 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 00:35:06 +1000 Subject: [PATCH 58/72] Cleanup legacy Julabo driver. --- .../temperature/sct_julabo_lh45.tcl | 85 ------------------- 1 file changed, 85 deletions(-) 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 5c21a3e6..9dfb08ca 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl @@ -439,88 +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" -} - - From c1b5b558f0654e6ca8aa8d824b21e307ad60da2c Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 10:56:27 +1000 Subject: [PATCH 59/72] Make all sct drivers. --- .../config/chopper/sct_astrium_chopper.tcl | 67 +++++---- .../bilby/config/motors/sct_shutters.tcl | 65 +++++---- .../bilby/config/motors/sct_tank.tcl | 67 +++++---- .../config/environment/sct_hiden_xcs.tcl | 127 ++++++++++-------- .../config/environment/sct_huber_pilot.tcl | 71 +++++----- .../config/environment/sct_isotech_ps.tcl | 67 +++++---- .../config/environment/sct_nhq_200.tcl | 75 ++++++----- .../config/environment/sct_omron_hldc.tcl | 67 +++++---- .../temperature/sct_julabo_lh45_gen.tcl | 95 +++++++------ .../temperature/sct_lakeshore_218.tcl | 65 +++++---- .../temperature/sct_lakeshore_m370.tcl | 27 ++-- .../temperature/sct_mercury_base.tcl | 97 +++++++------ .../temperature/sct_mercury_level.tcl | 87 +++++++----- .../temperature/sct_mercury_pres.tcl | 93 +++++++------ .../temperature/sct_mercury_scpi.tcl | 101 ++++++++------ .../temperature/sct_mercury_temp.tcl | 93 +++++++------ .../temperature/sct_mercury_valve.tcl | 91 ++++++++----- .../temperature/sct_pfeiffer_hg.tcl | 85 +++++++----- .../environment/temperature/sct_west4100.tcl | 27 ++-- .../config/source/sct_reactor_status.tcl | 67 +++++---- 20 files changed, 882 insertions(+), 652 deletions(-) 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/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_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/temperature/sct_julabo_lh45_gen.tcl b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl index 1a0f42a8..441631f5 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl @@ -643,14 +643,17 @@ clientput "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 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 } @@ -659,49 +662,53 @@ proc ::scobj::julabo_lh45_gen::read_config {} { continue } if { [string equal -nocase [dict get $v "driver"] "julabo_lh45_gen"] } { - 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"] - 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 + 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"]" } - } - set arg_list [list] - foreach arg {id ctrl_sensor 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" - } - } - if { [string equal -nocase ${asyncqueue} "sct"] } { - add_julabo_lh45_gen ${name} ${IP} ${PORT} {*}$arg_list + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] } else { - add_julabo_lh45_gen ${name} "aqadapter" ${asyncqueue} {*}$arg_list + 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 } } } 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_m370.tcl b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl index f9fd6a91..85f56563 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_m370.tcl @@ -27,7 +27,7 @@ proc ::scobj::lakeshore_m370::sics_log {debug_level debug_string} { } catch_message ] } -proc ::scobj::lakeshore_m370::mkDriver { sct_controller name tol} { +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 { @@ -80,21 +80,20 @@ clientput "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 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 enabled [string tolower [dict get $v "enabled"]] + set enabled [string tolower [dict get $u "enabled"]] if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { continue } - set name [dict get $v name] - set implementation [dict get $v "implementation"] + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } - set arg_list [list] set v [dict get $::config_dict $implementation] if { !([dict exists $v "driver"]) } { continue @@ -128,15 +127,21 @@ proc ::scobj::lakeshore_m370::read_config {} { ${asyncqueue} timeout "[dict get $v "timeout"]" } } - set arg_list [list] + set arg_list [list] + set missing_list [list] foreach arg {tol} { - if {[dict exists $v $arg]} { + 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" - error "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 { 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_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_west4100.tcl b/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl index 0933f6cf..e65bc7a5 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_west4100.tcl @@ -27,7 +27,7 @@ proc ::scobj::west4100::sics_log {debug_level debug_string} { } catch_message ] } -proc ::scobj::west4100::mkDriver { sct_controller name IP dev_id} { +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 { @@ -80,21 +80,20 @@ clientput "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"]) } { + 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 $v "enabled"]] + set enabled [string tolower [dict get $u "enabled"]] if { ! ([string equal -nocase $enabled "true" ] || [string equal -nocase $enabled "always"]) } { continue } - set name [dict get $v name] - set implementation [dict get $v "implementation"] + set name [dict get $u name] + set implementation [dict get $u "implementation"] if { !([dict exists $::config_dict $implementation]) } { continue } - set arg_list [list] set v [dict get $::config_dict $implementation] if { !([dict exists $v "driver"]) } { continue @@ -128,15 +127,21 @@ proc ::scobj::west4100::read_config {} { ${asyncqueue} timeout "[dict get $v "timeout"]" } } - set arg_list [list] + set arg_list [list] + set missing_list [list] foreach arg {IP dev_id} { - if {[dict exists $v $arg]} { + 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" - error "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 { 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} } } From d892d6c4df108fcb40eb59506defc5fe774e0452 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 12:51:41 +1000 Subject: [PATCH 60/72] Fix broken catch block --- .../instrument/config/environment/sct_protek_common.tcl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/config/environment/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index 0560674c..a5cb7656 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -152,10 +152,8 @@ proc MakeProtek {name sctName CID CTYPE {scale 1.0} {offset 0.0} {interval 0.5} $sctName poll /sics/$soState/state $interval $sctName poll /sics/$sobjName $interval } - } catch_message ] { - handle_exception ${catch_status} ${catch_message} - } - return /sics/$sobjName + } catch_message ] + handle_exception ${catch_status} ${catch_message} } From 4996d84187ff23545942c4090b820fd353e0ae10 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 15:17:59 +1000 Subject: [PATCH 61/72] Set an @description property on the protek sensor reading. --- site_ansto/instrument/config/environment/sct_protek_common.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/site_ansto/instrument/config/environment/sct_protek_common.tcl b/site_ansto/instrument/config/environment/sct_protek_common.tcl index a5cb7656..7ac292d4 100644 --- a/site_ansto/instrument/config/environment/sct_protek_common.tcl +++ b/site_ansto/instrument/config/environment/sct_protek_common.tcl @@ -136,6 +136,7 @@ proc MakeProtek {name sctName CID CTYPE {scale 1.0} {offset 0.0} {interval 0.5} 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 From 739ab393a506c00e52d8b07845f2a49f40fc500a Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 15:20:20 +1000 Subject: [PATCH 62/72] Add an Autolab setup to the Wombat config and fix the mercury configuration. --- site_ansto/instrument/hipd/util/sics_config.ini | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 1fc5f2ab..1bccb114 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -1,6 +1,9 @@ [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,V2:protek_02 +enabled = False [CF1] cascade = T1:CF1_ls340,sample_stage:normal_sample_stage enabled = False @@ -245,15 +248,18 @@ 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 From 994f4a48c13607a5af0719e4a22d3c9f7e1bc869 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Tue, 15 Jul 2014 17:30:51 +1000 Subject: [PATCH 63/72] Add 5T New Zealand magnet configuration to Quokka configuration. --- site_ansto/instrument/sans/util/sics_config.ini | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/site_ansto/instrument/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini index 84691877..81513818 100644 --- a/site_ansto/instrument/sans/util/sics_config.ini +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -166,6 +166,14 @@ port = 55001 desc = "Load the twenty position sample changer configuration" imptype = motion_axis +[5Tmagnet] +desc = "The New Zealand magnet" +driver = twi_smc +imptype = magnetic_field +ip = 137.157.202.79 +port = 4004 +timeout = 2000 + [CF1_ls340] desc = "cf1: Bottom loading cryofurnace" driver = "ls340" @@ -195,10 +203,10 @@ driver = "antonparr_MCR500" imptype = rheometry ip = noip port = noport -speed_name = rhSpeed -torque_name = rhTorque -tol = 0.01 settle = 5.0 +speed_name = rhSpeed +tol = 0.01 +torque_name = rhTorque [bruker_bec1] desc = "Bruker Magnet" From 8849dc90c54dbf350fa6f98e2b7a1e1e253db801 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 15 Jul 2014 10:06:35 +1000 Subject: [PATCH 64/72] SICS-760 Add NOREPLY mechanism in aqadapter and asyncqueue This removes the expectation of a reply when sending is suffixed with "{0}" or "@@NOREPLY@@" or, for asyncqueue, a custom string. --- asyncqueue.c | 36 +++++++++++++++++++++++++++++ site_ansto/hardsup/sct_asyncqueue.c | 11 ++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) 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) From 22b34395c1307b274d99045ab847aa4ca7737cc8 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 15 Jul 2014 12:02:44 +1000 Subject: [PATCH 65/72] SICS-761 Zero the motor step counter for rotary encoders. --- site_ansto/motor_dmc2280.c | 40 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/site_ansto/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index 08db73c6..7209021e 100644 --- a/site_ansto/motor_dmc2280.c +++ b/site_ansto/motor_dmc2280.c @@ -1640,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); @@ -2575,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); @@ -2625,6 +2644,23 @@ 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; + } + 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; + } } while (0); break; case eCommandEvent: From db24e031061bfd83fbf3d0aa29179efa148843fa Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 15 Jul 2014 18:46:35 +1000 Subject: [PATCH 66/72] Add sct driver for New Zealand magnet --- .../environment/magneticField/sct_tsi_smc.tcl | 580 ++++++++++++++++++ .../environment/magneticField/tsi_smc.sct | 79 +++ 2 files changed, 659 insertions(+) create mode 100644 site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl create mode 100644 site_ansto/instrument/config/environment/magneticField/tsi_smc.sct 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..c4f7c720 --- /dev/null +++ b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl @@ -0,0 +1,580 @@ +# 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 } { + ::scobj::tsi_smc::sics_log 9 "::scobj::tsi_smc::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}/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 false + 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 oldval 0.0 + 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 false + hsetprop ${scobj_hpath}/value nxsave true + hsetprop ${scobj_hpath}/value oldval 0.0 + 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" + + 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 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} { + set catch_status [ catch { + ::scobj::tsi_smc::sics_log 9 "add_tsi_smc ${name} ${IP} ${port}" + 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}" + ::scobj::tsi_smc::mkDriver sct_${name} ${name} + } 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"]" + } + } + if { [string equal -nocase ${asyncqueue} "sct"] } { + add_tsi_smc ${name} ${IP} ${PORT} + } else { + add_tsi_smc ${name} "aqadapter" ${asyncqueue} + } + } + } + } + } 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..7a614888 --- /dev/null +++ b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct @@ -0,0 +1,79 @@ +# 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; + + group = { + priv = user; + type = float; + property 'units' = 'G'; + control = true; + data = true; + nxsave = true; + + var 'value'; + var setpoint = { + writeable = 1; + write_function = setGauss; + lowerlimit = 0; upperlimit = 500.0; tolerance = 10; + property settle_time = 5; + 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} + %%} +}; From acec319ee3abdfb2b5b813f566ff00de2b603fca Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 15 Jul 2014 18:51:17 +1000 Subject: [PATCH 67/72] Zeroing rotary encoder motor steps fix --- site_ansto/instrument/TEST_SICS/fakeGalil/galilmotor.py | 2 ++ site_ansto/motor_dmc2280.c | 2 ++ 2 files changed, 4 insertions(+) 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/motor_dmc2280.c b/site_ansto/motor_dmc2280.c index 7209021e..c6a4ee71 100644 --- a/site_ansto/motor_dmc2280.c +++ b/site_ansto/motor_dmc2280.c @@ -2648,6 +2648,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) { cmdStatus(self); self->status_valid = false; self->subState = 4; + return; } else if (self->subState == 4) { /* Status after Zero */ int iRet; @@ -2660,6 +2661,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) { set_lastMotion(self, self->currSteps, self->currCounts); cmdOn(self); self->subState = 1; + return; } } while (0); break; From fd7d369ea23bee09a2f1268dba374b35dab9386e Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 15 Jul 2014 18:51:43 +1000 Subject: [PATCH 68/72] Julabo sct driver to use @@NOREPLY@@ --- .../instrument/config/environment/temperature/julabo_lh45.sct | 4 ++-- .../config/environment/temperature/sct_julabo_lh45_gen.tcl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct b/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct index 1f623c04..e7e78ca5 100644 --- a/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct +++ b/site_ansto/instrument/config/environment/temperature/julabo_lh45.sct @@ -94,14 +94,14 @@ driver julabo_lh45_gen = { # Put a space between command and param set cmd "${cmd_str} ${par}" # Hack to get a response - set cmd "${cmd}\r\nversion" + 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}\r\nversion" + set cmd "${cmd}@@NOREPLY@@" %%} # # This code is after database creation 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 index 441631f5..6fe8aa75 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_julabo_lh45_gen.tcl @@ -311,7 +311,7 @@ proc ::scobj::julabo_lh45_gen::setPoint {tc_root nextState cmd_str} { # Put a space between command and param set cmd "${cmd_str} ${par}" # Hack to get a response - set cmd "${cmd}\r\nversion" + set cmd "${cmd}@@NOREPLY@@" # setPoint hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" @@ -344,7 +344,7 @@ proc ::scobj::julabo_lh45_gen::setValue {tc_root nextState cmd_str} { # Put a space between command and param set cmd "${cmd_str} ${par}" # Hack to get a response - set cmd "${cmd}\r\nversion" + set cmd "${cmd}@@NOREPLY@@" # setValue hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" From b29eecc549852780ff867a0aad5001fb7797f2e3 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 16 Jul 2014 09:28:26 +1000 Subject: [PATCH 69/72] Use V1 with I1 for autolab setup on wombat --- site_ansto/instrument/hipd/util/sics_config.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 1bccb114..b51987bf 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -2,7 +2,7 @@ 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,V2:protek_02 +cascade = sample_stage:normal_sample_stage,I1:protek_01,V1:protek_02 enabled = False [CF1] cascade = T1:CF1_ls340,sample_stage:normal_sample_stage From c03bbdc38e1435d7d4fd47721dac2175ddf6a12b Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 16 Jul 2014 10:11:07 +1000 Subject: [PATCH 70/72] Add permlink to 5T magnet driver and load the driver in the quokka config. --- .../environment/magneticField/sct_tsi_smc.tcl | 34 ++++++++++++++----- .../environment/magneticField/tsi_smc.sct | 4 ++- .../instrument/sans/quokka_configuration.tcl | 2 +- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl index c4f7c720..b9b05149 100644 --- a/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl +++ b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl @@ -263,8 +263,8 @@ proc ::scobj::tsi_smc::setValue {tc_root nextState cmd_str} { handle_exception ${catch_status} ${catch_message} } -proc ::scobj::tsi_smc::mkDriver { sct_controller name } { - ::scobj::tsi_smc::sics_log 9 "::scobj::tsi_smc::mkDriver for ${name}" +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 { @@ -303,6 +303,8 @@ proc ::scobj::tsi_smc::mkDriver { sct_controller name } { hsetprop ${scobj_hpath}/value data true hsetprop ${scobj_hpath}/value mutable false 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 sdsinfo "::nexus::scobj::sdsinfo" hsetprop ${scobj_hpath}/value type "part" @@ -416,6 +418,7 @@ proc ::scobj::tsi_smc::mkDriver { sct_controller name } { 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 @@ -488,9 +491,9 @@ namespace eval ::scobj::tsi_smc { namespace export mkDriver } -proc add_tsi_smc {name IP port} { +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}" + ::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}" @@ -502,8 +505,8 @@ proc add_tsi_smc {name 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}" - ::scobj::tsi_smc::mkDriver sct_${name} ${name} + ::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} } @@ -561,10 +564,25 @@ proc ::scobj::tsi_smc::read_config {} { ${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} + add_tsi_smc ${name} ${IP} ${PORT} {*}$arg_list } else { - add_tsi_smc ${name} "aqadapter" ${asyncqueue} + add_tsi_smc ${name} "aqadapter" ${asyncqueue} {*}$arg_list } } } diff --git a/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct index 7a614888..a5a76759 100644 --- a/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct +++ b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct @@ -4,6 +4,8 @@ driver tsi_smc = { device = Superconducting_Magnet_Controller; protocol = std; class = environment; simulation_group = environment_simulation; + add_args = '{id 1}'; + make_args = 'id'; group = { priv = user; @@ -13,7 +15,7 @@ driver tsi_smc = { data = true; nxsave = true; - var 'value'; + var 'value' = {permlink = 'B.S01'}; var setpoint = { writeable = 1; write_function = setGauss; diff --git a/site_ansto/instrument/sans/quokka_configuration.tcl b/site_ansto/instrument/sans/quokka_configuration.tcl index 9b69af8e..6bdce7e5 100644 --- a/site_ansto/instrument/sans/quokka_configuration.tcl +++ b/site_ansto/instrument/sans/quokka_configuration.tcl @@ -63,7 +63,7 @@ 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)/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 From de264c5f02db81b7ede965abbafc627833891e71 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 16 Jul 2014 10:11:37 +1000 Subject: [PATCH 71/72] Update 5T magnet driver name in Quokka sics_config.ini --- site_ansto/instrument/sans/util/sics_config.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site_ansto/instrument/sans/util/sics_config.ini b/site_ansto/instrument/sans/util/sics_config.ini index 81513818..8a3356b0 100644 --- a/site_ansto/instrument/sans/util/sics_config.ini +++ b/site_ansto/instrument/sans/util/sics_config.ini @@ -168,7 +168,7 @@ imptype = motion_axis [5Tmagnet] desc = "The New Zealand magnet" -driver = twi_smc +driver = tsi_smc imptype = magnetic_field ip = 137.157.202.79 port = 4004 From 0e53fe3757610015651844677d21088306614a0c Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Wed, 16 Jul 2014 11:27:13 +1000 Subject: [PATCH 72/72] Save 5T magnet sensor reading and setpoint. --- .../config/environment/magneticField/sct_tsi_smc.tcl | 11 +++++++++-- .../config/environment/magneticField/tsi_smc.sct | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl index b9b05149..1cab0f7e 100644 --- a/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl +++ b/site_ansto/instrument/config/environment/magneticField/sct_tsi_smc.tcl @@ -286,12 +286,15 @@ proc ::scobj::tsi_smc::mkDriver { sct_controller name id } { hsetprop ${scobj_hpath}/setpoint driveable value hsetprop ${scobj_hpath}/setpoint control true hsetprop ${scobj_hpath}/setpoint data true - hsetprop ${scobj_hpath}/setpoint mutable false + 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" @@ -301,16 +304,20 @@ proc ::scobj::tsi_smc::mkDriver { sct_controller name id } { hfactory ${scobj_hpath}/value plain user float hsetprop ${scobj_hpath}/value control true hsetprop ${scobj_hpath}/value data true - hsetprop ${scobj_hpath}/value mutable false + 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 { diff --git a/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct index a5a76759..704f6d83 100644 --- a/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct +++ b/site_ansto/instrument/config/environment/magneticField/tsi_smc.sct @@ -14,13 +14,18 @@ driver tsi_smc = { control = true; data = true; nxsave = true; + group_property 'data' = true + group_property 'control' = true - var 'value' = {permlink = 'B.S01'}; + 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'; }; };