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.

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.7.0.tar.gz (103.1 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.7.0-py3-none-any.whl (106.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: openph_demand-0.7.0.tar.gz
  • Upload date:
  • Size: 103.1 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.7.0.tar.gz
Algorithm Hash digest
SHA256 3126c27e197581288c4b8bd6949e5e285cb6899b29ef9cee8dfa50cba9ad4bca
MD5 ed6f74bebfe98afea07ab95150c653c7
BLAKE2b-256 bc6ddd1c8da475c818731805bd94332a49af44edff6cca78506f2379f956a9d6

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: openph_demand-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 106.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.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 462b0728dcfebdc25625f9f6ac12a01f26411e0000b5b25ecff932043c07ef33
MD5 f0ca669e95c98f3784fed48729606a7f
BLAKE2b-256 51b7c8e6072e41a3f136f03c475d370fc634b904212b18c10d849e596251bee9

See more details on using hashes here.

Provenance

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

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

This release

0.7.0 This release

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