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:
- General Notes
- Rules
- Conditions
- Actions
- Variables
- Timers
- Tables
- Initial Conditions
- Comments
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
PST name SPEED = speed
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 condition1 THEN
action1
ELSEIF condition2 THEN
action2
ELSE
action3
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
- condition1 and condition2 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)
- action1, action2, action3 are either actions to be performed, or names of predefined actions. For example: PST LinkName PUMP 2 = ON or VAL LinkName OPENING = 45 (see the Actions section below for more details)
- 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:
CON[DITION] name = arg1 operator1 arg2 operator2 arg3 ...
where:
- arg1 is, or represents, some object attribute, run property or any predefined script object which provides an appropriate numerical or time value;
- operator can be any of the relational operators <, <=, =, >=, >, !=, and
- arg2 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.
Allowable object attributes for use in conditions take the form
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:
arg1 = arg2 [USING stream arg3]
where:
- arg1 is, or represents, some allowed object attribute
- arg2 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
- arg1 and arg3 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 [attribute] = arg1 operator1 arg2 operator2 arg3 ...
where:
- attribute (optional) is a single attribute (to specify output units)
- arg1, arg2, arg3, etc. can be numbers, object attributes or any script object returning a numerical value
- operator1, operator2, operator3 etc. can be +, -, /, *
IF and ELSE can also be used as operator1 and operator2 respectively:
VAR[IABLE] name [attribute] = arg1 IF arg2 ELSE arg3
where:
- name = arg1 IF arg2 is TRUE, ELSE name = arg3
- If operator2 is not ELSE or arg3 is missing, name = 0.0 if arg2 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 condition1 [RESET condition2] [PAUSE condition3]
where:
- the timer is started if not running when cond1 is TRUE
- the timer is stopped and reset to zero if cond2 is TRUE
- the timer is paused if cond3 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 arg1 OUT arg2 TYPE type
data1 data2
data1 data2
data1 data2
...
ENDTABLE
where:
- arg1 can be: an object attribute, another table name, variable name or timer name
- arg2 is the output quantity, e.g. HEAD, FLOW, etc.
- type is either LIN[EAR] or [STEP]
- data1 data2 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.