Skip to content
Automation
Skill

/swmm-water-quality

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.

From plugin
agentic-swmm-workflow
3117 skills

Claude Code

$ npx -y skills add Zhonghao1995/agentic-swmm-workflow --skill swmm-water-quality --agent claude-code

SKILL.md

swmm-water-quality.SKILL.md
name: swmm-water-quality
description: >
  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.

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

| 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 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
Read more
@zhonghao1995
Ships withagentic-swmm-workflow

Pre-1.0 · stable v0.9.5 · pip install aiswmm==0.9.5 · CHANGELOG

Stars on GitHub

Momentum

stars in total
31
Star history of Zhonghao1995/agentic-swmm-workflow on GitHub, a chart by star-history.com

Other skills on agentic-swmm-workflow.

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n11d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about swmm-water-quality.

Which coding agents can use swmm-water-quality?
swmm-water-quality installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.