SWMM Water Quality Skill
SkillDev toolsComplete SWMM engine coverage: pollutant buildup/washoff simulation support and load reporting. Validate water-quality config JSON, build INPs with WQ sections, and extract pollutant load summaries from completed runs.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the SWMM Water Quality Skill skill
What this skill tells your AI
The instructions your AI receives, as published by zhonghao1995/agentic-swmm-workflow in skills/swmm-water-quality/SKILL.md and read by ahel’s review.
Purpose
Complete SWMM engine coverage for pollutant buildup/washoff simulation and load reporting. This skill provides:
validate_wq_config.py— validate a WQ config JSON before passing it to the builder.extract_wq_loads.py— extract WQ load summaries from a SWMM RPT.
The water-quality sections ([POLLUTANTS], [LANDUSES], [COVERAGES],
[BUILDUP], [WASHOFF], [LOADINGS]) are emitted by
skills/swmm-builder/scripts/build_swmm_inp.py via the
--water-quality-json flag (see also build_inp tool's
water_quality_json argument).
Agent tool: read_wq_loads
Read pollutant load summaries from a completed run's .rpt file. Returns
wq_present=false for non-WQ runs.
read_wq_loads(rpt_path="runs/my_run/model.rpt")
Returns a structured JSON with:
wq_present(bool)pollutants— sorted list of pollutant namesrunoff_quality_continuity— mass-balance rows (metric + per-pollutant kg)quality_routing_continuity— routing mass-balance rowssubcatchment_washoff— per-subcatchment loads (kg per pollutant)link_loads— per-link transport loads (kg per pollutant)outfall_loads— per-outfall flow stats + pollutant loads
WQ config JSON schema
Top-level keys (all required when the key is present; empty arrays are valid):
{
"pollutants": [...],
"landuses": [...],
"coverages": [...],
"buildup": [...],
"washoff": [...],
"loadings": []
}
pollutants entries
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | No spaces |
units | string | required | MG/L, UG/L, or #/L |
c_rain | float | 0 | Concentration in precipitation |
c_gw | float | 0 | Concentration in groundwater |
c_ii | float | 0 | Concentration in RDII |
k_decay_per_day | float | 0 | First-order decay (1/days) |
snow_only | bool | false | Buildup during snow only |
co_pollutant | string | "*" | Co-pollutant name or "*" |
co_fraction | float | 0 | Co-pollutant fraction (0–1) |
init_conc | float | 0 | Initial dry-weather concentration |
landuses entries
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | |
sweep_interval | float | 0 | Days between sweeping (0 = no sweeping) |
availability | float | 0 | Fraction of buildup removed by sweeping (0–1) |
last_sweep | float | 0 | Days since last sweep at start |
coverages entries
| Field | Type | Notes |
|---|---|---|
subcatchment | string | Must reference an existing subcatchment |
landuse | string | Must reference a defined land use |
percent | float (0–100) | Percent coverage; per-subcatchment sum must be ≤ 100 |
buildup entries
| Field | Type | Notes |
|---|---|---|
landuse | string | Must reference a defined land use |
pollutant | string | Must reference a defined pollutant |
func_type | string | POW, EXP, or SAT (EXT not supported in v1) |
c1 | float | Max buildup (kg/ha or count/ha when normalizer=AREA) |
c2 | float | Rate constant |
c3 | float | Third coefficient (unused for EXP/SAT) |
normalizer | string | AREA or CURBLENGTH |
washoff entries
| Field | Type | Notes |
|---|---|---|
landuse | string | Must reference a defined land use |
pollutant | string | Must reference a defined pollutant |
func_type | string | EXP, RC, or EMC |
c1 | float | Coefficient 1 |
c2 | float | Coefficient 2 (0 for EMC) |
sweep_removal | float (0–1) | Fraction removed by sweeping |
bmp_removal | float (0–1) | Fraction removed |
loadings entries (optional)
| Field | Type | Notes |
|---|---|---|
subcatchment | string | Must reference an existing subcatchment |
pollutant | string | Must reference a defined pollutant |
init_buildup | float | Initial buildup mass |
Scripts
scripts/validate_wq_config.py— standalone CLI validatorscripts/extract_wq_loads.py— RPT load extractor
Executed examples
Validate a WQ config JSON
# Write a minimal WQ config JSON:
cat > /tmp/wq_example.json << 'EOJSON'
{
"pollutants": [{"name": "TSS", "units": "MG/L", "c_rain": 0, "c_gw": 0,
"c_ii": 0, "k_decay_per_day": 0, "snow_only": false,
"co_pollutant": "*", "co_fraction": 0, "init_conc": 0}],
"landuses": [{"name": "Residential", "sweep_interval": 0, "availability": 0, "last_sweep": 0}],
"coverages": [{"subcatchment": "S1", "landuse": "Residential", "percent": 100}],
"buildup": [{"landuse": "Residential", "pollutant": "TSS", "func_type": "EXP",
"c1": 15, "c2": 0.5, "c3": 0, "normalizer": "AREA"}],
"washoff": [{"landuse": "Residential", "pollutant": "TSS", "func_type": "EMC",
"c1": 50, "c2": 0, "sweep_removal": 0, "bmp_removal": 0}],
"loadings": []
}
EOJSON
python3 skills/swmm-water-quality/scripts/validate_wq_config.py \
--wq-json /tmp/wq_example.json
# Output: {"ok": true, "pollutant_count": 1, "landuse_count": 1, ...}
Extract WQ load summaries from a completed run RPT
python3 skills/swmm-water-quality/scripts/extract_wq_loads.py \
--rpt tests/fixtures/wq/wq_smoke.rpt
# Output: {"ok": true, "wq_present": true, "pollutants": ["TSS"],
# "runoff_quality_continuity": [...], ...}
Build an INP with water quality sections
python3 skills/swmm-builder/scripts/build_swmm_inp.py \
--subcatchments-csv <subcatchments.csv> \
--params-json <params.json> \
--network-json <network.json> \
--water-quality-json /tmp/wq_example.json \
--out-inp /tmp/wq_model.inp \
--out-manifest /tmp/wq_model_manifest.json
Validation constraints
Enforced by both validate_wq_config.py and build_swmm_inp.py:
- Referential: every
[BUILDUP]/[WASHOFF]landuse/pollutant must exist - Referential: every
[COVERAGES]/[LOADINGS]subcatchment must exist - Enum:
units∈ {MG/L,UG/L,#/L} - Enum: buildup
func_type∈ {POW,EXP,SAT} (EXT rejected with message) - Enum: washoff
func_type∈ {EXP,RC,EMC} - Range: coverage
percent∈ [0, 100]; per-subcatchment sum ≤ 100 - Range:
sweep_removal,bmp_removal,co_fraction∈ [0, 1]
Signals
- GitHub stars
- 28
- Forks
- 13
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
swmm-water-quality- Source
- github.com/zhonghao1995/agentic-swmm-workflow