breos 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
breos/__init__.py ADDED
@@ -0,0 +1,348 @@
1
+ """
2
+ BREOS - Building Renewable Energy Optimization Software
3
+
4
+ Python library for PV and battery energy-system simulation and optimization.
5
+ Supports both hourly ('h') and 15-minute ('15min') time resolutions.
6
+
7
+ Modules:
8
+ --------
9
+ - weather: Weather data fetching and interpolation
10
+ - solar: PV production calculations
11
+ - load_profiles: Load profile management
12
+ - battery: Energy balance and degradation simulation
13
+ - economics: Cost analysis and projections
14
+ - optimization: System sizing and tilt optimization
15
+ - plotting: Visualization utilities
16
+ - emissions: CO2 savings calculations
17
+
18
+ Usage:
19
+ ------
20
+ >>> import breos
21
+ >>> app = breos.App({"location": "porto", "n_modules": 10, "annual_consumption_kwh": 4000})
22
+ >>> app.simulate()
23
+ >>> result = app.result()
24
+ """
25
+
26
+ # Version — resolved from the installed package metadata so it always matches
27
+ # the version declared in pyproject.toml (the single source of truth). This is
28
+ # the same mechanism used by breos/cli.py and docs/conf.py, which keeps the
29
+ # literal from drifting out of sync with the distribution version on a release.
30
+ from importlib.metadata import PackageNotFoundError
31
+ from importlib.metadata import version as _version
32
+
33
+ try:
34
+ __version__ = _version("breos")
35
+ except PackageNotFoundError: # running from a source tree without an install
36
+ __version__ = "0.0.0+unknown"
37
+
38
+ # Public facade
39
+ from breos.app import App
40
+
41
+ # Battery
42
+ from breos.battery import (
43
+ BatteryConfig,
44
+ apply_indoor_temperature_model,
45
+ compute_cell_temperature,
46
+ compute_halfcycle_energy_throughput,
47
+ detect_cycles_rainflow,
48
+ detect_half_cycles_from_soc_series,
49
+ k_c_rate_Q,
50
+ k_c_rate_R,
51
+ k_doc_Q,
52
+ k_doc_R,
53
+ resistance_to_efficiency,
54
+ simulate_energy_balance,
55
+ update_battery_resistance_calendar,
56
+ update_battery_resistance_cyclewise,
57
+ update_battery_soc,
58
+ update_battery_soh_calendar,
59
+ update_battery_soh_cyclewise,
60
+ )
61
+
62
+ # Constants
63
+ from breos.constants import (
64
+ A_Q,
65
+ A_R,
66
+ B_Q,
67
+ B_R,
68
+ C_DOC_Q,
69
+ C_DOC_R,
70
+ D_DOC_Q,
71
+ D_DOC_R,
72
+ DEFAULT_CHARGE_EFFICIENCY,
73
+ DEFAULT_DISCHARGE_EFFICIENCY,
74
+ DEFAULT_INDOOR_CEILING_C,
75
+ DEFAULT_INDOOR_COUPLING_ALPHA,
76
+ DEFAULT_INDOOR_FLOOR_C,
77
+ DEFAULT_INDOOR_SETPOINT_C,
78
+ DEFAULT_MAX_SOC,
79
+ DEFAULT_MIN_SOC,
80
+ LAM_EA_J_MOL,
81
+ LAM_EXPONENT_B,
82
+ LAM_K0_FRAC,
83
+ LAM_SOC_EXPONENT_N,
84
+ NAUMANN_EA_J_MOL,
85
+ NAUMANN_EA_R_J_MOL,
86
+ NAUMANN_EXPONENT_B,
87
+ NAUMANN_K0_PERCENT,
88
+ NAUMANN_K0_R_PERCENT,
89
+ NAUMANN_SOC_EXPONENT_N,
90
+ R_GAS,
91
+ T_REF_K,
92
+ Z_Q,
93
+ Z_R,
94
+ )
95
+
96
+ # Economics
97
+ from breos.economics import (
98
+ CostParams,
99
+ calculate_costs,
100
+ calculate_lcoe,
101
+ calculate_lcoe_from_projection,
102
+ cost_analysis_projection,
103
+ cost_params_from_config,
104
+ find_payback_year,
105
+ )
106
+
107
+ # Emissions
108
+ from breos.emissions import (
109
+ EmissionsParams,
110
+ calculate_co2_projection,
111
+ calculate_co2_savings,
112
+ )
113
+
114
+ # Inverter
115
+ from breos.inverter import (
116
+ INVERTER_PRESETS,
117
+ InverterConfig,
118
+ InverterConversionResult,
119
+ calculate_dc_ac_power,
120
+ get_inverter_preset,
121
+ )
122
+
123
+ # I/O (export/import functions)
124
+ from breos.io import (
125
+ export_cost_analysis,
126
+ export_monthly_summary,
127
+ export_results,
128
+ export_summary,
129
+ export_yearly_summary,
130
+ load_results,
131
+ save_simulation_report,
132
+ )
133
+
134
+ # Load Profiles
135
+ from breos.load_profiles import (
136
+ align_load_to_pv,
137
+ load_profile,
138
+ scale_to_annual_consumption,
139
+ )
140
+
141
+ # Monte Carlo (weather + demand uncertainty)
142
+ from breos.montecarlo import (
143
+ MonteCarloResult,
144
+ MonteCarloSettings,
145
+ run_montecarlo,
146
+ )
147
+
148
+ # Optimization
149
+ from breos.optimization import (
150
+ OptimizationResult,
151
+ optimize_battery_size,
152
+ optimize_system_multi_objective,
153
+ optimize_tilt,
154
+ optimize_tilt_brent,
155
+ size_for_zeb,
156
+ )
157
+
158
+ # Polysun Degradation (comparison baseline)
159
+ from breos.polysun_degradation import (
160
+ PolysunDegradationConfig,
161
+ compute_dod_histogram,
162
+ compute_miner_damage,
163
+ predict_polysun_lifetime,
164
+ simulate_polysun_degradation,
165
+ woehler_cycles_to_failure,
166
+ )
167
+
168
+ # PV Module Database
169
+ from breos.pv_modules import (
170
+ MODULES,
171
+ get_module,
172
+ get_module_info,
173
+ list_modules,
174
+ )
175
+
176
+ # Solar
177
+ from breos.solar import (
178
+ PVModuleParams,
179
+ calculate_multi_array_production,
180
+ calculate_pv_production_ac,
181
+ calculate_pv_production_dc,
182
+ calculate_pv_production_dc_tracking,
183
+ calculate_pv_production_tmy,
184
+ dc_to_ac,
185
+ default_azimuth,
186
+ estimate_optimal_tilt,
187
+ zeb_sizer,
188
+ )
189
+
190
+ # Utils
191
+ from breos.utils import (
192
+ count_leap_years,
193
+ get_hours_per_step,
194
+ get_steps_per_day,
195
+ get_steps_per_year,
196
+ is_leap_year,
197
+ number_of_cores,
198
+ remap_datetime_index_years,
199
+ )
200
+
201
+ # Weather
202
+ from breos.weather import (
203
+ build_battery_temperature_series,
204
+ csv_15min_to_hourly,
205
+ csv_hourly_to_15min,
206
+ extract_ambient_temperature,
207
+ fetch_tmy_nsrdb,
208
+ fetch_tmy_weather_data,
209
+ fetch_weather_data,
210
+ load_weather,
211
+ parse_weather_filename,
212
+ preload_weather_by_year,
213
+ read_epw_file,
214
+ resample_tmy_to_15min,
215
+ resample_to_15min,
216
+ resample_to_hourly,
217
+ select_random_year_and_replace_datetime,
218
+ )
219
+
220
+ # Plotting (try to import, skip if matplotlib not installed)
221
+ try:
222
+ from breos.plotting import (
223
+ create_cost_plots,
224
+ degradation_plots,
225
+ monthly_graphs,
226
+ plot_azitilt_ew_1d,
227
+ plot_azitilt_landscape_2d,
228
+ plot_azitilt_landscape_3d,
229
+ plot_battery_soh_timeseries,
230
+ plot_breakeven,
231
+ plot_breakeven_comparison,
232
+ plot_breakeven_two,
233
+ # Sensitivity analysis
234
+ plot_calendar_aging_sensitivity,
235
+ plot_cell_temperature,
236
+ # CO2 savings
237
+ plot_co2_savings,
238
+ # Polysun vs BREOS comparison
239
+ plot_degradation_methodology_comparison,
240
+ # Batch comparison
241
+ plot_grid_independence_heatmap,
242
+ plot_lifetime_prediction_comparison,
243
+ plot_location_comparison_delta,
244
+ plot_loo_cv_summary,
245
+ plot_loo_param_stability,
246
+ plot_loo_predictions,
247
+ # Monte Carlo distributions
248
+ plot_montecarlo_final_soh_distribution,
249
+ plot_montecarlo_grid_independence_distribution,
250
+ plot_montecarlo_npv_distribution,
251
+ plot_montecarlo_simulation,
252
+ plot_monthly_balance,
253
+ plot_monthly_comparison,
254
+ plot_pareto_front_analysis,
255
+ plot_resistance_and_efficiency,
256
+ plot_temperature_sensitivity_comparison,
257
+ plot_tilt_optimization,
258
+ plot_timeseries,
259
+ plot_validation_degradation_split,
260
+ plot_validation_multi_system,
261
+ plot_validation_parity,
262
+ plot_validation_residuals,
263
+ plot_validation_soh_comparison,
264
+ plot_weather_annual_ghi_distribution,
265
+ plot_weather_monthly_comparison,
266
+ set_presentation_mode,
267
+ weekly_graphs,
268
+ yearly_graphs,
269
+ )
270
+ except ImportError:
271
+ pass # matplotlib not installed
272
+
273
+
274
+ # Numba kernels (lazy import to avoid slow import at package load)
275
+ def _get_numba():
276
+ """Lazy import of Numba-accelerated kernels."""
277
+ from breos import numba_kernels
278
+
279
+ return numba_kernels
280
+
281
+
282
+ __all__ = [
283
+ # Public facade
284
+ "App",
285
+ # Version
286
+ "__version__",
287
+ # Configuration and result objects
288
+ "BatteryConfig",
289
+ "CostParams",
290
+ "EmissionsParams",
291
+ "InverterConfig",
292
+ "InverterConversionResult",
293
+ "OptimizationResult",
294
+ "PVModuleParams",
295
+ # Weather
296
+ "load_weather",
297
+ "fetch_tmy_weather_data",
298
+ "fetch_tmy_nsrdb",
299
+ "fetch_weather_data",
300
+ "read_epw_file",
301
+ # Solar
302
+ "calculate_pv_production_dc",
303
+ "calculate_pv_production_dc_tracking",
304
+ "calculate_multi_array_production",
305
+ "calculate_pv_production_ac",
306
+ "dc_to_ac",
307
+ "estimate_optimal_tilt",
308
+ "default_azimuth",
309
+ # PV module catalogue
310
+ "get_module",
311
+ "get_module_info",
312
+ "list_modules",
313
+ # Load Profiles
314
+ "load_profile",
315
+ "scale_to_annual_consumption",
316
+ "align_load_to_pv",
317
+ # Inverter
318
+ "get_inverter_preset",
319
+ "calculate_dc_ac_power",
320
+ # Battery
321
+ "simulate_energy_balance",
322
+ "apply_indoor_temperature_model",
323
+ # Emissions
324
+ "calculate_co2_savings",
325
+ "calculate_co2_projection",
326
+ # Economics
327
+ "calculate_costs",
328
+ "cost_analysis_projection",
329
+ "cost_params_from_config",
330
+ "find_payback_year",
331
+ "calculate_lcoe",
332
+ "calculate_lcoe_from_projection",
333
+ # Optimization
334
+ "optimize_tilt",
335
+ "optimize_tilt_brent",
336
+ "optimize_battery_size",
337
+ "optimize_system_multi_objective",
338
+ # Monte Carlo
339
+ "run_montecarlo",
340
+ "MonteCarloSettings",
341
+ "MonteCarloResult",
342
+ # I/O
343
+ "export_results",
344
+ "export_summary",
345
+ "load_results",
346
+ "export_monthly_summary",
347
+ "export_yearly_summary",
348
+ ]
breos/app.py ADDED
@@ -0,0 +1,79 @@
1
+ """
2
+ BREOS public facade - single entry point for PV + battery simulations.
3
+
4
+ Usage:
5
+ import breos
6
+
7
+ app = breos.App({
8
+ "location": "porto",
9
+ "n_modules": 10,
10
+ "annual_consumption_kwh": 4000,
11
+ "battery_kwh": 5.0,
12
+ "cost_preset": "residential_pt",
13
+ "emissions_country": "PT",
14
+ })
15
+ app.simulate()
16
+ result = app.result()
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from typing import Any
22
+
23
+ from breos.app_config import resolve_app_config
24
+ from breos.app_inputs import AppRuntimeDependencies
25
+ from breos.app_results import build_result as build_app_result
26
+ from breos.load_profiles import load_profile
27
+ from breos.runners.app import run_app_simulation
28
+ from breos.weather import build_battery_temperature_series, fetch_tmy_weather_data, load_weather, resample_to_15min
29
+
30
+
31
+ class App:
32
+ """
33
+ Single entry point for BREOS simulations.
34
+
35
+ Parameters
36
+ ----------
37
+ config : dict
38
+ Simulation configuration. Required keys:
39
+
40
+ - ``location`` - preset key (``"porto"``) **or** dict with
41
+ ``latitude``, ``longitude``, ``timezone``.
42
+ - ``n_modules`` - number of PV modules (int, > 0), unless
43
+ ``pv_arrays`` is provided.
44
+ - ``annual_consumption_kwh`` - yearly electricity demand (float, > 0).
45
+
46
+ Optional keys include battery size, PV arrays, module selection, load
47
+ profile, tracking, resolution, projection years, cost and emissions
48
+ presets, degradation, and inverter assumptions.
49
+ """
50
+
51
+ def __init__(self, config: dict) -> None:
52
+ self._resolved = resolve_app_config(config)
53
+ self._cfg = self._resolved.cfg
54
+ self._result: dict[str, Any] | None = None
55
+
56
+ def simulate(self) -> None:
57
+ """Run the full simulation pipeline."""
58
+ artifacts = run_app_simulation(self._cfg, self._resolved, self._runtime_dependencies())
59
+ self._result = build_app_result(self._cfg, self._resolved, artifacts)
60
+
61
+ def result(self) -> dict[str, Any]:
62
+ """
63
+ Return simulation results as a plain dict.
64
+
65
+ Raises ``RuntimeError`` if :meth:`simulate` has not been called.
66
+ """
67
+ if self._result is None:
68
+ raise RuntimeError("Call simulate() before result().")
69
+ return self._result
70
+
71
+ @staticmethod
72
+ def _runtime_dependencies() -> AppRuntimeDependencies:
73
+ return AppRuntimeDependencies(
74
+ load_profile=load_profile,
75
+ load_weather=load_weather,
76
+ fetch_tmy_weather_data=fetch_tmy_weather_data,
77
+ resample_to_15min=resample_to_15min,
78
+ build_battery_temperature_series=build_battery_temperature_series,
79
+ )