Equipment Sizing

Equipment sizing (ASHRAE HSE 2020), duct sizing (ASHRAE HOF 2021 Ch.21), and ventilation compliance (ASHRAE 62.1-2022).

Cooling Equipment

class hvacpy.equipment.SplitSystem(cooling_load, cop_rated: float = 3.5, multi_split: bool = False)[source]

Bases: CoolingEquipment

Split system (residential or light commercial).

Selects ‘split_residential’ if required < 7 kW, else ‘split_light_commercial’.

property equipment_subtype: str

‘residential’ or ‘light_commercial’.

class hvacpy.equipment.PackagedRTU(cooling_load, cop_rated: float = 3.2, has_economiser: bool = False, has_gas_heat: bool = False)[source]

Bases: CoolingEquipment

Packaged rooftop unit (small or large).

Selects ‘packaged_rtu_small’ if required <= 24.6 kW, else ‘packaged_rtu_large’.

property eer: float

Energy Efficiency Ratio = COP * 3.412 (BTU/Wh).

class hvacpy.equipment.FanCoilUnit(cooling_load, chilled_water_supply_t=None, chilled_water_return_t=None, cop_rated: float = 4.5)[source]

Bases: CoolingEquipment

Fan coil unit with chilled water.

Calculates chilled water flow rate.

property chw_flow_rate: Quantity

Chilled water flow rate in L/s.

V_dot = Q_total / (CP_water * delta_T * rho_water)

property delta_t_chw: Quantity

Chilled water ΔT in K.

class hvacpy.equipment.Chiller(cooling_load, chiller_type: str = 'air_cooled', cop_rated: float | None = None, n_units: int = 1, redundancy: str = 'none')[source]

Bases: CoolingEquipment

Chiller (air-cooled or water-cooled).

Supports N+1 redundancy and condenser heat rejection calculation.

property capacity_per_unit: Quantity

Nominal capacity per chiller unit in kW.

property condenser_heat_rejection: Quantity

Total condenser heat rejection in kW.

Q_cond = Q_total * (1 + 1/COP)

property cooling_tower_flow: Quantity | None

Cooling tower water flow rate in L/s. None if air-cooled.

V_dot = Q_cond / (CP_water * delta_T_tower * rho_water) delta_T_tower default = 5K

Heat Pump

class hvacpy.equipment.AirSourceHeatPump(cooling_load, heating_load, cop_rated_cooling: float = 3.5, cop_rated_heating: float = 3.8, t_outdoor_cooling: Quantity | None = None, t_outdoor_heating: Quantity | None = None)[source]

Bases: object

Air-source heat pump sizing for both cooling and heating.

Determines binding mode, COP corrections, heating coverage, and supplemental heat requirements.

property binding_mode: str

‘cooling’ or ‘heating’ — which determined nominal size.

property cooling_oversizing: float

nominal / required_cooling.

property cop_at_design_cooling: float

COP at t_outdoor_cooling.

property cop_at_design_heating: float

COP at t_outdoor_heating.

property heating_coverage: float

actual_heating_at_design / required_heating.

property needs_supplemental_heat: bool

True if heating_coverage < 1.0.

property nominal_capacity_kw: Quantity

Nominal cooling capacity from heat pump table.

summary() str[source]

Box format showing both modes, binding, coverage, supplemental.

property supplemental_heat_kw: Quantity

Required backup heating. 0 if not needed.

property supply_airflow: Quantity

Supply airflow in m³/s.

Duct Sizing

class hvacpy.equipment.DuctSizer(airflow: Quantity, method: str = 'equal_friction', section_type: str = 'main_supply', friction_rate: float | None = None, upstream_velocity: float | None = None, section_length: float | None = None)[source]

Bases: object

Duct sizing using equal friction, velocity reduction, or static regain.

Parameters:
  • airflow – Volume flow rate as Quantity (m³/s).

  • method – ‘equal_friction’, ‘velocity_reduction’, or ‘static_regain’.

  • section_type – ‘main_supply’, ‘branch_supply’, or ‘return’.

  • friction_rate – Target friction rate in Pa/m (equal friction only).

  • upstream_velocity – Upstream velocity in m/s (static regain only).

  • section_length – Section length in m (static regain only).

property diameter: Quantity

Rounded up to nearest standard size (mm).

property diameter_exact: Quantity

Before rounding (mm).

property friction_loss: Quantity

Actual friction at sized diameter (Pa/m).

property rectangular_equivalent: tuple

1 aspect, rounded to nearest 50mm.

Type:

(width_mm, height_mm) at 1.5

summary() str[source]

One-line summary: ‘Dia250mm - 4.1m/s - 0.72Pa/m - or 300x200mm rect’.

property velocity: Quantity

Actual velocity in sized duct (m/s).

property velocity_ok: bool

True if velocity <= V_max for section_type.

Ventilation

class hvacpy.equipment.VentilationCheck(room: Room, supply_airflow: Quantity, space_type: str, oa_fraction: float = 0.15)[source]

Bases: object

ASHRAE 62.1-2022 single-zone ventilation compliance check.

Vz = Rp * Pz + Ra * Az [L/s]

Parameters:
  • room – Room object (provides floor_area_m2 and occupant count).

  • supply_airflow – Total supply airflow as Quantity (m³/s or L/s).

  • space_type – Key into VENTILATION_RATES.

  • oa_fraction – Outdoor air fraction of supply. Default 0.15.

property actual_oa_flow: Quantity

Actual outdoor air flow in L/s.

property compliant: bool

True if actual OA >= required OA.

property deficit: Quantity

Deficit in L/s (0 if compliant).

property required_oa_flow: Quantity

Required outdoor air flow in L/s.

summary() str[source]

Compliance summary string.

Airflow Functions

Supply airflow pure functions.

Calculates required supply air volume flow rates from sensible loads.

hvacpy.equipment._airflow.airflow_from_cooling_load(cooling_load, t_supply=None) Quantity[source]

Convenience wrapper — compute supply airflow from a CoolingLoad object.

Uses peak_sensible and the room’s indoor temperature.

hvacpy.equipment._airflow.supply_airflow_cooling(sensible_load: Quantity, t_room: Quantity | None = None, t_supply: Quantity | None = None) Quantity[source]

Calculate supply airflow for cooling from sensible load.

V_dot = Q_sensible / (rho_air * CP_DA * (T_room - T_supply))

Parameters:
  • sensible_load – Sensible cooling load as Quantity (W).

  • t_room – Room temperature. Default 24°C.

  • t_supply – Supply air temperature. Default 13°C.

Returns:

Volume flow rate as Quantity (m³/s).

Raises:

AirflowCalculationError – If T_supply >= T_room.

hvacpy.equipment._airflow.supply_airflow_heating(heating_load: Quantity, t_room: Quantity | None = None, t_supply: Quantity | None = None) Quantity[source]

Calculate supply airflow for heating from heating load.

V_dot = Q_heating / (rho_air * CP_DA * (T_supply - T_room))

Parameters:
  • heating_load – Heating load as Quantity (W).

  • t_room – Room temperature. Default 21°C.

  • t_supply – Supply air temperature. Default 40°C.

Returns:

Volume flow rate as Quantity (m³/s).

Convenience Functions

hvacpy.equipment.size_cooling_equipment(cooling_load, equipment_class=<class 'hvacpy.equipment._cooling.SplitSystem'>, **kwargs)[source]

Convenience function to size cooling equipment from a CoolingLoad.

hvacpy.equipment.size_heat_pump(cooling_load, heating_load, **kwargs)[source]

Convenience function to size an air-source heat pump.

Exceptions

Custom exceptions for the hvacpy package.

All hvacpy-specific exceptions are defined here. No exceptions are defined in any other module.

exception hvacpy.exceptions.AirflowCalculationError[source]

Bases: HvacpyError, ValueError

Raised when airflow calculation has invalid inputs.

exception hvacpy.exceptions.DesignConditionsNotFoundError[source]

Bases: HvacpyError, KeyError

Raised when a city is not in the design conditions database.

exception hvacpy.exceptions.DuctSizingError[source]

Bases: HvacpyError, ValueError

Raised when duct sizing fails to converge.

exception hvacpy.exceptions.EquipmentSizingError[source]

Bases: HvacpyError, ValueError

Raised when load exceeds all available nominal sizes.

exception hvacpy.exceptions.HvacpyError[source]

Bases: Exception

Base exception for all hvacpy errors.

exception hvacpy.exceptions.LoadCalculationError[source]

Bases: HvacpyError, ValueError

Raised when a load calculation cannot be completed.

exception hvacpy.exceptions.MaterialNotFoundError[source]

Bases: HvacpyError, KeyError

Raised when a material key is not in the database.

exception hvacpy.exceptions.PsychrometricInputError[source]

Bases: HvacpyError, ValueError

Raised when psychrometric input properties are invalid.

exception hvacpy.exceptions.UnitError[source]

Bases: HvacpyError, ValueError

Raised when a Quantity has an incompatible unit.