breos 0.3.0rc1__tar.gz

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.
Files changed (130) hide show
  1. breos-0.3.0rc1/.github/ISSUE_TEMPLATE/bug_report.yml +30 -0
  2. breos-0.3.0rc1/.github/ISSUE_TEMPLATE/feature_request.yml +18 -0
  3. breos-0.3.0rc1/.github/pull_request_template.md +6 -0
  4. breos-0.3.0rc1/.github/workflows/publish.yml +84 -0
  5. breos-0.3.0rc1/.github/workflows/tests.yml +46 -0
  6. breos-0.3.0rc1/.gitignore +20 -0
  7. breos-0.3.0rc1/.readthedocs.yaml +17 -0
  8. breos-0.3.0rc1/AGENTS.md +35 -0
  9. breos-0.3.0rc1/ATTRIBUTIONS.md +83 -0
  10. breos-0.3.0rc1/CHANGELOG.md +176 -0
  11. breos-0.3.0rc1/CITATION.cff +24 -0
  12. breos-0.3.0rc1/CODE_OF_CONDUCT.md +37 -0
  13. breos-0.3.0rc1/CONTRIBUTING.md +102 -0
  14. breos-0.3.0rc1/LICENSE +29 -0
  15. breos-0.3.0rc1/PKG-INFO +375 -0
  16. breos-0.3.0rc1/README.md +313 -0
  17. breos-0.3.0rc1/ROADMAP.md +117 -0
  18. breos-0.3.0rc1/SECURITY.md +33 -0
  19. breos-0.3.0rc1/breos/__init__.py +332 -0
  20. breos-0.3.0rc1/breos/acc.py +297 -0
  21. breos-0.3.0rc1/breos/acc_sizer.py +162 -0
  22. breos-0.3.0rc1/breos/app.py +149 -0
  23. breos-0.3.0rc1/breos/app_config.py +332 -0
  24. breos-0.3.0rc1/breos/app_inputs.py +187 -0
  25. breos-0.3.0rc1/breos/app_results.py +137 -0
  26. breos-0.3.0rc1/breos/app_simulation.py +5 -0
  27. breos-0.3.0rc1/breos/battery.py +1194 -0
  28. breos-0.3.0rc1/breos/cli.py +342 -0
  29. breos-0.3.0rc1/breos/constants.py +138 -0
  30. breos-0.3.0rc1/breos/data/__init__.py +1 -0
  31. breos-0.3.0rc1/breos/data/configs/__init__.py +1 -0
  32. breos-0.3.0rc1/breos/data/configs/costs.json +65 -0
  33. breos-0.3.0rc1/breos/data/configs/electricity.json +189 -0
  34. breos-0.3.0rc1/breos/data/configs/emissions.json +218 -0
  35. breos-0.3.0rc1/breos/data/configs/financials.json +7 -0
  36. breos-0.3.0rc1/breos/data/configs/locations.json +44 -0
  37. breos-0.3.0rc1/breos/data/rlp/__init__.py +1 -0
  38. breos-0.3.0rc1/breos/data/rlp/h0SLP_demandlib_1000kwh_15min.csv +35041 -0
  39. breos-0.3.0rc1/breos/data/rlp/h0SLP_demandlib_1000kwh_hourly.csv +8761 -0
  40. breos-0.3.0rc1/breos/economics.py +582 -0
  41. breos-0.3.0rc1/breos/emissions.py +130 -0
  42. breos-0.3.0rc1/breos/inverter.py +189 -0
  43. breos-0.3.0rc1/breos/io.py +300 -0
  44. breos-0.3.0rc1/breos/load_profiles.py +406 -0
  45. breos-0.3.0rc1/breos/numba_kernels.py +760 -0
  46. breos-0.3.0rc1/breos/optimization.py +734 -0
  47. breos-0.3.0rc1/breos/plotting.py +3252 -0
  48. breos-0.3.0rc1/breos/polysun_degradation.py +293 -0
  49. breos-0.3.0rc1/breos/pv_modules.py +199 -0
  50. breos-0.3.0rc1/breos/resources.py +21 -0
  51. breos-0.3.0rc1/breos/runners/__init__.py +5 -0
  52. breos-0.3.0rc1/breos/runners/app.py +189 -0
  53. breos-0.3.0rc1/breos/solar.py +774 -0
  54. breos-0.3.0rc1/breos/utils.py +159 -0
  55. breos-0.3.0rc1/breos/weather.py +1027 -0
  56. breos-0.3.0rc1/configs/README.md +10 -0
  57. breos-0.3.0rc1/configs/base/costs.json +65 -0
  58. breos-0.3.0rc1/configs/base/electricity.json +189 -0
  59. breos-0.3.0rc1/configs/base/emissions.json +218 -0
  60. breos-0.3.0rc1/configs/base/financials.json +7 -0
  61. breos-0.3.0rc1/configs/base/locations.json +44 -0
  62. breos-0.3.0rc1/configs/costs.json +65 -0
  63. breos-0.3.0rc1/configs/electricity.json +189 -0
  64. breos-0.3.0rc1/configs/emissions.json +218 -0
  65. breos-0.3.0rc1/configs/examples/external-rlp.toml +17 -0
  66. breos-0.3.0rc1/configs/examples/quickstart.toml +9 -0
  67. breos-0.3.0rc1/configs/financials.json +7 -0
  68. breos-0.3.0rc1/configs/locations.json +44 -0
  69. breos-0.3.0rc1/docs/_static/switcher.json +8 -0
  70. breos-0.3.0rc1/docs/adr/0001-docs-architecture.md +25 -0
  71. breos-0.3.0rc1/docs/adr/index.md +11 -0
  72. breos-0.3.0rc1/docs/api/appendix.md +16 -0
  73. breos-0.3.0rc1/docs/api/battery.md +56 -0
  74. breos-0.3.0rc1/docs/api/cost-analysis.md +47 -0
  75. breos-0.3.0rc1/docs/api/energy-balance.md +25 -0
  76. breos-0.3.0rc1/docs/api/index.md +98 -0
  77. breos-0.3.0rc1/docs/api/load-profiles.md +54 -0
  78. breos-0.3.0rc1/docs/api/optimization.md +38 -0
  79. breos-0.3.0rc1/docs/api/plotting.md +127 -0
  80. breos-0.3.0rc1/docs/api/pv.md +56 -0
  81. breos-0.3.0rc1/docs/api/weather.md +54 -0
  82. breos-0.3.0rc1/docs/architecture/string-inverter-sizing.md +146 -0
  83. breos-0.3.0rc1/docs/architecture/third-party-wrapping.md +168 -0
  84. breos-0.3.0rc1/docs/changelog.md +5 -0
  85. breos-0.3.0rc1/docs/conf.py +107 -0
  86. breos-0.3.0rc1/docs/getting-started/configuration.md +158 -0
  87. breos-0.3.0rc1/docs/getting-started/index.md +16 -0
  88. breos-0.3.0rc1/docs/getting-started/inputs.md +74 -0
  89. breos-0.3.0rc1/docs/getting-started/installation.md +80 -0
  90. breos-0.3.0rc1/docs/getting-started/interpreting-results.md +91 -0
  91. breos-0.3.0rc1/docs/getting-started/options.md +104 -0
  92. breos-0.3.0rc1/docs/getting-started/quickstart.md +139 -0
  93. breos-0.3.0rc1/docs/getting-started/recipes.md +151 -0
  94. breos-0.3.0rc1/docs/index.md +108 -0
  95. breos-0.3.0rc1/docs/legal/load-profile-data.md +84 -0
  96. breos-0.3.0rc1/docs/release.md +107 -0
  97. breos-0.3.0rc1/docs/resources.md +49 -0
  98. breos-0.3.0rc1/pyproject.toml +98 -0
  99. breos-0.3.0rc1/rlp/README.md +24 -0
  100. breos-0.3.0rc1/tests/__init__.py +0 -0
  101. breos-0.3.0rc1/tests/conftest.py +192 -0
  102. breos-0.3.0rc1/tests/test_app.py +554 -0
  103. breos-0.3.0rc1/tests/test_battery.py +235 -0
  104. breos-0.3.0rc1/tests/test_cli.py +174 -0
  105. breos-0.3.0rc1/tests/test_docs_options.py +16 -0
  106. breos-0.3.0rc1/tests/test_economics.py +181 -0
  107. breos-0.3.0rc1/tests/test_emissions.py +76 -0
  108. breos-0.3.0rc1/tests/test_golden_outputs.py +211 -0
  109. breos-0.3.0rc1/tests/test_inverter.py +41 -0
  110. breos-0.3.0rc1/tests/test_load_profiles.py +79 -0
  111. breos-0.3.0rc1/tests/test_numba_kernels.py +61 -0
  112. breos-0.3.0rc1/tests/test_optimization.py +100 -0
  113. breos-0.3.0rc1/tests/test_optimization_public.py +43 -0
  114. breos-0.3.0rc1/tests/test_public_api.py +48 -0
  115. breos-0.3.0rc1/tests/test_runners.py +16 -0
  116. breos-0.3.0rc1/tests/test_solar.py +240 -0
  117. breos-0.3.0rc1/tests/test_utils.py +83 -0
  118. breos-0.3.0rc1/tests/test_weather.py +202 -0
  119. breos-0.3.0rc1/tools/add_location.py +107 -0
  120. breos-0.3.0rc1/tools/analyze_results.py +74 -0
  121. breos-0.3.0rc1/tools/azitilt_optimizer.py +535 -0
  122. breos-0.3.0rc1/tools/batch_compare_locations.py +888 -0
  123. breos-0.3.0rc1/tools/compare_results.py +112 -0
  124. breos-0.3.0rc1/tools/compare_two_results.py +93 -0
  125. breos-0.3.0rc1/tools/fetch_historical_weather.py +157 -0
  126. breos-0.3.0rc1/tools/fetch_weather.py +161 -0
  127. breos-0.3.0rc1/tools/generate_option_docs.py +168 -0
  128. breos-0.3.0rc1/tools/recalculate_economics.py +228 -0
  129. breos-0.3.0rc1/tools/verify_release_artifacts.py +202 -0
  130. breos-0.3.0rc1/uv.lock +2348 -0
@@ -0,0 +1,30 @@
1
+ name: Bug Report
2
+ description: Report a bug in BREOS
3
+ labels: ["bug"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: Description
9
+ description: What happened? What did you expect?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: reproduce
14
+ attributes:
15
+ label: Steps to Reproduce
16
+ description: Minimal code or steps to reproduce the issue
17
+ render: python
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: environment
22
+ attributes:
23
+ label: Environment
24
+ description: Python version, OS, BREOS version
25
+ placeholder: |
26
+ Python: 3.13
27
+ OS: Ubuntu 24.04
28
+ breos: 0.2.0
29
+ validations:
30
+ required: true
@@ -0,0 +1,18 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature or improvement
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: Description
9
+ description: What would you like to see added or changed?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: use_case
14
+ attributes:
15
+ label: Use Case
16
+ description: How would this help your workflow?
17
+ validations:
18
+ required: false
@@ -0,0 +1,6 @@
1
+ ## Summary
2
+ <!-- Brief description of what this PR does -->
3
+
4
+ ## Test plan
5
+ <!-- How was this tested? -->
6
+ - [ ] Tests pass (`uv run pytest tests/ -v`)
@@ -0,0 +1,84 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ with:
15
+ fetch-depth: 0
16
+
17
+ - name: Check release tag points at main
18
+ if: github.event_name == 'push'
19
+ run: |
20
+ git fetch origin main
21
+ if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
22
+ echo "Refusing to publish: tag ${GITHUB_REF_NAME} is not on main." >&2
23
+ exit 1
24
+ fi
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v7
28
+
29
+ - name: Set up Python
30
+ run: uv python install 3.12
31
+
32
+ - name: Install dependencies
33
+ run: uv sync --extra dev
34
+
35
+ - name: Verify release artifacts
36
+ run: uv run python tools/verify_release_artifacts.py
37
+
38
+ - name: Build distributions
39
+ run: uv build
40
+
41
+ - uses: actions/upload-artifact@v4
42
+ with:
43
+ name: dist
44
+ path: dist/
45
+
46
+ publish-testpypi:
47
+ if: github.event_name == 'workflow_dispatch'
48
+ needs: build
49
+ runs-on: ubuntu-latest
50
+ environment:
51
+ name: testpypi
52
+ url: https://test.pypi.org/p/breos
53
+ permissions:
54
+ id-token: write
55
+
56
+ steps:
57
+ - uses: actions/download-artifact@v4
58
+ with:
59
+ name: dist
60
+ path: dist/
61
+
62
+ - name: Publish to TestPyPI
63
+ uses: pypa/gh-action-pypi-publish@release/v1
64
+ with:
65
+ repository-url: https://test.pypi.org/legacy/
66
+
67
+ publish-pypi:
68
+ if: github.event_name == 'push'
69
+ needs: build
70
+ runs-on: ubuntu-latest
71
+ environment:
72
+ name: pypi
73
+ url: https://pypi.org/p/breos
74
+ permissions:
75
+ id-token: write
76
+
77
+ steps:
78
+ - uses: actions/download-artifact@v4
79
+ with:
80
+ name: dist
81
+ path: dist/
82
+
83
+ - name: Publish to PyPI
84
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,46 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main, develop]
6
+ pull_request:
7
+ branches: [main, develop]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.11", "3.12", "3.13"]
17
+
18
+ env:
19
+ UV_PYTHON: ${{ matrix.python-version }}
20
+
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v7
26
+
27
+ - name: Set up Python
28
+ run: uv python install ${{ matrix.python-version }}
29
+
30
+ - name: Install dependencies
31
+ run: uv sync --extra dev --extra docs
32
+
33
+ - name: Lint
34
+ run: uv run ruff check breos/ tests/ tools/
35
+
36
+ - name: Check formatting
37
+ run: uv run ruff format --check breos/ tests/ tools/
38
+
39
+ - name: Run tests
40
+ run: uv run pytest tests/ -v
41
+
42
+ - name: Verify release artifacts
43
+ run: uv run python tools/verify_release_artifacts.py
44
+
45
+ - name: Build docs
46
+ run: uv run --extra docs sphinx-build -b html docs docs/_build/html
@@ -0,0 +1,20 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .cache/
7
+ *.egg
8
+ .venv/
9
+ .env
10
+ results/
11
+ dev/
12
+ *.csv
13
+ !breos/data/rlp/*.csv
14
+ .codex
15
+ .claude/
16
+ .DS_Store
17
+
18
+ # Sphinx
19
+ docs/_build/
20
+ docs/api/generated/
@@ -0,0 +1,17 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-24.04
5
+ tools:
6
+ python: "3.13"
7
+
8
+ sphinx:
9
+ configuration: docs/conf.py
10
+ fail_on_warning: false
11
+
12
+ python:
13
+ install:
14
+ - method: pip
15
+ path: .
16
+ extra_requirements:
17
+ - docs
@@ -0,0 +1,35 @@
1
+ # Agent Guide
2
+
3
+ This repository is the open-source core of BREOS. Keep changes scoped and preserve the `breos.App` facade as the most stable public entrypoint.
4
+
5
+ ## Project map
6
+
7
+ - `breos/app.py` - public facade that wires weather, PV, load, battery, economics, and emissions.
8
+ - `breos/load_profiles.py` - bundled demandlib H0 profile support plus user-supplied external RLPs.
9
+ - `breos/battery.py`, `breos/solar.py`, `breos/weather.py` - core simulation models.
10
+ - `breos/economics.py`, `breos/emissions.py`, `breos/optimization.py` - analysis and sizing helpers.
11
+ - `breos/data/` - packaged presets and redistributable sample data used after installation.
12
+ - `configs/` - editable example and template configuration files for users.
13
+ - `tests/` - pytest coverage for public behavior and lower-level modules.
14
+ - `docs/` - Sphinx/MyST source; generated output lives in `docs/_build/` and is ignored.
15
+
16
+ ## Common commands
17
+
18
+ ```bash
19
+ uv sync --extra dev --extra docs
20
+ uv run pytest -q
21
+ uv run ruff check breos tests
22
+ uv run ruff format --check breos tests
23
+ uv build
24
+ ```
25
+
26
+ ## Release data policy
27
+
28
+ Only redistribute profiles whose upstream terms are clear enough for a public package. BREOS currently bundles demandlib-derived H0 examples. E-REDES, REE, and direct BDEW downloads remain supported only as user-supplied local files via `rlp_directory`.
29
+
30
+ ## Change guidance
31
+
32
+ - Prefer extending `breos.App` through backwards-compatible config keys.
33
+ - Avoid repo-relative runtime paths; packaged resources should be loaded through `breos.resources`.
34
+ - Keep generated files out of git unless they are intentional release assets.
35
+ - Add focused tests for public API behavior when touching defaults, packaged data, or serialization.
@@ -0,0 +1,83 @@
1
+ # Attributions and Third-Party Notices
2
+
3
+ BREOS bundles or relies on third-party data, services, software, and published
4
+ methods. This document lists each source, its license posture, and any
5
+ redistribution, commercial-use, citation, or attribution caveats.
6
+
7
+ This is a project-maintainer note, not legal advice.
8
+
9
+ ## Bundled reference load profiles
10
+
11
+ | File | Source | License / Terms |
12
+ |------|--------|-----------------|
13
+ | `breos/data/rlp/h0SLP_demandlib_1000kwh_hourly.csv`, `breos/data/rlp/h0SLP_demandlib_1000kwh_15min.csv` | Generated with [demandlib](https://demandlib.readthedocs.io/) H0 logic | demandlib documents itself as MIT-licensed free software. Preserve demandlib attribution and license notices when redistributing derived profile examples. |
14
+
15
+ ## Supported but not redistributed
16
+
17
+ BREOS can load the following profile families when users provide their own licensed local copies through `breos.load_profile(..., rlp_directory="...")`:
18
+
19
+ | Profile family | Why not bundled in this public release |
20
+ |----------------|-----------------------------------------|
21
+ | Direct BDEW Standardlastprofile exports (`h0_SLP.csv`, `bdew_h0_2025_15min.csv`) | BDEW publishes downloadable SLP files, but its public site terms reserve copyright rights and limit downloads/copies to private, non-commercial use unless written permission is granted. |
22
+ | E-REDES BTN profiles (`EREDES_2025_BTN_*.csv`) | Public website terms reviewed for this release do not provide a clear redistribution grant for bundling derived CSVs in an OSS package. |
23
+ | REE 2.0TD profiles (`REE_2026_2.0TD_*.csv`) | REE legal terms reserve intellectual-property rights and do not clearly authorize republishing derived CSV datasets in this package. |
24
+
25
+ Users can still provide these files locally through `rlp_directory` when their source terms permit their use case. If written redistribution permission is granted, store the permission text with the release record before adding the files back to package data.
26
+
27
+ ## Runtime data sources (fetched on demand)
28
+
29
+ | Service | Used by | License | Caveats |
30
+ |---------|---------|---------|---------|
31
+ | **Open-Meteo** Historical & Forecast API | `breos/weather.py` (`fetch_*_openmeteo`) | Data licensed **CC-BY 4.0**. | **Free API tier is non-commercial.** Commercial workloads require a paid Open-Meteo subscription. Attribution required: "Weather data by Open-Meteo.com". |
32
+ | **NREL NSRDB** (via pvlib) | `breos/weather.py:fetch_tmy_nsrdb` | NSRDB data is a U.S. government work, generally in the public domain in the U.S. | Citation requested by NREL. Refer to the NSRDB "How to cite" page for the current canonical citation. Users must obtain their own NREL API key. |
33
+ | **PVGIS** (JRC) | `breos/weather.py` (PVGIS endpoints) | Governed by Commission Decision 2011/833/EU on reuse of Commission documents — free reuse including commercial, with attribution. | Attribution: "© European Union, [year], PVGIS". |
34
+
35
+ ## Python dependencies
36
+
37
+ BREOS's Python dependencies are open-source packages under their respective
38
+ licenses. See `pyproject.toml`, `uv.lock`, and each package's own metadata for
39
+ the authoritative license text. Current runtime dependencies include:
40
+
41
+ - **geopy** — MIT
42
+ - **joblib** — BSD 3-Clause
43
+ - **matplotlib** — Matplotlib / PSF-style license terms
44
+ - **numba** — BSD
45
+ - **openpyxl** — MIT
46
+ - **openmeteo-requests** — MIT
47
+ - **pandas** — BSD 3-Clause
48
+ - **pyarrow** — Apache 2.0
49
+ - **NREL-PySAM** — BSD 3-Clause. Refer to the NREL-PySAM license and SAM
50
+ notices for bundled model details.
51
+ - **pvlib** — BSD 3-Clause
52
+ - **pymoo** — Apache 2.0
53
+ - **rainflow** — MIT
54
+ - **requests-cache** — BSD 2-Clause
55
+ - **timezonefinder** — MIT
56
+
57
+ ## Scientific and model credits
58
+
59
+ BREOS implements or wraps methods from the photovoltaic, battery, optimization,
60
+ and reliability literature. These credits are separate from software-license
61
+ requirements, but they should be preserved in papers, reports, and downstream
62
+ documentation where the relevant models affect results.
63
+
64
+ | Area | Used by | Credit / citation note |
65
+ |------|---------|------------------------|
66
+ | PV modelling | `breos/solar.py`, `breos/weather.py` | BREOS uses [pvlib python](https://pvlib-python.readthedocs.io/) for solar position, irradiance transposition, temperature, CEC/SAM-style module fitting, PVWatts losses, tracking, and inverter helpers. Cite pvlib in published work that relies on these calculations. |
67
+ | SAM / CEC PV parameters | `breos/solar.py`, `breos/pv_modules.py` | CEC/SAM-style single-diode parameters and NREL SAM documentation inform module modelling assumptions. |
68
+ | Multi-objective optimization | `breos/optimization.py` | BREOS uses [pymoo](https://pymoo.org/) for NSGA-II multi-objective optimization. Cite pymoo where optimizer behavior is material to the study. |
69
+ | Rainflow cycle counting | `breos/battery.py` | BREOS uses the `rainflow` Python package and ASTM E1049-style rainflow counting for battery cycle detection in the reference path. |
70
+ | Battery cycle and calendar ageing | `breos/battery.py`, `breos/constants.py`, `breos/numba_kernels.py` | Naumann et al. (2020) parameterization and equations are used for cycle ageing and selected calendar/resistance ageing behavior. |
71
+ | LFP calendar ageing calibration | `breos/constants.py`, `breos/battery.py` | Lam et al. (2025) LFP calendar ageing behavior informs the `naumann_lam*` calendar-model variants and field-calibrated defaults. |
72
+ | Polysun-style degradation comparison | `breos/polysun_degradation.py`, `breos/plotting.py` | The comparison baseline follows Polysun / Vela Solaris battery-lifetime methodology: Woehler curve, Miner's linear damage accumulation, DOD histograms, fixed calendar lifetime, and no continuous SOH feedback. |
73
+ | PerMod comparison context | `breos/polysun_degradation.py` | Weniger et al., "Performance Model for PV-Battery Systems (PerMod)", HTW Berlin, 2023, is used as a comparison reference for PV-battery performance modelling. |
74
+ | Linear damage accumulation | `breos/polysun_degradation.py` | Palmgren-Miner linear damage accumulation is used for Polysun-style cycle damage aggregation. |
75
+
76
+ ## Notes for downstream users
77
+
78
+ If you redistribute BREOS or derived datasets:
79
+
80
+ 1. Preserve attributions above.
81
+ 2. If you call Open-Meteo from a commercial deployment, obtain a paid Open-Meteo subscription.
82
+ 3. Do not assume a public download page grants redistribution rights; keep externally sourced RLPs outside public package artifacts unless the source license is explicit.
83
+ 4. Cite the scientific/model references that materially affect published or customer-facing results.
@@ -0,0 +1,176 @@
1
+ # Changelog
2
+
3
+ All notable changes to BREOS are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/).
4
+
5
+ ## [0.3.0] - 2026-06-10
6
+
7
+ ### Fixed
8
+ - **TMY timezone misalignment (results-changing):** `fetch_tmy_weather_data`
9
+ relabeled PVGIS's UTC-ordered rows with local-time labels, shifting
10
+ irradiance against the computed solar position by the location's UTC offset
11
+ (~1 h for Berlin, ~10 h for Melbourne; UTC+0 locations were unaffected).
12
+ Rows are now rolled to start at local midnight while each timestamp keeps
13
+ its correct UTC instant.
14
+ - **Battery phantom export (results-changing):** when temperature derating or
15
+ daily SOH decline shrank `Emax` below the stored energy, the negative
16
+ charge room silently drained the battery into `Sell_To_Grid`. Stored energy
17
+ is now clamped into the derated window, mirroring the Numba kernel.
18
+ - Load profiles are pinned to the location's wall clock instead of the UTC
19
+ clock, so H0 morning/evening peaks land at the correct local hours across
20
+ DST (previously ~1 h off in Iberia during summer).
21
+ - `optimize_tilt`/`optimize_tilt_brent` reported "kWh" without accounting for
22
+ the timestep (4x off at 15-minute resolution; ranking was unaffected).
23
+ - `BatteryConfig.initial_resistance_growth` was never read by
24
+ `simulate_energy_balance`; it now seeds the resistance state when the
25
+ continuation argument is not supplied.
26
+ - `get_module_info` printed the efficiency fraction as a percent and crashed
27
+ on modules without efficiency metadata.
28
+ - Removed three dead, shadowed plotting functions and an undefined
29
+ `MONTH_LABELS` reference that crashed the TMY-vs-historical monthly plot.
30
+
31
+ ### Added
32
+ - Inverter AC clipping in the `App` energy pipeline: PV output, export, and
33
+ battery discharge now saturate at the AC rating implied by
34
+ `inverter_loading_ratio` — the same rating used for inverter CAPEX. DC
35
+ surplus above the rating still charges a DC-coupled battery
36
+ (`BatteryConfig.inverter_ac_capacity_w`, `None` = legacy uncapped model).
37
+ - Configurable PVWatts system losses: `breos.solar.DEFAULT_PVWATTS_LOSSES`
38
+ (~14.1% combined) with a `loss_overrides` hook on the production functions
39
+ and a `pv_loss_overrides` App config key.
40
+ - Battery operating parameters as App config keys: `battery_min_soc`,
41
+ `battery_max_soc`, `battery_eol_percentage`, and `battery_rte` (previously
42
+ hardcoded to 0.10/0.90/0.70/sqrt(0.95)).
43
+ - `enable_resistance_fade` now feeds the resistance-derated round-trip
44
+ efficiency back into the energy loop (previously tracking-only).
45
+ - Parity tests for the optional Numba kernels: the duplicated LFP derate
46
+ constants against `battery.lfp_capacity_factor`, and the energy-balance
47
+ kernel against the reference path under shared-model conditions.
48
+ - CLI discovery and inspection commands: `breos list
49
+ {locations,modules,cost-presets,emissions,load-profiles}` prints packaged
50
+ option keys, `breos validate-config <config>` checks a config file and
51
+ summarizes the resolved choices, and `breos run --dry-run` writes the
52
+ resolved configuration as JSON without running a simulation. `list` and
53
+ `validate-config` accept `--json` for machine-readable output.
54
+ - PyPI distribution: 0.3.0 is the first release installable with
55
+ `pip install breos`. Tagged `v*` releases on `main` now publish to PyPI
56
+ through GitHub Actions trusted publishing (OIDC), running the release
57
+ artifact verifier before upload, with a manually triggered TestPyPI
58
+ dry-run path.
59
+
60
+ ### Changed
61
+ - Cost defaults are single-sourced from the `CostParams` dataclass:
62
+ `cost_params_from_config` and the App preset fallbacks no longer carry
63
+ their own diverging literals (packaged presets are unaffected).
64
+ - Config validation rejects out-of-range values at load time: negative
65
+ `battery_kwh`, top-level `tilt`/`azimuth`, `inverter_efficiency`,
66
+ `inverter_loading_ratio`, `projection_years`, `pv_degradation_rate`, and
67
+ the new battery keys.
68
+ - PV-only App runs construct an explicit inverter model, so a configured
69
+ `inverter_efficiency` now applies without a battery (previously ignored).
70
+ - Library progress messages (weather file discovery, saved files, CSV
71
+ conversions) go through `logging` under `breos.*` logger names instead of
72
+ unconditional `print()`. Functions with a `verbose` flag still print.
73
+ - Slimmed the default runtime dependency set to the BREOS core simulation
74
+ stack and moved heavier workflow packages behind extras: `plots`,
75
+ `optimization`, `weather`, `fast`, `cec-fit`, `validation`, and
76
+ `location-tools`.
77
+ - The `dev` extra now installs optional feature dependencies so contributor
78
+ test runs continue to cover optional paths.
79
+
80
+ ### Documentation
81
+ - Install snippets in the README and docs point at PyPI (`pip install breos`)
82
+ instead of git tag installs, and the quickstart gained a "10-minute first
83
+ run" walkthrough built on `configs/examples/quickstart.toml`, the new
84
+ option-discovery commands, and a representative output excerpt with
85
+ plausibility ranges.
86
+ - New recipes page with validated copy-paste configs: PV-only home, PV plus
87
+ battery, custom latitude/longitude/timezone, east-west roof with
88
+ `pv_arrays`, 15-minute resolution, external E-REDES/BDEW/REE load
89
+ profiles, and offline runs with cached weather.
90
+ - New generated "Packaged options" reference page listing locations, PV
91
+ modules, cost presets, emissions factors, and load profiles. It is built
92
+ by `tools/generate_option_docs.py` from the packaged data and source
93
+ constants, and a test fails CI when the page drifts.
94
+ - README documents the fixed PVWatts loss components, the inverter clipping
95
+ convention, the `weather/` working-directory override, the Open-Meteo
96
+ `.cache.sqlite` file, logging configuration, and the new config keys.
97
+ - README describes the Numba kernels honestly as approximate standalone
98
+ screening engines that `breos.App` does not use; the module docstring
99
+ carries the same warning.
100
+ - Clarified that the `bdew_h0` alias maps to the bundled demandlib
101
+ BDEW-H0-shaped profile `"1"`, distinct from the external BDEW H0 2025
102
+ dataset (profile `"7"`).
103
+ - Replaced stream-of-consciousness working notes in `economics`,
104
+ `optimization`, `acc_sizer`, and `plotting` with factual comments, and
105
+ fixed mislabeled docstrings (`total_pv` is post-inverter AC; the Suntech
106
+ NOMT catalog entry documents its NMOT-condition rating).
107
+
108
+ ## [0.2.3] - 2026-06-08
109
+
110
+ ### Changed
111
+ - Lowered the minimum supported Python from 3.13 to 3.11 — the real floor, set by
112
+ pandas, timezonefinder, and stdlib `tomllib`. CI now runs a 3.11/3.12/3.13 matrix.
113
+ - Relaxed the pvlib constraint from `==0.14.0` to `>=0.14.0,<0.16` after verifying
114
+ the full API surface and the test suite against pvlib 0.15.1.
115
+ - `breos.__version__` is now resolved from installed package metadata
116
+ (`importlib.metadata`) instead of a hardcoded literal, so it can no longer drift
117
+ from `pyproject.toml`.
118
+
119
+ ### Added
120
+ - `CITATION.cff`, `CODE_OF_CONDUCT.md`, and `SECURITY.md` for open-source release
121
+ readiness.
122
+
123
+ ### Removed
124
+ - Duplicate top-level `rlp/*.csv` load-profile files (byte-identical to the
125
+ packaged `breos/data/rlp/` copies that runtime actually uses). `rlp/README.md` is
126
+ retained as external-RLP guidance.
127
+
128
+ ### Documentation
129
+ - README badge and installation docs now state Python 3.11+.
130
+ - Trimmed `ATTRIBUTIONS.md` to reference only the packaged load-profile paths.
131
+
132
+ ## [0.2.2] - 2026-06-07
133
+
134
+ ### Documentation
135
+ - Expanded third-party notices with dependency credits, runtime data-source
136
+ caveats, and scientific/model attribution guidance.
137
+
138
+ ## [0.2.1] - 2026-06-03
139
+
140
+ ### Documentation
141
+ - Updated installation guidance to use the stable GitHub tag until PyPI
142
+ publishing is available.
143
+ - Added PyPI trusted publishing to the roadmap.
144
+ - Documented the full CI/release validation gates in the contributor guide.
145
+ - Standardized API documentation wording around domain areas.
146
+
147
+ ## [0.2.0] - 2026-06-03
148
+
149
+ ### Changed
150
+ - Narrowed the top-level `breos.__all__` release surface to the stable facade,
151
+ key configuration/result objects, and core composition helpers. Lower-level
152
+ module APIs remain importable from their modules.
153
+
154
+ ## [0.1.0] - 2026-04-30
155
+
156
+ ### Added
157
+ - Public API facade (`breos.App`) — single entry point for simulations: config dict in, plain dict out.
158
+ - Command line entry point (`breos run`) for running simulations from shell flags or TOML/JSON config files.
159
+ - Test suite — pytest coverage of the public API, battery, economics, emissions, and solar modules (all offline).
160
+ - GitHub Actions CI on every push/PR.
161
+ - `cost_params_from_config()` — config parser for `CostParams`.
162
+ - Marginal grid carbon intensity support in `EmissionsParams` for more accurate CO₂ avoidance accounting.
163
+
164
+ ### Changed
165
+ - Renamed PV `slope` → `tilt` everywhere: function parameters, dataclass fields, docstrings, CLI/config keys, public API. Includes `optimize_slope()` → `optimize_tilt()` and the `tools/azitilt_optimizer.py` script.
166
+ - Calendar model name canonicalized to `naumann_lam_field_calibrated` (the legacy alias `naumann_lam_calibrated` has been removed).
167
+ - Constants renamed: `LAM_NAUMANN_FIELD_CALIBRATED_*` → `NAUMANN_LAM_FIELD_CALIBRATED_*`; alias indirections (`LAM_CAL_K0_FRAC` …) dropped.
168
+ - Configs modernized: per-unit cost keys (`maintenance_cost_per_panel`, `other_cost_per_module`); emissions schema renamed and country list expanded.
169
+ - Polysun degradation now tracks the actual `last_replacement_year` instead of approximating with `n_replacements × int(total_life)` — handles fractional lifetimes and cycle-driven replacements correctly.
170
+ - Numba degradation kernel now treats SOC reversals as half-cycles (rainflow-aligned) and applies LFP temperature derating per timestep, matching the Python reference path.
171
+
172
+ ### Fixed
173
+ - NPV discount factor now uses `(1 + r) ** Year` (time-0 NPV) instead of `(1 + r) ** (Year - 1)`. Affects all `cost_analysis_projection` outputs.
174
+
175
+ ### Removed
176
+ - Out-of-scope kernels (`combined_energy_balance_kernel`, `batch_combined_energy_balance_kernel`) and any thermal storage / heat-pump / V2H / time-of-use code paths. BREOS focuses on PV + battery simulation.
@@ -0,0 +1,24 @@
1
+ cff-version: 1.2.0
2
+ title: "BREOS: Building Renewable Energy Optimization Software"
3
+ message: "If you use BREOS in your research, please cite it as below."
4
+ type: software
5
+ authors:
6
+ - given-names: Leonardo
7
+ family-names: Rodrigues
8
+ email: lrodrigues@fe.up.pt
9
+ repository-code: "https://github.com/Str4vinci/breos"
10
+ url: "https://github.com/Str4vinci/breos"
11
+ abstract: >-
12
+ A Python library for PV and battery energy-system simulation and
13
+ optimization, designed for research and engineering applications.
14
+ keywords:
15
+ - photovoltaic
16
+ - battery
17
+ - energy
18
+ - simulation
19
+ - optimization
20
+ - solar
21
+ - degradation
22
+ license: BSD-3-Clause
23
+ version: 0.3.0
24
+ date-released: "2026-06-10"
@@ -0,0 +1,37 @@
1
+ # Code of Conduct
2
+
3
+ BREOS is an open-source project for energy-system simulation and optimization.
4
+ Contributions are welcome from people with different backgrounds, levels of
5
+ experience, and perspectives.
6
+
7
+ ## Expected Behavior
8
+
9
+ - Be respectful and constructive in issues, pull requests, discussions, and
10
+ other project spaces.
11
+ - Focus criticism on ideas, code, data, documentation, and project decisions,
12
+ not on people.
13
+ - Assume good intent when possible, and ask for clarification when something is
14
+ ambiguous.
15
+ - Respect maintainers' time by keeping reports actionable and discussions
16
+ relevant to the project.
17
+
18
+ ## Unacceptable Behavior
19
+
20
+ The project does not tolerate harassment, threats, insults, intimidation,
21
+ discriminatory language, sexualized attention, doxxing, sustained disruption, or
22
+ other conduct that makes participation unsafe or unwelcome.
23
+
24
+ ## Reporting
25
+
26
+ Report conduct concerns to the maintainer at lrodrigues@fe.up.pt. Include the
27
+ relevant context, links, screenshots, or timestamps when available. Reports will
28
+ be handled with discretion and shared only with people needed to review and
29
+ respond to the situation.
30
+
31
+ ## Enforcement
32
+
33
+ Maintainers may take action to protect the project community, including editing
34
+ or removing comments, closing threads, requesting a change in behavior, issuing
35
+ temporary restrictions, or banning participation in project spaces. Enforcement
36
+ decisions should be proportionate to the conduct and focused on maintaining a
37
+ productive, respectful environment.