power-dispatch-studio
The PH WESM dispatch engine behind Power Dispatch Studio, as an importable, citable Python module and CLI.
The studio runs the same linear optimization and lowest-cost-first dispatch (merit order) in the browser with HiGHS compiled to WebAssembly. This package is the Python reference code for replaying one recorded day. It builds a supply stack for each island grid from a calculated snapshot of public IEMOP data, applies scenario changes, and clears the three connected grids with inter-grid limits, storage, reserves, and a daily hydro-energy limit. The same calculation and numbers can run in a notebook.
Install
pip install power-dispatch-studio
The only runtime dependency is highspy
(the HiGHS solver). A dated snapshot of the public data archive ships in the
wheel, so it runs with no network access.
CLI
power-dispatch days # recorded days available
power-dispatch run --date 2026-06-15 # hourly CSV to stdout
power-dispatch days --offer # days that carry an offer book
power-dispatch run --date 2026-06-15 --offer-mode # replay the market's own bids
power-dispatch run --date 2026-06-15 --demand luzon=1500 -o out.csv
power-dispatch run --scenario scenario.json -o out.csv
Python
import power_dispatch as pd
pd.list_days()[:3]
# ['2026-05-01', '2026-05-02', '2026-05-03']
result = pd.run_scenario({
"date": "2026-06-15",
"opts": {"demand_delta": {"luzon": 1500}}, # +1.5 GW data-center load
})
result["summary"]["mean_price"]["luzon"] # PhP/kWh
The scenario override map
A scenario is {"date": "YYYY-MM-DD", "opts": {...}}. The engine accepts
the following override keys.
| key | type | meaning |
|---|---|---|
demand_delta |
{grid: MW} or {grid: [24 MW]} |
load added or removed, flat or with an hourly shape |
fuel_cost |
{fuel: PhP/kWh} |
marginal-cost override |
fuel_avail_delta |
{grid: {fuel: MW}} |
availability edit |
solar_delta_mw |
{grid: MW} |
installed solar edit |
hydrology |
float |
water multiplier (1.0 = observed) |
caps |
{leyte|mvip: MW or [24]} |
link limits |
storage |
[{grid, power_mw, energy_mwh}] |
added BESS |
reserve_deduction |
bool |
withhold scheduled reserve |
offer_mode |
bool |
replay the recorded offer book. False uses the cost calculation |
gas_budget |
{grid: MWh} |
daily gas-energy limit, for a lower-supply case |
grid is one of luzon, visayas, mindanao.
The scenario file
A scenario carries a schema stamp, so a file written in one place runs in
another. The studio writes it, this package reads it, and validate says what is
wrong before the solver ever sees it.
power-dispatch validate myscenario.json
power-dispatch validate --keys myscenario.json # every option, with its meaning
power-dispatch run --scenario myscenario.json -o out.csv
import power_dispatch as pd
pd.validate_scenario(scenario) # a list of messages, and never raises
pd.load_scenario("myscenario.json") # raises ValueError carrying all of them
Your contract position
A scenario file can carry a contract book, and the engine never reads it.
settle marks the book against the modeled spot price, and compare_position
reports what a scenario does to it.
pos = pd.compare_position(base, scenario, book, load_mw={"luzon": 400})
pos["net_change_php"] # the contract gain less the open position's extra cost
It marks energy against modeled spot and stops there. No capacity fee, no wheeling charge, no tax, and no credit terms.
The full key table is in the scenario schema.
The operator publishes an offer book several days after the day itself, so the
newest replayable day usually has none. days --offer lists the ones that do,
and --offer-mode on a day without one says so and stops.
The data snapshot
The bundled data is a dated snapshot of the public archive at build time (see
power_dispatch/data/meta.json). To run against newer calculated data, point the
engine at a copy of the deployed web/data/.
power-dispatch run --date 2026-07-01 --data-dir /path/to/web/data
# or: export POWER_DISPATCH_DATA=/path/to/web/data
That same flag runs your own system. The directory needs dispatch.json and
profiles.json, and nothing in it has to be Philippine. The
data contract
lists every key, with a 30-line system that runs. A test in the repository
builds that system, solves it, and fails when the document stops matching the
engine.
What this is and is not
This replays recorded days with scenario what-ifs on a documented calculation. It is not a price forecast, and offer mode replays the market's published bids rather than simulating bidding strategy. Recorded market inputs trace to the Independent Electricity Market Operator of the Philippines (IEMOP). Fleet and cost inputs cite their own sources. Caller inputs and model assumptions have separate labels. The Historical replay view and method page report the calculation error. Read the full method.
The engine dispatches fuel blocks per island grid, so it holds no named units and
no unit commitment. That is a measured choice. Committing each thermal block with
a generic minimum-stable floor lowered the price correlation in all five scored
series, from 0.442 to -0.003 in Visayas. pipeline/uc_probe.py in the repository
carries the test.
MIT licensed.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file power_dispatch_studio-0.2.1.tar.gz.
File metadata
- Download URL: power_dispatch_studio-0.2.1.tar.gz
- Upload date:
- Size: 888.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6156ff1dca3ee10bf3eb373e93f720823a10cf9a2ce43546bf262c58ad38f463
|
|
| MD5 |
87336a668727d41d05de86686bd446c6
|
|
| BLAKE2b-256 |
fae134105d263f62beb2b6d621b6c03e77016d8c6e27efd6f930c4a606120765
|
File details
Details for the file power_dispatch_studio-0.2.1-py3-none-any.whl.
File metadata
- Download URL: power_dispatch_studio-0.2.1-py3-none-any.whl
- Upload date:
- Size: 632.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ab7c6e736711415756f8f089c0034415e106273c9515a8e77dc90dc91a4dc6b
|
|
| MD5 |
4192cf4c343539759bdd9af1578422a6
|
|
| BLAKE2b-256 |
8fba67685e1cca7c543be164331486babcafb7e03614946570e7175d3023ca92
|