Mpod device code implementation details

Details of the code implementation are given. The idea is to get the reader to the a level where coding solutions can be understood and changes can be made efficiently.

Updating property values

The device.py bound api base class inherited by mpod.py does not, apologies if wrong, impose a policy of not sending ‘unchanged’ property values. Hence, mpod.py overwrites set() with a version that removes unchanged properties from the (key, value or hash) input parameters before calling the base class set().

An ‘unchanged’ channel (V,I) value is defined by the channel state. When the channel has reached a constant state (ON or OFF, TRIPPED, ERROR) values are defined to be ‘unchanged’. In other states property value changes are not ‘unchanged’ and will be updated.

Special treatment of some ISEG HV channel properties

OutputSupervisionMinSenseVoltage, OutputSupervisionMaxSenseVoltage and OutputSupervisionMaxPower properties are reported as “not-a-number” (nan). As such their values, if any, cannot be read or set. This constellation is probably related to f/w and h/w of HV channels - there is no sense measurement and power is not an issue for very low current HV channels. The same read/set issues are present when snmpget/set tools are used, therefore the problem is unlikely to be psynmp or the related karabo s/w implementation.

OutputSupervisionMaxTerminalVoltage for negative supplies can only be read and set as a positive number. This is also seen when using snmpget/get.

$ pwd
/home/xbeam/cy_caslab_work/snmp/ireasoning/mibbrowser
$ snmpget -v 2c -M mibs -m WIENER-CRATE-MIB -c guru exflqr18568 outputConfigMaxTerminalVoltage.u1
WIENER-CRATE-MIB::outputConfigMaxTerminalVoltage.u1 = Opaque: Float: -10000.000000 V
$ snmpget -v 2c -M mibs -m WIENER-CRATE-MIB -c guru exflqr18568 outputSupervisionMaxTerminalVoltage.u1
WIENER-CRATE-MIB::outputSupervisionMaxTerminalVoltage.u1 = Opaque: Float: 10000.000000 V
$ snmpset -v 2c -M mibs -m WIENER-CRATE-MIB -c guru exflqr18568 outputSupervisionMaxTerminalVoltage.u1 F -10000.0
WIENER-CRATE-MIB::outputSupervisionMaxTerminalVoltage.u1 = Opaque: Float: 10000.000000 V
$ snmpset -v 2c -M mibs -m WIENER-CRATE-MIB -c guru exflqr18568 outputSupervisionMaxTerminalVoltage.u1 F -5000.0
WIENER-CRATE-MIB::outputSupervisionMaxTerminalVoltage.u1 = Opaque: Float: 10000.000000 V
$ snmpget -v 2c -M mibs -m WIENER-CRATE-MIB -c guru exflqr18568 outputSupervisionMaxTerminalVoltage.u1
WIENER-CRATE-MIB::outputSupervisionMaxTerminalVoltage.u1 = Opaque: Float: 10000.000000 V

The side-effect of this is that outputConfigMaxTerminalVoltage (the channel’s maximum output voltage which is fixed by the manufacturer has -ve or +ve parity) absolute value is used as the maxInc limit on outputSupervisionMaxTerminalVoltage with the minInc value set to 0.0. Target voltage maxInc and minInc limit values are set to the value of outputSupervisionMaxTerminalVoltage with the sign defined by outputConfigMaxTerminalVoltage.

Special treatment of V and I set values, their s/w limits and h/w actions

This section describes how:

  • s/w limit properties are used to limit the maximum and minimum settable values of Target voltage and Maximum current properties via their maxInc and minInc attribute.
  • s/w limits can be used to define the threshold V or I value which when exceeded will cause the controller’s f/w to act on the channel output, e.g. to turn the channel OFF. This activity is referred to as supervision-behaviour in the mpod manual.

Channel supervision-behaviour is easier to understand by breaking it down into two parts:

  • the supervisor evaluates if channel-value exceeds threshold-value clauses for fault conditions:

    • MinSenseVoltageFailure - LV channels
    • MaxSenseVoltageFailure - LV channels
    • MaxTerminalVoltageFailure - LV and HV channels
    • MaxCurrentFailure - LV and HV channels
    • MaxTemperatureFailure - LV and HV(?) channels
    • MaxPowerFailure - LV channels
    • InhibitFailure - LV channels
    • TimeoutFailure - LV(?) and HV channels
  • the action performed if the clause is True can be:
    • ignore
    • channelOff
    • groupOff
    • crateOff

The supervisor continuously evaluates all clauses of all channels and supervisionBehaviorCheckBox should be used to set the action required per channel to avoid unexpected behaviour. As indicated not all clauses apply to both LV and HV (no 4-wire sense measurement, etc) channels and where not applicable their actions should be set to ignore.

The above discussion exposes a triple property partition

  • operation properties, the values of which the operator would like to set
    • Target voltage is the operator specified channel target voltage when the channel is ON.
    • Maximum current is the operator specified maximum current the channel can drive when ON.
  • applied limit properties, which define maxInc, minInc, and behaviour
    • s/w (max) applied V limit is the s/w limit of the channel sense voltage
    • s/w (max abs) applied V limit is the s/w limit of the channel terminal voltage
    • s/w (max) applied I limit is the s/w limit of the channel current
  • supply maximum properties fixed by the board h/w capabilities
    • h/w (max) supplied V limit is the maximum channel voltage the supply h/w can deliver.
    • h/w (max) supplied I limit is the maximum channel current the supply h/w can deliver.
    • SupervisionBehavior in words lists all actions applied to the channel.

Note that MinSenseVoltageFailure channel maxInc, minInc attribute setting is not yet implemented in mpod.py.

Maximum current LV and HV channel maxInc, minInc attribute and behaviour value sources:

LimitSource Property attribute set to value of
VENDOR supervisionMaxCurrent MaxInc configMaxCurrent
supervisionMaxCurrent MinInc 0.0
current MaxInc configMaxCurrent
current MinInc 0.0
USER supervisionMaxCurrent MaxInc configMaxCurrent
supervisionMaxCurrent MinInc 0.0
current MaxInc supervisionMaxCurrent
current MinInc 0.0

Target voltage LV channel maxInc, minInc attribute and behaviour value sources:

LimitSource Property attribute set to value of
VENDOR supervisionMaxSenseVoltage MaxInc configMaxSenseVoltage
supervisionMaxSenseVoltage MinInc 0.0
voltage MaxInc configMaxSenseVoltage
voltage MinInc 0.0
USER supervisionMaxSenseVoltage MaxInc configMaxSenseVoltage
supervisionMaxSenseVoltage MinInc 0.0
voltage MaxInc supervisionMaxSenseVoltage
voltage MinInc 0.0

Target voltage HV channel behaviour value sources:

LimitSource Property attribute set to value of
VENDOR supervisionMaxTerminalVoltage MaxInc fabs(configMaxTerminalVoltage) + 0.15
supervisionMaxTerminalVoltage MinInc -0.15
USER supervisionMaxTerminalVoltage MaxInc fabs(configMaxTerminalVoltage) + 0.01
supervisionMaxTerminalVoltage MinInc -0.01

Target voltage HV -ve channel maxInc and minInc value sources:

LimitSource Property attribute set to value of
VENDOR voltage MaxInc 0.01
voltage MinInc -1.0 * fabs(configMaxTerminalVoltage) + 0.01
USER voltage MaxInc 0.01
voltage MaxInc -1.0 * fabs(supervisionMaxTerminalVoltage) + 0.01

Target voltage HV +ve channel maxInc and minInc value sources:

LimitSource Property attribute set to value of
VENDOR voltage MaxInc fabs(configMaxTerminalVoltage)
voltage MinInc -0.01
USER voltage MaxInc fabs(supervisionMaxTerminalVoltage)
voltage MaxInc | -0.01

Controlling maxInc and minInc attribute setting whilst STARTING

Processing in the STARTING state provides two phases during which attributes can be set.

  • Phase 1. immediately following crate board channel discovery when the crate’s currently set values, i.e. those in NVRAM, are used.
  • Phase 2. later when a saved configuration is loading, which may not have the same values set as those previously found in NVRAM.

Which attribute values are set when mpod.py enters ACTIVE is controlled by properties shown in the picture of mpod.py’s configuration view below.

Phase 1 control is via V limit source and I limit source, where

  • NONE - sets no attributes
  • VENDOR - sets supply maximum property values to both operation and applied limit properties
  • USER - sets applied limit properties to operation, and supply maximum values to applied mimit properties.

Phase 2 control is via Loadfile limit source, where

  • NONE = do not update attribute values
  • USER = set values found in the configuration load file

Phase 2 is disabled if Load channel configs is False.

vi_attributes

Controlling maxInc and minInc attribute setting whilst ACTIVE

GUI and CLI client requested value changes to operation and applied limit properties mpod.py use preReconfigure() code to insert maxInc and minInc attributes according according to the USER definition shown in the tables above.

Loading a configuration file applies maxInc, minInc attribute and behaviour value sources as in STARTING Phase 2. Whilst ACTIVE the value of Load channel configs is ignored.

Controlling behaviour settings during STARTING and whilst ACTIVE

The values of a s/w applied property is not controlled by property flags. The Phase 1 NVRAM value found is used unless updated by Phase 2 or GUI/CLU requests. More importantly the behaviour action follows the same pattern.

Special treatment of LV channel User Config settings

Control of LV channel voltage regulation and external interlock is performed through setting or clearing bits in a f/w RW integer. The s/w device uses the ChannelUserConfig (derived from MpodCsrBitEnum(Enum)) to manipulate the set and clear:

>>> from enum import Enum, unique
>>> from mpodConstants import *
>>> [print(x) for x in ChannelUserConfig]
name bitNoOffRampdown mask 0x1 rbox 0x1 rdef 0x0 rest 0xfffffffe
   desc "Bit 0: No voltage rampdown at switch off"
name bitRegulation1to30m mask 0x2 rbox 0xe rdef 0x8 rest 0xfffffff1
   desc "Bit 1: Output regulation for 1 to 30 meter cables"
name bitRegulationAbove30m mask 0x4 rbox 0xe rdef 0x8 rest 0xfffffff1
   desc "Bit 2: Output regulation for 30+ meter cables"
name bitRegulationOutputVoltage mask 0x8 rbox 0xe rdef 0x8 rest 0xfffffff1
   desc "Bit 3: Output regulation for short or no cables (sense loopback)"
name bitExternalInhibitEnabled mask 0x10 rbox 0x10 rdef 0x0 rest 0xffffffef
   desc "Bit 4: External inhibit enabled"
name bitDisableGlobalInhibit mask 0x20 rbox 0x20 rdef 0x0 rest 0xffffffdf
   desc "Bit 5: Disable global inhibit"
name bitAutomaticPowerOn mask 0x40 rbox 0x40 rdef 0x0 rest 0xffffffbf
   desc "Bit 6: Automatically power on after main switch on"

Warning

Bit 3 should be set when cables less than 1 meter and when no cables are connected. Additionally connecting longer cables at the supply but not at the load can cause unexpected behaviour if the the 4-wire sense measurement lines are not connected directly at the load connector as the sense feedback is then broken.

Note

The Mpod manual definitions for Bit 1 thru 3 are strange and their implementation in the s/w device is as follows. The setting where Bit 1 and 2 are both set is not allowed - the manual states that this setting should not be used, the s/w does not allow both to be set. The setting where Bit 1 and 2 are both clear is for cables of less than 1 meter, the s/w does not allow both to be clear, instead Bit 4 has to be used.

Bits 1 thru 3 requiring radio-box functionality, one and only one must be set. Bits 0 and 4-6 require check-box functionality. It would be attractive to do both selections in a combined GUI-client widget sending the resulting integer to the client, but this is not supported in the GUI and might be difficult in a CLI-client. Instead the following s/w device properties are used to emulate radio- and check-box functionality:

  • userConfig, a readOnly integer containing the bit settings written to and read from the crate controller.
  • userConfigCheckBox, a node of reconfigurable booleans one per user bit definition.

This requires additional device side code

  • preReconfigure() - bit value change requests are caught, their content (set or clear) are integrated into userConfig, with bit 3 set if bits 1 and 2 are clear. If userConfig changes, then both it and additionally changed bits, i.e. bit 3, are added to the incoming hash for setting on preConfiguration return. The changed userConfig is also sent to the f/w.
  • preReconfigure() - the bit handling implemented should provide similar results for CLI- and GUI-clients. The single action of clearing a radio-box bit can have a side-effect of setting a default bit. Setting or clearing multiple bits is implemented by blocking all changes to separate channels together.
  • pollingmpod() - the read userConfig value is decomposed into all userConfigCheckBox property values. All are set. Note that no attempt is made to apply a correct bit 1 thru 3 (radio-box) setting, this is delegated to the configuration application stage.

Warning

In initial device s/w versions only userConfig was present and consequently reconfigurable, but with the introduction of userConfigCheckBox it is now readOnly.

Special treatment of HV and LV channel Supervision Behavior settings

Control of how the controller f/w reacts when channel properties exceed or undercut threshold values is controlled by the supervisionBehavior status word. Two bit fields are associated with the channels reaction to MinSenseVoltage, MaxSenseVoltage, MaxTerminalVoltage, MaxCurrent, MaxTemperature, MaxPower, Inhibit and Timeout failures. For LV channels the 2 bit fields have the following meaning: 0x0 = ignore failure, 0x1 = switch channel off, 0x2 = switch all channels with the same group number off, and 0x3 = switch off the complete crate. For HV channels 0x0 = ignore, 0x1 = switch channel off by ramping down, 0x2 = switch channel off with ‘Emergency off’, and 0x3 switch entire board off with ‘Emergency off’.

A similar implementation route has been taken by expanding the 2-bit field values into 4 check-box booleans, using s/w device properties

  • supervisionBehavior, a readOnly integer containing the bit settings written to and read from the crate controller.
  • supervisionBehaviorCheckBox, a node of reconfigurable booleans one per user action definition.

Controlling channel property exposure and whether readOnly or reconfigurable

Channel property schema definition functions are in vchannel.py. Which definition, readonly (RO) or reconfigurable (RW), is used for a LV or HV channel and whether it is exposed (applied) is determined by the type property setting before application instantiation. The value of type selects which (defined by an expert) list of properties are used.

The type property lists are defined in the ChannelViews class in mpodViewables.py. The definitions used in vchannel.py and mpodViewables.py allow the lists of properties to be built without error if an auto-complete editor is used based on the schema insertion function name which is a concatenation of the key name of the property, whether it is readOnly or reconfigurable, and whether it is applied to LV or HV channels. Lists containing voltage_RO_HV will result in readOnly ‘voltage’ key properties appearing in a HV channel configurator panel view.

The s/w device’s channel schemas are rebuilt according to the property list chosen and injected during transition through the STARTING state by mpodRebuildSchema() which additionally adds dependencies and must-be-present properties, removes identical duplicates, and removes lesser precedence property definitions (as required). Required property dependencies are added into the list immediately before the property requiring them. Must-be-properties are added to the tail of the list. Duplicate properties have their tail end instance removed. Lesser precedence (RO) are removed keeping the higher precedence (RW) properties. The ordering of adding and removing properties aims at producing a GUI-client configurator panel which should be as close as possible to that aimed at by the specifier of the list.

Simple awk scripts are useful if internals of mpodViewables.py require modification due to changes in vchannel.py follow.

$ grep 'def sf' vchannel.py | awk -F ' ' '{print $2}' |
awk -F '(' '{print $1}' | awk -F '_' '{print $2"_"$3"_"$4}' |
awk -F '_'
'/_LV/ {print "    "$0"    = (sf_"$0", \""$1"\", True, False, [], None)";
next};
/_HV/ {print "    "$0"    = (sf_"$0", \""$1"\", False, True, [], None)";
next}' | sort

produces output like

voltage_RO_HV    = (sf_voltage_RO_HV, "voltage", False, True, [], None)
voltage_RO_LV    = (sf_voltage_RO_LV, "voltage", True, False, [], None)

which can be pasted directly into mpodViewables.py. Similarly, for imports

$ grep 'def sf' vchannel.py | awk -F ' ' '{print $2}' |
awk -F '(' '{print "    "$1","}' | sort

The decision to itemize property schema definitions and provide type lists of properties results partially from the lack of access authorization limits to the UI-Clients ‘who-sees-what’ property access mechanism. If the latter appears then the special treatment outlined here may collapse into a single list.

Channel ON/OFF ‘switch’ and ‘operator’ differences

switch and operator properties (displayed names “Switch” and “Operator’s switch”, respectively) are used to request change of channel state, i.e. turn ON, OFF, etc.

The channel operator property shadows the switch property and provides a text version (‘off’, ‘on’,…) of the latter (0, 1,…). UI-Client changes to either are applied automatically to the other. There is however a difference, switch is directly coupled to the RW register of the channel’s f/w and is updated on every poll cycle and currently switch updates are not applied to operator. The reason lies in the different handling of actions initiated. LV and HV channel switch stable state values are 0 and 1 indicating OFF and ON, respectively, but when turn ON or OFF actions are requested the following is found:

  • For LV channels:
    • To turn an ON channel OFF requires setting switch = 0, the request is granted, but the f/w sets switch back to 1 until the channel is OFF.
  • For HV channels:
    • the value of switch remains as requested throughout the action

Not applying switch f/w updates to operator provides the operator with a WYSIWYG view of the last channel request action and alignment of switch and operator is required only on entering the ACTIVE state.