agentsclimarketplace

Swmm water quality

Skill Zhonghao1995/agentic-swmm-workflow/skills/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 its SKILL.md

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.

2 things 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.
  • runs commandsInstructs the agent to run 3 commands, including `python3 skills/swmm-water-quality/scripts/validate_wq_config.py --wq-json /tmp/wq_example.json` and 2 more.

SKILL.md

6.4 KB, ~2.0k tokens by cl100k_base, 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]

What ships with it: 4 files

54.4 KB alongside SKILL.md, 3 of them executable

scripts/

Keep looking

Skills are one crate of 325,949. 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.