NEMSweep.Model 0.1.0

dotnet add package NEMSweep.Model --version 0.1.0
                    
NuGet\Install-Package NEMSweep.Model -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NEMSweep.Model" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NEMSweep.Model" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="NEMSweep.Model" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NEMSweep.Model --version 0.1.0
                    
#r "nuget: NEMSweep.Model, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NEMSweep.Model@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NEMSweep.Model&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=NEMSweep.Model&version=0.1.0
                    
Install as a Cake Tool

NEMSweep

NEMSweep is a free, open-source tool that checks whether a proposed electricity grid could have met a full year of real demand hour by hour, works out how much storage it would take if it couldn't, and tells you what that costs.

Repository: https://github.com/HasinthaAttanayake/NEMSweep. Licence: BSD-3-Clause.

NEMSweep ships with no numbers of its own. Every cost, every carbon intensity, every demand trace and every weather year is supplied by whoever runs it. The model does the accounting. The assumptions belong to the person who supplies them.

Underneath that sentence is a deterministic engine for grid dispatch, reliability assessment, storage sizing, system cost and emissions accounting. You describe a set of regions, each with its demand, generation and storage, and a reliability standard. The engine dispatches them in merit order for every hour of the modelled period, grows battery storage in the regions that miss the standard, and reports the technical and economic result. It is written for analysts building or scrutinising an energy-system policy or investment case, who will quote its numbers in their own work.

The engine does not hardcode a region list or couple to AEMO: region identifiers are free-form strings. Its grid model runs on a fixed one-hour timestep, and sub-hourly input is resampled to it. The market-time offset is a run parameter, taken from the scenario period bounds and defaulting to the National Electricity Market's UTC+10; a run works in one fixed offset with no daylight saving. NEMSweep.Model and NEMSweep.Contracts have no package dependencies, so you can embed them in your own software.

Documentation: how to run it, what it assumes, and how to explore the scenario space Live results: https://www.nemsweep.com/

The three layers

A statement about NEMSweep belongs to exactly one of three layers. Keeping them apart is how you read the rest of this repository without mistaking the published example for the limit of the engine.

Layer What it is Where it lives
Framework The dispatch, reliability, storage-sizing and cost engine described above. No hardcoded region list and no AEMO coupling. Fixed one-hour timestep; the market-time offset is a run parameter that defaults to UTC+10. Deterministic, no package dependencies, embeddable. NEMSweep.Model, NEMSweep.Contracts
NEM scoping The command-line tool that binds the framework to Australia. It ingests AEMO operational demand, EnergyPlus Weather data and AEMO generation data, and validates scenarios against the five National Electricity Market regions (NSW1, QLD1, SA1, TAS1, VIC1). NEMSweep.CLI
Published example One scenario: the National Electricity Market configured for the 2026 financial year, plus a sweep that adds data-centre load across the regions. Everything on nemsweep.com is this one example. the repository artifacts, the live site

The five NEM regions are the CLI's constraint, enforced because the data it ingests is National Electricity Market data. The one-hour timestep is the framework's, fixed in NEMSweep.Model. The market-time offset is a run parameter the framework reads from the scenario period; the CLI takes it from the ingested data, so a NEM run gets UTC+10.

What the framework does

Given a realised system and a reliability standard, the framework:

  • dispatches generation in merit order by short-run marginal cost for every hour, and meters flow and loss on each directed interconnector;
  • grows battery storage in the regions that miss the standard, re-dispatching the whole linked system for each candidate, and stops when the standard is met or the bounded search reaches a limit;
  • costs the build and operation of the resulting system and divides annualised cost by energy served (demand minus unserved energy) to give a system levelised cost of electricity (SLCoE), in AUD per MWh;
  • accounts operational combustion emissions from that same dispatch, on gross generated energy, and divides them by the same energy-served denominator to give an emissions intensity in t CO2-e per MWh served. The per-technology intensity a scenario supplies is an input assumption in t CO2-e per MWh generated; the published intensity is an output per MWh served. Combustion only, so not a life-cycle figure.

Only battery capacity is sized. Pumped hydro is fixed at whatever the scenario declares.

Where a region does not reach the standard, the search reports what stopped it: a battery capacity ceiling, a dispatch-pass budget, storage that has stopped reducing unserved energy, or system generation energy below demand energy. Only the last of these establishes that no battery size could have met the standard.

What the framework does not do

  • It is not a market model. There is no bidding, no settlement, no unit commitment, and no security-constrained economic dispatch. Merit-order dispatch only.
  • It is not a forecast. Each run is one system against one weather profile, with no stochastic draws, so it reports a realised outcome rather than an expectation over a distribution. The trustworthy output is the gap between two scenarios, not the level of any single one.
  • It is not a general-purpose energy-system model. The dispatch method is fixed. The flexibility is in the system you describe, not in the modelling approach.
  • The cost it reports covers building and running the system. It excludes retail, network and scheme costs. SLCoE is not a retail price anyone pays.

The project treats this low fidelity as a feature: fast feedback, no proprietary solver, no linear-programming background required, and it runs on a laptop. Read Limitations before you quote a figure from it.

Determinism and provenance

The same inputs at the same commit reproduce every modelled value. Every result records the SHA-256 digest of the exact input bytes it was built from, and that digest, not the file path, is the reproducibility boundary. The model constants a scenario cannot override are listed in an assumptions register that a test suite (ModelAssumptionsTests) checks against the code on every change.

Dispatch artifacts are not byte-identical between reruns, because each run stamps a fresh runId that identifies the run rather than describing its contents. Outputs and provenance sets out exactly what differs.

The published example

nemsweep.com publishes one worked example, not a dataset and not a forecast:

  • a baseline scenario, scenarios/nem-fy2026-all-regions.json, dispatching all five National Electricity Market regions together over directed interconnectors, built from AEMO operational demand for the 2026 financial year, a typical-meteorological-year weather profile, and a declared generation and storage fleet;
  • a sweep, sweeps/datacentre-nameplate-fy2026.json, that holds that baseline fixed and adds data-centre nameplate load across the regions, from 0 to 12,000 MW, one run per step.

The data-centre framing follows the Australian Government's expectations for data-centre and AI infrastructure developers. Any load increase behaves the same way in the model.

The example demonstrates what the framework does. It is not the limit of what the framework does. Generation mix, economics, the reliability standard and transmission capacity are all scenario inputs, and each can be swept the same way. Designing a study covers how.

The example's artifacts are published with the results site. They are an illustrative example, not a dataset, and they derive from AEMO and EnergyPlus Weather sources under their own terms. Run your own scenario before quoting a figure.

Repository

Project Contents
NEMSweep.Model The framework: domain models, units, time series, generation models, dispatch, storage sizing, economics. No package dependencies.
NEMSweep.Contracts The exported data contracts. No package dependencies.
NEMSweep.CLI The National Electricity Market scoping: source-data validation and ingestion, and the commands that produce the published datasets.
NEMSweep.Model.Tests, NEMSweep.CLI.Tests Cover model and ingestion behaviour.
docs The docfx documentation site.

NEMSweep.CLI is organised by workflow, with application mechanics kept separate:

Folder Responsibility
Application Argument routing, workspace-override parsing, exit codes, shared command context, and the commands that run without a workspace (--new-scenario, --describe-schema)
Configuration Typed CLI settings, the input-bundle manifest, and the scenario config and sweep definition formats, each with its validation
Infrastructure Workspace-root resolution, the shared JSON read and write policy, JSON merge-patch, staged atomic file writes, and build provenance
Demand Operational-demand import, validation, and export
Weather EPW parsing, provenance analysis, the weather basis, and weather export
Generation Generation-information workbook import and export
Ingest Input-bundle validation and coordinated artifact ingestion
Scenarios Scenario validation and dispatch, sweep fan-out and runs, and result export as JSON and the CSV star schema

NEMSweep.CLI.Tests mirrors the same feature folders. The implemented aggregate roots and domain-service boundaries are tracked in the domain model.

Licence and data

The code is BSD-3-Clause: use it in your own software, including proprietary software, with attribution and no copyleft. NEMSweep.Model and NEMSweep.Contracts have no package dependencies, so a project reference from a clone, or a reference to the built assembly, is all it takes to embed them.

The data is not covered by that licence. The demand, generation and weather artifacts derive from AEMO and EnergyPlus Weather sources with their own terms. Read DATA-LICENSE.md before redistributing any of it. This repository carries none of them: the artifacts published alongside the results site are an illustrative example, not a dataset.

Using NEMSweep in published work? CITATION.cff carries the citation metadata. Cite the run rather than the tool, because a result is reproducible only against a specific version, commit and scenario:

Modelled with NEMSweep <version> at commit <commit>, scenario <scenario config>, run <runId>.
https://github.com/HasinthaAttanayake/NEMSweep

nemsweep --version reports the version, and every result carries provenance.gitCommitSha, the commit the binary was built from, and runId. The scenario config is yours to record: a dispatch result does not name the file it was configured from. Outputs and provenance covers the block those fields sit in.

Contributions are welcome: see CONTRIBUTING.md.

Install

The CLI is published to NuGet as a .NET tool, so a machine with the .NET 10 SDK needs neither a clone nor a container to run it:

dotnet tool install --global NEMSweep.CLI

That installs the nemsweep command. The framework and its published artifact contracts are packages of their own, for building something else on top of the model rather than running it:

dotnet add package NEMSweep.Model
dotnet add package NEMSweep.Contracts

Releases are cut by pushing a v* tag, which is the version the packages are published at.

Local development

There are three ways to run NEMSweep: install the tool as above, clone it and build it with the .NET SDK, or run the published container image, which needs no toolchain and works under Docker or Podman.

The image is published to the GitHub Container Registry as ghcr.io/<owner>/nemsweep, where <owner> is the repository owner. It contains the tool and nothing else: demand, weather and generation artifacts are inputs you bring. The image defaults the data root to /data and the output root to /out, so mount your own directories over those and pass a scenario by absolute path:

docker run --rm -v ./reference:/data:ro -v ./study:/out ghcr.io/<owner>/nemsweep:latest --run-scenario /data/my-scenario.json

Podman takes the same arguments. Running the container covers the mounts, where the input data comes from, and pinning a run by image digest.

NEMSweep targets .NET 10 for a source build. The dotnet commands below are identical on Windows, macOS and Linux.

dotnet build NEMSweep.slnx
dotnet test NEMSweep.slnx
dotnet run --project NEMSweep.CLI -- --help

Copy NEMSweep.CLI/appsettings.example.json to NEMSweep.CLI/appsettings.local.json for machine-local input and output paths. The local file is ignored by Git, and the example is the fallback when it is absent. Set dataRoot in your local file to wherever --ingest wrote its artifacts: the committed example still points at a path the repository no longer contains, so a fresh clone will not run a scenario until you supply a data root.

A run reads its inputs from a data root and writes results to an output root. The demand, weather and generation artifacts a scenario reads are not carried in this repository: assemble an input bundle from upstream sources and run --ingest to produce them, then point the data root at where they landed. The output root defaults to a gitignored out/, so an ordinary run never disturbs published results. Override either per run:

dotnet run --project NEMSweep.CLI -- --run-scenario --output ./my-study

NEMSWEEP_DATA_ROOT and NEMSWEEP_OUTPUT do the same for environments where editing a settings file is awkward. Nothing searches for the repository, so the built executable runs from wherever you put it.

The full walkthrough covering configuration, the first scenario run and every command is in Getting started and the CLI reference.

Validation runs

Run the committed hand-calculated dispatch fixtures with:

dotnet test NEMSweep.Model.Tests/NEMSweep.Model.Tests.csproj --filter FullyQualifiedName~ManualScenarioFixtureTests

Run the synthetic 8,760-hour storage-sizing acceptance in Release mode with:

dotnet test NEMSweep.Model.Tests/NEMSweep.Model.Tests.csproj -c Release --filter FullyQualifiedName~FullYearSizingAcceptanceTests --logger "console;verbosity=detailed"

The full-year test prints solver wall-clock time, dispatch-pass count, and the selected battery capacity. Treat a runtime above a few minutes as a scope issue to record rather than an automatic optimisation task.

Documentation site

The docs under docs/ are built with docfx, pinned in .config/dotnet-tools.json.

dotnet tool restore
dotnet docfx docs/docfx.json --serve

The site is then at http://localhost:8080. docs/api and docs/_site are generated and ignored by Git. CI builds the site with --warningsAsErrors, so a broken cross-reference fails the build.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 122 9/13/2026