Configuration#
The App constructor accepts a single config dict. Only
three keys are strictly required:
locationannual_consumption_kwhn_modules— orpv_arraysfor multi-array systems
Every other key has a sensible default.
Defaults are useful for examples. For real studies, provide project-specific weather/data access, load profiles, PV system data, and cost assumptions; see Required Inputs.
All keys#
Key |
Default |
Description |
|---|---|---|
|
required |
Preset key (e.g. |
|
required unless |
Number of PV modules |
|
|
List of arrays with |
|
required |
Annual electricity demand (kWh) |
|
|
Nominal battery capacity in kWh ( |
|
|
Module key from the built-in catalogue. |
|
|
Bundled demandlib-derived H0 profile; |
|
|
Directory containing licensed external RLP CSVs for non-bundled load profiles |
|
auto |
Tilt angle (degrees). Auto-estimated from latitude when |
|
auto |
Surface azimuth (degrees). Auto-set to 180 in the northern hemisphere |
|
|
Tracking mode ( |
|
|
Single-axis tracker axis tilt |
|
auto |
Tracker axis azimuth. Auto-set from latitude when |
|
|
Single-axis tracker maximum rotation angle |
|
|
Whether single-axis trackers backtrack to avoid row shading |
|
|
Ground coverage ratio for single-axis tracking |
|
|
Cross-axis terrain slope for single-axis tracking |
|
|
Maximum panel tilt for dual-axis tracking |
|
|
Sky-diffusion model used to project GHI/DHI/DNI onto the plane of array (see below) |
|
|
Ground reflectance (0-1) for the ground-diffuse component; |
|
|
Named ground cover (e.g. |
|
|
Perez coefficient set; only used when |
|
|
Time resolution ( |
|
|
Economic projection horizon |
|
|
Cost preset key from packaged defaults |
|
|
Annual electricity price inflation |
|
|
Annual inflation of the grid export (sell) price |
|
|
Discount rate for NPV |
|
|
Country code for CO2 calculations ( |
|
|
Annual PV degradation rate (0.5% / year) |
|
|
Battery calendar aging model. Default is the v1 field calibration; use |
|
|
Battery SOC floor (fraction of nominal, SOH-derated capacity) |
|
|
Battery SOC ceiling (same basis as |
|
|
SOH fraction that triggers battery replacement |
|
|
Battery round-trip efficiency ( |
|
|
DC-coupled / hybrid inverter (vs AC-coupled) |
|
|
Inverter efficiency |
|
|
DC/AC oversizing ratio; also sets the inverter AC rating that clips production |
|
|
Per-component overrides (percent) for the fixed PVWatts system losses, e.g. |
|
|
First simulation date |
Unknown top-level keys are rejected at load time. A misspelled key such as
batery_kwh raises an error listing the offending key rather than being
silently ignored (which would quietly fall back to the default). The optional
[sweep] and [montecarlo] sections used by their dedicated CLI commands are
recognised and allowed.
Battery capacity and the SOC window#
battery_kwh is the nominal pack capacity. The energy balance only
cycles the battery between battery_min_soc and battery_max_soc, so the
effective storage swing is:
usable swing = battery_kwh × (battery_max_soc − battery_min_soc)
With the defaults (0.10–0.90) that is 80% of nominal: battery_kwh = 5.0
gives a 4.0 kWh swing at full state of health.
Battery datasheets usually advertise usable capacity. To match a spec
sheet, either enter usable / 0.8 as battery_kwh or widen the SOC window.
Keep in mind that calendar and cycle aging are evaluated on the absolute SOC,
so the window also shapes degradation results — the defaults reflect the
operating range the field-calibrated aging parameters were fit for, and
simulating a 0–1.00 window models a battery management system that no real
product ships.
Battery degradation calibration#
calendar_model = "naumann_lam_field_calibrated" is the stable default and
maps to the v1 field calibration. The explicit
"naumann_lam_field_calibrated_v1" alias is equivalent. Use
"naumann_lam_field_calibrated_v2" for the v2 field-calibrated fit with Lam
Ea/n fixed and k0/b fitted to field data.
The native BREOS degradation path is currently calibrated for LFP cells only.
Lower-level BatteryConfig(battery_type="LFP") normalizes to "lfp"; other
chemistries raise instead of silently reusing LFP cycle-aging parameters. See
the roadmap for the planned opt-in multi-chemistry degradation engine.
Discovering available options#
Use the CLI to list packaged option keys:
breos list locations
breos list modules
breos list cost-presets
breos list emissions
breos list load-profiles
Add --json to any breos list command for machine-readable output.
Before running a full simulation, validate and inspect a config:
breos validate-config quickstart.toml
breos run --config quickstart.toml --dry-run
These commands resolve packaged presets, modules, inverter sizing, battery
settings, load-profile choices, emissions settings, and the static PVWatts loss
stack without fetching weather or simulating. In JSON output, pv.losses
contains the resolved component percentages plus the combined PVWatts loss
percentage after applying any pv_loss_overrides.
Custom location#
Pass an explicit coordinate dict instead of a preset key:
breos.App({
"location": {
"latitude": 41.1579,
"longitude": -8.6291,
"timezone": "Europe/Lisbon",
},
"n_modules": 10,
"annual_consumption_kwh": 4000,
})
Multi-array PV systems#
For roofs with panels facing different directions, use pv_arrays. Each
array is simulated independently and its DC output combined before the
energy balance — east-west or pitched-roof layouts are not collapsed into
one representative tilt/azimuth:
breos.App({
"location": "porto",
"annual_consumption_kwh": 4000,
"pv_arrays": [
{"modules": 8, "module": "Erlangen_445W", "tilt": 10, "azimuth": 90},
{"modules": 8, "module": "Erlangen_445W", "tilt": 10, "azimuth": 270},
],
})
When pv_arrays is set, n_modules is computed from the array totals and
any explicit n_modules key is ignored.
Each array may also set its own transposition_model, overriding the
top-level default for that array only.
Sky-diffusion (transposition) model#
To compute plane-of-array (POA) irradiance, BREOS transposes the horizontal
irradiance components (GHI/DHI/DNI) onto the tilted module surface using a
sky-diffusion (transposition) model. The default, "isotropic", treats
diffuse sky radiance as uniform — simple and robust, but it underestimates POA
on clear days because it ignores circumsolar and horizon brightening.
Anisotropic models capture those effects and are generally more accurate; over
a full year, Perez can raise modeled POA by a few percent relative to
isotropic at mid-latitude sites. Set transposition_model to any of:
isotropic (default), klucher, haydavies, reindl, king, perez,
perez-driesse.
breos.App({
"location": "porto",
"n_modules": 10,
"annual_consumption_kwh": 4000,
"transposition_model": "perez",
})
The extra inputs the anisotropic models need (extraterrestrial DNI and, for
the Perez variants, relative airmass) are derived internally from the time
index and solar position, so no additional weather columns are required. All
models are provided by
pvlib.irradiance.get_total_irradiance.
Ground reflectance (albedo)#
Every transposition model adds a ground-reflected diffuse component, which
depends on how reflective the ground around the array is. By default BREOS
uses pvlib’s 0.25 albedo. If you know your site, set it explicitly — either a
numeric albedo (0-1) or a named surface_type that pvlib maps to an albedo
("snow" ≈ 0.65, "sea", "grass", "sand", "urban", …). Set one or the
other, not both. A snowy or sandy foreground can add a few percent to annual
POA on tilted arrays.
breos.App({
"location": "berlin",
"n_modules": 10,
"annual_consumption_kwh": 4000,
"transposition_model": "perez",
"surface_type": "snow", # or: "albedo": 0.65
})
Perez coefficient set#
The perez model uses an empirically fitted coefficient set. model_perez
selects it (default "allsitescomposite1990"); the other sets are
location/era-specific fits from the Perez papers and are only consulted when
transposition_model = "perez".
Cost and emissions presets#
Built-in presets are packaged with BREOS. Editable copies and examples live
in configs/base/ and configs/examples/.
Pass the key:
breos.App({
"location": "porto",
"n_modules": 10,
"annual_consumption_kwh": 4000,
"cost_preset": "residential_pt",
"emissions_country": "PT",
})
For full control, build a CostParams and
EmissionsParams yourself and call the lower-level
functions documented in the Cost and emissions API.
Load profiles#
The public package default is load_profile = "1", a demandlib-derived H0
example bundled with BREOS. load_profile = "demandlib_h0" is the same
profile under a readable alias and is preferred in examples. Other standard
profile keys remain supported when you provide the required CSV files yourself
through rlp_directory:
breos.App({
"location": "porto",
"n_modules": 10,
"annual_consumption_kwh": 4000,
"load_profile": "6",
"rlp_directory": "/path/to/licensed/rlp/files",
"resolution": "15min",
})
Use external BDEW, E-REDES, REE, or custom profiles only under terms that permit your intended use. See Load Profile Data for the expected filenames and the reason these CSVs are not bundled.