From e971cd8b64a0733131c93176eaff7dea2b3587a0 Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Mon, 30 Jun 2014 09:08:19 +1000 Subject: [PATCH] New sicsconfig.ini file configuration editor. Updated wombat sics_config.ini and gen_sct.py Generated new tcl files from sct templates and modified some old sct_*.tcl drivers. TODO sct_keithley_2700.tcl magneticField/sct_oxford_labview.tcl magneticField/sct_bruker_BEC1.tcl temperature/sct_watlow_st4.tcl temperature/sct_oxford_mercury.tcl temperature/sct_mercury_pres.tcl temperature/sct_julabo_lh45.tcl temperature/sct_lakeshore_340.tcl temperature/sct_julabo_lh45_gen.tcl temperature/sct_watlow_rm.tcl temperature/sct_eurotherm_2000.tcl temperature/sct_lakeshore_336.tcl temperature/sct_watlow_pm.tcl temperature/sct_oxford_itc.tcl temperature/sct_lakeshore_370.tcl temperature/west400.tcl --- .../config/chopper/sct_astrium_chopper.tcl | 7 +- .../bilby/config/motors/sct_shutters.tcl | 7 +- .../bilby/config/motors/sct_tank.tcl | 7 +- .../magneticField/sct_oxford_labview.tcl | 88 ++- .../config/environment/sct_hiden_xcs.tcl | 7 +- .../config/environment/sct_huber_pilot.tcl | 7 +- .../config/environment/sct_isotech_ps.tcl | 7 +- .../config/environment/sct_nhq_200.tcl | 7 +- .../config/environment/sct_omron_hldc.tcl | 7 +- .../temperature/sct_lakeshore_218.tcl | 7 +- .../temperature/sct_lakeshore_336.tcl | 93 ++- .../temperature/sct_lakeshore_340.tcl | 91 ++- .../temperature/sct_mercury_base.tcl | 7 +- .../temperature/sct_mercury_level.tcl | 7 +- .../temperature/sct_mercury_pres.tcl | 7 +- .../temperature/sct_mercury_scpi.tcl | 7 +- .../temperature/sct_mercury_temp.tcl | 7 +- .../temperature/sct_mercury_valve.tcl | 7 +- .../temperature/sct_pfeiffer_hg.tcl | 7 +- .../config/source/sct_reactor_status.tcl | 7 +- .../config/motors/motor_configuration.tcl | 23 +- .../instrument/hipd/util/sics_config.ini | 132 ++-- .../instrument/hipd/wombat_configuration.tcl | 6 +- site_ansto/instrument/util/config_edit.py | 567 +++++++++++------- site_ansto/instrument/util/gen_sct.py | 7 +- 25 files changed, 782 insertions(+), 344 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 c56f12fc..9750f7ee 100644 --- a/site_ansto/instrument/bilby/config/chopper/sct_astrium_chopper.tcl +++ b/site_ansto/instrument/bilby/config/chopper/sct_astrium_chopper.tcl @@ -568,10 +568,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "astrium_chopper" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [chopper_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[chopper_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl index 4685fa3e..49acee34 100644 --- a/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl +++ b/site_ansto/instrument/bilby/config/motors/sct_shutters.tcl @@ -306,10 +306,13 @@ proc ::scobj::shutters::read_config {} { set catch_status [ catch { set ns "::scobj::shutters" dict for {k v} $::config_dict { - if { [dict exists $v "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "shutters" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [motor_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[motor_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/bilby/config/motors/sct_tank.tcl b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl index c781bac7..fe44dece 100644 --- a/site_ansto/instrument/bilby/config/motors/sct_tank.tcl +++ b/site_ansto/instrument/bilby/config/motors/sct_tank.tcl @@ -341,10 +341,13 @@ proc ::scobj::tank::read_config {} { set catch_status [ catch { set ns "::scobj::tank" dict for {k v} $::config_dict { - if { [dict exists $v "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "tank" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [motor_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[motor_simulation] => using null asyncqueue" 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 34b7be6d..4ba20241 100644 --- a/site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl +++ b/site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl @@ -495,7 +495,7 @@ publish OxfordSetHTemp user publish OxfordSetDTemp user publish OxfordSetHS user -proc add_oxmag { name IP PORT {interval 5} } { +proc add_oxford_labview { name IP PORT {interval 5} } { ::scobj::magnetic::mkMagnetic [subst { name $name IP $IP @@ -504,11 +504,83 @@ proc add_oxmag { name IP PORT {interval 5} } { interval $interval }] } - -if { [ info exists ::config_dict ] && [ dict get $::config_dict 12tmagnet enabled ] } { - set IP [dict get $::config_dict 12tmagnet ip] - set PORT [dict get $::config_dict 12tmagnet port] - set NAME [dict get $::config_dict 12tmagnet name] - puts "MAGNET: add_oxmag $NAME $IP $PORT" - add_oxmag $NAME $IP $PORT +# NEW START +namespace eval ::scobj::oxford_labview { +set debug_threshold 5 } +proc ::scobj::oxford_labview::sics_log {debug_level debug_string} { + set catch_status [ catch { + set debug_threshold ${::scobj::oxford_labview::debug_threshold} + if {${debug_level} >= ${debug_threshold}} { + sicslog "::scobj::oxford_labview::${debug_string}" + } + } catch_message ] +} +proc ::scobj::oxford_labview::read_config {} { + set catch_status [ catch { + set ns "::scobj::oxford_labview" + dict for {k v} $::config_dict { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] + if { [dict get $v "driver"] == "oxford_labview" } { + if { $enabled == "true" || $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 {interval} { + if {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + error "Missing configuration value $arg" + } + } + add_oxford_labview ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } + } + } + } + } catch_message ] + handle_exception ${catch_status} ${catch_message} +} + +if { [info exists ::config_dict] } { + ::scobj::oxford_labview::read_config +} else { + ::scobj::oxford_labview::sics_log 5 "No config dict" +} +# NEW END +#OLD START +# if { [ info exists ::config_dict ] && [ dict get $::config_dict 12tmagnet enabled ] } { +# set IP [dict get $::config_dict 12tmagnet ip] +# set PORT [dict get $::config_dict 12tmagnet port] +# set NAME [dict get $::config_dict 12tmagnet name] +# puts "MAGNET: add_oxmag $NAME $IP $PORT" +# add_oxmag $NAME $IP $PORT +# } +#OLD END diff --git a/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl b/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl index e9c0ec96..8b33af39 100644 --- a/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl +++ b/site_ansto/instrument/config/environment/sct_hiden_xcs.tcl @@ -1155,10 +1155,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "hiden_xcs" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/config/environment/sct_huber_pilot.tcl b/site_ansto/instrument/config/environment/sct_huber_pilot.tcl index d879ed90..1acc23c4 100644 --- a/site_ansto/instrument/config/environment/sct_huber_pilot.tcl +++ b/site_ansto/instrument/config/environment/sct_huber_pilot.tcl @@ -459,10 +459,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "huber_pilot" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/config/environment/sct_isotech_ps.tcl b/site_ansto/instrument/config/environment/sct_isotech_ps.tcl index 63e760ed..afc21544 100644 --- a/site_ansto/instrument/config/environment/sct_isotech_ps.tcl +++ b/site_ansto/instrument/config/environment/sct_isotech_ps.tcl @@ -346,10 +346,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "isotech_ps" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/config/environment/sct_nhq_200.tcl b/site_ansto/instrument/config/environment/sct_nhq_200.tcl index 6ea8513f..21d90e09 100644 --- a/site_ansto/instrument/config/environment/sct_nhq_200.tcl +++ b/site_ansto/instrument/config/environment/sct_nhq_200.tcl @@ -706,10 +706,13 @@ proc ::scobj::nhq_200::read_config {} { set catch_status [ catch { set ns "::scobj::nhq_200" dict for {k v} $::config_dict { - if { [dict exists $v "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "nhq_200" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/config/environment/sct_omron_hldc.tcl b/site_ansto/instrument/config/environment/sct_omron_hldc.tcl index 41eb0266..49b18cc3 100644 --- a/site_ansto/instrument/config/environment/sct_omron_hldc.tcl +++ b/site_ansto/instrument/config/environment/sct_omron_hldc.tcl @@ -273,10 +273,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "omron_hldc" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 974c0432..1f0d48dd 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_218.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_218.tcl @@ -339,10 +339,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "lakeshore_218" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 873f5428..00509b7f 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl @@ -1886,7 +1886,7 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # @param port port number on the moxabox (typ. 4001, 4002, 4003, or 4004) # @param tol temperature tolerance in Kelvin (typ. 1) # @return nothing (well, the sct object) -proc add_sct_ls336 {name IP port terminator {_tol1 1.0} {_tol2 1.0} {CID 1} {CTYPE T} {_verbose 0} } { +proc add_lakeshore_336 {name IP port {terminator \r\n} {_tol1 1.0} {_tol2 1.0} {CID 1} {CTYPE T} {_verbose 0} } { # ffr 2009-11-09, Don't create a temperature controller for the script validator, this causes the # lakeshore to lock up. # NOTE: I put this outside the catch block because "return" raises an exception @@ -1896,10 +1896,10 @@ proc add_sct_ls336 {name IP port terminator {_tol1 1.0} {_tol2 1.0} {CID 1} {CTY if {[ catch { if {[string equal -nocase "aqadapter" "${IP}"]} { # dcl 2013-05-27: in this case the port is the name of the AsyncQueue - puts "\nadd_ls336: makesctcontroller sct_ls336_$name aqadapter ${port} for Lakeshore model 336" + puts "\add_lakeshore_336: makesctcontroller sct_ls336_$name aqadapter ${port} for Lakeshore model 336" makesctcontroller sct_ls336_$name aqadapter ${port} } else { - puts "\nadd_ls336: makesctcontroller sct_ls336_$name std ${IP}:$port $terminator for Lakeshore model 336" + puts "\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 @@ -1911,26 +1911,77 @@ proc add_sct_ls336 {name IP port terminator {_tol1 1.0} {_tol2 1.0} {CID 1} {CTY } } -if {[ catch { - if { [ info exists ::config_dict ] } { - dict for {secname secinfo} $::config_dict { - if { [dict exists $secinfo "driver"] && ([dict get $secinfo "driver"] == "ls336") } { - if { [ dict get $::secinfo enabled ] } { - set IP [dict get $::secinfo ip] - set PORT [dict get $::secinfo port] - set name [dict get $::secinfo name] - set ctype [dict get $::secinfo type] - set cid [dict get $::secinfo id] - set term [dict get $::secinfo terminator] - set tol1 [dict get $::secinfo tol1] - set tol2 [dict get $::secinfo tol2] - - add_sct_ls336 $name $IP $PORT $term $tol1 $tol2 $cid $ctype +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 ] +} +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"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] + if { [dict get $v "driver"] == "lakeshore_336" } { + if { $enabled == "true" || $enabled == "always" } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + foreach arg {tol1 tol2 id} { + if {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + error "Missing configuration value $arg" + } + } + add_lakeshore_336 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } } } } - } -} message ]} { - puts "ERROR: $message" + } 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 2bc10804..81af1900 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl @@ -2083,14 +2083,14 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p # end of namespace mk_sct_lakeshore_340 ## -# @brief add_ls340() adds a scriptcontext object for a Lakeshore 336 o 340 temperature controller +# @brief add_lakeshore_340() adds a scriptcontext object for a Lakeshore 336 o 340 temperature controller # and makes it available to SICServer # @param name short name for the temperature controller scriptcontext object (typ. tc1 or tc2) # @param IP IP address of the device (e.g. IP of moxabox that hooks up to the Lakeshore 340) # @param port port number on the moxabox (typ. 4001, 4002, 4003, or 4004) # @param tol temperature tolerance in Kelvin (typ. 1) # @return nothing (well, the sct object) -proc add_sct_ls340 {name IP port terminator {_tol1 1.0} {_tol2 1.0} {CID 1} {CTYPE T} {_verbose 0} } { +proc add_lakeshore_340 {name IP port {terminator \r\n} {_tol1 1.0} {_tol2 1.0} {CID 1} {CTYPE T} {_verbose 0} } { # ffr 2009-11-09, Don't create a temperature controller for the script validator, this causes the # lakeshore to lock up. # NOTE: I put this outside the catch block because "return" raises an exception @@ -2100,10 +2100,10 @@ proc add_sct_ls340 {name IP port terminator {_tol1 1.0} {_tol2 1.0} {CID 1} {CTY if {[ catch { set _ls340_LSmodel 340 if {[string equal -nocase "aqadapter" "${IP}"]} { - puts "\nadd_ls340: makesctcontroller sct_ls340_$name aqadapter ${port} for Lakeshore model 340" + puts "\add_lakeshore_340: makesctcontroller sct_ls340_$name aqadapter ${port} for Lakeshore model 340" makesctcontroller sct_ls340_$name aqadapter ${port} } else { - puts "\nadd_ls340: makesctcontroller sct_ls340_$name std ${IP}:$port $terminator for Lakeshore model 340" + puts "\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 @@ -2111,30 +2111,77 @@ proc add_sct_ls340 {name IP port terminator {_tol1 1.0} {_tol2 1.0} {CID 1} {CTY # set m2 "_2" # makesctemon $name$m2 /sics/$name/emon/monMode_Lp2 /sics/$name/emon/isInTolerance_Lp2 /sics/$name/emon/errhandler } message ]} { - return -code error "in add_ls340: $message" + return -code error "in add_lakeshore_340: $message" } } -if {[ catch { - if { [ info exists ::config_dict ] } { - dict for {secname secinfo} $::config_dict { - if { [dict exists $secinfo "driver"] && ([dict get $secinfo "driver"] == "ls340") } { - if { [ dict get $::secinfo enabled ] } { - set IP [dict get $::secinfo ip] - set PORT [dict get $::secinfo port] - set name [dict get $::secinfo name] - set ctype [dict get $::secinfo type] - set cid [dict get $::secinfo id] - set term [dict get $::secinfo terminator] - set tol1 [dict get $::secinfo tol1] - set tol2 [dict get $::secinfo tol2] - - add_sct_ls340 $name $IP $PORT $term $tol1 $tol2 $cid $ctype +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 ] +} +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"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] + if { [dict get $v "driver"] == "lakeshore_340" } { + if { $enabled == "true" || $enabled == "always" } { + if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { + set asyncqueue "null" + ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" + } elseif { [dict exists $v "asyncqueue"] } { + set asyncqueue [dict get $v "asyncqueue"] + } else { + if { [dict exists $v "asyncprotocol"] } { + set asyncprotocol [dict get $v "asyncprotocol"] + } else { + set asyncprotocol ${name}_protocol + MakeAsyncProtocol ${asyncprotocol} + if { [dict exists $v "terminator"] } { + ${asyncprotocol} sendterminator "[dict get $v "terminator"]" + ${asyncprotocol} replyterminator "[dict get $v "terminator"]" + } + } + set asyncqueue ${name}_queue + set IP [dict get $v ip] + set PORT [dict get $v port] + MakeAsyncQueue ${asyncqueue} ${asyncprotocol} ${IP} ${PORT} + if { [dict exists $v "timeout"] } { + ${asyncqueue} timeout "[dict get $v "timeout"]" + } + } + set arg_list [list] + foreach arg {tol1 tol2 id} { + if {[dict exists $v $arg]} { + lappend arg_list "[dict get $v $arg]" + } else { + ${ns}::sics_log 9 "Missing configuration value $arg" + error "Missing configuration value $arg" + } + } + add_lakeshore_340 ${name} "aqadapter" ${asyncqueue} {*}$arg_list + } } } } + } catch_message ] + handle_exception ${catch_status} ${catch_message} } -} message ]} { - puts "ERROR: $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_mercury_base.tcl b/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl index dd9b6e2b..b88ddb36 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_base.tcl @@ -549,10 +549,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "mercury_base" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 41993631..8630ba24 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_level.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_level.tcl @@ -226,10 +226,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "mercury_level" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 d9ca99b0..08a87c73 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_pres.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_pres.tcl @@ -390,10 +390,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "mercury_pres" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 b83d22c4..e6e76cd7 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_scpi.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_scpi.tcl @@ -745,10 +745,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "mercury_scpi" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 1de9e634..d5d981ff 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_temp.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_temp.tcl @@ -395,10 +395,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "mercury_temp" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 68a5522b..f894889c 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_mercury_valve.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_mercury_valve.tcl @@ -344,10 +344,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "mercury_valve" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" 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 20baf081..69567def 100644 --- a/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl +++ b/site_ansto/instrument/config/environment/temperature/sct_pfeiffer_hg.tcl @@ -494,10 +494,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "pfeiffer_hg" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [environment_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[environment_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/config/source/sct_reactor_status.tcl b/site_ansto/instrument/config/source/sct_reactor_status.tcl index b3dedab2..3379acba 100644 --- a/site_ansto/instrument/config/source/sct_reactor_status.tcl +++ b/site_ansto/instrument/config/source/sct_reactor_status.tcl @@ -345,10 +345,13 @@ 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 "driver"] } { + if { [dict exists $v "implementation"] } { + set name [dict get $v name] + set enabled [string tolower [dict get $v "enabled"]] + set implementation [dict get $v "implementation"] + set v [dict get $::config_dict $implementation] if { [dict get $v "driver"] == "reactor_status" } { if { [dict get $v enabled] } { - set name [dict get $v name] if { ![string equal -nocase [SplitReply [opal_simulation]] "false"] } { set asyncqueue "null" ${ns}::sics_log 9 "[opal_simulation] => using null asyncqueue" diff --git a/site_ansto/instrument/hipd/config/motors/motor_configuration.tcl b/site_ansto/instrument/hipd/config/motors/motor_configuration.tcl index ad8d84b6..6f78edfc 100644 --- a/site_ansto/instrument/hipd/config/motors/motor_configuration.tcl +++ b/site_ansto/instrument/hipd/config/motors/motor_configuration.tcl @@ -111,16 +111,19 @@ set move_count 10 set axis_config 0 if { [ info exists ::config_dict ] } { - if {[ dict get $::config_dict normal_sample_stage enabled ] } { - set axis_config 0 - } elseif {[ dict get $::config_dict eularian_cradle enabled ] } { - set axis_config 1 - } elseif {[ dict get $::config_dict small_omega enabled ] } { - set axis_config 2 - } elseif {[ dict get $::config_dict 12tmagnet_sample_insert enabled ] } { - set axis_config 3 - } else { - set axis_config 0 + if { [ dict exists $::config_dict sample_stage implementation ] } { + set implementation [ dict get $::config_dict sample_stage implementation ] + if {$implementation == "normal_sample_stage"} { + set axis_config 0 + } elseif {$implementation == "eularian_cradle"} { + set axis_config 1 + } elseif {$implementation == "small_omega"} { + set axis_config 2 + } elseif {$implementation == "12tmagnet_sample_insert"} { + set axis_config 3 + } else { + set axis_config 0 + } } } diff --git a/site_ansto/instrument/hipd/util/sics_config.ini b/site_ansto/instrument/hipd/util/sics_config.ini index 9f881c9b..c3ffaafb 100644 --- a/site_ansto/instrument/hipd/util/sics_config.ini +++ b/site_ansto/instrument/hipd/util/sics_config.ini @@ -1,32 +1,76 @@ [12tmagnet] desc = "12 Tesla Oxford Magnet" driver = "12tmagnet" -enabled = False -group = environment:magnet +group = implementation id = 11 ip = 10.157.205.3 name = magnetic port = 55001 type = B +imptype = magnetic_field [12tmagnet_sample_insert] desc = "som will be redefined as the magnet sample insert rotation. Sample stage will be renamed to somss" -enabled = False -group = motors +group = implementation offifon = normal_sample_stage,eularian_cradle,small_omega radio = samstage +imptype = motion_axis + +[Default] +cascade = sample_stage:normal_sample_stage +enabled = True +group = Configuration [12tmagnet_setup] -cascade = 12tmagnet,12tmagnet_sample_insert,mercury_scpi -enabled = False -group = 0setup +cascade = B1:12tmagnet,sample_stage:12tmagnet_sample_insert,T1:mercury_scpi +enabled = True +group = Configuration onifoff = normal_sample_stage [CF1] -desc = "cf1: Bottom loading cryofurnace" -driver = "ls340" +cascade = T1:CF1_ls340,sample_stage:normal_sample_stage enabled = False -group = environment:temperature +group = Configuration + +[T1] +name = tc1 +enabled = True +group = Configuration Components +implementation = mercury_scpi +type = temperature + +[T2] +name = tc2 +enabled = False +group = Configuration Components +implementation = ls336_02 +type = temperature + +[T3] +name = tc3 +enabled = False +group = Configuration Components +implementation = ls336_04 +type = temperature + +[B1] +name = magnet1 +enabled = True +group = Configuration Components +implementation = 12tmagnet +type = magnetic_field + +[sample_stage] +name = sample_stage +enabled = Always +group = Configuration Components +implementation = 12tmagnet_sample_insert +type = motion_axis + +[CF1_ls340] +desc = "cf1: Bottom loading cryofurnace" +driver = "lakeshore_340" +group = implementation id = 12 ip = 10.157.205.43 name = cf1 @@ -35,19 +79,19 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [eularian_cradle] desc = "Load the Eulerian cradle configuration" -enabled = False -group = motors +group = implementation offifon = normal_sample_stage,small_omega,12tmagnet_sample_insert radio = samstage +imptype = motion_axis [ls336_01] desc = "tc1: Lakeshore 336 temperature controller" -driver = "ls336" -enabled = False -group = environment:temperature +driver = "lakeshore_336" +group = implementation id = 1 ip = 10.157.205.28 name = tc1 @@ -56,12 +100,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls336_02] desc = "tc2: Lakeshore 336 temperature controller" -driver = "ls336" -enabled = False -group = environment:temperature +driver = "lakeshore_336" +group = implementation id = 2 ip = 10.157.205.29 name = tc2 @@ -70,12 +114,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls336_04] desc = "tc3: Lakeshore 336 temperature controller" -driver = "ls336" -enabled = False -group = environment:temperature +driver = "lakeshore_336" +group = implementation id = 3 ip = 10.157.205.30 name = tc3 @@ -84,12 +128,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls336_05] desc = "tc4: Lakeshore 336 temperature controller" -driver = "ls336" -enabled = False -group = environment:temperature +driver = "lakeshore_336" +group = implementation id = 4 ip = 137.157.201.21 name = tc4 @@ -98,12 +142,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls336_06] desc = "tc5: Lakeshore 336 temperature controller" -driver = "ls336" -enabled = False -group = environment:temperature +driver = "lakeshore_336" +group = implementation id = 5 ip = 137.157.201.21 name = tc5 @@ -112,12 +156,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls336_12] desc = "tc6: Lakeshore 336 temperature controller" -driver = "ls336" -enabled = False -group = environment:temperature +driver = "lakeshore_336" +group = implementation id = 6 ip = 10.157.205.31 name = tc6 @@ -126,11 +170,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls340_01] desc = "tc7: Lakeshore 340 temperature controller" -enabled = False -group = environment:temperature +group = implementation +driver = "lakeshore_340" id = 7 ip = 137.157.201.86 name = tc7 @@ -139,11 +184,12 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [ls340_02] desc = "tc8: Lakeshore 340 temperature controller" -enabled = False -group = environment:temperature +group = implementation +driver = "lakeshore_340" id = 8 ip = 137.157.201.86 name = tc8 @@ -152,42 +198,42 @@ terminator = \r\n tol1 = 1.0 tol2 = 1.0 type = T +imptype = temperature [mercury_scpi] desc = "tc9: Oxford Mercury temperature controller in Mercury mode" driver = "mercury_scpi" -enabled = False -group = environment:temperature +group = implementation id = 9 ip = 10.157.205.5 name = tc9 -offifon = mercury_itc500 port = 7020 terminator = \r tol = 2.0 type = T +imptype = temperature [normal_sample_stage] desc = "This is the default sample stage configuration with xy translation and phi and chi tilt stages" -enabled = True -group = motors +group = implementation offifon = eularian_cradle,small_omega,12tmagnet_sample_insert radio = samstage +imptype = motion_axis [small_omega] desc = "Load the small omega configuration" -enabled = False -group = motors +group = implementation offifon = normal_sample_stage,eularian_cradle,12tmagnet_sample_insert radio = samstage +imptype = motion_axis [west4100] desc = "tc10: Blue furnace temperature controller" driver = "west4100" -enabled = False -group = environment:temperature +group = implementation id = 10 ip = 10.157.205.19 name = tc10 type = T +imptype = temperature diff --git a/site_ansto/instrument/hipd/wombat_configuration.tcl b/site_ansto/instrument/hipd/wombat_configuration.tcl index 7512cde2..cd29c804 100644 --- a/site_ansto/instrument/hipd/wombat_configuration.tcl +++ b/site_ansto/instrument/hipd/wombat_configuration.tcl @@ -76,9 +76,9 @@ SetVoltScale 2000.0 # LS336 01 at 205.28 # LS336 02 at 205.29 -add_sct_ls336 tc2 10.157.205.30 7777 "\r\n" 1.0 1.0 -add_sct_ls336 tc1 10.157.205.31 7777 "\r\n" 1.0 1.0 -add_sct_ls340 tc3 137.157.201.86 4001 "\r\n" 1.0 1.0 +# add_sct_ls336 tc2 10.157.205.30 7777 "\r\n" 1.0 1.0 +# add_sct_ls336 tc1 10.157.205.31 7777 "\r\n" 1.0 1.0 +# add_sct_ls340 tc3 137.157.201.86 4001 "\r\n" 1.0 1.0 server_init ########################################### diff --git a/site_ansto/instrument/util/config_edit.py b/site_ansto/instrument/util/config_edit.py index 481d6bf6..a5ce4d7c 100755 --- a/site_ansto/instrument/util/config_edit.py +++ b/site_ansto/instrument/util/config_edit.py @@ -1,236 +1,401 @@ #!/usr/bin/env python # vim: tabstop=8 softtabstop=2 shiftwidth=2 nocin si et ft=python +# View Screen has 3 parts +# (SICS Configuration), (Configuration Components), (Component Implementation) +# Uses MVC implemented as InstConfigData, InstConfigView, ConfigEdit +# +# InstConfigData <>--- ConfigParser.SafeConfig +# |--set_cfparse() + +# ConfigEdit <>--- InstConfigData, PresentationData +# |--set_cfdata(), set_presdata() +# |--set_xyz_data() call self.cfgdata.set_xyz() methods +# +# urwid.Frame +# ^ +# InstConfigView <>--- ConfigEdit, PresentationData +# |--set_cfedit(), set_presdata() +# +# PresentationData +# |--set_cfdata() + +# TODO +# cfgini = ConfigParser.SafeConfig() +# cfgdata = InstConfigData() +# DONE presentation = PresentationData() +# cfgedit = ConfigEdit() +# DONE cf_viewer = InstConfigView() + +# config = ConfigParser.SafeConfig() +# cfgdata.set_cfparse(config) +# presentation.set_cfdata(cfgdata) +# cfgedit.set_cfdata(cfgdata) +# cfgedit.set_presdata(presentation) +# cf_viewer.set_cfedit(cfgedit) +# cf_viewer.set_presdata(presentation) +# +# cf_viewer calls self.cfgedit.set_xyz_data() methods on state change +# cf_viewer + import os -import sys +import argparse +import ConfigParser +import urwid +import copy +from collections import defaultdict -global config -global verbose -global depth_list, line_list -config = None -verbose = False -depth_list = [] -line_list = [] -Radio_Groups = {} -def read_config_file(config_filename): - import ConfigParser - config = ConfigParser.SafeConfigParser() - config.read(config_filename) - return config +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) -def reread_config_file(config_filename, cb_list): - config = read_config_file(config_filename) - for cb in cb_list: - lbl = cb.original_widget.get_label() - if ":" in lbl: - lbl = lbl.split(":")[0] - state = False - if 'enabled' in config.options(lbl): - if config.get(lbl, 'enabled').lower() in ['1', 'yes', 'true']: - state = True - config.set(lbl, 'enabled', str(state)) - cb.original_widget.set_state(state, False) - return config + # opt_dict: dict of configuration options as defined below, + # {optname:{'enabled': T/F/Always, 'imptype':type, 'selected_imp':dflt}} + opt_dict = defaultdict(dict) -def write_config_file(config, config_filename): - for idx in range(8, 0, -1): - if os.path.exists(config_filename + "." + str(idx)): - os.rename(config_filename + "." + str(idx), - config_filename + "." + str(idx + 1)) - if os.path.exists(config_filename): - os.rename(config_filename, config_filename + ".1") - with open(config_filename, "wb") as configfile: - for section in sorted(config.sections()): - configfile.write("[%s]\n" % section) - for option in sorted(config.options(section)): - configfile.write("%s = %s\n" % (option, config.get(section, option))) - configfile.write("\n") - #config.write(configfile) + # imp_dict: dict of implementations indexed by type, + # {type: [impname] } + imp_dict = defaultdict(list) -def do_cascade(config, name, cb_list, label, new_state): - global depth_list - try: - if name in depth_list: - depth_list.append(name) - raise Exception("Recursion on " + str(depth_list)) - depth_list.append(name) - if label in config.options(name): - cascade_list = config.get(name, label).lower().split(",") - for cb in cb_list: - lbl = cb.original_widget.get_label().lower() - if ":" in lbl: - lbl = lbl.split(":")[0] - if lbl in cascade_list: - cb.original_widget.set_state(new_state) - finally: - depth_list.pop() + def __init__(self): + return -def main(config_filename): - import urwid - global config + 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 - config = read_config_file(config_filename) - text_header = ( - u"SICS Config Editor! SPACE/ENTER: Toggle, w/W/F12: Write+Exit\n" - u"UP/DOWN/PAGE UP/PAGE DOWN: scroll, r/R: Reread, q/Q/F8: Quit") + 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, 'type') + 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 checkbox_change(check_box, new_state, user_data): - global config, verbose, depth_list, line_list - if len(depth_list) == 0: - line_list = [] - frame.footer = urwid.AttrMap(urwid.Text(""), 'header') - config.set(user_data, 'enabled', str(new_state)) - if verbose: - line = u"Checkbox: name=%s, new_state=%s, user_data=%s" % ( - check_box.get_label(), str(new_state), str(user_data)) - line_list.append(line + "\n") - frame.footer = urwid.AttrMap(urwid.Text(line_list), 'header') - try: - order = ['offifoff', 'offifon', 'onifon', 'onifoff', 'cascade'] - if 'order' in config.options(user_data): - order = config.get(user_data, 'order').lower().split(",") - for item in order: - if 'cascade' == item: - do_cascade(config, user_data, cb_list, 'cascade', new_state) - if (True == new_state) and 'onifon' == item: - do_cascade(config, user_data, cb_list, 'onifon', True) - if (True == new_state) and 'offifon' == item: - do_cascade(config, user_data, cb_list, 'offifon', False) - if (False == new_state) and 'onifoff' == item: - do_cascade(config, user_data, cb_list, 'onifoff', True) - if (False == new_state) and 'offifoff' == item: - do_cascade(config, user_data, cb_list, 'offifoff', False) - except Exception as prang: - line = "Exception: %s" % prang - line_list.append(line + "\n") - frame.footer = urwid.AttrMap(urwid.Text(line_list), 'header') + 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 - text_cb_list = list(config.sections()) - cb_map = {} - for txt in sorted(text_cb_list): - if 'group' in config.options(txt): - group = config.get(txt, 'group').lower() - else: - group = "" - if group not in cb_map: - cb_map[group] = [] - cb_map[group].append(txt) - lb_list = [] - cb_list = [] - for key in sorted(cb_map.keys()): - if len(key) > 0: - lb_list.append(urwid.AttrMap(urwid.Text("Group: %s" % key), 'bright')) - for txt in sorted(cb_map[key]): - state = False - if 'enabled' in config.options(txt): - if config.get(txt, 'enabled').lower() in ['1', 'yes', 'true']: - state = True - config.set(txt, 'enabled', str(state)) - cb_text = txt - if 'group' in config.options(txt) or 'desc' in config.options(txt): - cb_text += ": (" - if 'group' in config.options(txt): - cb_text += config.get(txt, 'group').strip("\"") + ": " - if 'desc' in config.options(txt): - cb_text += config.get(txt, 'desc').strip("\"") - cb_text += ")" - if 'radio' in config.options(txt): - radio = config.get(txt, 'radio').strip("\"") - if radio not in Radio_Groups: - Radio_Groups[radio] = [] - cb = urwid.AttrMap(urwid.RadioButton( - Radio_Groups[radio], - cb_text, - state=state, - on_state_change=checkbox_change, - user_data=txt), 'buttn', 'buttnf') + 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) + + 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() + 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): + os.rename(self.config_filename, self.config_filename + ".1") + return + + def write_config_file(self): + for item,dict in self.opt_dict.iteritems(): + if self.file_parser.get(item, 'enabled').lower() == 'always': + enabled = 'Always' else: - cb = urwid.AttrMap(urwid.CheckBox(cb_text, - state=state, - on_state_change=checkbox_change, - user_data=txt), 'buttn', 'buttnf') - cb_list.append(cb) - lb_list.append(cb) + 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, 'type', dict['imptype']) + for item,dict in self.configuration_dict.iteritems(): + enabled = dict['enabled'].__str__() + self.file_parser.set(item, 'enabled', enabled) + with open(self.config_filename,'w') as cfile: + self.file_parser.write(cfile) - def fcc(focus): - frame.footer = urwid.AttrMap(urwid.Text( - [u"Focus: " + str(focus)]), 'header') + def cf_statechange(self, checkbox, new_state, udat=None): + cfg_id = checkbox.get_label() + self.configuration_dict[cfg_id]['enabled'] = new_state + + def opt_statechange(self, checkbox, new_state, udat=None): + opt = checkbox.get_label() + dbg.msg(3, 'InstConfigData:opt_statechange({},{},{})'.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() + dbg.msg(self.msg_index, 'InstConfigData:imp_statechange({},{},{})'.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 - blank = urwid.Divider() - listbox_content = [ - blank, - urwid.Padding(urwid.GridFlow( - cb_list, - 76, 1, 0, 'left'), - left=2, right=2, min_width=76), - blank, - blank - ] +## TODO Configuration Editor +## Configuration Viewer +Palette = [ + ('body', 'dark cyan', '', 'standout'), + ('focus', 'dark red', '', 'standout'), + ('head', 'light red', 'black'), +] - header = urwid.AttrMap(urwid.Text(text_header), 'header') - sflw = urwid.SimpleListWalker(lb_list) - listbox = urwid.ListBox(sflw) - frame = urwid.Frame(urwid.AttrMap(listbox, 'body'), header=header) - frame.footer = urwid.AttrMap(urwid.Text(""), 'header') +#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) - palette = [ - ('body', 'black', 'light gray', 'standout'), - ('reverse', 'light gray', 'black'), - ('header', 'white', 'dark red', 'bold'), - ('important', 'dark blue', 'light gray', ('standout', 'underline')), - ('editfc', 'white', 'dark blue', 'bold'), - ('editbx', 'light gray', 'dark blue'), - ('editcp', 'black', 'light gray', 'standout'), - ('bright', 'dark gray', 'light gray', ('bold', 'standout')), - ('buttn', 'black', 'dark cyan'), - ('buttnf', 'white', 'dark blue', 'bold'), - ] + super(RadioButtonListWalker, self).__init__(mapped_rb_list) + return - def unhandled(key): - global config - if key in ['w', 'W', 'f12']: - write_config_file(config, config_filename) - raise urwid.ExitMainLoop() - elif key in ['r', 'R']: - config = reread_config_file(config_filename, cb_list) - elif key in ['e', 'E', 'f4']: - f = sflw.get_focus() - frame.footer = urwid.AttrMap(urwid.Text([u"EditE: " + str(dir(f[0]))]), 'header') - elif key in ['q', 'Q', 'f8']: - raise urwid.ExitMainLoop() -# elif key in ['b', 'B']: -# l = sflw[1].base_widget -# f = l.focus_cell -# b = l.cells.index(f) -# l.cells.insert(b + 1, urwid.AttrMap(urwid.Edit(edit_text=u"Hello"), 'header')) -# l.set_focus(b + 1) -# frame.footer = urwid.AttrMap(urwid.Text([u"EditB: " + str(b)]), 'header') + +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({}) -> 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: - if not key[0] == 'mouse release': - frame.footer = urwid.AttrMap(urwid.Text([u"Press: " + str(key)]), 'header') - - urwid.MainLoop(frame, palette, unhandled_input=unhandled).run() + return super(ClosedListBox, self).keypress(size, key) -if '__main__'==__name__: - global verbose - import argparse +# List of Checkboxes +class OptionListBox(ClosedListBox): + def __init__(self, listwalker): + super(OptionListBox, self).__init__(listwalker) + return - # set default_ini to the name of the file to edit when no name is supplied +# Contains OptionListWalker dict indexed by option +# Contains ImpListBox +# Connects OptionListWalker 'focus_change' signal to update_imp_lb handler +# Tracks selected implementation for each option +# and sets selection on ImpListBox +class InstConfigManager: + cf_msg_index = 8 + options = [] + imp_lw_dict = {} + def __init__(self, cfdat): + self.cfdat = cfdat + urwid.register_signal(InstConfigManager, ['focus_change']) + for opt,dict in cfdat.opt_dict.iteritems(): + self.options.append((opt, dict['imptype'])) + imp_items = [] + for imp in cfdat.imp_dict[dict['imptype']]: + if imp == dict['selected_imp']: + imp_items.append((imp, True)) + else: + imp_items.append((imp, False)) + + imp_items.sort() + self.imp_lw_dict[opt] = RadioButtonListWalker(imp_items, on_state_change=self.imp_statechange, user_data=opt) + + self.options.sort() + self.option_lw = OptionListWalker(cfdat.opt_dict, self.opt_statechange) + opt = self.options[0][0] + self.imp_lb = ImpListBox(copy.copy(self.imp_lw_dict[opt])) + 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) + self.config_lb = OptionListBox(self.cfg_lw) + self.opt_lb = OptionListBox(self.option_lw) + return + + def cf_statechange(self, button, new_state, udat=None): + self.cfdat.cf_statechange(button, new_state, udat) + b = button.get_label() + cascade = self.cfdat.configuration_dict[b]['cascade_list'] + if new_state == True: + for opt in self.cfdat.opt_dict.keys(): + if self.cfdat.opt_dict[opt]['permanent'] == False: + self.option_lw.button_dict[opt].set_state(False) + for opt,imp in cascade: + self.option_lw.button_dict[opt].set_state(True) + self.imp_lw_dict[opt].button_dict[imp].set_state(True) + + dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({},{},{}), cascade = {}'.format(b, new_state, udat, cascade)) + self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8 + return + + def opt_statechange(self, button, new_state, udat=None): + self.cfdat.opt_statechange(button, new_state, udat) + return + + def imp_statechange(self, button, new_state, udat=None): + self.cfdat.imp_statechange(button, new_state, udat) + return + + def update_imp_lb(self, pos): + optname = self.options[pos][0] + type = self.options[pos][1] + mstr = 'InstConfigManager:update_imp_lb({}) -> select {}'.format(pos, type) + dbg.msg(1, mstr) + self.imp_lb.use_listwalker(self.imp_lw_dict[optname]) + 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 = {} + 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 {}'.format(msgID)) + self.msgTextDict[msgID] = msgText + self.msglist.append(urwid.AttrMap(msgText, 'body', 'focus')) + + mlw = urwid.SimpleListWalker(self.msglist) + self.mlb = urwid.ListBox(mlw) + return + + def msg(self, index, msg): + if self.enabled: + mid = self.msg_ids[index] + self.msgTextDict[mid].set_text(msg) + return + + +dbg = DEBUG(enabled=True) +def main(config_ini): + global cf_dat, cf_man, cf_viewer + # Make configuration data + cf_dat = InstConfigData() + cf_dat.read_config_file(config_ini) + + # Make configuration editor + cf_man = InstConfigManager(cf_dat) + + # Make configuration viewer + cf_viewer = InstConfigView(cf_dat, cf_man, dbg.mlb) + urwid.MainLoop(cf_viewer, Palette, unhandled_input=cf_viewer.keyinput).run() + 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 infor in the footer") + 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) - if args.verbose: - verbose = True main(default_ini) - diff --git a/site_ansto/instrument/util/gen_sct.py b/site_ansto/instrument/util/gen_sct.py index 02d55c68..dcae9424 100755 --- a/site_ansto/instrument/util/gen_sct.py +++ b/site_ansto/instrument/util/gen_sct.py @@ -1399,10 +1399,13 @@ def put_read_config(MyDriver): txt += [' set catch_status [ catch {'] txt += [' set ns "%s"' % MyDriver['namespace']] txt += [' dict for {k v} $::config_dict {'] - txt += [' if { [dict exists $v "driver"] } {'] + txt += [' if { [dict exists $v "implementation"] } {'] + txt += [' set name [dict get $v name]'] + txt += [' set enabled [string tolower [dict get $v "enabled"]]'] + txt += [' set implementation [dict get $v "implementation"]'] + txt += [' set v [dict get $::config_dict $implementation]'] txt += [' if { [dict get $v "driver"] == "%s" } {' % MyDriver['name']] txt += [' if { [dict get $v enabled] } {'] - txt += [' set name [dict get $v name]'] 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']]