This topic describes the UPC Script language that can be used to define logical controls of valves and Pump Stations.
The topic is divided into the following subsections:
Simple examples of UPC scripts can be found in the UPC Script Examples topic.
General Notes
This section includes some general notes about the use of UPC Scripts.
Units
- Attribute units, e.g., m, l/s are not defined in the script; User Units are assumed.
Dates
- Dates are specified using ISO Standard 8601 format: YYYY-MM-DD
Global and Local Scripts
UPC Scripts may be set up either as Global or Local scripts.
- All scripts can be stored as Global scripts. Global scripts can set up action definitions targeting more than one regulator, and contain rules with actions which target more than one regulator.
- Rules and / or action definitions that target a single network object only can be stored as a Local Script.
Local Scripts are stored as part of the control for individual network objects. Local Scripts associated with a network objects will override any Global Scripts referring to the object.
In a Local Script, references to the object that the script is associated with can be abbreviated. For example, to define a valve opening in a Global Script, the Valve ID must be specified, followed by the attribute to be controlled:
VALVE K470024.K470023.1 OPENING = 75
In a Local Script stored as part of the control for Valve K470024.K470023.1, this can be abbreviated to just the attribute:
OPENING = 75
Similarly in a Local Script stored as part of the control for a Pump Station, the reference to the Pump Station ID can be omitted.
Global Script:
PST KCH2PMP.KCH20001.1 PUMP 1 = ON AND KCH2PMP.KCH20001.1 PUMP 1 SPEED = 1800
Local Script:
PUMP 1 = ON AND PUMP 1 SPEED = 1800
Evaluation of UPC Script Rules
At the beginning of every time-step all Conditions in all Rules are evaluated to either TRUE or FALSE.
The rules are evaluated in the order they appear in the script to determine which actions should be activated. In general, if activated actions appear to contradict each other or set different values for the same object attribute, the last action in the sequence is used.
The exception to this is when an Action targets a pump station,
e.g.
PST <name> STATE = <state value> PST <name> SPEED = <speed value>
or any indirect action USING a pump station
In this case
- any activated actions targeting individual pumps which appear earlier in the script are overridden
- any actions targeting individual pumps which follow are performed independently
For example:
-
PST name PUMP 1 = ON AND PST name PUMP 2 = OFF PST name STATE = 010
will result in pumps 1 and 3 being switched off and pump 2 on.
-
PST name STATE = 010 PST name PUMP 3 = ON
will result in pump 1 off and pumps 2 and 3 on.
Rules
UPC rules can be written in the general form:
RULE <name> IF <condition 1> THEN <action 1> ELSEIF <condition 2> THEN <action 2> ELSE <action 3> ENDIF
where:
- There may be any number of successive "ELSEIF <condition> THEN <action>" blocks;
- Nested IF...ENDIF blocks can be used
- <name> is a label used to identify the rule and must not contain embedded spaces unless enclosed in double quotes
- <condition 1> and
<condition 2> are conditions which are used to test the state of network objects, or names of predefined conditions.
- For example:
RES NodeName DEPTH < 3.0
tests if the depth in a Reservoir with ID "NodeName" is less than 3.0 (see the Conditions section below for more details)
- For example:
- <action 1>,
<action 2> and
<action 3> are either actions to be performed, or names of predefined actions.
- For example:
PST LinkName PUMP 2 = ON
VAL LinkName OPENING = 45
(see the Actions section below for more details)
- For example:
- In general, any node or link name with embedded blanks must be enclosed in double quotes
Example
RULE rule1 IF RES CRES2 DEPTH < 3.4 THEN PST KCH2PMP.KCH20001.1 PUMP 1 = ON AND PST KCH2PMP.KCH20001.1 PUMP 1 SPEED = 1800 ELSEIF RES CRES2 DEPTH < 3.8 THEN PST KCH2PMP.KCH20001.1 PUMP 1 = ON AND PST KCH2PMP.KCH20001.1 PUMP 1 SPEED = 1500 ELSE PST KCH2PMP.KCH20001.1 PUMP 1 = OFF ENDIF
If the depth in Reservoir CRES2 is less than 3.4, Pump 1 in Pumping Station KCH2PMP.KCH20001.1 will be turned on and set at 1800 rpm.
If the depth in Reservoir CRES2 is between 3.4 and 3.8, Pump 1 in Pumping Station KCH2PMP.KCH20001.1 will be turned on and set at 1500 rpm.
If the depth in Reservoir CRES2 is above 3.8, Pump 1 in Pumping Station KCH2PMP.KCH20001.1 will be turned off.
In this example the first action consists of two separate actions joined by the keyword AND. Any number of sub-actions can be joined in this way whenever an action is expected, see Actions below.
Also, object attributes e.g. "PST KCH2PMP.KCH20001.1 PUMP 1 SPEED" have been used a number of times. In order to simplify the rule, an object attribute can be aliased by defining a variable (see Variables below).
Default Rules
To set a default Rule, use _Default_ as the name of the Rule. e.g.
RULE _Default_ IF TRUE THEN PUMP 1 = ON ENDIF
If none of the other rules defined in the UPC Script are satisfied, the default rule will be applied.
Conditions
Conditions are various tests on the state of network objects or a limited set of network wide run properties.
Conditions are defined by using the CONDITION keyword:
COND[ITION] <name> = <arg 1> {operator 1} <arg 2> {operator 2} <arg 3> ...
where:
- <arg 1> is, or represents, some object attribute, run property or any predefined script object which provides an appropriate numerical or time value
- {operator n} can be any of the relational operators: <, <=, =, >=, >, !=, AND
- <arg 2> is either a number, time value, an expression, another object attribute or any other predefined script object returning a numerical or time value
- The result is either TRUE or FALSE
For example:
Example
COND condition1 = RES CRES2 PRESSURE >= 4 RULE rule1 IF condition1 THEN PST KCH2PMP.KCH20001.1 PUMP 1 = OFF ELSE PST KCH2PMP.KCH20001.1 PUMP 1 = ON ENDIF
If the pressure in Reservoir, CRES2 is more than or equal to 4, Pump 1 in Pumping Station KCH2PMP.KCH20001.1 will be turned off. Otherwise, Pump 1 will be turned on.
When using a Local UPC Script the definition of the Pump Station can be omitted. (See the General Notes section above.)
If the number of the pump is not defined, Pump 1 will be assumed.
<object> <ID> <attribute>
where:
- <object> is the object type (see Object Types below)
- <ID> is the object ID
- <attribute> is the object attribute (see Object Attributes below)
Notes
- For PSTs, conditions can target either the whole pump station or individual pumps in the pump station.
- Condition arguments, can consist of numerical expressions using arithmetic operators (*, /, +, -) to combine numbers or object attributes.
- More complicated conditions can be built by combining simple conditions with logical operators, written, in order of precedence, NOT, NAND, NOR, AND and OR.
Object Types
Allowable object types for use in UPC Script Conditions are detailed below:
RUN is also an allowable object type and can be used to define times and dates and refer to Control Profiles.
Object | Object Type |
---|---|
Nodes |
NODE RES[ERVOIR] FIX[EDHEAD] TRANS[FER] WELL HYD[RANT] |
Links |
LINK PIPE VAL[VE] PST |
Object Groups |
GROUP LINK GROUP RES[ERVOIR] GROUP PST |
Object Attributes
Allowable object attributes for use in UPC Script Conditions are detailed below:
Object | Description | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Nodes |
All Nodes:
RES[ERVOIR]
HYD[RANT]
|
||||||||||||||||||||||||||||||||||
Links |
All Links:
VAL[VE]
PST
|
||||||||||||||||||||||||||||||||||
Object Groups |
GROUP LINK
GROUP RES[ERVOIR]
GROUP PST
|
||||||||||||||||||||||||||||||||||
RUN |
|
Actions
Actions specify the changes to be made to object attributes. Actions can be:
- Direct, e.g. turn a pump on:
PST pstup.pstdn.1 PUMP1 = ON
- Indirect, e.g. using a pump to maintain the level in a reservoir:
RES res_name DEPTH = 3.0 USING UPSTREAM VALVE valve_name
where valve valve_name is used to maintain a level of 3 at reservoir res_name and the valve is upstream from the reservoir, that is, it acts as a pressure reducing valve.
In general, an action can be written as:
<arg 1> = <arg 2>
<arg 1> = <arg 2> USING <stream> <arg 3>
where:
- <arg 1> is, or represents, some allowed object attribute
- <arg 2> is either a number, some script object returning a value or a numerical expression containing numbers and/or any script objects returning values
- the optional keyword USING signifies an indirect control
- stream is either UP[STREAM] or DOWN[STREAM] to indicate that the regulator is either up or downstream from the control point
- <arg 1> and <arg 3> can only specify object attributes and cannot contain arithmetic expressions
Example
COND condition1 = RUN TIME >= 07:00 AND RUN TIME < 10:00 RULE rule1 IF condition1 THEN RES CRES2 DEPTH = 3 USING UPSTREAM PST KCH2PMP.KCH20001.1 ELSE RES CRES2 DEPTH = 2.5 USING UPSTREAM PST KCH2PMP.KCH20001.1 ENDIF
If the time is between 07:00 and 10:00 the depth in Reservoir CRES2 will be maintained at 3 using PST KCH2PMP.KCH20001.1, else a depth of 2.5 will be maintained.
When using a Local UPC Script the definition of the Pump Station can be replaced with REGULATOR:
RES CRES2 DEPTH = 2.5 USING UPSTREAM REGULATOR
Actions can be explicit in a rule or can be given an alias by using the ACTION keyword:
Example
COND condition1 = RUN TIME >= 07:00 AND RUN TIME < 10:00 ACTION action1 RES CRES2 DEPTH = 3 USING UPSTREAM PST KCH2PMP.KCH20001.1 ACTION action2 RES CRES2 DEPTH = 2.5 USING UPSTREAM PST KCH2PMP.KCH20001.1 RULE rule1 IF condition1 THEN action1 ELSE action2 ENDIF
If the time is between 07:00 and 10:00 the depth in Reservoir CRES2 will be maintained at 3 using PST KCH2PMP.KCH20001.1, else a depth of 2.5 will be maintained.
When using a Local UPC Script the definition of the Pump Station can be replaced with REGULATOR:
RES CRES2 DEPTH = 2.5 USING UPSTREAM REGULATOR
ACT[ION] name action
where:
- action is either a single action or a concatenation of sub-actions
ACT[ION] name = action1 AND action2 AND action3 ...
For example:
Example
COND condition1 = RUN TIME >= 07:00 AND RUN TIME < 10:00 ACTION action1 PUMP 1 = ON AND PUMP 1 SPEED = 1500 ACTION action2 PUMP 1 = ON AND PUMP 1 SPEED = 1800 RULE rule1 IF condition1 THEN action1 ELSE action2 ENDIF
Object Attributes
Allowable object attributes for use in UPC Script Actions, depend on whether the Action is Direct or Indirect:
Direct Actions
Object | UPC Attribute | Description |
---|---|---|
VAL[VE] |
OPEN[ING] |
Valve Opening |
PST |
SPEED |
SPEED will set the speed of the first running variable speed pump in PST name against the value speed. Use PUMP followed by the pump number to define speed of a particular pump in the PST. |
STATE |
STATE will set the pump state of all pumps in the PST to the value specified, where ON = 1 and OFF = 0. e.g. STATE = 010 tests for pumps 1 and 3 off and pump 2 on |
|
PUMP |
PST name PUMP number = setting will switch pump number to setting where setting is either ON or OFF. (PUMP implies pump 1 unless followed by the pump number.) |
Indirect Actions
For indirect actions, regulators can only control:
- Head or Pressure at a node
- Depth at a Reservoir
- Flow through a link
Variables
Variables can be used as an alias for object attributes, or numerical expressions involving object attributes.
An alias for an object attribute is defined:
VAR[IABLE] <name> = <object attribute>
Example
COND condition_1 RES res1 DEPTH < 2 VAR var_1 = PST pstup.pstdn.1 PUMP 1 VAR var_2 = PST pstup.pstdn.1 PUMP 1 SPEED COND condition_2 var_2 >= 1450 ACTION action_1 var_name = ON AND var_2 = 1450 RULE rule_name IF condition_1 THEN action_1 ELSEIF RES res1 DEPTH >= 5 THEN IF condition_2 THEN var_2 = 1150 ELSE var_1 = OFF ENDIF ENDIF
var_1 and var_2 are aliases for the state of pump 1 (ON or OFF) and the speed of pump 1.
An alias for a numerical expression is defined:
VAR[IABLE] <name> = <arg 1> {operator 1} <arg 2> {operator 2} <arg 3> ...
VAR[IABLE] <name> <attribute> = <arg 1> {operator 1} <arg 2> {operator 2} <arg 3> ...
where:
- <attribute> (optional) is a single attribute (to specify output units)
- <arg 1>, <arg 2>, <arg 3> etc. can be numbers, object attributes or any script object returning a numerical value
- {operator 1}, {operator 2}, {operator 3} etc. can be +, -, /, *
IF and ELSE can also be used as {operator 1} and {operator 2} respectively:
VAR[IABLE] <name> = <arg 1> IF <arg 2> ELSE <arg 3>
VAR[IABLE] <name> <attribute> = <arg 1> IF <arg 2> ELSE <arg 3>
where:
- <name> = <arg 1> IF <arg 2> is TRUE, ELSE <name> = <arg 3>
- If {operator 2} is not ELSE or <arg 3> is missing, <name> = 0.0 if <arg 2> is FALSE
Using Time Variables
All Time object attributes (DATETIME, DATE, DAY, TIME, DAYTIME, SIMTIME) can be used as Variables. The rules when adding or subtracting these variables are listed below.
When adding Time Variables:
- Two time variables of the same type can be added together
- SIMTIME can be added to any time. The resulting variable type will be:
- DATETIME when adding to DATE or DATETIME
- DAYTIME when adding to DAY, TIME or DAYTIME
- DAY and TIME can be added resulting in a DAYTIME type
When subtracting Time Variables:
- Two time variables of the same type can be subtracted from each other
- SIMTIME can be subtracted from any time. The resulting variable type will be:
- DATETIME when subtracting from DATE or DATETIME
- DAYTIME when subtracting from DAY, TIME or DAYTIME
- DATE or DATETIME can be subtracted from DATE or DATETIME resulting in type SIMTIME
- DAY, TIME or DAYTIME can be subtracted from DAY, TIME or DAYTIME, resulting in type SIMTIME
Using Variables as Accumulators
Variables can be used as accumulators. The accumulator function is achieved by redefining a variable as itself, plus or minus the attribute to be accumulated.
A variable can be re-zeroed using the IF...ELSE form (see above).
Example
RULE _Default_ IF TRUE THEN PUMP 1 = ON ENDIF VAR Outflow = LINK K200032.K200236.1 FLOW VAR CumulativeFlow = Outflow * 300.00000 VAR Total = Total + CumulativeFlow COND Reset = RUN TIME < 00:01 COND Off = Total >= 100000 RULE Off IF Off THEN PUMP 1 = OFF ENDIF VAR Total = 0.00000 IF Reset ELSE Total
The cumulative flow in a link is calculated by using variable Total as an accumulator. When the cumulative flow reaches 100000, Pump1 is switched off.
Timers
A Timer provides a means for measuring time elapsed between specified trigger conditions.
Timers are defined by:
TIMER <name> START <condition 1>
TIMER <name> START <condition 1> RESET <condition 2> PAUSE <condition 3>
where:
- the timer is started if not running when <condition 1> is TRUE
- the timer is stopped and reset to zero (optional) if <condition 2> is TRUE
- the timer is paused (optional) if <condition 3> is TRUE
Conditions can either be explicit or predefined condition names. The output from a timer is the elapsed time in seconds.
Tables
Tables allow the translation from an input value to a new output value where values are given in tabular form. The output value is found either from linear interpolation or from a step function interpretation.
Tables are defined by:
TAB[LE] <name> IN <arg 1> OUT <arg 2> TYPE <type> <data value 1> <data value 2> <data value 1> <data value 2> <data value 1> <data value 2> ... ENDTABLE
where:
- <arg 1> can be: an object attribute, another table name, variable name or timer name
- <arg 2> is the output quantity, e.g. HEAD, FLOW, etc.
- <type> is either LIN[EAR] or STEP
- <data value 1> <data value 2> are data pairs
For example:
Example
COND Time = RUN DATETIME >= 1998-10-01 02:00 AND RUN DATETIME < 1998-10-02 00:00 TABLE NewTable IN RUN DATETIME OUT OPENING TYPE LINEAR 1998-10-01 00:00 100 1998-10-01 12:00 90 1998-10-01 14:00 100 ENDTABLE RULE Time IF Time THEN VALVE K200229.K200230.1 OPENING = NewTable ENDIF
If the time is between 1 Oct 1998 02:00 and 2 Oct 1998 00:00, the opening of Valve K200229.K200230.1 will follow the profile described in Table NewTable.
When using a Local UPC Script the definition of the Valve can be omitted.
Initial Conditions
Initial conditions are defined by using the INITIALISE keyword:
INIT[IALISE] <object> <ID> <attribute> = <attribute value>
where:
- <object> is the regulator type: PST or VALVE
- <ID> is the object ID
- <attribute> is the object attribute: SPEED or STATE for Pump Stations, or OPENING for Valves
- <attribute value> is the numeric value to which the SPEED, STATE or OPENING of the regulator is to be set
For example:
Example
INITIALISE VALVE K470024.K470023.1 OPENING = 75
Initialise the opening of Valve K470024.K470023.1 at 75%.
INITIALISE PST KCH2PMP.KCH20001.1 PUMP 1 SPEED = 1500
Initialise the speed of Pump 1 at Pump Station KCH2PMP.KCH20001.1 at 1500 rpm
When using a Local UPC Script the definition of the PST / Valve can be omitted.
Comments
Comments can be added to a script by using the COMMENT keyword:
COM[MENT] Logical Rule for controlling Pump Station KCH2PMP
Any text on a line following the keyword COM[MENT] is ignored and treated as a comment.