agentsclimarketplace

Swmm water quality

Skill Zhonghao1995/agentic-swmm-workflow/skills/swmm-water-quality

Agentic SWMM is an automated, auditable, and memory-informed framework for reproducible stormwater modelling, integrating QGIS and EPA SWMM through the aiswmm runtime, reusable Skills, and MCP interfaces, with QA verification, provenance tracking, calibration support, and Codex, Hermes, Claude code as well as OpenClaw compatibility

Install
npx -y skills add Zhonghao1995/agentic-swmm-workflow --skill swmm-water-quality

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Complete 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.

SKILL.md

6.4 KB, as published. Nobody here has run it

SWMM Water Quality Skill

Purpose

Complete SWMM engine coverage for pollutant buildup/washoff simulation and load reporting. This skill provides:

  1. validate_wq_config.py — validate a WQ config JSON before passing it to the builder.
  2. 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 names
  • runoff_quality_continuity — mass-balance rows (metric + per-pollutant kg)
  • quality_routing_continuity — routing mass-balance rows
  • subcatchment_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

FieldTypeDefaultNotes
namestringrequiredNo spaces
unitsstringrequiredMG/L, UG/L, or #/L
c_rainfloat0Concentration in precipitation
c_gwfloat0Concentration in groundwater
c_iifloat0Concentration in RDII
k_decay_per_dayfloat0First-order decay (1/days)
snow_onlyboolfalseBuildup during snow only
co_pollutantstring"*"Co-pollutant name or "*"
co_fractionfloat0Co-pollutant fraction (0–1)
init_concfloat0Initial dry-weather concentration

landuses entries

FieldTypeDefaultNotes
namestringrequired
sweep_intervalfloat0Days between sweeping (0 = no sweeping)
availabilityfloat0Fraction of buildup removed by sweeping (0–1)
last_sweepfloat0Days since last sweep at start

coverages entries

FieldTypeNotes
subcatchmentstringMust reference an existing subcatchment
landusestringMust reference a defined land use
percentfloat (0–100)Percent coverage; per-subcatchment sum must be ≤ 100

buildup entries

FieldTypeNotes
landusestringMust reference a defined land use
pollutantstringMust reference a defined pollutant
func_typestringPOW, EXP, or SAT (EXT not supported in v1)
c1floatMax buildup (kg/ha or count/ha when normalizer=AREA)
c2floatRate constant
c3floatThird coefficient (unused for EXP/SAT)
normalizerstringAREA or CURBLENGTH

washoff entries

FieldTypeNotes
landusestringMust reference a defined land use
pollutantstringMust reference a defined pollutant
func_typestringEXP, RC, or EMC
c1floatCoefficient 1
c2floatCoefficient 2 (0 for EMC)
sweep_removalfloat (0–1)Fraction removed by sweeping
bmp_removalfloat (0–1)Fraction removed

loadings entries (optional)

FieldTypeNotes
subcatchmentstringMust reference an existing subcatchment
pollutantstringMust reference a defined pollutant
init_buildupfloatInitial buildup mass

Scripts

  • scripts/validate_wq_config.py — standalone CLI validator
  • scripts/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]

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.