Skip to main content

led-ticker-calendar

Calendar widget for led-ticker — displays upcoming events from any .ics feed as a rotating agenda, a live next-event countdown, or per-event two-row cards.

calendar — agenda layout: each upcoming event scrolls as its own line; the day + time render in amber and the title in rainbow, with the highlighted "1:1 with Sam" event in amber

calendar — next layout: the single soonest upcoming event shown as one live line, title in rainbow

Prerequisites

  • A working led-ticker install.
  • A public .ics URL (Google Calendar "Secret address in iCal format", iCloud shared calendar link, or an Outlook/Office365 ICS link) — or a local file:// path.

Install

This plugin 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): the plugin is already listed in config/requirements-plugins.example.txt. Copy that to the live file and rebuild:

# in your led-ticker checkout
cp config/requirements-plugins.example.txt config/requirements-plugins.txt
docker compose up -d --build

That example file lists every first-party plugin — trim the live copy to just the ones you want. The calendar line is:

led-ticker-calendar

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

pip install led-ticker-calendar

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

Once installed, the calendar.events widget is available automatically.

What it provides

One widget: type = "calendar.events" — an .ics feed subscriber with three layouts.

Layouts

  • layout = "agenda" (default) — one scrolling line per upcoming event. Two-tone: the time phrase (Tomorrow 3:09 PM ·) renders in time_color; the event title renders in font_color. Events matching highlight appear in highlight_color (both segments, whole-line attention state). Up to max_events events from the next lookahead_days days.
  • layout = "next" — a single live countdown to the soonest event (Standup · in 25m, Standup · now). The countdown phrase ticks down live every display cycle. All-day events today show · today.
  • layout = "two_row" — one card per event: the held top row shows the day + time (Tomorrow 3:09 PM); the scrolling bottom row shows the event title. Supports the top_* per-row knobs below.

The widget is a Container: a background task polls the feed at update_interval; the display loop re-reads feed_stories on every pass so updates surface within one cycle without restarting.

Config

New to led-ticker configs? The first-config tutorial walks through the overall structure. The blocks below show only the calendar-specific keys.

Agenda (default)

[[playlist.section]]
mode = "swap"
content_height = 16
hold_time = 8

[[playlist.section.widget]]
type = "calendar.events"
ics_url = "https://calendar.google.com/calendar/ical/.../basic.ics"
layout = "agenda"
timezone = "America/New_York"
time_format = "12h"
max_events = 5
lookahead_days = 7
highlight = ["1:1", "interview"]
time_color = [0, 200, 255]
font_color = "rainbow"

Two-row cards (bigsign)

The held day+time row can overflow at default_scale = 4 (only 64 logical pixels wide). Drop to scale = 2 to give each row more room, and use a smaller font:

[[playlist.section]]
mode = "swap"
scale = 2
content_height = 24
hold_time = 10

[[playlist.section.widget]]
type = "calendar.events"
ics_url = "https://calendar.google.com/calendar/ical/.../basic.ics"
layout = "two_row"
timezone = "America/New_York"
time_format = "12h"
max_events = 5
font = "Inter-Regular"
font_size = 16
font_threshold = 80
time_color = [255, 200, 60]
font_color = [255, 255, 255]
highlight = ["1:1", "interview"]

Next (live countdown)

[[playlist.section]]
mode = "swap"
content_height = 16
hold_time = 20

[[playlist.section.widget]]
type = "calendar.events"
ics_url = "https://calendar.google.com/calendar/ical/.../basic.ics"
layout = "next"
timezone = "America/New_York"
font_color = [255, 255, 255]
time_color = "rainbow"
empty_text = "No upcoming events"

Field reference

ics_url is the only required field — everything below is optional tuning.

Option Type Default Description
ics_url string required Public .ics URL (e.g. Google Calendar "Secret address in iCal format"), webcal:// link (auto-rewritten to https://), or a file:// path for a local file (e.g. "file:///home/pi/cal.ics").
layout string "agenda" "agenda" — rotating event lines; "next" — live countdown to the soonest event; "two_row" — per-event card (held day+time on top, scrolling title below).
max_events int 5 Maximum upcoming events to display in agenda and two_row modes. 0 means no cap.
lookahead_days int 7 Days ahead to scan for events. Recurrence rules are expanded within this window (max 366).
time_format string "12h" "12h"3:00 PM; "24h"15:00; or any strftime template string (e.g. "%H:%M").
timezone string system local IANA timezone name for display (e.g. "America/New_York"). Defaults to the system local timezone.
empty_text string "No upcoming events" Text shown when the feed loads but has no events in the lookahead window.
error_text string "Calendar unavailable" Text shown when the feed fails to load on the first attempt. Subsequent transient failures keep the last-good events instead.
filter list of strings [] Keep only events whose summary contains any of these keywords (case-insensitive). Empty = all events.
highlight list of strings [] Events matching any keyword render in highlight_color and are guaranteed to appear even if max_events would otherwise drop them.
highlight_color RGB / string / table amber [255, 200, 60] Color for highlighted events (both the time phrase and title segments). Constant [r,g,b], "rainbow", "color_cycle", "random", or {style="gradient", from=[...], to=[...]}.
font_color RGB / string / table white [255, 255, 255] Color for the event title on non-highlighted lines. Same provider forms as highlight_color.
time_color RGB / string / table amber [255, 200, 60] Color for the time / relative phrase on non-highlighted lines (e.g. Tomorrow 3:00 PM · in agenda, · in 5m in next). Set both font_color and time_color to the same value for a single-color line.
bg_color RGB list none Background fill painted across the full panel before text.
border string / table none Perimeter border ring — "rainbow", "color_cycle", "lightbulbs", [r,g,b], or an inline table.
padding int 6 Horizontal padding (logical pixels) appended to each event line when scrolling.
font string "6x12" BDF font (e.g. "5x8", "6x12") or hires font (e.g. "Inter-Bold"). In two_row mode the widget automatically substitutes "5x8" when the configured font is the default "6x12" (too tall for a split row); pick a fitting font/font_size for hires text.
font_size int none Point size; required for a hires (TTF/OTF) font.
font_threshold int 128 Hires anti-alias threshold (0–255); 80 suits Inter Regular.
update_interval int 900 Seconds between feed fetches (default 15 minutes).
top_row_height int half the canvas two_row only. Logical rows for the held top (day+time) band. The bottom (title) row takes the rest — must be less than the section's content_height. Omit for a 50/50 split.
top_text_y_offset int 0 two_row only. Vertical nudge (logical pixels) for the top row's text.
bottom_text_y_offset int 0 two_row only. Vertical nudge (logical pixels) for the bottom row's text.

top_row_height, top_text_y_offset, and bottom_text_y_offset apply only with layout = "two_row" — they are silently ignored under other layouts.

Development

led-ticker isn't on PyPI, so this plugin resolves it from a sibling checkout. Clone both side by side:

~/projects/.../led-ticker
~/projects/.../led-ticker-calendar
uv sync --extra dev      # resolves led-ticker from ../led-ticker
uv run pytest -q
uv run ruff check src tests

Tests that need a headless canvas obtain one via HeadlessBackend(...).create_canvas() from led_ticker.plugin (the shipped headless backend in led-ticker-core ≥ 2.1) — no rgbmatrix stub or PYTHONPATH plumbing required.

The plugin imports only the public led_ticker.plugin surface — tests/test_import_purity.py enforces it.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

led_ticker_calendar-0.1.1.tar.gz (132.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

led_ticker_calendar-0.1.1-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

Details for the file led_ticker_calendar-0.1.1.tar.gz.

File metadata

  • Download URL: led_ticker_calendar-0.1.1.tar.gz
  • Upload date:
  • Size: 132.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for led_ticker_calendar-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e0028b39ee511ac20088bb9262751c53a12ff6593084d6a1687e905d3bee8831
MD5 b44b580ebd31b7514e006b3a64e64b9c
BLAKE2b-256 7bbd7f250f44ca9d9a29d43f19cade5cd489abba001dabdae9732d065eeecf42

See more details on using hashes here.

Provenance

The following attestation bundles were made for led_ticker_calendar-0.1.1.tar.gz:

Publisher: publish.yml on JamesAwesome/led-ticker-plugins

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file led_ticker_calendar-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for led_ticker_calendar-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 97f7861fb3f350bf1bba7c23a7964fbc0383bad470126e8d0a86b04364daf6cb
MD5 70ebab3faeaf54f5926597057177de4d
BLAKE2b-256 1d73cbbd17de9feda84435e4c83299600376431546348bfab8f36a05d2337407

See more details on using hashes here.

Provenance

The following attestation bundles were made for led_ticker_calendar-0.1.1-py3-none-any.whl:

Publisher: publish.yml on JamesAwesome/led-ticker-plugins

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 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