Skip to main content

led-ticker-weather

A weather plugin for led-ticker, backed by WeatherAPI.com. It contributes two widgets: weather.current (location label, current temperature, and a condition icon) and weather.forecast (a held multi-day forecast card).

This package split out of led-ticker-feeds (its feeds.weather widget); the type is now weather.current.

Prerequisites

  • A working led-ticker install.
  • A free WeatherAPI.com API key, exported as WEATHERAPI_KEY.
  • Internet access on the Pi (the widget calls the WeatherAPI.com API).

Install

The widget auto-registers via the led_ticker.plugins entry point — once the package is installed, no [plugins] config change is needed.

Into a containerized led-ticker (recommended): add this package to config/requirements-plugins.txt (copy it from config/requirements-plugins.example.txt), then rebuild:

led-ticker-weather
# in your led-ticker checkout
docker compose up -d --build

Standalone (a venv that already has led-ticker):

pip install led-ticker-weather

See the led-ticker Plugins docs for the constraint-based install the Docker image uses.

Configuration

Set the API key in your .env:

WEATHERAPI_KEY=your-key-here

Then add the widget:

[[playlist.section]]
[[playlist.section.widget]]
type = "weather.current"
location = "London"

The widget polls WeatherAPI.com in the background and renders the label, temperature, and a condition icon. Conditions map to icon slugs via _match_condition (sun / cloud / rain / snow / thunder / fog).

weather.forecast

A held multi-day forecast card. Layout is auto-detected per sign: smallsign (scale 1) shows a 3-day strip (today + 2 more); bigsign (scale > 1, physical width < 400px) shows a today hero next to a 4-day strip; longboi (scale > 1, physical width >= 400px) shows an expanded hero next to a 6-day strip with precipitation percentages.

[[playlist.section]]
[[playlist.section.widget]]
type = "weather.forecast"
location = "Boston, MA"

Configuration

Option Type Default Description
location string or {lat = ..., lon = ...} required (unless demo = true) Same location forms as weather.current: name / zip / "lat,lon" / a {lat=…, lon=…} table.
layout string "auto" "auto" | "strip" | "big" | "long". auto picks by sign shape (see above). An explicit "long" on a panel narrower than 400px degrades to "big"; an explicit "big" or "long" on a scale-1 sign renders as "strip" — hi-res is impossible there (led-ticker validate warns in both cases).
units string "imperial" "imperial" | "metric".
update_interval int (seconds) 10800 How often the widget re-polls WeatherAPI.com (3 hours by default — forecasts don't need current-conditions cadence).
demo bool false Render a fixed sample week (BOSTON) instead of calling the network — no API key or location needed. Useful for previews.
demo_days int 0 Demo-only: truncate the fixed sample week to this many strip days (0 = full 6-day week) so a config can preview a short feed — the strip justifying fewer days across the panel — without a live key. Ignored unless demo = true.

Requirements

Same WEATHERAPI_KEY env var as weather.current (see Prerequisites above). The widget calls /v1/forecast.json?days=7. Free-tier WeatherAPI.com keys only return 3 forecast days; the widget degrades gracefully — it renders however many days the feed actually provides and widens the strip columns to fill the available space (a 3-day key on longboi shows the hero next to a 2-day strip instead of 6).

Divergences from the design handoff

The normative visual spec lives at design/ (design/README.md + the .dc.html prototype). This widget faithfully reproduces its layouts and palette, with six deliberate divergences:

  • Condition icons are the packaged emoji, not the handoff's procedural glyphs. smallsign strips always draw the curated 8x8 weather sprite; bigsign/longboi strips and the hero slot both draw the hero's HIRES/32x32 sprite (box-downscaled to the strip's icon size on the strip, native on the hero) — this upgrades two hero-only distinctions (overcast, patchy rain) to standard-pack sprites the curated set can't draw on its own, and gives every hi-res sign the same icon language in the hero and the strip. Icon boxes snap to sprite sizes (8/16/24/32px) rather than the handoff's 14/18/22/30/40px boxes, so partly-cloudy-at-night is still approximated (partly_cloudy lowres on smallsign, a plain moon elsewhere).
  • Hi-res strip icons are downscaled from the 32x32 hires sprite, not upscaled from the 8x8 lowres one. An earlier iteration integer-upscaled the curated 8x8 sprite (k=2 bigsign, k=3 longboi); a later pass switched to box-area-downscaling the same hires source the hero uses, for crisper edges and a consistent icon per condition across hero and strip.
  • Small hi-res text (day labels, hi/lo, precip %, FEELS) is the bundled spleen-6x12 pixel font, not Inter. An earlier iteration used Inter/freetype at every text size; spleen reads more crisply at small sizes on the panel and is deterministic (no freetype cross-platform variance) — so this text is now exact-pinned in tests, unlike the big hero temperature and location label, which stay Inter.
  • smallsign text uses the nearest bundled BDF font (5x8), not the handoff's Silkscreen px7 — metrics may differ by up to a row.
  • No °F/°C runtime toggle or GLOW control. Those were prototype chrome; units come from the units config field, and glow is a property of the physical hardware, not something the widget can render.
  • No 15 FPS re-render loop. The card is static per data update and follows the engine's normal held-card cadence — there's nothing to animate between polls.

Weather value token (:id: in any widget's text)

Besides the weather.current widget, this plugin registers a weather.current source — a live value you embed in another widget's text with a :id: token.

[[source]]
id = "weather.nyc"
type = "weather.current"
location = "New York, US"          # name / zip / "lat,lon" / {lat=…, lon=…}
interval = 1800                    # seconds; how often to refresh
format = "{temp_f}°F {condition}"  # optional; this is the default
# placeholder = "…"                # optional; shown until the first fetch

Then reference it anywhere text is drawn:

[[playlist.section]]
[[playlist.section.widget]]
type = "message"
text = "NYC: :weather.nyc:"        # -> "NYC: 72°F Clear", updating live

WEATHERAPI_KEY comes from your .env (never config). Available format fields (current conditions): temp_f, temp_c, condition, feelslike_f, feelslike_c, humidity, wind_mph, and emoji. The emoji field expands to a condition icon — format = "{temp_f}° {emoji}" → 72° ☀. The source polls on its own interval, independently of the weather.current widget.

A full bigsign example that exercises the token (default format, the {emoji} sprite, feels-like/humidity fields, and a resilience check) lives at config/config.weather_smoketest.bigsign.toml — edit the location fields and copy it to your config.toml.

Development

This package lives in the led-ticker-plugins monorepo. Run tooling from the repo root:

uv sync --extra dev
uv run pytest plugins/weather
uv run ruff check plugins/weather

Metadata

Release files for led-ticker-weather 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for led-ticker-weather 0.4.1
File Size Uploaded
led_ticker_weather-0.4.1.tar.gz 138.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for led-ticker-weather 0.4.1
File Interpreter ABI Platform
led_ticker_weather-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 166.3 kB

Release files / led_ticker_weather-0.4.1.tar.gz

Download URL led_ticker_weather-0.4.1.tar.gz
Size 138.7 kB
Tags Source
SHA-256 checksum
How to use checksums
39c615744dfa0c1e30bb5e9f2da7448e0d5463913a0e9807977d017ebcb6d8af
BLAKE2b-256 checksum
How to use checksums
a78a38311b0307995a11b460e738830d25b82e9e90895da8414ce127648f5b55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / led_ticker_weather-0.4.1-py3-none-any.whl

Download URL led_ticker_weather-0.4.1-py3-none-any.whl
Size 27.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f976e1d59e187cd13f7eb535445e094b6b48a4c02806c70f1622600236377f5b
BLAKE2b-256 checksum
How to use checksums
9885b10b54cd94f009b462ced700a66455bf888c7c4219a1803c23b45f4d16fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page