Releases: Str4vinci/breos
Release list
BREOS 0.5.1
Purpose
0.5.1 prepares BREOS for the 0.6.0 cleanup without removing compatibility yet. It also tightens configuration validation, consolidates internal configuration metadata, and aligns a public battery-degradation helper with the simulation path.
Highlights
A clear 0.6.0 deprecation window. The unused breos.numba_kernels module and breos[fast] extra, the article-scoped Wöhler/Miner comparison subsystem, and six undocumented orphaned helpers now emit targeted DeprecationWarnings when used. They keep their 0.5.x signatures and behaviour and are scheduled for removal in 0.6.0; the migration guide contains the complete inventory.
Configuration consistency. App configuration metadata now lives in one declarative registry that derives defaults, accepted keys, CLI options, and CLI override handling. Historical ordering, aliases, precedence, validation messages, and simulation results are preserved.
Sweep validation fixed. validate-config now accepts the documented [sweep] section, rejects empty or malformed sweep grids, and regression-tests every shipped example configuration.
Battery helper consistency. resistance_to_efficiency() now uses the same mapping as the live resistance-fade simulation path, preserving configured charge/discharge asymmetry. Simulation results are unchanged because the runtime path already used this mapping.
Compatibility and provenance
The article lifetime comparison remains available throughout 0.5.x, but its wording now accurately describes it as a documentation-derived BREOS approximation rather than Polysun output or source code. Generated plot legends use “documentation-derived baseline.”
Python 3.14 was already in the CI matrix and has run successfully since June; this release also makes that job a required branch-protection check alongside Python 3.11–3.13.
Validation
The full suite passed with 799 tests, plus both slow validation tests. Ruff, formatting, strict Sphinx documentation, release artifact verification, and the Python 3.11–3.14 CI matrix all passed. The validation baseline changed only in its version and date stamps; all numerical outputs are identical.
What's Changed
- Sync 0.5.0 release back to develop by @Str4vinci in #109
- Accept the documented
[sweep]config section by @Str4vinci in #110 - Verify releases with uv instead of pip in the checklist by @Str4vinci in #111
- Plan economic scenario and sensitivity analysis by @Str4vinci in #112
- Record the 0.5.x dead code and bloat cleanup plan by @Str4vinci in #113
- Consolidate resistance-fade efficiency mapping by @Str4vinci in #114
- Centralize App configuration metadata by @Str4vinci in #115
- Deprecate cleanup candidates for 0.6.0 by @Str4vinci in #116
- Prepare 0.5.1 release by @Str4vinci in #117
Full Changelog: v0.5.0...v0.5.1
BREOS 0.5.0
Purpose
0.5.0 brings optional bifacial rear-gain modelling. You can also choose the PV physics: the IAM model, cell-temperature model and mount-appropriate presets. Every choice ships with seven-site benchmark rows, so you can see what it costs before you switch.
Highlights
Bifacial rear gain. Set bifacial_model="infinite_sheds" with a sourced module bifaciality plus explicit row height and pitch, and rear irradiance feeds both DC power and the cell-temperature model — so rear gain is never credited with power but no heat. It gets its own bifacial_rear_gain stage in the loss waterfall and its own provenance block. Left at the default "none", nothing changes.
Selectable IAM optics. iam_model now takes ashrae (the historical default), physical, or martin_ruiz. With diffuse_iam="marion" enabled, the same model is integrated for sky and ground, so beam and diffuse optics cannot silently disagree.
Cell-temperature fidelity. Named SAPM construction/mounting presets, strict opt-in noct-sam, and PVsyst presets that model a realistic module efficiency instead of pvlib's legacy 0.1 placeholder.
Inverter datasheet limits. InverterConfig accepts the DC voltage/power ceilings, MPPT window, startup voltage, per-MPPT current limits, and strings-per-MPPT. They validate against each other but are not read by any model yet — no result changes.
Documentation. Read the Docs is reorganized around task-oriented guides, model assumptions, and API reference, with internal design notes moved to the repository.
Breaking-ish changes
Three fixes move numbers. None affect a default configuration:
- Multi-array tracking honours the top-level
gcr. Per-array tracking previously fell back to a hardcoded0.35, so a non-default top-levelgcrnever reached it. Setgcrexplicitly on eachpv_arraysentry to keep the old geometry. - An out-of-range
gcris now rejected atApp()construction. pvlib silently derives a different backtracking rotation instead of complaining, so a mistyped3.5used to return roughly half the annual energy with no error. pvsyst-*temperature presets model a realistic module efficiency. Expect cell temperatures roughly 2.5–3 °C lower and annual yield 1.0–1.3% higher for those presets.
Also: provenance.ledger_schema_version is now 1.1 (additive — new waterfall stage, new provenance.pv_model block, iam stage relabelled to name the front side). Consumers that pin the value need to accept 1.1. And InverterConfig now validates its long-standing fields on construction, so a negative rating or an efficiency above 1 raises ValueError instead of quietly producing nonsense.
Validation
Seven sites on four continents, with the self-baseline drift test holding every model variant to 0.1%. The bifacial, IAM, temperature, and equal-nameplate comparison rows are all in validation/REPORT.md, alongside their geometry, albedo, inverter loading, and the front-shading limitation that keeps dense-row rear-gain numbers from being a bankable layout estimate.
What's Changed
- Sync 0.4.2 release back to develop by @Str4vinci in #91
- Add inert bifacial module metadata by @Str4vinci in #92
- Add opt-in bifacial rear-gain modeling by @Str4vinci in #93
- Add bifacial diagnostics and benchmarks by @Str4vinci in #95
- Refactor PV model core and validate reachable configuration by @Str4vinci in #96
- Add selectable PV IAM models by @Str4vinci in #97
- Add PV temperature model fidelity by @Str4vinci in #98
- Add recommended PV guidance and evidence by @Str4vinci in #99
- chore: move core coverage off the per-PR test matrix by @Str4vinci in #106
- docs: correct fast extra description by @Str4vinci in #101
- docs: reorganize public onboarding documentation by @Str4vinci in #102
- refactor: extract battery dispatch seams by @Str4vinci in #103
- Extend inverter datasheet domain model by @Str4vinci in #100
- chore: broaden package metadata, credit pvlib, and route questions to Discussions by @Str4vinci in #105
- docs: describe coverage as a separate report, not a per-PR check by @Str4vinci in #107
- Prepare 0.5.0 release by @Str4vinci in #108
Full Changelog: v0.4.2...v0.5.0
BREOS 0.4.2
Purpose
This is a minor patch, removing dependencies and improving onboarding. I tried dependabot but realised it is a bit too much for now. Moved it to security-only!
What's Changed
- Sync 0.4.1 release back to develop by @Str4vinci in #80
- Improve 0.4.2 onboarding and repository health by @Str4vinci in #78
- Bump the python-minor-and-patch group with 12 updates by @dependabot[bot] in #84
- Bump actions/checkout from 6 to 7 by @dependabot[bot] in #83
- Bump actions/upload-artifact from 4 to 7 by @dependabot[bot] in #81
- Bump actions/download-artifact from 4 to 8 by @dependabot[bot] in #82
- Remove Dependabot version-update config (security-only) by @Str4vinci in #89
- Drop unused Excel and Arrow dependencies by @Str4vinci in #88
- Make BLAST parity fixtures reproducible by @Str4vinci in #86
- Add internal degradation lifecycle protocol by @Str4vinci in #87
- Prepare 0.4.2 release by @Str4vinci in #90
New Contributors
- @dependabot[bot] made their first contribution in #84
Full Changelog: v0.4.1...v0.4.2
BREOS 0.4.1
BREOS 0.4.1 is a minor patch focused on clearer internal degradation and configuration boundaries.
Changed
- Extracted BLAST experimental-range and aging-horizon validation into a focused warning collector while preserving warning records, snapshot continuation, replacement resets, and the
breos.Appresult schema. - Centralized native and BLAST degradation-result construction in a schema-aware builder while preserving public fields, engine-specific SOH precision, and provenance.
- Decomposed
breos.Appconfiguration validation into subsystem validators while preserving validation order, errors, normalization, defaults, and resolution precedence.
The stable breos.App facade, scientific outputs, configuration keys, result schemas, and BLAST continuation behavior remain compatible with 0.4.0.
pip install --upgrade breos==0.4.1The release was validated on Python 3.11–3.14, including slow degradation tests and installed wheel/source-distribution verification.
BREOS v0.4.0
BREOS 0.4.0 adds opt-in multi-chemistry BLAST-Lite degradation modeling while preserving breos.App as the stable public entrypoint.
Highlights
- Vendors and integrates 14 BLAST-Lite cell degradation models with stable model keys, scientific provenance, experimental-range and aging-horizon warnings, JSON-safe state snapshots, cross-year threading, and replacement reset handling.
- Chemistries include Li-ion LFP, NMC, NCA and LMO.
- Adds public Python and CLI battery-model discovery plus explicit
degradation_engine="blast"/blast_modelconfiguration; the existing native LFP degradation path remains the default. - Guards time-varying BLAST power and sigmoid state updates against trajectory-domain overshoot, preventing NaN failures under varying field profiles and preventing artificial capacity recovery when a sigmoid asymptote shrinks.
- Adds fail-loud
BlastNumericalErrordiagnostics, 15-minute BLAST integration coverage, real multi-replacement runner coverage, varying-profile split/thread equivalence, and deterministic 20-year endurance coverage across every model. - Unifies App dispatch on the PVWatts part-load inverter curve, preserving explicit inverter sharing, clipping, conversion losses, and the versioned energy ledger across PV, battery, economics, emissions, and optimization paths.
- Adds model/profile metadata, configuration migration guidance, strengthened release validation, updated documentation, and a nightly plus release-gated BLAST endurance job.
Upgrade notes
Existing breos.App entry points remain available. Native Naumann/Lam LFP degradation remains the default; BLAST is enabled only when explicitly selected with a valid model key. BLAST models are empirical cell models rather than pack-calibrated field models, and long-horizon or out-of-range operation is reported through structured warnings. The Panasonic NCA model warns after its sourced 300-day aging-data horizon.
BLAST remains intentionally unsupported with Monte Carlo and native resistance-fade dispatch in 0.4.0; those combinations raise instead of silently falling back. Numerical results may also change where the corrected PVWatts part-load inverter treatment replaces flat conversion assumptions.
IMPORTANT: BLAST-Lite's models are fit to 1–3 years of accelerated lab aging and extrapolated to decade-plus lifetimes, so its own authors recommend treating the results as qualitative. They're also cell-level models. Upstream suggests real packs run 20–30% short of cell lifetime, and BREOS applies no such derate. Read the SOH curves as scenarios and not as warranties.
Verification
- Python 3.11–3.14 release CI passed.
- 553 fast tests and 2 slow endurance tests passed, with 7 optional/skipped tests.
- All 14 models completed the deterministic 20-year varying-condition endurance fixture with finite states and bounded SOH.
- Strict lint, formatting, documentation, wheel/sdist build, installed-wheel resource smoke, release provenance, and trusted PyPI publishing checks passed.
Acknowledgements
Thanks to Paul Gasper for the BLAST-Lite suggestion!
See CHANGELOG.md for the complete list of changes.
BREOS v0.3.4
BREOS 0.3.4 is a physical-correctness and validation release for the public breos.App simulation path.
Highlights
- Adds a versioned DC/AC timestep energy ledger covering PV routing, inverter and battery conversion losses, standby, curtailment, capacity-window changes, storage boundary state, and PV-origin battery delivery.
- Preserves battery energy and PV-origin inventory across simulation years instead of resetting at each January boundary.
- Reconciles public AC production, self-consumption, export, emissions, optimizer objectives, economics, and PV loss-waterfall reporting while retaining compatibility aliases.
- Adds optional battery charge/discharge power limits, stricter configuration validation, leap-year-safe load profiles, and reproducibility provenance.
- Adds a standing seven-site validation suite plus opt-in mid-interval solar position, diffuse IAM, and mounting-temperature presets.
- Fixes tracker diffuse-IAM performance through a cached interpolation grid while retaining the exact fixed-tilt path.
Upgrade notes
Existing breos.App entry points and compatibility result aliases remain available. Numerical results may change because 0.3.4 corrects DC/AC boundary accounting, inverter sharing, cross-year storage continuity, optimizer parity, and daily battery-resistance temperature treatment. Invalid or unsupported configurations that previously produced misleading output may now raise a clear validation error.
Verification
- Python 3.11–3.14 CI passed.
- 400 tests passed, with 7 optional/skipped tests.
- Strict documentation, wheel/sdist build, installed-wheel resource smoke, and public PyPI installation checks passed.
See CHANGELOG.md for the complete list of changes.
BREOS v0.3.3
[0.3.3] - 2026-07-02
Removed
The Suntech_STP550S_NOMT catalog module. Its datasheet points were NMOT ratings (800 W/m², Mpp = 415 W), but the CEC single-diode fit interprets Vmp/Imp/Voc/Isc as STC values, so the entry produced silently wrong model parameters. Configs referencing it now fail with the standard "Module '...' not found. Available: ..." error; use Suntech_STP550S_STC (the same physical module at STC) instead.
Added
-
breos sweep, a serial parameter-grid CLI command that expands a [sweep] section in a normal App config and writes one combined CSV with varied parameters, resolved system sizing, BREOS version, and scalar result metrics.
-
configs/examples/sweep.toml as a runnable sweep example over module count and battery size.
-
Release-smoke tests for the README quickstart, the Monte Carlo example path, and the pymoo-backed multi-objective optimization helper.
-
breos.solar.resolve_pvwatts_losses, used by dry-run/config inspection to report resolved PVWatts loss components and their combined percentage.
-
sell_price_inflation App config key and --sell-price-inflation CLI flag (default 0.0). CostParams and cost_analysis_projection already supported an annual export-price inflation, but no config key existed and neither the App runner nor the Monte Carlo runner passed it, so the public paths always projected with 0.0. The value is validated in validate_config, threaded through both projection call sites, and shown in breos run --dry-run / validate-config --json. The 0.0 default reproduces existing results bit-for-bit.
Changed
- breos run --dry-run and breos validate-config --json now include the fully resolved static PVWatts loss stack instead of only echoing pv_loss_overrides.
- BatteryConfig.battery_type is now explicit about the native degradation model being LFP-only: "LFP" normalizes to "lfp", while unsupported chemistries raise instead of silently reusing LFP cycle-aging parameters.
- BatteryConfig.eol_percentage now defaults to 0.70, aligning with the App config default battery_eol_percentage = 0.70 and the optimizer's battery-spec fallback (previously 0.80 and 0.8 respectively — three surfaces, two values). App and CLI results are unchanged (they always pass the config value explicitly), but direct BatteryConfig users who relied on the implicit 0.80 will now see batteries replaced later, at 70% SOH; pass eol_percentage=0.8 to keep the old threshold. The same applies to optimization battery specs without an explicit eol_percentage.
Documentation
- Updated the README and CITATION.cff to cite the SSRN preprint DOI (10.2139/ssrn.7032064).
- Added the BLAST degradation-engine design note and refreshed roadmap priorities around model accuracy, validation, energy-loss accounting, and future default-model profiles.
Fixed
- dc_to_ac (and therefore calculate_pv_production_ac) clipped ~4% below the intended inverter AC nameplate: it passed the nameplate (pv_peak_power_w / inverter_loading_ratio) as pvlib's pdc0, which is a DC-input limit whose AC nameplate is eta_inv_nom * pdc0. The DC limit is now derived as nameplate / eta_inv_nom, so clipping happens at the same AC rating used by InverterConfig.size_from_pv, the App energy balance, economics.calculate_costs, and the CLI's reported ac_rating_kw. This raises dc_to_ac / calculate_pv_production_ac outputs slightly at every operating point (most visibly during clipping hours); App simulation results are unchanged because the App path converts DC through simulate_energy_balance, not dc_to_ac.
- PVModuleParams no longer discards a user-supplied gamma_pmp: the constructor argument existed but post_init unconditionally overwrote it with T_Pmax_pct. It now only defaults to T_Pmax_pct when not given, matching the alpha_sc_abs / beta_voc_abs override pattern. Catalog modules and configs that never set gamma_pmp are unaffected.
BREOS 0.3.2
[0.3.2] - 2026-06-26
Upgrading: config validation is now strict — a config with an unknown
top-level key (e.g. a typo likebatery_kwh) that silently defaulted in
0.3.1 now raises listing the offending key(s). Fix or remove stray keys
before upgrading. All other changes preserve prior behaviour by default.
Removed
- The
nrel-pysamruntime dependency. It was only ever reached transitively,
through pvlib'sfit_cec_sam, to fit the CEC single-diode parameters on the
default PV path.nrel-pysampublishes no Python 3.14 wheel or sdist and was
the sole blocker to running BREOS on 3.14.
Added
breos.cec_fit.fit_cec_params: a pure-scipy/pvlibimplementation of the
CEC 6-parameter coefficient calculator (Dobos 2012, DOI:10.1115/1.4005759),
a drop-in forpvlib.ivtools.sdm.fit_cec_sam. Across every bundled module it
reproduces the SAM fit to within 0.03% on maximum power over a
temperature x irradiance grid and 0.004% on annual energy, so model results
are unchanged. Validated against thenrel-pysamoracle by
tools/validate_cec_fit.py.- Python 3.14 support: the
3.14classifier and CI matrix entry, now that the
nrel-pysamblocker is gone. - Config validation now rejects unknown top-level keys. A typo such as
batery_kwhpreviously slipped throughmerge_defaultsand silently
defaulted (e.g. the battery to0), producing plausible-but-wrong results;
it now raises listing the offending key(s). The optionalmontecarlo
section is recognised so Monte Carlo configs still validate. - Configurable sky-diffusion (transposition) model via a
transposition_model
config key and--transposition-model/--sky-modelCLI flag, threaded
throughcalculate_pv_production_dc, the tracking and multi-array variants,
and theAppconfig surface. Supportsisotropic(default),klucher,
haydavies,reindl,king,perez, andperez-driessevia pvlib's
get_total_irradiance; the extra inputs the anisotropic models need
(extraterrestrial DNI, relative airmass) are derived internally. The default
isotropicreproduces prior results bit-for-bit. Per-array overrides are
supported inpv_arrays. - Configurable ground reflectance and Perez coefficients to drive those models
with real site information:albedo(0-1) or a namedsurface_type
("snow","sea","grass", ...) sets the ground-diffuse reflectance for
every model (previously fixed at pvlib's 0.25), andmodel_perezselects
the Perez coefficient set. All three are App config keys with matching
--albedo/--surface-type/--perez-modelCLI flags and per-array
overrides; not setting them leaves the previous defaults unchanged.
Changed
- The default PV path fits CEC parameters via
breos.cec_fit.fit_cec_params
instead ofpvlib.ivtools.sdm.fit_cec_sam;breos/solar.pyand the public
API are otherwise unchanged. - The two placeholder
Generic_400WandGeneric_600W_Bifacialcatalog
modules now carry realistic mono-PERC datasheet specifications (their
previous made-up values fit cleanly under SAM only via an internal
short-circuit-current heuristic); their nameplate power and keys are
unchanged. resolve_pv_systemno longer mutates the merged config in place to record
the derivedn_modules; the resolved count is materialised into a fresh
dict byresolve_app_config, so the dict wrapped by the frozen
ResolvedAppConfigis built once and the caller's input dict is left
untouched.
BREOS 0.3.1
Changed
- Pinned
requires-pythonto>=3.11,<3.14. The transitivenrel-pysamdependency, reached through pvlib's CEC fit, publishes no Python 3.14 wheel or sdist, so installs on 3.14 could not resolve. This is a stopgap; 0.3.2 removesnrel-pysamand lifts the cap.
BREOS 0.3.0
BREOS 0.3.0 public release.
Highlights:
- PyPI packaging with trusted publishing.
- Monte Carlo weather-year and demand uncertainty studies with CLI and plots.
- Public pymoo-backed multi-objective PV/battery sizing.
- Refreshed README, docs, examples, attributions, and release workflow.
- Updated release date: 2026-06-24.
Validation:
- CI passed on Python 3.11, 3.12, and 3.13.
- Release artifact verifier passed.
- PyPI install check passed: breos 0.3.0.