Metadata-Version: 2.4
Name: smhi2epw
Version: 1.2.0
Summary: Build complete-year EnergyPlus weather files from SMHI observations, with documented gap recovery.
Author: smhi2epw contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/SB-Chalmers/smhi2epw
Project-URL: Documentation, https://sb-chalmers.github.io/smhi2epw/
Project-URL: Repository, https://github.com/SB-Chalmers/smhi2epw.git
Project-URL: Issues, https://github.com/SB-Chalmers/smhi2epw/issues
Keywords: smhi,epw,energyplus,weather,amy,strang,metobs
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=1.5.3
Requires-Dist: requests>=2.28
Requires-Dist: pvlib<0.17,>=0.16.1
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: pandas-stubs>=2.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.9; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: types-requests>=2.28; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Provides-Extra: docs
Requires-Dist: nbsphinx>=0.9; extra == "docs"
Requires-Dist: nbsphinx-link>=1.3; extra == "docs"
Requires-Dist: sphinx>=7.2; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=2.0; extra == "docs"
Provides-Extra: tutorials
Requires-Dist: ipykernel>=6.25; extra == "tutorials"
Requires-Dist: ipython>=8.12; extra == "tutorials"
Requires-Dist: jupyterlab>=4.0; extra == "tutorials"
Requires-Dist: matplotlib>=3.7; extra == "tutorials"
Requires-Dist: nbclient>=0.9; extra == "tutorials"
Requires-Dist: nbformat>=5.9; extra == "tutorials"
Dynamic: license-file

# smhi2epw

[![CI](https://github.com/SB-Chalmers/smhi2epw/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/SB-Chalmers/smhi2epw/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/smhi2epw)](https://pypi.org/project/smhi2epw/)
[![Python versions](https://img.shields.io/pypi/pyversions/smhi2epw)](https://pypi.org/project/smhi2epw/)
[![MIT license](https://img.shields.io/github/license/SB-Chalmers/smhi2epw)](LICENSE)
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://sb-chalmers.github.io/smhi2epw/)

Build complete-year EnergyPlus weather files (`.epw`) from Swedish weather data.
`smhi2epw` combines SMHI station observations and STRÅNG solar data, fills gaps,
and can use nearby stations or same-year ERA5 when needed. Each automatic run
writes a JSON receipt describing its sources and recovery steps.

## Install

Python 3.11 or newer is required:

```bash
python -m pip install smhi2epw
```

Creating a weather file needs internet access to SMHI and may use Open-Meteo for
ERA5 recovery. Reading an existing EPW works offline.

## Use

```bash
smhi2epw 2023 gothenburg.epw --station 71420 --city Gothenburg
```

Or use the Python API:

```python
from smhi2epw import EPWConfig, compile_epw

result = compile_epw(EPWConfig(
    year=2023,
    output_path="gothenburg.epw",
    station_id=71420,
    city="Gothenburg",
))
print(result.report.warnings)
```

Automatic recovery is the default. Use `--weather-policy strict` to stop when
required source data are missing. See the [quick start](docs/quickstart.rst)
and [CLI guide](docs/cli.rst) for options, and the
[method limitations](docs/limitations.rst) before using
reconstructed weather in calibration or event analysis.

## Docs and examples

The [online documentation](https://sb-chalmers.github.io/smhi2epw/) covers the API,
methods, and limitations. The [notebook course](examples/README.md) covers EPW
inspection, comparisons, heat waves, gap filling, solar components, batch runs,
and EnergyPlus. To run the notebooks from a source checkout:

```bash
git clone https://github.com/SB-Chalmers/smhi2epw.git
cd smhi2epw
python -m pip install -e ".[tutorials]"
jupyter lab examples/
```

## Completeness evidence

The archived EPSM runs covered jobs from 2017–2024. Their recorded results were:

| Run | Recovery policy | Completed |
| --- | --- | ---: |
| v1 | Temporal filling | 32 / 85 |
| v2 | Opt-in station donors | 124 / 128 |
| v3 | Assessed donors and ERA5 | **128 / 128** |

All 128 v3 files were rechecked for calendar, row, field, range, and dew-point
validity. They all used some reconstruction; completeness does not establish
local weather accuracy. The archived results predate the pvlib solar refactor.
See the [run summary](examples/data/completeness_2026-10-05.json) and
[notebook 08](examples/08_batch_generation.ipynb) for details and limitations.

## Related SMHI packages

Thanks to the maintainers of [`smhi-open-data`](https://pypi.org/project/smhi-open-data/),
[`smhi-weather`](https://pypi.org/project/smhi-weather/),
[`smhi-pkg`](https://pypi.org/project/smhi-pkg/), and
[`ifk-smhi`](https://pypi.org/project/ifk-smhi/). These projects provide SMHI
API clients and forecast access; `smhi2epw` focuses on complete-year weather
files for EnergyPlus.

## Development

```bash
python -m pip install -e ".[dev,docs,tutorials]"
pytest -m "not network and not energyplus"
ruff check src tests examples docs
python -m sphinx -W --keep-going -b html docs docs/_build/html
```

The [CI workflow](.github/workflows/ci.yml) also checks minimum dependencies,
installed wheels, notebooks, and required EnergyPlus cases. Live provider tests
run separately on the weekly schedule.

## License

[MIT](LICENSE)

## Operation logging

Library calls use Python's standard `logging` module and install no console or
file output. Instrumented operations accept optional keyword-only `log_context`
with small identifier mappings; nested events carry operation and parent IDs.
INFO describes major stages; DEBUG exposes selections, conversions and caches.
Logging context does not change physical models or scientific cache inputs.

For an application using EPSM's coordinated logging setup:

```python
from epsm import configure_logging, reset_logging

configure_logging(directory="outputs/example")  # INFO stderr, DEBUG JSONL
# Run operations here.
configure_logging(enabled=False)  # Stop console and file logging.
reset_logging()  # Restore the host application's settings.
```

EPSM is needed only for this combined configuration, not for ordinary library
logging. Existing scripts can keep using `logging.basicConfig(level=logging.INFO)`.

Migration: `compile_epw()` no longer configures a handler automatically. Select output in the calling application. The standalone CLI still configures stderr; use `--log-level OFF` to silence status.
