EcosizerEngine (Top-Level API)¶
The EcosizerEngine class is the
primary public interface. All sizing, simulation, and result-retrieval methods
are accessed through it.
Module-level convenience functions are also re-exported from the top-level
ecoengine package.
EcosizerEngine class¶
- class ecoengine.interfaces.EcosizerEngine.EcosizerEngine(building_type: str, magnitude: int | float, zip_code_or_climate_zone, supply_temp_f: float, storage_temp_f: float, schematic: str, gpdpp: float | None = None, custom_peak_load_shape: list[float] | None = None, custom_avg_load_shape: list[float] | None = None, num_heaters: int = 1, hpwh_model: str | None = None, max_daily_run_hr: float = 16.0, defrost_factor: float = 1.0, aquastat_fract: float = 0.5, off_sensor_fract: float = 0.1, on_trigger_t_f: float | None = None, off_trigger_t_f: float | None = None, load_shift_schedule: list[int] | None = None, load_up_hours: int = 0, shed_aquastat_fract: float | None = None, load_up_aquastat_fract: float | None = None, shed_off_sensor_fract: float | None = None, load_up_off_sensor_fract: float | None = None, load_up_off_trigger_t_f: float | None = None, load_shift_percent: float = 0.95, return_temp_f: float | None = None, return_flow_gpm: float | None = None, tm_on_temp_f: float | None = None, tm_off_temp_f: float | None = None, tm_off_time_hr: float = 0.5, tm_safety_factor: float = 1.75, utility_cost_tracker=None, storage_volume_storageT_gal: float | None = None, heating_capacity_kbtuh: float | None = None, tm_storage_vol: float | None = None, tm_capacity_kbtuh: float | None = None, tm_model: str | None = None, num_tm_heaters: int = 1)[source]¶
Bases:
objectPrimary backend interface for the Ecosizer tool.
Accepts building and system parameters, builds and sizes the appropriate DHWSystem subclass, and runs simulations. All input-range validation is expected to be handled by the frontend before calling this class.
Construction immediately builds and sizes the system — no separate build() or size() calls are required:
engine = EcosizerEngine( building_type = "multi_family", magnitude = 100, zip_code_or_climate_zone = {"design_oat_f": 47, "design_inlet_water_temp_f": 47}, supply_temp_f = 125.0, storage_temp_f = 150.0, schematic = "primary_no_recirc", ) result = engine.simulate_3day() result.to_plotly(filepath="output.html")
- __init__(building_type: str, magnitude: int | float, zip_code_or_climate_zone, supply_temp_f: float, storage_temp_f: float, schematic: str, gpdpp: float | None = None, custom_peak_load_shape: list[float] | None = None, custom_avg_load_shape: list[float] | None = None, num_heaters: int = 1, hpwh_model: str | None = None, max_daily_run_hr: float = 16.0, defrost_factor: float = 1.0, aquastat_fract: float = 0.5, off_sensor_fract: float = 0.1, on_trigger_t_f: float | None = None, off_trigger_t_f: float | None = None, load_shift_schedule: list[int] | None = None, load_up_hours: int = 0, shed_aquastat_fract: float | None = None, load_up_aquastat_fract: float | None = None, shed_off_sensor_fract: float | None = None, load_up_off_sensor_fract: float | None = None, load_up_off_trigger_t_f: float | None = None, load_shift_percent: float = 0.95, return_temp_f: float | None = None, return_flow_gpm: float | None = None, tm_on_temp_f: float | None = None, tm_off_temp_f: float | None = None, tm_off_time_hr: float = 0.5, tm_safety_factor: float = 1.75, utility_cost_tracker=None, storage_volume_storageT_gal: float | None = None, heating_capacity_kbtuh: float | None = None, tm_storage_vol: float | None = None, tm_capacity_kbtuh: float | None = None, tm_model: str | None = None, num_tm_heaters: int = 1)[source]¶
- Parameters:
building_type (str) – Building use type (e.g.
'multi_family','office').magnitude (int or float) – Occupancy metric appropriate to the building type (people, units, etc.).
zip_code_or_climate_zone (str | int | dict) –
Climate lookup key. Accepted forms:
5-digit CA zip code string or int →
ClimateZone.from_zip_code()Integer 1–96 →
ClimateZone.from_zone_id()Non-numeric string →
ClimateZone.from_weather_station()Dict with keys
'design_oat_f'and/or'design_inlet_water_temp_f'→ClimateZone.from_design_conditions()
supply_temp_f (float) – DHW delivery temperature [°F].
storage_temp_f (float) – Hot water storage setpoint [°F].
schematic (str) –
Piping configuration. Supported values:
'primary_no_recirc'— base DHWSystem (heat pump + stratified tank)'parallel_loop'— separate TM tank in parallel for recirc losses'swing_tank'— swing-tank recirc system'single_pass_rtp'— single-pass return-to-primary'multi_pass_rtp'— multi-pass return-to-primary'instant_wh'— instantaneous (tankless) water heater, no storage
gpdpp (float, optional) – Gallons per person per day. If None, building-type defaults are used.
custom_peak_load_shape (list[float], optional) – 24-element normalized peak-hour DHW load shape. Required when
building_typeis None.custom_avg_load_shape (list[float], optional) – 24-element normalized average-hour DHW load shape. Used for annual simulation load profiles.
num_heaters (int) – Number of primary HPWH units. Default 1.
hpwh_model (str, optional) – HPWH model name for performance map lookup (future use).
max_daily_run_hr (float) – Maximum hours the primary heating system may run per day. Default 16. NOT YET USED FOR MPRTP
defrost_factor (float) – Fraction of rated capacity available after defrost cycles (0–1). Default 1.0.
aquastat_fract (float) – Fractional tank height of the ON aquastat (0–1). Default 0.5.
off_sensor_fract (float) – Fractional tank height of the OFF aquastat (0–1). Default 0.1.
on_trigger_t_f (float, optional) – Temperature at which the ON aquastat fires. Defaults to supply_temp_f.
off_trigger_t_f (float, optional) – Temperature at which the OFF aquastat fires. Defaults to storage_temp_f.
load_shift_schedule (list[int], optional) – 24-element list (0 = shed hour, 1 = run hour). None → no load shifting.
load_up_hours (int) – Hours spent in load-up mode before the first shed window.
shed_aquastat_fract (float, optional) – ON aquastat fraction during shed hours (higher → more storage).
load_up_aquastat_fract (float, optional) – ON aquastat fraction during load-up hours (lower → fires sooner).
shed_off_sensor_fract (float, optional) – OFF aquastat fraction during shed hours. Defaults to off_sensor_fract.
load_up_off_sensor_fract (float, optional) – OFF aquastat fraction during load-up hours. Defaults to off_sensor_fract.
load_up_off_trigger_t_f (float, optional) – OFF trigger temperature during load-up hours. Defaults to off_trigger_t_f.
load_shift_percent (float) – Percentile of days the load-shift sizing must cover [0.25, 1.0]. Default 0.95 — size for 95% of days, accepting that the highest-demand 5% of days may occasionally breach the shed window. Only applied during load-shift sizing; normal sizing always uses the full daily demand.
return_temp_f (float, optional) – Recirc loop return temperature [°F]. Required for recirc schematics.
return_flow_gpm (float, optional) – Recirc loop flow rate [GPM]. Required for recirc schematics.
tm_on_temp_f (float, optional) – TM element turn-on temperature [°F]. Defaults to supply_temp_f − 5.
tm_off_temp_f (float, optional) – TM element turn-off temperature [°F]. Defaults to supply_temp_f.
tm_off_time_hr (float) – Max TM heater off-cycle duration [hr]. Default 0.5.
tm_safety_factor (float) – TM capacity safety multiplier (> 1.0). Default 1.2.
utility_cost_tracker (UtilityCostTracker, optional) – Attached to the building for annual cost estimates.
storage_volume_storageT_gal (float, optional) – Pre-sized primary storage tank volume at storage temperature [gallons]. When provided together with
heating_capacity_kbtuh(orhpwh_model), the sizing step is skipped entirely.heating_capacity_kbtuh (float, optional) – Pre-sized total primary heating capacity [kBTU/hr]. Must be paired with
storage_volume_storageT_gal(except forinstant_wh). For multi-heater systems this is the combined fleet capacity; each WaterHeater is assignedheating_capacity_kbtuh / num_heaters. Ignored whenhpwh_modelis also provided.tm_storage_vol (float, optional) – Pre-sized TM tank volume [gallons]. Required for
parallel_loopandswing_tankwhen using the pre-sized path.tm_capacity_kbtuh (float, optional) – Pre-sized TM heater capacity [kBTU/hr]. Required for
parallel_loopandswing_tankwhentm_modelis not provided.tm_model (str, optional) – HPWH model name for the TM heater’s performance map. When provided,
tm_capacity_kbtuhis used only as the ER fallback capacity.return_temp_fis used asdesign_inlet_temp_f.num_tm_heaters (int) – Number of identical TM heater units for
parallel_loopschematics. The singletm_water_heaterobject represents one unit; its output is multiplied by this value before being applied to the TM tank and recorded. For the sized path, per-unit capacity =_minimum_tm_capacity_kbtuh / num_tm_heaters; for the pre-sized path withtm_capacity_kbtuh, per-unit =tm_capacity_kbtuh / num_tm_heaters. Default 1.
- get_sizing_results() dict[source]¶
Return the sizing results from the built DHWSystem.
- Returns:
Always contains
'min_capacity_kbtuh'and'min_storage_storageT_gal'. Parallel loop systems also include'min_tm_volume_gal'and'min_tm_capacity_kbtuh'.- Return type:
- simulate_3day(**sim_run_kwargs)[source]¶
Run a 3-day design-day simulation at 1-minute timesteps.
- Parameters:
**sim_run_kwargs – Optional keyword arguments forwarded to SimulationRun.__init__(), e.g.
outlet_deficit_threshold_f=5.0,outlet_deficit_max_min=10.- Return type:
- simulate_annual(**sim_run_kwargs)[source]¶
Run a full annual simulation at 10-minute timesteps.
- Parameters:
**sim_run_kwargs – Optional keyword arguments forwarded to SimulationRun.__init__().
- Return type:
- get_simulation_summary(simulation_run) dict[source]¶
Return a summary dict from a completed SimulationRun.
- Parameters:
simulation_run (SimulationRun)
- Returns:
Keys: ‘successful’, ‘total_outage_min’, ‘total_energy_kwh’, ‘peak_demand_kw’, ‘num_steps_recorded’, ‘stopped_early’.
- Return type:
- get_annual_cost_estimate(simulation_run) dict[source]¶
Compute annual utility cost from a completed annual SimulationRun.
- Parameters:
simulation_run (SimulationRun)
- Returns:
Monthly energy breakdown (kWh) by month.
- Return type:
- get_hw_magnitude() float[source]¶
Return the total daily DHW usage for the building [gallons at supply temperature].
- Return type:
- plot_simulation(title: str = 'Simulation Results', filepath: str | None = None, include_temperatures: bool = False, return_as_div: bool = False)[source]¶
Run a 3-day design-day simulation and return a Plotly figure of the results.
- Parameters:
title (str) – Figure title. Default
"Simulation Results".filepath (str, optional) – If provided, write the figure to this path as a self-contained HTML file. The figure is also returned regardless.
include_temperatures (bool) – If True, add a right Y axis showing OAT, inlet water temperature, and all tank node temperatures. Default False.
return_as_div (bool) – If True, return the figure as an HTML
<div>string instead of aplotly.graph_objects.Figure. Default False.
- Returns:
A Plotly figure, or an HTML div string when
return_as_div=True.- Return type:
plotly.graph_objects.Figure or str
- Raises:
ImportError – If
plotlyis not installed.
- plot_sizing_curve(title: str = 'Primary Sizing Curve', filepath: str | None = None, strat_slope: float = 2.8, return_as_div: bool = False, return_with_x_y_points: bool = False)[source]¶
Return a Plotly figure of the sizing curve for the built system.
For systems without load shifting, produces the primary sizing curve (storage volume vs. heating capacity as a function of daily run hours).
For systems with load shifting (
load_shift_schedulewas provided), produces the load-shift sizing curve (storage volume vs. coverage percentile), with a slider to explore the capacity/storage trade-off.The recommended point — corresponding to the
max_daily_run_hrorload_shift_percentpassed to the engine — is highlighted on the curve at page load.- Parameters:
title (str) – Figure title. Default
"Primary Sizing Curve".filepath (str, optional) – If provided, write the figure to this path as a self-contained HTML file. The figure is also returned regardless.
strat_slope (float) – Temperature gradient [°F / %-height] for stratification factor calculation. Default 2.8.
return_as_div (bool) – If True, return the figure as an HTML
<div>string instead of aplotly.graph_objects.Figure. Default False.return_with_x_y_points (bool) – If True, return
[figure_or_div, x_values, y_values, start_index]instead of just the figure/div, wherex_valuesandy_valuesare the plot coordinates andstart_indexis the recommended slider position. Default False.
- Returns:
plotly.graph_objects.Figure – When both flags are False.
str – HTML div string when
return_as_div=Trueandreturn_with_x_y_points=False.list –
[figure_or_div, x_values, y_values, start_index]whenreturn_with_x_y_points=True.
- Raises:
ImportError – If
plotlyis not installed.
Module-level functions¶
- ecoengine.interfaces.EcosizerEngine.get_oat_buckets(zip_code: str | int | None = None, zone_id: int | None = None, weather_station: str | None = None) dict[float, int][source]¶
Return the distribution of daily average outdoor air temperatures across 5°F buckets for a given location’s typical meteorological year.
Exactly one of
zip_code,zone_id, orweather_stationmust be provided to identify the climate zone.- Parameters:
- Returns:
Mapping of bucket temperature [°F] → number of days per year with a daily average OAT in that 5°F bucket. Only populated buckets are included.
- Return type:
Examples
>>> get_oat_buckets(zip_code=90210) {50.0: 46, 55.0: 83, ...} >>> get_oat_buckets(zone_id=19) {65.0: 25, ...}
- ecoengine.interfaces.EcosizerEngine.get_list_of_models(multi_pass: bool = False, include_residential: bool = True, exclude_models: list[str] | None = None, sgip_models_only: bool = True) list[list[str]][source]¶
Return available HPWH model codes and display names.
- Parameters:
multi_pass (bool) –
True→ return only multi-pass (_MP) models.False→ return only single-pass (_SP) models.include_residential (bool) –
True→ include residential (_R_) models.False→ commercial (_C_) models only.exclude_models (list[str] | None) – Model codes to omit from the result. Defaults to no exclusions.
sgip_models_only (bool) –
True(default) → restrict to models flaggedSGIP_availin the performance-map database.
- Returns:
Each element is
[model_code, display_name]wheremodel_codeis the string accepted byWaterHeater.from_model_name()anddisplay_nameis the human-readable label.- Return type:
- ecoengine.interfaces.EcosizerEngine.get_weather_stations(exclude_zones: list[int] | None = None) list[list][source]¶
Return all available weather stations and their corresponding climate zone IDs.
- Parameters:
exclude_zones (list[int], optional) – Climate zone IDs to omit from the result. Defaults to
[96].- Returns:
Each element is
[weather_station_name, climate_zone_id]whereweather_station_nameis the string accepted byClimateZone.from_weather_station()andclimate_zone_idis the corresponding integer zone number. Weather data sourced from https://energyplus.net/weather.- Return type:
- ecoengine.interfaces.EcosizerEngine.get_hpwh_output_capacity(model: str, oat_f: float, inlet_water_temp_f: float, outlet_water_temp_f: float, num_heaters: int = 1, return_as_kw: bool = True, defrost_derate: float = 0.0) float[source]¶
Return the output capacity of an HPWH model at the given operating conditions.
- Parameters:
model (str) – Model code string (see
get_list_of_models()).oat_f (float) – Outdoor air temperature [°F].
inlet_water_temp_f (float) – Incoming cold-water temperature [°F].
outlet_water_temp_f (float) – Hot storage outlet temperature [°F].
num_heaters (int) – Number of HPWH units. Output is multiplied by this. Default 1.
return_as_kw (bool) – If True (default), return output in kW. If False, return in kBTU/hr.
defrost_derate (float) – Fractional capacity reduction due to defrost [0.0–1.0]. Default 0.0.
- Returns:
Output capacity after defrost derate in the requested unit.
- Return type:
- Raises:
ValueError – If
defrost_derateis outside [0, 1] ornum_heaters< 1.
- ecoengine.interfaces.EcosizerEngine.get_sizing_curve_plot(x: list, y: list, start_index: int, load_shifting: bool = False, er_sized: bool = False, return_as_div: bool = False)[source]¶
Build a Plotly sizing-curve figure from pre-computed x/y points.
This is a lightweight alternative to
EcosizerEngine.plot_sizing_curve()for callers that already have the curve data (e.g. fromEcosizerEngine.plot_sizing_curve(return_with_x_y_points=True)).- Parameters:
x (list) –
X-axis values. Interpretation depends on the mode:
Normal sizing — storage volume [gal at storage temperature]
Load-shifting — load-shift coverage percentile [%]
ER sizing — percent of building covered [%]
y (list) –
Y-axis values. Interpretation depends on the mode:
Normal sizing — heating capacity [kBTU/hr]
Load-shifting — storage volume [gal at storage temperature]
ER sizing — ER element capacity [kW]
start_index (int) – Index into
x/ywhere the recommended-size diamond starts.load_shifting (bool) – If True, use load-shift axis labels. Default False.
er_sized (bool) – If True, use ER-sizing axis labels (overrides
load_shifting). Default False.return_as_div (bool) – If True, return an HTML
<div>string instead of a Figure. Default False.
- Return type:
plotly.graph_objects.Figure or str
- Raises:
ImportError – If
plotlyis not installed.
- ecoengine.interfaces.EcosizerEngine.get_annual_utility_comparison_graph(sim_run_hp, sim_run_iwh, utility_cost_tracker, return_as_div: bool = False, return_as_array: bool = False)[source]¶
Build a stacked bar chart comparing monthly utility costs for an HPWH system vs. an instantaneous electric resistance (UER) baseline.
Each month shows two adjacent bars — one for the HP system, one for UER — stacked by charge type: base, energy, and demand.
- Parameters:
sim_run_hp (SimulationRun) – Annual simulation result for the heat pump system.
sim_run_iwh (SimulationRun) – Annual simulation result for the instantaneous/UER baseline.
utility_cost_tracker (UtilityCostTracker) – Rate structure applied to both runs.
return_as_div (bool) – If True, return an HTML
<div>string instead of a Figure.return_as_array (bool) – If True, return
(hp_breakdown, iwh_breakdown)dicts instead of a figure. Each dict has keys'energy'(12 floats),'demand'(12 floats), and'base'(float).
- Return type: