Documentation · Quickstart · Tutorials · PyPI
popo
Low-voltage network simulation and state estimation for distributed energy resource studies.
popo is Swahili for bat. It is a companion to twiga, Swahili for giraffe: twiga sees far, which is forecasting ahead in time; popo sees in the dark, which is inferring the state of a network that is not measured.
Low-voltage distribution is largely unobservable. There are measurements at the secondary substation and very little downstream, yet the decisions that matter, how much solar or how many electric vehicles a feeder can take, depend on what is happening at every customer terminal. This library is about reconstructing that from what little is metered, and about simulating what a network would do under a given level of DER uptake.
Install
The solvers are optional, because reading a network definition or checking a voltage limit against a standard needs neither:
uv add popo-flow # core: networks, standards, results
uv add popo-flow[opendss] # + time-series power flow
uv add popo-flow[estimation] # + weighted-least-squares state estimation
uv add popo-flow[all]
The distribution is named popo-flow because popo was already taken on PyPI;
the package itself is still imported as import popo.
What is in it
| module | purpose |
|---|---|
popo.network |
load an OpenDSS circuit, inspect topology and elements |
popo.powerflow |
time-series solution, monitors, substation results |
popo.estimation |
WLS state estimation from a sparse measurement set |
popo.standards |
EN 50160 and ANSI C84.1 limits, violation reporting |
popo.scenarios |
DER penetration scenarios, EV and PV allocation |
popo.profiles |
household, PV and EV profile synthesis, and the SMART-DS pool |
Learn it
Three tutorial notebooks under notebooks/, each running end to end against
vendored data:
01-opendss-lv-modeling.ipynb: build an LV circuit from scratch (transformer, linecodes, lines, loads), read it back withpopo.network.Circuitandpopo.powerflow.results, check compliance and list violations withpopo.standards.VoltageLimits, and three worked network-expansion exercises.02-timeseries-der-modeling.ipynb: a real 188-customer UK feeder with real household, PV and EV profiles, a time-series solve withpopo.powerflow.solve_time_series, a hosting-capacity sweep withrun_uk_sweep, every customer's voltage traced alongside the substation's, Volt-VAr, Volt-Watt and storage compared, and diversified against uncoordinated EV charging.03-lv-state-estimation.ipynb: the same feeder converted to pandapower and checked against OpenDSS, then estimated from the substation, smart meters and line sensors withpopo.estimation, including how many meters are enough and why a coherent substation forecast estimates better than three separate ones.
uv sync --all-extras installs everything the notebooks use.
Development
uv sync --all-extras # environment with both solvers
make test # suite with the coverage gate, solvers deselected
make test-solver # only the tests that need OpenDSS or pandapower
make lint # ruff check
make fmt # ruff format
make typecheck # ty
make docs # serve the docs locally
Commits follow conventional commits,
checked by commitizen through a pre-commit hook. Install the hooks once with
uv run pre-commit install --install-hooks -t pre-commit -t commit-msg.
Status
Alpha, version 0.1.0. Nothing is published yet.
popo is cited in the thesis as \texttt{Popo} \cite{faustine2026popo} (Chapter 2, "The Three
Simulated Datasets"). What it can reproduce today, of the three:
- DSS-US: SMART-DS
AUS_P1U, 596 pole transformers, around 6 customers each through a 0.12 kV split-phase secondary, measured (not fixed-power-factor) P/Q, ANSI C84.1, mean customer power factor 0.911±0.041. Reproducible today:popo.powerflow.sweep.run_us_sweep, regression tested against a real recorded run intests/integration/test_us_sweep_regression.py. - DSS-UK: UK Generic Distribution System models, two substations selected by voltage
sensitivity ("Feeder A", stiff,
21_1_1135, 157 customers, 315 kVA; "Feeder B", weak,17_1_1149, 188 customers, 500 kVA), Low Carbon London demand ADMD-scaled to 0.8 kW/customer, PVWatts-driven PV, recorded EV charging sessions at constant 7.4 kW, and three modifications that decouple P from Q: independent customer power-factor profiles (0.88 to 0.995 lagging), a Q(U) droop on PV inverters (±0.33 pu per EN 50549-1/IEEE 1547), and an 11 kV source voltage that follows a demand-dependent profile within ±2% with a 0.5% tap-changer deadband. Reproducible today:popo.powerflow.sweep.run_uk_sweep, regression tested against a freshly generated real run intests/integration/test_uk_sweep_regression.py. - DSS-EU: a four-feeder Hybrid European MV-LV network (Deakin2021/Koirala2020 topology),
AusNet demand/PV, Fachrizal2021 EV profiles, fixed power factor throughout with unity-PF PV
inverters, EN 50160. Not reproducible: the generating script was never located in
ml-energy-disaggregation, across two separate audits. Seedocs/simulations.mdfor the full account anddocs/EXTRACTION_PLAN.mdfor the extraction history.
The core mechanics are extracted from ml-energy-disaggregation's two legacy power-flow runners
and generalized across them: DER attachment and Volt-VAr control (popo.scenarios), the
time-series solve loop with convergence reported rather than printed (popo.powerflow),
transformer parsing and utilisation-based selection (popo.network), state estimation
(popo.estimation), and named voltage/inverter standards replacing the runners' divergent bare
constants (popo.standards). See docs/simulations.md for copy-pasteable end-to-end commands for
DSS-US and DSS-UK, and docs/EXTRACTION_PLAN.md for the extraction this package is built from.
Expect the API to change.
Licence
Apache-2.0.
Metadata
Release files for popo-flow 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| popo_flow-0.1.0.tar.gz | 1.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| popo_flow-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / popo_flow-0.1.0.tar.gz
| Download URL | popo_flow-0.1.0.tar.gz |
|---|---|
| Size | 1.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ca64b8ec86158f0dbdbca1f8f85cc6b415234ab60d7563e4295f528e60e9ac18
|
|
BLAKE2b-256 checksum How to use checksums |
bfa07c2acb92cf752d201b6ea5c00805707d607acc5c81265d063e2a7f693341
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / popo_flow-0.1.0-py3-none-any.whl
| Download URL | popo_flow-0.1.0-py3-none-any.whl |
|---|---|
| Size | 284.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ac65435b56018ee539c37381802d8ab3601ae4c714af8da0ef60548c99bfdba
|
|
BLAKE2b-256 checksum How to use checksums |
0db0c088fdb180d75122c4ad969c42c9127b4a18aba1f5336d3770de9b46afdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log