A native Home Assistant integration for the world's ski resorts, anchored on OpenSkiMap — the open, OpenStreetMap-derived ski database. Search ~6,000 ski areas, add one as a device, and get a real weather entity, snow forecast, terrain metadata, and optional live lift status — no API key required to get started.
Everything is polled locally and exposed as first-class HA entities, so you can build dashboards and automations ("Vail powder day tomorrow", "the mountain just opened") from open data.
Unofficial. Not affiliated with any resort. It combines open data from OpenSkiMap (OpenStreetMap + Skimap.org), Open-Meteo, and Liftie.
- Search by name, no key needed. Setup searches a bundled OpenSkiMap index (~6,000 downhill areas); pick your resort and you're done. Weather comes from the free Open-Meteo service — no account, no key.
- A real weather entity per resort — current conditions + a 7-day forecast, from Open-Meteo at the resort's exact coordinates.
- Snow sensors — fresh snowfall (next 24h), snow depth, freezing level, plus temperature and wind.
- Terrain metadata (from OpenSkiMap, offline) — lift count (by type), run count (by difficulty), vertical drop, summit & base elevation, snowmaking.
- Live lift status (optional) — Lifts open, % open (against OpenSkiMap's authoritative total), and a Resort open binary sensor, from a self-hosted Liftie instance or the RapidAPI ski-resorts-and-conditions product. The Liftie slug is auto-mapped from your chosen ski area.
- Powder day binary sensor.
- Trail map (open data) — the skimap.org trail map as an HA image entity, plus a resort-info diagnostic sensor with links and facts.
- Canonical IDs. Every resort is keyed by its OpenSkiMap id, so entities are stable and consistent with the wider open-ski-data ecosystem.
| Source | Used for | License |
|---|---|---|
| OpenSkiMap (OpenStreetMap + Skimap.org) | Resort identity, geography, terrain metadata | ODbL |
| Open-Meteo | Weather + snow forecast | CC-BY 4.0 |
| Liftie | Live lift status (self-hosted) | BSD-3 |
| NWS (api.weather.gov) | Weather alerts (US, optional) | US public domain |
| avalanche.org | Avalanche danger rating (US, optional) | free (gov/nonprofit) |
| Avalanche Canada | Avalanche danger rating (Canada, optional) | free |
| RapidAPI ski-resorts-and-conditions / ski-resort-forecast | Optional lift status / snow-forecast | proprietary |
The bundled index and Liftie crosswalk are derived data under ODbL/BSD; see
custom_components/ski_resort/data/NOTICE.md.
- Add this repository as a custom repository (category: Integration):
https://github.com/yieldhog/ski-resort-ha. - Install Ski Resort and restart Home Assistant.
Copy custom_components/ski_resort into config/custom_components/ and restart.
Settings → Devices & Services → Add Integration → Ski Resort.
- Search for your resort by name (optionally filter by country).
- Pick the matching OpenSkiMap ski area.
That's it — the weather entity, snow sensors, and terrain sensors appear with no key. The Liftie slug is filled in automatically when known.
Configure on the integration exposes:
- Update interval and units (imperial/metric).
- NWS weather alerts (US) — on by default for US resorts (free, keyless;
turn off under Configure, and never fetched for non-US resorts). Adds a
Weather alert sensor whose state is the active alert's event name (e.g.
Flood Watch, orNonewhen clear) with the headline, description, and instruction as attributes, plus a Weather alert active binary sensor for automations. When several alerts are active the most significant is surfaced first. - Avalanche danger (US & Canada) — opt-in; adds an Avalanche danger sensor with the danger rating for the resort's forecast zone (level, zone, travel advice, expiry, and forecast link as attributes). Keyless. The source is chosen by the resort's country — avalanche.org in the US, Avalanche Canada in Canada. Europe isn't covered yet; resorts outside a forecast zone won't report.
- Lift slug — auto-filled; override if the auto-map missed.
- Self-hosted Liftie base URL — the host and port only (e.g.
http://homeassistant.local:3000), not the/api/resort/...path. If set, lift status comes from your free Liftie instance. See Self-hosted lift status below. - RapidAPI key — enables the RapidAPI snow-forecast, and skiapi lift status
only as a fallback. A self-hosted Liftie URL always wins for lifts — with
both set, lifts come from Liftie and the key is used solely for the
snow-forecast (no RapidAPI quota spent on lifts). The
lifts_opensensor'ssourceattribute (liftie/skiapi) shows which is in use. - RapidAPI snow-forecast resort name — adds reported base/summit depth etc.
- RapidAPI snow refresh interval (hours) — polls the metered snow-forecast source on its own slow cadence (default 12h, independent of the main update interval) so a bring-your-own key stays inside free-tier quotas; the last reading is kept between refreshes.
- Webcam image URL — a direct still-image link to a resort webcam, shown as an
imageentity. You can also paste an OpenSnow cam page URL (opensnow.com/location/.../cams/ID) and it's converted automatically. Some resorts block hotlinking.
Lift status is optional. liftie.info's public API is Cloudflare-protected against server-side calls, so live lifts need either a self-hosted Liftie or a RapidAPI key (skiapi is the same Liftie data). Everything else works without either.
For live lift open/closed counts with no API key and no request quota, run Liftie on your own network. The easiest way is the companion Home Assistant add-on:
- In Home Assistant: Settings → Add-ons → Add-on Store → ⋮ → Repositories,
add
https://github.com/yieldhog/hass-liftie-addon, then install and start Liftie. (Add-ons require Home Assistant OS or Supervised.) - In this integration's Configure:
- Liftie base URL → the add-on's host and port, e.g.
http://homeassistant.local:3000(or your host's IP) — not the/api/resort/...path. - Lift slug → your resort (e.g.
vail); usually auto-filled.
- Liftie base URL → the add-on's host and port, e.g.
- Leave the RapidAPI key blank — when a Liftie base URL is set, it wins.
The add-on lets you limit which resorts it tracks, tune scrape frequency, and it opens an automatic PR when upstream Liftie updates. See its docs.
| Entity | Platform | Source |
|---|---|---|
| Weather (current + daily forecast) | weather | Open-Meteo |
| Fresh snowfall (24h) · Precipitation (24h) · Snow depth · Freezing level · Temperature · Feels like · Wind | sensor | Open-Meteo |
Snow forecast (5-day total; per-day snowfall in the daily attribute) |
sensor | Open-Meteo |
| Lifts · Runs · Vertical drop · Summit / Base elevation | sensor | OpenSkiMap |
| Lifts open · % open | sensor | Liftie/skiapi (optional) |
| Reported summit/base depth · fresh snow · last snowfall date | sensor | RapidAPI (optional) |
| Resort information (status + links/facts) | sensor (diagnostic) | OpenSkiMap + Wikidata |
| Trail map | image | skimap.org |
| Webcam | image | your resort webcam URL (optional) |
| Avalanche danger (rating + zone/advice/expiry) | sensor | avalanche.org / Avalanche Canada (optional, US & CA) |
| Weather alert (event name; headline/description/instruction as attributes) | sensor | NWS (optional, US) |
| Powder day | binary_sensor | Open-Meteo |
| Resort open | binary_sensor | Liftie/skiapi (optional) |
| Weather alert active (any NWS alert in effect) | binary_sensor | NWS (optional, US) |
The integration polls on a fixed interval (default 3 hours, minimum 60 minutes — set it under Configure). Weather/snow come from Open-Meteo; live lift status from Liftie/skiapi when configured; terrain metadata is bundled and never fetched. Each source updates independently — if one is down, the others still refresh. Static enrichment (trail map, website, opening year) is fetched once and cached.
- Lift status needs a source. liftie.info's public API blocks server-side calls, so live lifts require a self-hosted Liftie or a RapidAPI key. Without either, the lift/resort-open entities are simply absent.
- Off-season shows 0 open. Correctly reflects reality — Liftie reports lifts
as
scheduled/closedoutside the season. - Lift total vs. open source. The lift total comes from OpenSkiMap (authoritative); open count comes from Liftie, so the two can occasionally disagree (e.g. a resort adds a lift OpenSkiMap hasn't mapped yet).
- RapidAPI is metered. The optional RapidAPI sources have request quotas; the self-hosted Liftie add-on avoids this entirely.
- Bundled resort index. Search covers the resorts in the bundled OpenSkiMap snapshot; regenerate it (below) to pick up newly added areas.
- Lift sensors are
unavailable. Check two things under Configure: (1) the Lift slug is set (e.g.vail), and (2) the Liftie base URL is the host and port only (e.g.http://homeassistant.local:3000) — a full.../api/resort/<slug>URL produces a doubled path and a 404. Then look at Settings → System → Logs for aski_resortline naming the cause. - Weather is missing. Open-Meteo is keyless and global; a transient failure clears on the next poll. Persistent failure usually means outbound HTTPS is blocked on the HA host.
- Fresh snowfall is near zero but it's clearly wet out. That's rain, not a
bug. Compare the Precipitation (24h) sensor (liquid) with Fresh snowfall
(24h) and the Freezing level: when the freezing level is above the
resort, the moisture falls as rain and snowfall stays ~0. The 5-day Snow
forecast sensor's
dailyattribute lists snow and precipitation per day for the same reason. - RapidAPI source
unavailable. The log will sayrate or quota limit reached (429)when the plan's quota is spent — switch to the self-hosted Liftie add-on, or wait for the quota to reset. - Webcam not showing. Confirm the URL returns an image directly (some resorts block hotlinking). OpenSnow cam page URLs are auto-converted.
type: entities
title: Vail
entities:
- entity: weather.vail_weather
- entity: sensor.vail_fresh_snowfall_24h
- entity: sensor.vail_snow_depth
- entity: sensor.vail_snow_forecast_5_day # state = 5-day total; `daily` attr = per-day
- entity: sensor.vail_lifts_open
- entity: binary_sensor.vail_powder_day
- entity: binary_sensor.vail_resort_open
- entity: image.vail_trail_mapSettings → Devices & Services → Ski Resort → ⋮ → Delete removes the config entry and all its entities. Then remove the repository from HACS. (The self-hosted Liftie add-on, if installed, is uninstalled separately from the add-on store.)
The integration is held to Home Assistant's Integration Quality Scale — Bronze,
Silver, and Gold complete, and it meets the Platinum strict-typing bar (mypy --strict in CI). See docs/quality-scale.md for the
full checklist.
The OpenSkiMap index and Liftie crosswalk are regenerated by a script (run it periodically to pick up new resorts):
python3 scripts/build_ski_area_index.py /path/to/liftie/checkoutpython3.13 -m venv .venv
.venv/bin/pip install -r requirements_test.txt
.venv/bin/python -m pytest -qCI runs hassfest, the HACS action, ruff, mypy (strict), and pytest with coverage.
Integration code: MIT. Bundled data retains its upstream licenses (see above).