A full-screen weather dashboard for a Windows PC / Raspberry Pi kiosk. Search any city and the whole display — forecast, map, radar, alerts — recenters on it. The map fills the window (full-bleed) and two panels float on top as glass overlays:
- Left card — current conditions for the selected location: big temperature + live condition icon, a compact hourly temperature strip, three info tiles (sun arc · humidity · wind), and an upcoming-days outlook.
- Map (full window) — a dark basemap with live RainViewer radar, NHC tropical disturbances / storm tracks (all basins: Atlantic + E/Central Pacific), and real-time Blitzortung lightning.
- Alert ticker — a strip floating bottom-right that stays quiet (just a clock) until there are active NWS warnings or NHC tropical text, then scrolls them in a severity colour.
The whole look (left card, tiles, ticker, map surround) switches automatically between day / night / rain palettes chosen from the current weather.
pip install -r requirements.txt
python run.pyNo API keys required. Weather comes from Open-Meteo and the basemap from CARTO — both free and keyless. Just install and run.
(Optional) For satellite imagery instead of the dark vector base, set
BASEMAP_SOURCE = "mapbox_sat" in weather_kiosk/config.py and add a Mapbox
token: copy weather_kiosk/secrets_local.example.py to
weather_kiosk/secrets_local.py and paste your pk. token (or set the
MAPBOX_TOKEN env var). secrets_local.py is git-ignored.
| Key | Action |
|---|---|
Ctrl+K / Ctrl+F |
Open city search — type a place, Enter to search, ↑↓ + Enter to pick |
Ctrl+↑ / Ctrl+↓ |
Zoom the map in / out (recenters on the current location) |
Esc |
Close the search overlay, or quit |
F / F11 |
Toggle fullscreen |
L |
Toggle the 16:9 aspect lock |
M |
Cycle the theme (auto → day → night → rain) |
The last location and zoom are saved to user_settings.json (git-ignored) and
restored on the next launch. In windowed mode, drag the window edge to resize (it
stays 16:9).
CLI flags: --fullscreen, --no-nhc, --no-radar, --no-lightning,
--no-alerts. (On a Raspberry Pi the app auto-detects and starts fullscreen.)
run.py Launcher (writes crash_log.txt on startup failure)
weather_kiosk/ Application package
├── __main__.py Entry point; starts Qt + the 6 data daemon threads
├── config.py Tunables: default location, map source, zoom, toggles, timing, palettes
├── secrets_local.py Optional Mapbox token (git-ignored; see secrets_local.example.py)
├── geo.py Web Mercator projection — the shared transform every layer uses
├── state.py Thread-safe shared state + Qt signals (active location, epoch)
├── settings.py Persist/restore the last location + zoom (user_settings.json)
├── fonts.py Registers the bundled Inter Display font (SIL OFL) with Qt
├── data/ Background data feeds (one daemon thread each)
│ ├── basemap.py CARTO Dark Matter (or Mapbox/ESRI) -> stitched/cached basemap
│ ├── radar.py RainViewer tiles -> stitched/cropped radar frames
│ ├── nhc.py NHC ArcGIS tropical outlook areas / storms / tracks (all basins)
│ ├── weather.py Open-Meteo (current + hourly + daily; native WMO codes)
│ ├── geocode.py Open-Meteo city search (keyless) for the search overlay
│ ├── lightning.py Blitzortung WebSocket strike feed
│ ├── alerts.py NWS active alerts + NHC tropical text (AT/EP/CP) for the ticker
│ └── tiles.py Shared Web Mercator tile fetch + stitch + crop
└── ui/ Qt widgets (all QPainter — no matplotlib)
├── main_window.py Full-bleed _Stage: map fills the window, card + ticker float on top
├── map_panel.py Layered Qt map: basemap + radar + NHC + lightning + marker
├── search_overlay.py City-search panel (Ctrl+K)
├── conditions_panel.py Current-conditions card (temp, icon, stat line)
├── hourly_chart.py Compact hourly temperature strip
├── info_tiles.py Sun-arc / humidity / wind tiles
├── forecast.py Upcoming-days outlook rows
├── alert_ticker.py Quiet/active alert marquee
├── theme.py day / night / rain palettes (single source of truth)
├── glass.py Cross-platform frosted-glass panel treatment
└── rounded.py Shared rounded-card mask helper
assets/ Runtime assets the app loads (weather icons, NHC symbols, font)
cache/ Generated basemap PNGs (git-ignored; re-fetched)
docs/PROJECT_NOTES.md How this build came to be + architecture decisions
Tunables live in weather_kiosk/config.py:
- Default location:
WX_LAT,WX_LON,WX_CITY(where the kiosk opens before any search; overridden by a saveduser_settings.json) - Basemap:
BASEMAP_SOURCE("carto_dark"·"mapbox_sat"·"esri_dark") - Map zoom:
MAP_SPAN_DEG(degrees across the map when you search a place),MAP_SPAN_MIN/MAP_SPAN_MAX(Ctrl+↑/↓ zoom limits) - Feature toggles:
ENABLE_NHC_TRACKER,ENABLE_RADAR,ENABLE_LIGHTNING,ENABLE_ALERTS,ENABLE_HOME_MARKER - Radar:
RADAR_ZOOM,RADAR_ALPHA,RADAR_FRAME_DWELL,RADAR_ANIM_FRAMES - Lightning feel:
LIGHTNING_HOLD_SECS(full-brightness hold) thenLIGHTNING_FADE_SECS(fade-out) - Glass / layout:
GLASS_*,SPLIT_LEFT_FRAC,STAGE_MARGIN,TICKER_H_FRAC
Every layer is Web Mercator and goes through the single transform in
geo.py, so the basemap, radar tiles, NHC overlays, and lightning all line up
with zero reprojection — composited by Qt's QPainter. See
docs/PROJECT_NOTES.md.
- Weather & geocoding: Open-Meteo (CC-BY 4.0)
- Basemap: CARTO Dark Matter — © OpenStreetMap contributors, © CARTO (or Mapbox / Esri if selected)
- Radar: RainViewer · Lightning: Blitzortung.org · Tropical: NOAA/NHC · Alerts: NWS / api.weather.gov
- UI font: Inter Display by Rasmus Andersson (SIL Open Font License; see
assets/fonts/Inter-LICENSE.txt)
This project's own code is released under the MIT License — see
LICENSE. Bundled third-party assets retain their own upstream
licenses (e.g. Inter under the SIL OFL, the weather icon set under its own
terms); the MIT license covers this project's source, not those assets.
