Skip to content

Weather API Overview

The weather module provides station search, file downloads, and design day management.

Quick Reference

Class/Function Description
StationIndex Weather station search and filtering
WeatherStation Station metadata container
WeatherDownloader EPW/DDY file downloads
WeatherFiles Downloaded file paths
DesignDayManager Design day parsing and injection
DesignDayType Design day type enumeration
apply_ashrae_sizing() Quick design day application
geocode() Address to coordinates

Module Contents

Weather station search, download, and design day injection.

This sub-package provides tools for:

  • Searching the climate.onebuilding.org TMYx station index by name, coordinates, or metadata filters.
  • Downloading EPW and DDY weather files with local caching.
  • Parsing DDY files and injecting ASHRAE design day conditions into EnergyPlus models.
  • Geocoding addresses to coordinates via the free Nominatim API.

Station Index

The bundled index contains ~55,000 dataset entries representing ~17,300 unique physical weather stations worldwide. The difference is because each station may have multiple TMYx year-range variants (e.g., TMYx.2007-2021, TMYx.2009-2023), each stored as a separate entry with its own download URL.

Quick Start

Search by name:

```python
from idfkit.weather import StationIndex, WeatherDownloader

index = StationIndex.load()  # Instant, no network needed
results = index.search("chicago ohare")
station = results[0].station

downloader = WeatherDownloader()
files = downloader.download(station)
print(files.epw, files.ddy)
```

Search by Address (Splat Pattern)

Combine geocode with nearest using the splat operator to find weather stations near any address:

```python
from idfkit.weather import StationIndex, geocode

index = StationIndex.load()

# Find stations near an address (one line!)
results = index.nearest(*geocode("350 Fifth Avenue, New York, NY"))

for r in results[:3]:
    print(f"{r.station.display_name}: {r.distance_km:.0f} km")

# Output:
# New York La Guardia AP, NY, USA: 10 km
# New York J F Kennedy Intl AP, NY, USA: 18 km
# Newark Liberty Intl AP, NJ, USA: 22 km
```

The geocode function uses the free Nominatim (OpenStreetMap) service, which requires no API key. Requests are rate-limited to 1 per second.

Apply Design Days

Inject ASHRAE sizing design days into your model:

```python
from idfkit import load_idf
from idfkit.weather import StationIndex, apply_ashrae_sizing

model = load_idf("building.idf")
station = StationIndex.load().search("chicago ohare")[0].station

# Apply ASHRAE 90.1 design conditions
added = apply_ashrae_sizing(model, station, standard="90.1")
print(f"Added {len(added)} design days")
```

Index Freshness

StationIndex.load() is purely local and requires no extra dependencies. Use StationIndex.refresh() (requires openpyxl) to re-download the upstream Excel indexes and rebuild the local cache:

```python
if index.check_for_updates():
    index = StationIndex.refresh()  # requires openpyxl
```

NoDesignDaysError

Bases: IdfKitError

Raised when a DDY file contains no SizingPeriod:DesignDay objects.

This typically occurs for weather stations that lack ASHRAE design conditions data in the climate.onebuilding.org database.

Attributes:

Name Type Description
station_name

Display name of the station (if available).

ddy_path

Path to the DDY file that was parsed.

nearby_suggestions

List of nearby stations that may have design days.

DesignDayManager

Parse DDY files and inject design day conditions into IDF models.

A DDY file is a valid IDF-syntax file containing Site:Location and SizingPeriod:DesignDay objects. This class uses [idfkit.load_idf][idfkit.load_idf] to parse the file and classifies each design day by its ASHRAE condition type.

Parameters:

Name Type Description Default
ddy_path Path | str

Path to a .ddy file.

required
version tuple[int, int, int] | None

EnergyPlus version to use for schema resolution. Defaults to the latest supported version (design day fields are stable across versions).

None

all_design_days property

All SizingPeriod:DesignDay objects from the DDY file.

annual property

All classified annual design day objects.

monthly property

All monthly design day objects.

Monthly design days follow the naming pattern {Location} {Month} {pct}% Condns {type} and are not classified into the DesignDayType enum.

heating property

All heating design days.

cooling property

All cooling dry-bulb, wet-bulb, enthalpy, and dehumidification design days.

location property

The Site:Location object from the DDY file, if present.

from_station(station, *, dataset=None, version=None) classmethod

Download the DDY file for a station and parse it.

Parameters:

Name Type Description Default
station WeatherStation

The weather station.

required
dataset str | None

TMYx variant to download. Defaults to the most recent.

None
version tuple[int, int, int] | None

EnergyPlus version for schema resolution.

None

get(dd_type)

Get a specific design day by type.

raise_if_empty()

Raise :exc:NoDesignDaysError if this DDY has no design days.

When constructed via from_station, the error message includes suggestions for nearby stations that may have design day data.

Raises:

Type Description
NoDesignDaysError

If all_design_days is empty.

apply_to_model(model, *, heating='99.6%', cooling='1%', include_wet_bulb=False, include_enthalpy=False, include_dehumidification=False, include_wind=False, update_location=True, replace_existing=True)

Inject design day objects into an IDF model.

Selects the appropriate design days based on common ASHRAE sizing practices and adds them as SizingPeriod:DesignDay objects.

Parameters:

Name Type Description Default
model IDFDocument

The target IDFDocument.

required
heating Literal['99.6%', '99%', 'both']

Which heating percentile to include.

'99.6%'
cooling Literal['0.4%', '1%', '2%', 'all']

Which cooling dry-bulb percentile to include.

'1%'
include_wet_bulb bool

Also include cooling wet-bulb design days.

False
include_enthalpy bool

Also include cooling enthalpy design days.

False
include_dehumidification bool

Also include dehumidification design days.

False
include_wind bool

Also include heating wind-speed design days.

False
update_location bool

Update the Site:Location object to match the DDY file metadata.

True
replace_existing bool

Remove existing SizingPeriod:DesignDay objects before adding new ones.

True

Returns:

Type Description
list[str]

List of design day names that were added.

summary()

Human-readable summary of all design days in the DDY file.

DesignDayType

Bases: Enum

Classification of ASHRAE annual design day conditions.

Values encode the condition type and annual percentile.

WeatherDownloader

Download and cache weather files from climate.onebuilding.org.

Downloaded ZIP archives are extracted and cached locally so that subsequent requests for the same station and dataset are served from disk without a network call.

Examples:

from idfkit.weather import StationIndex, WeatherDownloader

station = StationIndex.load().search("chicago ohare")[0].station
downloader = WeatherDownloader()
files = downloader.download(station)
print(files.epw)

Parameters:

Name Type Description Default
cache_dir Path | None

Override the default cache directory.

None
max_age timedelta | float | None

Maximum age of cached files before re-downloading. Can be a timedelta or a number of seconds. If None (default), cached files never expire.

None
Note

The cache has no size limit. For CI/CD environments with limited disk space, consider using clear_cache periodically or setting a max_age to force re-downloads of stale files.

download(station)

Download and extract weather files for station.

If the files are already cached and not stale, no network request is made.

Parameters:

Name Type Description Default
station WeatherStation

The weather station to download files for.

required

Returns:

Type Description
WeatherFiles

A WeatherFiles with paths to the extracted files.

Raises:

Type Description
RuntimeError

If the download or extraction fails.

get_epw(station)

Download and return the path to the EPW file.

get_ddy(station)

Download and return the path to the DDY file.

clear_cache()

Remove all cached weather files.

This removes the entire files/ subdirectory within the cache, which contains all downloaded ZIP archives and extracted files.

WeatherFiles dataclass

Paths to downloaded and extracted weather files.

Attributes:

Name Type Description
epw Path

Path to the .epw file (always present after extraction).

ddy Path

Path to the .ddy file (always present after extraction).

stat Path | None

Path to the .stat file, or None if not included.

zip_path Path

Path to the original downloaded ZIP archive.

station WeatherStation

The station this download corresponds to.

GeocodingError

Bases: Exception

Raised when an address cannot be geocoded.

StationIndex

Searchable index of weather stations from climate.onebuilding.org.

Use load to load the bundled (or user-refreshed) station index. No network access or openpyxl is required for load.

Use check_for_updates to see if upstream data has changed, and refresh to re-download and rebuild the index.

Examples:

index = StationIndex.load()
results = index.search("chicago ohare", limit=3)
for r in results:
    print(r.station.display_name, r.score)

stations property

All stations in the index.

countries property

Sorted list of unique country codes in the index.

load(*, cache_dir=None) classmethod

Load the station index from a local compressed file.

Checks for a user-refreshed cache first, then falls back to the bundled index shipped with the package. No network access is required.

Parameters:

Name Type Description Default
cache_dir Path | None

Override the default cache directory.

None

from_stations(stations) classmethod

Create an index from an explicit list of stations (useful for tests).

refresh(*, cache_dir=None) classmethod

Re-download Excel indexes from climate.onebuilding.org and rebuild the cache.

Requires openpyxl. Install with pip install idfkit[weather].

Parameters:

Name Type Description Default
cache_dir Path | None

Override the default cache directory.

None

check_for_updates()

Check if upstream Excel files have changed since this index was built.

Sends lightweight HEAD requests to climate.onebuilding.org. Returns True if any file has a newer Last-Modified date. Returns False if all files match or if the check fails (offline, timeout, etc.).

get_by_wmo(wmo)

Look up stations by WMO number.

Parameters:

Name Type Description Default
wmo str

WMO station number as a string (e.g. "722950").

required

Returns a list because a single WMO number can correspond to multiple stations or dataset variants.

search(query, *, limit=10, country=None)

Fuzzy-search stations by name, city, state, or WMO number.

Matching is case-insensitive and uses substring / token-prefix heuristics (no external NLP dependencies).

Parameters:

Name Type Description Default
query str

Free-text search query.

required
limit int

Maximum number of results to return.

10
country str | None

If given, restrict to stations in this country code.

None

nearest(latitude, longitude, *, limit=5, max_distance_km=None, country=None)

Find stations nearest to a geographic coordinate.

Uses the Haversine formula for great-circle distance. A bounding-box pre-filter is applied when max_distance_km is specified to avoid computing distances for stations that are obviously too far.

Parameters:

Name Type Description Default
latitude float

Decimal degrees, north positive.

required
longitude float

Decimal degrees, east positive.

required
limit int

Maximum results to return.

5
max_distance_km float | None

Exclude stations farther than this.

None
country str | None

If given, restrict to this country code.

None

filter(*, country=None, state=None, wmo_region=None)

Filter stations by metadata criteria.

All specified criteria must match (logical AND).

SearchResult dataclass

A text search result with relevance score.

score instance-attribute

Relevance score from 0.0 to 1.0, higher is better.

match_field instance-attribute

Which field matched: "wmo", "name", "state", "country".

SpatialResult dataclass

A spatial proximity result with great-circle distance.

distance_km instance-attribute

Great-circle distance in kilometres.

WeatherStation dataclass

Metadata for a single weather file entry from climate.onebuilding.org.

Each instance represents one downloadable weather dataset. The same physical station may appear multiple times with different source or year-range variants (e.g. TMYx.2007-2021 vs TMYx.2009-2023).

Attributes:

Name Type Description
country str

ISO 3166 country code (e.g. "USA").

state str

State or province abbreviation (e.g. "CA").

city str

City or station name as it appears in the index (e.g. "Marina.Muni.AP").

wmo str

WMO station number as a string to preserve leading zeros (e.g. "722950" or "012345").

source str

Dataset source identifier (e.g. "SRC-TMYx").

latitude float

Decimal degrees, north positive.

longitude float

Decimal degrees, east positive.

timezone float

Hours offset from GMT (e.g. -8.0).

elevation float

Meters above sea level.

url str

Full download URL for the ZIP archive.

display_name property

Human-readable station name with location context.

Dots in the city name are replaced with spaces for readability.

dataset_variant property

Extract the TMYx dataset variant from the download URL.

Returns a string like "TMYx", "TMYx.2007-2021", or "TMYx.2009-2023".

to_dict()

Serialize to a plain dictionary for JSON storage.

from_dict(data) classmethod

Deserialize from a plain dictionary.

apply_ashrae_sizing(model, station, *, standard='general', version=None)

Apply standard ASHRAE sizing design days to a model.

This is the one-line convenience function for the most common use case.

Presets
  • "90.1": Heating 99.6% + Cooling 1% DB + Cooling 1% WB (per ASHRAE Standard 90.1 requirements).
  • "general": Heating 99.6% + Cooling 0.4% DB (conservative general practice).

Parameters:

Name Type Description Default
model IDFDocument

The IDFDocument to modify.

required
station WeatherStation

Weather station whose DDY file to use.

required
standard Literal['90.1', 'general']

ASHRAE preset to apply.

'general'
version tuple[int, int, int] | None

EnergyPlus version for schema resolution.

None

Returns:

Type Description
list[str]

List of design day names that were added.

Raises:

Type Description
NoDesignDaysError

If the station's DDY file contains no design days. The exception includes suggestions for nearby stations that may have design day data.