Connectivity Rule Domain Codes for Water Distribution Networks
A connectivity rule in a water-distribution utility network is only as reliable as the coded values behind it. Every rule is expressed in terms of an asset group, an asset type (subtype), a terminal, and the association it permits — and each of those is a domain code that must match exactly, or the rule silently fails to fire. When a service lateral carries the wrong subtype code, or a gate valve is loaded with a terminal count of one, the network will happily accept geometry that connects a hydrant directly to a transmission main, and no trace will complain until an isolation analysis returns a boundary that leaves customers energized who should be shut off. This reference collects the domain codes, terminal configurations, and permitted associations for a representative water-distribution network into a single table so engineers can validate features against a known baseline before they enable tracing. It is the code-level companion to the configuring connectivity rules for pipe and cable workflow, sits within the broader topology and tracing workflows discipline, and supplies the subtype and terminal facts that both valve and isolator mapping strategies and the containment model in asset hierarchy design for water and electric depend on.
Environment Prerequisites
The codes below are a baseline to validate against, not a substitute for reading your own deployed domains. Confirm the following before you trust them:
- ArcGIS Pro 3.2+ with a Standard or Advanced license and
arcpyimportable from Python 3.11, so you can export the network’s actual coded-value domains witharcpy.da.ListDomainsand compare them against this reference. - The deployed asset package — the codes in the table follow the conventions of a typical water-distribution data model, but every organization renumbers subtypes during configuration. Treat the exported domain as authoritative and this table as the shape it should take.
- A validated Utility Network topology with terminal configurations already assigned to every device asset type; terminal counts drive the association rules and cannot be inferred from geometry.
- networkx 3.x and geopandas 1.x pinned in an isolated environment for the validation helper, with feature data exported from a reconciled, unversioned snapshot rather than an open edit session.
- Read access to the published connectivity rules so you can confirm the permitted junction-edge and edge-junction associations in the table match the rules actually enforced by the network.
Schema Validation Protocol — Run Before You Trust the Codes
Domain-code errors are quiet: the feature saves, the map draws, and only a trace exposes the fault. Work this ordered protocol first; the earliest item is the most common source of a wrong association.
- Confirm the subtype code exists in the deployed domain. Export the coded-value domain and check that every asset type in your data maps to a code present in this reference’s shape. A subtype value with no matching domain entry is unclassified and connects under no rule at all.
- Verify terminal counts match the device class. A line valve is a two-terminal device; a coupling is two-terminal; a tee is three-terminal; a cross is four-terminal. A device loaded with the wrong terminal count either over-connects or refuses valid associations.
- Check that permitted associations are directional-correct. A junction-edge rule (device-to-line) and an edge-junction rule (line-to-device) are distinct; a rule authored in only one direction leaves the reverse association unpermitted and breaks continuity.
- Reconcile structural containment against connectivity. A valve housed in a vault is structurally attached, not topologically connected through the vault; conflating the two, exactly the hazard described for valve and isolator mapping, fractures isolation boundaries.
- Validate before you trace. Never evaluate the table against a dirty-area backlog — run topology validation first so the codes you check reflect a consistent network state.
The Domain-Code Reference Table
The table maps each water-distribution asset group and asset type to its representative subtype domain code, terminal configuration, and the associations the connectivity rules should permit. Junction-edge associations describe which line assets a device or junction may connect to; edge-junction associations describe which devices or junctions a line may terminate against. Codes are grouped by feature class — mains and laterals (line), valves and hydrants and meters (device), and fittings and service points (junction).
| Asset Group | Asset Type (subtype) | Domain code | Terminal config | Permitted junction–edge / edge–junction associations |
|---|---|---|---|---|
| Distribution Pipe (Line) | Distribution Main | 1 | linear (no terminals) | Gate Valve, Butterfly Valve, Hydrant Lateral, Tee, Cross, Reducer, Service Tap |
| Distribution Pipe (Line) | Transmission Main | 2 | linear (no terminals) | Gate Valve, Butterfly Valve, Air Release Valve, Tee, Cross, Reducer |
| Distribution Pipe (Line) | Pressurized Lateral | 3 | linear (no terminals) | Curb Stop, Meter, Tee, Coupling, Service Point |
| Service Pipe (Line) | Service Lateral | 41 | linear (no terminals) | Curb Stop, Water Meter, Service Point, Coupling |
| Service Pipe (Line) | Hydrant Lateral | 42 | linear (no terminals) | Hydrant, Gate Valve (auxiliary), Tee |
| Service Pipe (Line) | Fire Service Lateral | 43 | linear (no terminals) | Detector Check Valve, Water Meter, Service Point |
| Distribution Device (Junction) | Gate Valve | 101 | 2 (inlet / outlet) | Distribution Main, Transmission Main, Hydrant Lateral |
| Distribution Device (Junction) | Butterfly Valve | 102 | 2 (inlet / outlet) | Distribution Main, Transmission Main |
| Distribution Device (Junction) | Check Valve | 103 | 2 (inlet / outlet) | Distribution Main, Pressurized Lateral |
| Distribution Device (Junction) | Pressure Reducing Valve | 104 | 2 (high / low side) | Transmission Main, Distribution Main |
| Distribution Device (Junction) | Air Release Valve | 105 | 1 (inlet) | Transmission Main, Distribution Main |
| Distribution Device (Junction) | Curb Stop | 106 | 2 (inlet / outlet) | Service Lateral, Pressurized Lateral |
| Distribution Device (Junction) | Detector Check Valve | 107 | 2 (inlet / outlet) | Fire Service Lateral |
| Hydrant (Device) | Dry-Barrel Hydrant | 121 | 1 (inlet) | Hydrant Lateral |
| Hydrant (Device) | Wet-Barrel Hydrant | 122 | 1 (inlet) | Hydrant Lateral |
| Hydrant (Device) | Flush Hydrant | 123 | 1 (inlet) | Distribution Main, Hydrant Lateral |
| Water Meter (Device) | Positive-Displacement Meter | 141 | 2 (inlet / outlet) | Service Lateral, Pressurized Lateral |
| Water Meter (Device) | Turbine Meter | 142 | 2 (inlet / outlet) | Service Lateral, Fire Service Lateral |
| Water Meter (Device) | Compound Meter | 143 | 2 (inlet / outlet) | Fire Service Lateral |
| Fitting (Junction) | Tee | 161 | 3 (branch) | Distribution Main, Transmission Main, Service Lateral |
| Fitting (Junction) | Cross | 162 | 4 (branch) | Distribution Main, Transmission Main |
| Fitting (Junction) | Reducer | 163 | 2 (large / small) | Distribution Main, Transmission Main |
| Fitting (Junction) | Coupling | 164 | 2 (inline) | Distribution Main, Service Lateral, Pressurized Lateral |
| Fitting (Junction) | Cap / End | 165 | 1 (inline) | Distribution Main, Service Lateral |
| Service Point (Junction) | Metered Service Point | 181 | 1 (connection) | Service Lateral, Pressurized Lateral |
| Service Point (Junction) | Fire Service Point | 182 | 1 (connection) | Fire Service Lateral |
| Network Structure (Junction) | Valve Vault | 201 | structural (containment only) | none — structural attachment, not connectivity |
Two reading rules make the table safe to apply. First, a device asset type may associate only with the line asset types listed in its row; a gate valve that connects a service lateral to a transmission main violates its permitted set even though the geometry snaps cleanly. Second, terminal count is a hard constraint on association arity — a one-terminal air release valve or hydrant terminates a single edge, so it can never sit inline splitting a main, while a tee’s three terminals are exactly what let it branch a lateral off a distribution main. The valve vault at the bottom of the table is the deliberate exception: it carries no connectivity terminals at all, because it participates through structural containment, and any rule that treats it as a connective junction is a defect.
The helper below encodes the reference as a lookup and validates a feature’s asset group, subtype code, terminal count, and proposed association against it. It returns a structured verdict suitable for a build gate rather than raising on the first mismatch:
from dataclasses import dataclass, field
import logging
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
@dataclass(frozen=True)
class RuleEntry:
"""One row of the water-distribution connectivity-rule reference."""
asset_group: str
asset_type: str
terminals: int
permitted: frozenset[str] = field(default_factory=frozenset)
# Representative subtype domain codes -> reference entries.
DOMAIN_CODES: dict[int, RuleEntry] = {
1: RuleEntry("Distribution Pipe", "Distribution Main", 0,
frozenset({"Gate Valve", "Butterfly Valve", "Tee", "Cross", "Reducer"})),
101: RuleEntry("Distribution Device", "Gate Valve", 2,
frozenset({"Distribution Main", "Transmission Main", "Hydrant Lateral"})),
121: RuleEntry("Hydrant", "Dry-Barrel Hydrant", 1,
frozenset({"Hydrant Lateral"})),
161: RuleEntry("Fitting", "Tee", 3,
frozenset({"Distribution Main", "Transmission Main", "Service Lateral"})),
181: RuleEntry("Service Point", "Metered Service Point", 1,
frozenset({"Service Lateral", "Pressurized Lateral"})),
201: RuleEntry("Network Structure", "Valve Vault", 0, frozenset()),
}
def validate_domain_code(code: int, terminals: int, associate_to: str) -> dict:
"""Validate a feature's subtype code, terminal count, and proposed association.
Returns a structured verdict: whether the code is known, the terminal count
matches the reference, and the proposed association is permitted.
"""
entry = DOMAIN_CODES.get(code)
if entry is None:
logging.warning("Unknown subtype code %s — feature is unclassified", code)
return {"code": code, "known": False, "ok": False,
"reason": "subtype code not in reference domain"}
terminal_ok = terminals == entry.terminals
assoc_ok = associate_to in entry.permitted
ok = terminal_ok and assoc_ok
if not terminal_ok:
logging.error("Code %s (%s): terminal count %d != expected %d",
code, entry.asset_type, terminals, entry.terminals)
if not assoc_ok:
logging.error("Code %s (%s): association to %r not permitted",
code, entry.asset_type, associate_to)
return {
"code": code,
"asset_type": entry.asset_type,
"known": True,
"terminal_ok": terminal_ok,
"association_ok": assoc_ok,
"ok": ok,
}
if __name__ == "__main__":
print(validate_domain_code(101, terminals=2, associate_to="Distribution Main"))
print(validate_domain_code(121, terminals=1, associate_to="Distribution Main"))
The second example fails deliberately: a hydrant coded 121 with a single terminal cannot associate directly to a distribution main, because its permitted set contains only the hydrant lateral. That is exactly the class of error the reference is meant to catch before it reaches a trace.
Production Deployment Pattern
Turn the reference from documentation into an enforced control:
- Export and diff the live domain. On every schema change, export the deployed coded-value domains with
arcpy.da.ListDomainsand diff them against this reference’s shape, so a renumbered or dropped subtype is caught at configuration time rather than during an outage. - Wire the validator into CI. Run
validate_domain_codeover a sample of committed features from a build agent, and fail the pipeline when an unknown code, a terminal mismatch, or an unpermitted association appears — the same gating discipline detailed in automating connectivity rule validation in CI pipelines. - Reconcile against a snapshot, not the live edit version. Read features from a reconciled, unversioned snapshot so the codes you validate reflect committed geometry and never contend with editor locks.
- Persist an audit trail. Append each validation run’s unknown-code count, terminal mismatches, and unpermitted associations to a timestamped, version-controlled log, along with the exported domain hash, so a reliability or AWWA G400 review can confirm the network was configured against a known baseline.
- Keep the reference under version control. Treat the domain-code table as code: any change to a subtype code or permitted association is a reviewed commit, so the network’s connectivity contract has a history rather than a memory.
Conclusion
Connectivity rules live or die on their domain codes, and in a water-distribution network those codes are the difference between a trace that isolates the right section and one that leaves a main energized. Validating each feature’s asset group, subtype code, terminal configuration, and permitted associations against a known reference — before tracing is ever enabled — turns a silent configuration error into a caught defect. Use the table as the shape your exported domains should take, enforce it with the validator on every commit, and keep the reference itself under version control so the connectivity contract is auditable rather than assumed. Correct codes are the quiet foundation every downstream isolation and impact trace inherits.
Related
- Up to the parent topic: Configuring Connectivity Rules for Pipe & Cable
- Up to the section: Topology & Tracing Workflows
- Automating Connectivity Rule Validation in CI Pipelines
- Valve & Isolator Mapping Strategies
- Asset Hierarchy Design for Water & Electric
For authoritative reference, consult the ArcGIS Pro utility network connectivity documentation and the AWWA standards program.