Skip to content

Latest commit

 

History

History
143 lines (109 loc) · 5.59 KB

File metadata and controls

143 lines (109 loc) · 5.59 KB

GitHub Contribution LED Matrix

Your GitHub contribution heatmap, live on a physical WS2812B LED matrix.

runtime language controller tests

Fetches the last 16 weeks of your GitHub contributions and paints them onto a 16×8 WS2812B LED matrix driven by a WLED controller (Gledopto GL-C-618WL). Runs on a Windows laptop, refreshes hourly.

Features

  • Faithful heatmap — 16 weeks × 7 weekday rows, GitHub's green intensity ramp.
  • Exact intensity buckets — pulled from GitHub's GraphQL API (levels 0–4), not scraped.
  • Fail-safe — never blanks or half-writes the panel; on any error it keeps the last frame.
  • Power-cycle safe — turns the panel on and sets pixels in separate requests, so a rebooted controller shows the correct frame on the very next run.
  • No serpentine math — WLED's built-in 2D matrix mapping handles physical wiring.
  • Fully tested — pure core + dependency-injected I/O, 29 unit tests, zero live calls in CI.

Layout

16 columns wide, 8 rows tall. Newest week on the right; bottom row always dark.

 week ->  oldest ................................ newest
        ┌───────────────────────────────────────────────┐
 Sun    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=0
 Mon    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=1
 Tue    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=2
 Wed    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=3
 Thu    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=4
 Fri    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=5
 Sat    │ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪               │  y=6
 (off)  │ · · · · · · · · · · · · · · · ·               │  y=7  always dark
        └───────────────────────────────────────────────┘
          x=0                                       x=15

Intensity ramp (GitHub dark palette; level 0 fully off):

Level Color (r,g,b)
0 off (0,0,0)
1 (14,68,41)
2 (0,109,50)
3 (38,166,65)
4 (57,211,83)

How it works

Windows Task Scheduler (hourly)
        │
        ▼
   bun run start
        │
        ├─ github.ts  ── GraphQL ─▶ daily contribution levels (0–4)
        ├─ grid.ts    ── pure ────▶ 128-pixel RGB frame (16×8, bottom row off)
        └─ wled.ts    ── HTTP ────▶ POST on/bri, then POST pixels  →  WLED
                                     (3× retry on failure)
Module Responsibility
src/github.ts Fetch + parse the contribution calendar via GitHub GraphQL
src/grid.ts Pure transform: levels → 128-entry row-major RGB frame
src/wled.ts Build payloads + push to WLED /json/state with retry
src/ramp.ts Level → RGB color lookup
src/index.ts Config, wiring, top-level error handling

Prerequisites

  • Bun installed on Windows.
  • WLED controller with the 2D matrix already configured as 16×8 (correct serpentine + orientation) and reachable on your LAN.
  • A GitHub personal access token with read:user scope.

Setup

bun install
copy .env.example .env    # macOS/Linux: cp .env.example .env

Edit .env:

GITHUB_TOKEN=ghp_xxx        # personal access token, read:user scope
GITHUB_USERNAME=your_username
WLED_HOST=192.168.1.50      # your controller's LAN IP
WLED_BRIGHTNESS=128         # optional, 0–255, default 128

Run once:

bun run start

Expected: a log line like Pushed 128 pixels to 192.168.1.50, and the matrix lights up.

Test

bun test

Schedule hourly on Windows

Create a scheduled task that runs every hour. In an Administrator PowerShell, adjust the paths and run:

$bun = "$env:USERPROFILE\.bun\bin\bun.exe"
$proj = "C:\path\to\github-contribution-led"
$action = New-ScheduledTaskAction -Execute $bun -Argument "run start" -WorkingDirectory $proj
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
  -RepetitionInterval (New-TimeSpan -Hours 1)
Register-ScheduledTask -TaskName "github-led" -Action $action -Trigger $trigger `
  -Description "Refresh GitHub contribution LED matrix hourly"

Missed runs (laptop asleep/off/off-LAN) are simply picked up on the next run; the panel keeps its last frame in the meantime.

Behavior on errors

  • GitHub fetch fails → logs, exits non-zero, panel untouched (keeps last frame).
  • WLED unreachable → retries 3× (2s apart), then logs and exits; panel keeps last frame.

Tuning

  • BrightnessWLED_BRIGHTNESS (0–255) is WLED's master brightness, independent of the color ramp.
  • Colors — edit the RAMP table in src/ramp.ts to change the palette or intensity buckets.
  • Empty row — the bottom row (y=7) is reserved dark; it's a natural spot for a future status strip.

License

MIT