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.11.0.tar.gz (105.7 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.11.0-py3-none-any.whl (108.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: openph_demand-0.11.0.tar.gz
  • Upload date:
  • Size: 105.7 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.11.0.tar.gz
Algorithm Hash digest
SHA256 625cbadfe32836143204e9a1560593458e6cc5d7942ddb6f3b6fe6735b8032d5
MD5 286a49fb7443f4747e3ff73c24fa454a
BLAKE2b-256 f1032a44aa662bd003c53b45cd8cd5ee269eff766d59036447751eac67831798

See more details on using hashes here.

Provenance

The following attestation bundles were made for openph_demand-0.11.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.11.0-py3-none-any.whl.

File metadata

  • Download URL: openph_demand-0.11.0-py3-none-any.whl
  • Upload date:
  • Size: 108.8 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.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2a252c61343046ad213e0c72583edf6160da8fabcb3e8ac3c799e662c01e6ec7
MD5 cb1ecb8152621aad26ec8830aefa5f7a
BLAKE2b-256 320a9aa1684cbf761c404f8d752873c3ffafd333b43e886922d012a7e1a83ef5

See more details on using hashes here.

Provenance

The following attestation bundles were made for openph_demand-0.11.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

This release

0.11.0 This release

2 files

0.10.0

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