Skip to main content

OpenPH-Demand

Energy demand calculations for Passive House (PHPP)

Part of the openph UV workspace - implements PHPP energy demand calculations with exact numerical fidelity to Excel PHPP.

Purpose

OpenPH-Demand calculates:

  • Annual Heating Demand: Transmission and ventilation heat losses, internal/solar gains
  • Annual Cooling Demand: Solar gains, internal gains, cooling strategies
  • Solar Radiation: Window and opaque surface solar radiation for heating/cooling periods
  • Ground Heat Transfer: Temperature calculations for ground-coupled surfaces

It does not yet implement the PHPP Heating load / Cooling load worksheets — only the peak-load climate inputs those worksheets consume. So there is no design-load (W) result, and the energy demand summary reports peak_w: null rather than a misleading zero.

Structure

openph-demand/
├── src/
│   └── openph_demand/
│       ├── heating_demand/      # Heating demand calculations
│       ├── cooling_demand/      # Cooling demand calculations
│       ├── ground/              # Ground heat transfer
│       ├── solar/               # Solar radiation calculations
│       ├── to_table/            # Table view renderers
│       ├── summary.py           # EnergyDemandSummary + build_energy_demand_summary
│       ├── get_solvers.py       # Type-safe solver accessors
│       └── solvers.py           # Solver classes (Energy, Ground, Solar)
├── tests/
└── pyproject.toml

Usage

from openph.phpp import OpPhPHPP
from openph_demand.get_solvers import (
    get_openph_energy_demand_solver,
    get_openph_ground_solver,
    get_openph_solar_solver,
)

# Create PHPP model
phpp = OpPhPHPP()

# Get solvers (registered via entry points)
energy_solver = get_openph_energy_demand_solver(phpp)
ground_solver = get_openph_ground_solver(phpp)
solar_solver = get_openph_solar_solver(phpp)

# Access demand calculations
heating_demand = energy_solver.heating_demand
cooling_demand = energy_solver.cooling_demand

# Get results -- read the canonical annual scalars; never sum a monthly row
annual_heating_kwh = heating_demand.total_yearly_heating_demand              # Heating!AF117
annual_heating_kwh_m2a = heating_demand.total_yearly_specific_heating_demand  # Heating!Q78
annual_cooling_kwh = cooling_demand.total_annual_cooling_demand_kwh           # Cooling!AG155
ground_temps = ground_solver.periods
window_radiation = solar_solver.annual_demand

Energy Demand Summary

For an application — a web request, a batch parametric run, a stored record — use the compact summary rather than reading solver properties one at a time:

from openph_demand import build_energy_demand_summary

summary = build_energy_demand_summary(phpp)
payload = summary.to_dict()   # JSON-ready
text = summary.to_json()      # stable ordering, no NaN/Infinity
{
  "schema_version": "1.0",
  "floor_area_m2": 307.40378,
  "heating": {
    "annual_kwh": 7092.797,
    "annual_kwh_m2a": 23.073228,
    "monthly_kwh": [{"period": "jan", "value": 1552.683}, "…"],
    "peak_w": null
  },
  "cooling": {"annual_kwh": 1769.475, "annual_kwh_m2a": 5.756192, "…": "…"},
  "warnings": [],
  "engine_versions": {"openph": "0.6.0", "openph-demand": "0.6.0", "PHX": "1.56.82"}
}

What it is, and is not:

  • It supplements openph.results.collect_results — the complete, PHPP-addressable audit document — and does not replace or shrink it. The summary is ~200x smaller and carries no worksheet addresses.
  • Annual values are canonical PHPP results, not sums the builder computed. Callers must not re-aggregate monthly_kwh.
  • Monthly values carry "jan""dec" period labels; array position is never the contract.
  • null means "OpenPH does not calculate this quantity", never zero. That is why peak_w is null today.
  • cooling is sensible useful cooling demand and excludes dehumidification — it is not the combined PHI Verification!I39 figure.
  • schema_version is independent of the package version. A reader accepts any matching major version, so additive 1.x fields stay readable.
  • No pandas, no rich: the summary is core output, not a table view.

Wanting a subset of the audit document instead

If you need PHPP-addressable demand records rather than the compact payload — QA against a workbook, say — narrow the audit document with openph.results.ResultSelection instead of collecting everything:

from openph.results import ResultSelection, collect_results

results = collect_results(phpp, selection=ResultSelection(key_prefixes={"energy_demand"}, tiers={"final"}))

The semantics — the four selectors, how they combine, and which of them raise rather than silently matching nothing — live in the openph package README and in ResultSelection's own docstring (help(ResultSelection)), and are not repeated here. One caveat specific to this package: selecting energy_demand still constructs ground and solar_radiation, because the demand solvers call them as calculation dependencies. The guarantee is that the collector does not instantiate a solver you excluded, not that an excluded solver is never built.

For a per-request application payload, reach for build_energy_demand_summary above rather than a selection — it is the surface designed for that job.

Registered Solvers

This package registers three solver plugins with OpenPH:

  • energy_demandOpPhEnergyDemandSolver (heating + cooling)
  • groundOpPhGroundSolver (ground heat transfer)
  • solar_radiationOpPhSolarRadiationSolver (solar gains)

Development

Part of UV workspace - see root context/ENVIRONMENT.md:

uv sync                           # Install all workspace packages
uv run pytest openph-demand/tests/ # Run tests

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openph_demand-0.10.0.tar.gz (104.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openph_demand-0.10.0-py3-none-any.whl (107.3 kB view details)

Uploaded Python 3

File details

Details for the file openph_demand-0.10.0.tar.gz.

File metadata

  • Download URL: openph_demand-0.10.0.tar.gz
  • Upload date:
  • Size: 104.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for openph_demand-0.10.0.tar.gz
Algorithm Hash digest
SHA256 6a91707ce22586430be1e8abf5208ba2121c3ddfc29021732dc9cf854b5d8b56
MD5 e9ba3994b8cef766adef021360754298
BLAKE2b-256 2e5baaed5d79dfe8477ebef1f08323c082578df5f89f78a435641910af79ef2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for openph_demand-0.10.0.tar.gz:

Publisher: publish.yml on Open-PH/openph-demand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openph_demand-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: openph_demand-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 107.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for openph_demand-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c3d47781082b6bd30bf1380d6f5134a49eef83ebae100bf4c67e29d9034cd273
MD5 21812af5296e5f54155bcd33e33dcaee
BLAKE2b-256 6624fa9e0962c307415235b89c5e89274fe0ba3ac5f04e3bc603131c3d98ce92

See more details on using hashes here.

Provenance

The following attestation bundles were made for openph_demand-0.10.0-py3-none-any.whl:

Publisher: publish.yml on Open-PH/openph-demand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

This release

0.10.0 This release

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page