Skip to content

Releases: Str4vinci/breos

BREOS 0.5.1

Choose a tag to compare

@Str4vinci Str4vinci released this 11 Aug 15:11
62ab4f4

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

Full Changelog: v0.5.0...v0.5.1

BREOS 0.5.0

Choose a tag to compare

@Str4vinci Str4vinci released this 05 Aug 14:03
134c99e

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:

  1. Multi-array tracking honours the top-level gcr. Per-array tracking previously fell back to a hardcoded 0.35, so a non-default top-level gcr never reached it. Set gcr explicitly on each pv_arrays entry to keep the old geometry.
  2. An out-of-range gcr is now rejected at App() construction. pvlib silently derives a different backtracking rotation instead of complaining, so a mistyped 3.5 used to return roughly half the annual energy with no error.
  3. 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

Full Changelog: v0.4.2...v0.5.0

BREOS 0.4.2

Choose a tag to compare

@Str4vinci Str4vinci released this 27 Jul 12:37
848da94

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

New Contributors

Full Changelog: v0.4.1...v0.4.2

BREOS 0.4.1

Choose a tag to compare

@Str4vinci Str4vinci released this 23 Jul 13:34
a020ba3

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.App result 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.App configuration 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.1

The release was validated on Python 3.11–3.14, including slow degradation tests and installed wheel/source-distribution verification.

BREOS v0.4.0

Choose a tag to compare

@Str4vinci Str4vinci released this 20 Jul 13:15
5b5072b

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_model configuration; 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 BlastNumericalError diagnostics, 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

Choose a tag to compare

@Str4vinci Str4vinci released this 14 Jul 15:00
3287409

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

Choose a tag to compare

@Str4vinci Str4vinci released this 02 Jul 14:56
2cca302

[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

Choose a tag to compare

@Str4vinci Str4vinci released this 26 Jun 14:29
7529900

[0.3.2] - 2026-06-26

Upgrading: config validation is now strict — a config with an unknown
top-level key (e.g. a typo like batery_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-pysam runtime dependency. It was only ever reached transitively,
    through pvlib's fit_cec_sam, to fit the CEC single-diode parameters on the
    default PV path. nrel-pysam publishes 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/pvlib implementation of the
    CEC 6-parameter coefficient calculator (Dobos 2012, DOI:10.1115/1.4005759),
    a drop-in for pvlib.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 the nrel-pysam oracle by
    tools/validate_cec_fit.py.
  • Python 3.14 support: the 3.14 classifier and CI matrix entry, now that the
    nrel-pysam blocker is gone.
  • Config validation now rejects unknown top-level keys. A typo such as
    batery_kwh previously slipped through merge_defaults and silently
    defaulted (e.g. the battery to 0), producing plausible-but-wrong results;
    it now raises listing the offending key(s). The optional montecarlo
    section is recognised so Monte Carlo configs still validate.
  • Configurable sky-diffusion (transposition) model via a transposition_model
    config key and --transposition-model / --sky-model CLI flag, threaded
    through calculate_pv_production_dc, the tracking and multi-array variants,
    and the App config surface. Supports isotropic (default), klucher,
    haydavies, reindl, king, perez, and perez-driesse via pvlib's
    get_total_irradiance; the extra inputs the anisotropic models need
    (extraterrestrial DNI, relative airmass) are derived internally. The default
    isotropic reproduces prior results bit-for-bit. Per-array overrides are
    supported in pv_arrays.
  • Configurable ground reflectance and Perez coefficients to drive those models
    with real site information: albedo (0-1) or a named surface_type
    ("snow", "sea", "grass", ...) sets the ground-diffuse reflectance for
    every model (previously fixed at pvlib's 0.25), and model_perez selects
    the Perez coefficient set. All three are App config keys with matching
    --albedo / --surface-type / --perez-model CLI 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 of pvlib.ivtools.sdm.fit_cec_sam; breos/solar.py and the public
    API are otherwise unchanged.
  • The two placeholder Generic_400W and Generic_600W_Bifacial catalog
    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_system no longer mutates the merged config in place to record
    the derived n_modules; the resolved count is materialised into a fresh
    dict by resolve_app_config, so the dict wrapped by the frozen
    ResolvedAppConfig is built once and the caller's input dict is left
    untouched.

BREOS 0.3.1

Choose a tag to compare

@Str4vinci Str4vinci released this 25 Jun 11:17
59a4d8c

Changed

  • Pinned requires-python to >=3.11,<3.14. The transitive nrel-pysam dependency, 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 removes nrel-pysam and lifts the cap.

BREOS 0.3.0

Choose a tag to compare

@Str4vinci Str4vinci released this 23 Jun 23:11
f6f98f3

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.