Control rules#

Note

Engine: OpenSWMM 6 — refactored.

solver.controls is a MutableSequence of ControlRule records over the [CONTROLS] block, plus runtime link-override helpers.

Reference: openswmm_controls.h.


Quickstart#

from openswmm.engine import Solver

with Solver("model.inp") as s:
    # Append a rule.
    s.controls.append(\"\"\"
        RULE r1
          IF NODE J1 DEPTH > 1.0
          THEN ORIFICE OR1 SETTING = 0.5
    \"\"\")

    # Iterate / inspect.
    for rule in s.controls:
        print(rule.id, rule.text)

    # Direct runtime actions on a link.
    s.controls.set_link_setting("OR1", 0.25)
    s.controls.set_link_status("OR1", closed=False)

Controls — MutableSequence#

Operation

What it does

len(s.controls) / s.controls[i] / for r in s.controls:

Container protocol over ControlRule records.

s.controls.append(text)

Append a rule. Accepts a raw string, a ControlRule, or {"text": ...}.

s.controls.insert(i, text)

Insert in the middle. Emulated by clear + rebuild.

del s.controls[i] / s.controls.clear()

Remove entries.

s.controls.remove_rule(i)

Remove a single rule by zero-based index; later rule indices shift down by one. Raises IndexError if i is out of range.

Direct runtime actions#

Method

What it does

set_link_setting(link, setting)

Set the link’s control setting. link accepts int | str.

set_link_status(link, *, closed)

Open / close the link.

validate_message(rule_text)

Check a rule without adding it. Returns (ok, message)ok is True and message empty when the rule parses, otherwise False with the engine’s error description.

Validate a rule before appending it:

ok, msg = s.controls.validate_message(rule_text)
if not ok:
    raise ValueError(f"bad rule: {msg}")
s.controls.append(rule_text)

Find rules that reference an object#

find_references(object_name) scans every rule’s clauses for an object-type keyword (NODE, LINK, CONDUIT, PUMP, ORIFICE, WEIR, OUTLET) immediately followed by object_name (case-insensitive) and returns the ascending list of matching zero-based rule indices. It is read-only — no rule text is edited. Combine it with remove_rule() to prune rules before deleting an object:

for i in reversed(s.controls.find_references("OR1")):
    s.controls.remove_rule(i)     # delete from the end so indices stay valid

See also#