From 075af25c7dd936ea6b25c0227bc1bcddec0df93c Mon Sep 17 00:00:00 2001 From: Martin Tazl Date: Wed, 27 May 2026 08:33:45 +0200 Subject: [PATCH] Initial commit --- .gitignore | 29 ++++ LICENSE | 0 README.md | 230 +++++++++++++++++++++++++++ config/horizon.txt | 0 config/site.yaml | 0 notebooks/clear_sky_fit.ipynb | 0 notebooks/shading_analysis.ipynb | 0 notebooks/weather_factor.ipynb | 0 requirements.txt | 0 scripts/compare_day.py | 0 scripts/fetch_weather.py | 0 scripts/fit_horizon.py | 0 scripts/generate_forecast.py | 0 src/__init__.py | 0 src/astronomy/clear_sky.py | 0 src/astronomy/irradiance.py | 0 src/astronomy/sun_position.py | 0 src/io/csv_loader.py | 0 src/io/exporter.py | 0 src/io/home_assistant.py | 0 src/model/calibration.py | 0 src/model/forecast.py | 0 src/model/pv_model.py | 0 src/shading/horizon.py | 0 src/shading/horizon_interpolation.py | 0 src/shading/shading_factor.py | 0 src/utils/plotting.py | 0 src/utils/time.py | 0 src/weather/dwd.py | 0 src/weather/metar.py | 0 src/weather/open_meteo.py | 0 tests/test_astronomy.py | 0 tests/test_forecast.py | 0 tests/test_horizon.py | 0 34 files changed, 259 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 config/horizon.txt create mode 100644 config/site.yaml create mode 100644 notebooks/clear_sky_fit.ipynb create mode 100644 notebooks/shading_analysis.ipynb create mode 100644 notebooks/weather_factor.ipynb create mode 100644 requirements.txt create mode 100644 scripts/compare_day.py create mode 100644 scripts/fetch_weather.py create mode 100644 scripts/fit_horizon.py create mode 100644 scripts/generate_forecast.py create mode 100644 src/__init__.py create mode 100644 src/astronomy/clear_sky.py create mode 100644 src/astronomy/irradiance.py create mode 100644 src/astronomy/sun_position.py create mode 100644 src/io/csv_loader.py create mode 100644 src/io/exporter.py create mode 100644 src/io/home_assistant.py create mode 100644 src/model/calibration.py create mode 100644 src/model/forecast.py create mode 100644 src/model/pv_model.py create mode 100644 src/shading/horizon.py create mode 100644 src/shading/horizon_interpolation.py create mode 100644 src/shading/shading_factor.py create mode 100644 src/utils/plotting.py create mode 100644 src/utils/time.py create mode 100644 src/weather/dwd.py create mode 100644 src/weather/metar.py create mode 100644 src/weather/open_meteo.py create mode 100644 tests/test_astronomy.py create mode 100644 tests/test_forecast.py create mode 100644 tests/test_horizon.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f5911f --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Python +__pycache__/ +*.pyc +*.pyo +*.pyd +.venv/ +venv/ + +# macOS +.DS_Store + +# Jupyter +.ipynb_checkpoints/ + +# VSCode +.vscode/ + +# Plot/Output Daten +plots/ +data/raw/ +data/tmp/ + +# Home Assistant lokale Configs +*.db +*.sqlite +secrets.yaml + +# Logs +*.log diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..886ec22 --- /dev/null +++ b/README.md @@ -0,0 +1,230 @@ +# local-pv-forecast + +Local, horizon-aware photovoltaic forecast engine for Home Assistant and standalone use. + +--- + +## Features + +- Fully local PV forecast calculation +- Horizon-aware shading model +- Open-Meteo / DWD / METAR weather integration +- Clear-sky irradiance calculation +- Calibration against historical production data +- Home Assistant integration +- CSV import/export tools +- Plotting and diagnostics +- Forecast comparison and horizon fitting scripts + +--- + +## Motivation + +Most cloud-based PV forecast systems have limited knowledge of the real installation environment: + +- local horizon obstructions +- trees and buildings +- seasonal shading +- module orientation differences +- site-specific losses + +This project aims to build a transparent and fully local forecasting pipeline that can be calibrated against real production data and local horizon measurements. + +The long-term goal is to improve short-term PV forecast accuracy for Home Assistant energy management and battery optimization. + +--- + +## Architecture + +```text +Weather Data +(Open-Meteo / DWD / METAR) + │ + ▼ +Clear Sky Model + │ + ▼ +Solar Position Calculation + │ + ▼ +Local Horizon / Shading Model + │ + ▼ +PV System Model + │ + ▼ +Calibration Layer + │ + ▼ +Forecast Output +(Home Assistant / CSV / Plots) +``` + +--- + +## Repository Structure + +```text +src/ +├── astronomy/ Solar position & irradiance +├── shading/ Horizon and shading calculations +├── weather/ Weather providers +├── model/ PV and forecast models +├── io/ Home Assistant & CSV interfaces +└── utils/ Shared utilities + +scripts/ +├── fetch_weather.py +├── generate_forecast.py +├── compare_day.py +└── fit_horizon.py + +tests/ +└── Unit tests +``` + +--- + +## Installation + +### Clone repository + +```bash +git clone https://github.com//local-pv-forecast.git +cd local-pv-forecast +``` + +### Create virtual environment + +```bash +python3 -m venv .venv +source .venv/bin/activate +``` + +### Install dependencies + +```bash +pip install -r requirements.txt +``` + +--- + +## Configuration + +Example configuration files are located in: + +```text +config/ +``` + +Typical configuration parameters: + +- latitude / longitude +- panel azimuth +- panel tilt +- installed peak power +- horizon profile +- inverter efficiency +- weather provider selection + +--- + +## Horizon Model + +The forecast engine supports custom local horizon profiles. + +Example: + +```text +azimuth,elevation +0,2 +45,5 +90,12 +135,18 +180,4 +``` + +This allows modeling of: + +- buildings +- trees +- terrain +- seasonal shading effects + +--- + +## Home Assistant Integration + +Forecast values can be exported as Home Assistant compatible sensors. + +Planned integration targets: + +- Energy Dashboard +- Battery charging automation +- EV charging optimization +- Dynamic load shifting + +--- + +## Example Usage + +### Fetch weather data + +```bash +python scripts/fetch_weather.py +``` + +### Generate forecast + +```bash +python scripts/generate_forecast.py +``` + +### Compare forecast vs. measured data + +```bash +python scripts/compare_day.py +``` + +### Fit local horizon from historical production + +```bash +python scripts/fit_horizon.py +``` + +--- + +## Planned Features + +- [ ] Fully local weather fallback model +- [ ] Automatic horizon fitting +- [ ] Multi-array support +- [ ] Battery-aware optimization +- [ ] Probabilistic forecast +- [ ] Docker container +- [ ] Native Home Assistant Add-on +- [ ] Web UI +- [ ] ML-assisted calibration + +--- + +## Design Philosophy + +- Local-first +- Transparent calculations +- Reproducible results +- No cloud dependency required +- Easy Home Assistant integration +- Open and inspectable models + +--- + +## License + +MIT License + +--- + +## Contributing + +Pull requests, issue reports and calibration datasets are welcome. diff --git a/config/horizon.txt b/config/horizon.txt new file mode 100644 index 0000000..e69de29 diff --git a/config/site.yaml b/config/site.yaml new file mode 100644 index 0000000..e69de29 diff --git a/notebooks/clear_sky_fit.ipynb b/notebooks/clear_sky_fit.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/notebooks/shading_analysis.ipynb b/notebooks/shading_analysis.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/notebooks/weather_factor.ipynb b/notebooks/weather_factor.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/scripts/compare_day.py b/scripts/compare_day.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/fetch_weather.py b/scripts/fetch_weather.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/fit_horizon.py b/scripts/fit_horizon.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/generate_forecast.py b/scripts/generate_forecast.py new file mode 100644 index 0000000..e69de29 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/astronomy/clear_sky.py b/src/astronomy/clear_sky.py new file mode 100644 index 0000000..e69de29 diff --git a/src/astronomy/irradiance.py b/src/astronomy/irradiance.py new file mode 100644 index 0000000..e69de29 diff --git a/src/astronomy/sun_position.py b/src/astronomy/sun_position.py new file mode 100644 index 0000000..e69de29 diff --git a/src/io/csv_loader.py b/src/io/csv_loader.py new file mode 100644 index 0000000..e69de29 diff --git a/src/io/exporter.py b/src/io/exporter.py new file mode 100644 index 0000000..e69de29 diff --git a/src/io/home_assistant.py b/src/io/home_assistant.py new file mode 100644 index 0000000..e69de29 diff --git a/src/model/calibration.py b/src/model/calibration.py new file mode 100644 index 0000000..e69de29 diff --git a/src/model/forecast.py b/src/model/forecast.py new file mode 100644 index 0000000..e69de29 diff --git a/src/model/pv_model.py b/src/model/pv_model.py new file mode 100644 index 0000000..e69de29 diff --git a/src/shading/horizon.py b/src/shading/horizon.py new file mode 100644 index 0000000..e69de29 diff --git a/src/shading/horizon_interpolation.py b/src/shading/horizon_interpolation.py new file mode 100644 index 0000000..e69de29 diff --git a/src/shading/shading_factor.py b/src/shading/shading_factor.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/plotting.py b/src/utils/plotting.py new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/time.py b/src/utils/time.py new file mode 100644 index 0000000..e69de29 diff --git a/src/weather/dwd.py b/src/weather/dwd.py new file mode 100644 index 0000000..e69de29 diff --git a/src/weather/metar.py b/src/weather/metar.py new file mode 100644 index 0000000..e69de29 diff --git a/src/weather/open_meteo.py b/src/weather/open_meteo.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_astronomy.py b/tests/test_astronomy.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_forecast.py b/tests/test_forecast.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_horizon.py b/tests/test_horizon.py new file mode 100644 index 0000000..e69de29