• v0.9.0 838c95484d

    LedGrab v0.9.0
    Build Release / create-release (push) Successful in 4s
    Build Android APK / build-android (push) Failing after 22s
    Build Release / build-linux (push) Successful in 2m54s
    Build Release / build-windows (push) Successful in 4m50s
    Build Release / build-docker (push) Successful in 6m34s
    Build Release / publish-release (push) Successful in 4s
    Stable

    alexei.dolgolyov released this 2026-06-23 14:48:51 +03:00 | 0 commits to master since this release

    v0.9.0 (2026-06-23)

    A large feature release: a full activity/audit log, two roadmap batches of
    capture and smart-light improvements, per-pixel control for LIFX/Hue/Nanoleaf,
    and new outbound integrations (webhooks + Home Assistant MQTT discovery).

    Features

    Activity Log

    • Persistent activity/audit log: storage model with migration, recorder with
      actor context and retention, and event instrumentation across four
      categories (1ac4a0f, 726f39e, 25c613c)
    • REST API for list / export / settings / clear (4a09275)
    • Activity tab with smart filtering, live updates, and export, plus a
      dashboard widget and settings panel (9a0137f, 6e1dd21)

    Per-pixel smart lights

    • LIFX multizone (SetExtendedColorZones) and Tile per-pixel streaming,
      auto-detected on connect with single-colour fallback (39b0554)
    • Philips Hue gradient-lightstrip mapping: Entertainment v2 frames keyed by
      channel id, with a hue_gradient_mode toggle (39b0554)
    • Nanoleaf extControl v2 per-panel UDP streaming (per_panel mode) (6745e25)

    Capture & effects

    • Linear-light blending and spatio-temporal dithering, opt-in per calibration (6745e25)
    • Audio-reactive palette modulation across all 12 procedural effects (6745e25)
    • Color-harmony gradient generator (complementary / analogous / triadic / …) (6745e25)

    Automations & integrations

    • Solar sunrise/sunset automation trigger (new utils/solar.py) (6745e25)
    • Outbound webhook automation action (Discord / IFTTT / Zapier / Node-RED),
      SSRF-gated at save and fire time (39b0554)
    • Home Assistant MQTT auto-discovery: read-only binary sensors per automation,
      availability via birth/will, with cleanup on disable/delete (39b0554)
    • League of Legends poller wired via a LoLPollManager + shared runtime state (6745e25)
    • auth.expose_docs flag (default off) to view /docs, /redoc, and
      /openapi.json without a token; all real endpoints stay protected (126d8f2)

    Bug Fixes

    • Pre-release review hardening: solar timezone crash, webhook header CRLF,
      MQTT topic-prefix injection, thread-safe get_stats copy, MQTT discovery
      lock, reactive_mode Literal, and calibration-modal accessibility (0c096db)
    • Comprehensive review fixes across security, concurrency, performance,
      Android, and UI (17dd2e0)
    • Activity Log polish: accessible export menu, i18n placeholders, dashboard
      section reconciliation, column alignment, ticking time, and no spinner
      flash on instant filtering (3dd1ac3, ff1ff06, 77284e8, ae74cca, 077c99c)

    Development / Internal

    CI/Build

    • Best-effort arm64 multi-arch Docker manifest via QEMU + docker manifest
      (amd64 path untouched) (6745e25)

    Chores

    • Activity Log feature plan/subplan scaffold, post-merge cleanup, and context
      graduated into CLAUDE.md (1afe7d6, e584235)

    Tests: ~180 new unit tests added across the activity log, roadmap features,
    and integrations. Release gate green: ruff + tsc + build clean,
    pytest 2739 passed / 2 skipped.


    All Commits
    Hash Message Author
    0c096db fix: address pre-release review findings (2026-06-23) alexei.dolgolyov
    39b0554 feat: roadmap round two (2026-06-23) — per-pixel smart-lights + integrations alexei.dolgolyov
    6745e25 feat: roadmap batch (2026-06-19) — solar/linear-light/dither/nanoleaf + integrations alexei.dolgolyov
    126d8f2 feat(auth): add auth.expose_docs flag to view API docs without a token alexei.dolgolyov
    e584235 chore(activity-log): post-merge cleanup + graduate context to CLAUDE.md alexei.dolgolyov
    077c99c fix(activity-log): no spinner flash on instant filtering alexei.dolgolyov
    ae74cca fix(activity-log): UI polish - accessible export menu, i18n placeholders, zero-result spinner fix alexei.dolgolyov
    77284e8 fix(activity-log): dashboard section reconciliation + activity column alignment alexei.dolgolyov
    ff1ff06 fix(activity-log): post-test polish - localize descriptions, dashboard widget, ticking time alexei.dolgolyov
    3dd1ac3 fix(activity-log): final-review fixes - crosslink keys + sanitize parity alexei.dolgolyov
    6e1dd21 feat(activity-log): phase 6 - dashboard widget + settings panel + docs alexei.dolgolyov
    9a0137f feat(activity-log): phase 5 - Activity tab (smart filtering, live updates, export) alexei.dolgolyov
    4a09275 feat(activity-log): phase 4 - REST API (list/export/settings/clear) alexei.dolgolyov
    25c613c feat(activity-log): phase 3 - event instrumentation (4 categories) alexei.dolgolyov
    726f39e feat(activity-log): phase 2 - recorder, actor context, retention, lifecycle alexei.dolgolyov
    1ac4a0f feat(activity-log): phase 1 - storage model, migration, repository alexei.dolgolyov
    1afe7d6 chore(activity-log): scaffold feature plan and phase subplans alexei.dolgolyov
    17dd2e0 fix: resolve comprehensive review findings (security, concurrency, perf, Android, UI) alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.9.0-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.9.0-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.9.0-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.9.0-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.9.0
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.9.0
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.8.2 7a12f39f49

    LedGrab v0.8.2
    Build Release / create-release (push) Successful in 3s
    Build Android APK / build-android (push) Failing after 11s
    Build Release / build-docker (push) Successful in 3m14s
    Build Release / build-linux (push) Successful in 4m3s
    Build Release / build-windows (push) Successful in 4m25s
    Build Release / publish-release (push) Successful in 1s
    Stable

    alexei.dolgolyov released this 2026-06-08 20:18:46 +03:00 | 22 commits to master since this release

    v0.8.2 (2026-06-08)

    User-facing changes

    Features

    WLED native realtime UDP output
    • New realtime UDP sink speaking WLED's DRGB / DRGBW / DNRGB protocols, with automatic revert to the device's prior state when streaming stops (7728aec)
    Automatic brightness limiting (ABL) / power budget
    • Per-LED power budgeting that caps total draw by scaling brightness to a configurable current/PSU limit, preventing brownouts on long strips (ffee156)
    Scene playlists
    • Scenes can be grouped into playlists with timed auto-cycling, so a target can rotate through looks on a schedule (f71e10e)
    • Playlist + cycling state is included in the aggregated /snapshot response (abc204c)
    Auto edge-calibration + guided first-run setup wizard
    • Backend core for automatic screen-edge calibration (0409cd8), a one-call setup scaffold with an onboarding flag (9dcd76d), and a browser-driven calibration UI (9550688)
    • A guided first-run setup wizard ties it together for new installs (81b1808), with all-provider source discovery and a spatial corner picker (dd43f38)
    Region-of-interest (ROI) screen capture
    • Screen sampling can now be cropped to a region of interest instead of the whole display (ca59546)
    Built-in "look" presets
    • One-click looks: Cinematic / Vivid / Cozy / Soft / Cool (e18d56c)
    Weekday + timezone scheduling
    • The time-of-day automation rule now supports weekday selection and explicit timezones (1ada5ac)
    Value sources
    • New sandboxed-Jinja template combinator for composing value sources (6de61b9) and optional normalization for magnitude sources (669ae20)
    Visual graph editor
    • The editor is now a full wiring control surface (2e51f46), and you can duplicate a selected subgraph server-side (15cfb82)
    Android on-device capture
    • System audio playback capture (fd62db1), OS notification capture via NotificationListenerService (0be3f83), webcam capture via Camera2 (4bf3fe6), and a foreground-app automation condition (1c1bbe2)

    Bug Fixes

    • Security: removed an active weak default API key from the shipped config — fresh installs no longer ship with a guessable key. Set your own key on first run (5686ae5)
    • Removed a broken legacy /system/mqtt/settings route (fdc9201)
    • Scene brightness value-source changes now sync to the live processor immediately (02e2ea3)
    • Wizard hardening: scaffolded targets are registered with the ProcessorManager and the final review step is more robust (6cd5e05)
    • Installer opens the WebUI only once after "Launch LedGrab" (05cf121)

    Development / Internal

    Backend / Storage

    • clone() is now gated behind an opt-in allowlist, with expanded duplicate-handling tests (498854f)

    Frontend

    • In-progress dashboard customization groundwork (6180569)

    Docs

    • Actualized README + API reference with embedded screenshots (12b40e6), graph-editor wiring-control roadmap (d505388), Android audio-capture design notes (4b2e8fc); removed stale ANDROID-REVIEW planning docs (9960f15)

    Tests

    • Large new suites for calibration solver/session (incl. adversarial), setup & scene-playlist routes, playlist engine, and ROI capture. Full suite: 2149 passing, 2 skipped

    All Commits (31)
    Hash Message Author
    dd43f38 fix(calibration-wizard): all-provider discovery + spatial corner picker alexei.dolgolyov
    6cd5e05 fix(setup): register scaffolded target with ProcessorManager + final-review hardening alexei.dolgolyov
    81b1808 feat(onboarding): guided first-run setup wizard (phase 4, final) alexei.dolgolyov
    abc204c feat(snapshot): include scene playlists + cycling state in snapshot alexei.dolgolyov
    9550688 feat(calibration): browser-driven auto edge-calibration UI (phase 3) alexei.dolgolyov
    9dcd76d feat(setup): one-call setup scaffold + onboarding flag (phase 2) alexei.dolgolyov
    0409cd8 feat(calibration): auto edge-calibration backend core (phase 1) alexei.dolgolyov
    6180569 wip(dashboard): in-progress dashboard customization changes alexei.dolgolyov
    f71e10e feat(scenes): scene playlists with timed auto-cycling alexei.dolgolyov
    ca59546 feat(capture): region-of-interest (ROI) crop for screen sampling alexei.dolgolyov
    1ada5ac feat(automations): weekday + timezone scheduling for time-of-day rule alexei.dolgolyov
    e18d56c feat(processing): built-in 'look' presets (Cinematic/Vivid/Cozy/Soft/Cool) alexei.dolgolyov
    7728aec feat(wled): native realtime UDP output (DRGB/DRGBW/DNRGB) with auto-revert alexei.dolgolyov
    ffee156 feat(targets): automatic brightness limiting (ABL) / per-LED power budget alexei.dolgolyov
    02e2ea3 fix(scenes): sync brightness value-source change to live processor alexei.dolgolyov
    fdc9201 fix(api): remove broken legacy /system/mqtt/settings route alexei.dolgolyov
    5686ae5 fix(security): remove active weak default API key from shipped config alexei.dolgolyov
    9960f15 docs(android): remove ANDROID-REVIEW planning/review docs alexei.dolgolyov
    1c1bbe2 feat(android): foreground-app automation condition alexei.dolgolyov
    4bf3fe6 feat(android): on-device webcam capture via Camera2 (AndroidCameraEngine) alexei.dolgolyov
    0be3f83 feat(android): on-device OS notification capture (NotificationListenerService) alexei.dolgolyov
    4b2e8fc docs(android): add audio-capture design + missing-functionality review alexei.dolgolyov
    fd62db1 feat(audio): Android on-device system playback capture alexei.dolgolyov
    669ae20 feat(value-sources): optional normalization for magnitude sources alexei.dolgolyov
    6de61b9 feat(value-sources): add sandboxed-Jinja template combinator alexei.dolgolyov
    12b40e6 docs: actualize README and API reference, embed screenshots alexei.dolgolyov
    498854f refactor(storage): gate clone() behind an opt-in allowlist; expand duplicate tests alexei.dolgolyov
    15cfb82 feat(graph): duplicate a selected subgraph server-side alexei.dolgolyov
    2e51f46 feat(graph): make the visual editor a full wiring control surface alexei.dolgolyov
    05cf121 fix(installer): open WebUI once after "Launch LedGrab" alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.8.2-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.8.2-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.8.2-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.8.2-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.8.2
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.8.2
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.8.1 6aeda935f1

    LedGrab v0.8.1
    Build Android APK / build-android (push) Failing after 11s
    Build Release / create-release (push) Successful in 6s
    Build Release / build-docker (push) Successful in 2m57s
    Build Release / build-linux (push) Successful in 1m49s
    Build Release / build-windows (push) Successful in 3m35s
    Build Release / publish-release (push) Successful in 2s
    Stable

    alexei.dolgolyov released this 2026-05-28 23:36:03 +03:00 | 62 commits to master since this release

    v0.8.1 (2026-05-28)

    User-facing changes

    Features

    Multi-broker MQTT devices
    • The device editor now shows an MQTT broker picker for device_type=mqtt (in both the add-device and device-settings modals), wired into load / save / validate / dirty-check / clone. An empty selection means "first available broker"
    • mqtt_source_id is now threaded end-to-end through DeviceCreate / DeviceUpdate / DeviceResponse and the device routes; the referenced broker is validated on create and update (a5effba)
    Schema-driven wiring-graph editor
    • The visual graph editor now renders ports and edges generically from a backend-served schema (GET /api/v1/graph/schema) instead of hard-coding the connectable-field topology in two places — so client and server can no longer drift
    • New GET /api/v1/graph returns the full nodes + edges + validation topology, and GET /api/v1/graph/dependents/{kind}/{id} reports what references an entity (a5effba)
    Aggregated snapshot endpoint
    • New GET /api/v1/snapshot returns all output targets (with processing state + metrics), devices (with brightness), the source / preset / clock lists, and the system block in a single response — collapsing the Home Assistant integration's previous ~2N+M request fan-out into one round trip
    • ?include= fetches only a subset of sections, and an excluded section also skips its server-side work (e.g. cold-cache hardware brightness probes or the blocking NVML performance query) (a5effba)

    Bug Fixes

    • Graceful shutdown no longer hangs: uvicorn's graceful-shutdown wait is now bounded (GRACEFUL_SHUTDOWN_TIMEOUT, shared by the desktop, Android, and demo launchers). A lingering events WebSocket (which the browser auto-reconnects) used to keep connections from draining, so the lifespan shutdown never ran — leaving LED targets lit and blocking process exit. Ctrl+C / OS shutdown with the UI open now reliably stops targets and checkpoints the DB (a5effba)
    • Device update error codes: update_device no longer masks an intentional 4xx (e.g. an unknown mqtt_source_id or failed group validation) as a generic 500 (a5effba)

    Development / Internal

    Backend

    • Wiring-graph schema engine (api/graph_schema.py): a pure, unit-tested module that is the single source of truth for which reference fields connect which entity kinds; builds the topology and performs dependency lookup plus cycle / dangling-reference detection without booting the app or any store. The route layer only gathers serialized entities and delegates (a5effba)
    • Structured access log: a new middleware emits one structured line per request, attributing it to the authenticated token's friendly label (the key name, never the secret) so traffic can be traced to a client (e.g. homeassistant vs android). uvicorn's own access log is disabled to avoid duplicate lines (a5effba)
    • Shared validate_mqtt_source_exists (_mqtt_validation.py) deduplicates the MQTT-source existence check between the device and output-target routes (a5effba)

    Frontend

    • Service-worker refresh for the new bundle (a5effba)

    Tests

    • New suites: graph routes + schema engine, snapshot routes, access-log middleware, mqtt_source_id device regressions, and the bounded-shutdown entrypoint. Full suite: 1614 passing (a5effba)

    All Commits (1)
    Hash Message Author
    a5effba feat: aggregated snapshot + wiring-graph APIs, MQTT device brokers alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.8.1-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.8.1-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.8.1-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.8.1-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.8.1
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.8.1
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.8.0 b83a72e63f

    LedGrab v0.8.0
    Build Release / create-release (push) Successful in 3s
    Build Android APK / build-android (push) Failing after 8s
    Build Release / build-linux (push) Successful in 3m8s
    Build Release / build-docker (push) Successful in 4m11s
    Build Release / build-windows (push) Successful in 4m55s
    Build Release / publish-release (push) Successful in 1s
    Stable

    alexei.dolgolyov released this 2026-05-28 17:48:18 +03:00 | 64 commits to master since this release

    v0.8.0 (2026-05-28)

    User-facing changes

    Features

    Android TV — production-readiness pass
    • Security: per-install random API key (persisted, threaded into the embedded server via env, embedded in the pairing QR as a URL-fragment so it never reaches HTTP logs); root-shell injection eliminated via POSIX-quoted runAsRoot(argv) overload; broadcast receivers locked to the app package; release builds refuse to silently sign with the debug keystore; crash log retention capped at 10 entries
    • Performance: single reusable RGBA buffer in ScreenCapture / RootScreenrecord (eliminates ~15 MB/s GC churn at 30 fps); frame pacer switched to elapsedRealtimeNanos with catch-up accumulator (fixes ~30.3 fps drift); capture dimensions derived from source aspect ratio so non-16:9 displays aren't squashed; QR bitmap cached by URL
    • Compatibility: compileSdk/targetSdk → 35 (Play Store requirement); armeabi-v7a build path; foreground service type declared as mediaProjection|specialUse with proper ServiceCompat.startForeground promotion; Ethernet > Wi-Fi > VPN > cellular selection in NetworkUtils; Android 15 predictive-back via enableOnBackInvokedCallback; splash screen API hides Chaquopy cold-start delay
    • UI/UX: all hardcoded English strings localised across en/ru/zh; monochrome notification icon; 320×180 TV banner; ViewStub-based running panel; pulse animator on Running dot; "Starting…" button while probing root; autostart checkbox hidden on unrooted devices
    • Lifecycle hardening: processLock serialises EOF respawn vs stop() to prevent orphaned screenrecord; publish-before-start under @Synchronized in CaptureService.restartRootPipeline closes the orphan window during watchdog restarts; watchdog give-up bound corrected (ef1f9ea)
    Backup format — bundled DB + assets ZIP
    • Auto-backups now produce a .zip containing ledgrab.db plus every file from the assets directory under assets/ — matching the manual GET /api/v1/system/backup download. Restore accepts both .zip and legacy .db interchangeably
    • Partial-write hardening: writes stage to <name>.partial then os.replace into place — a crash mid-write never leaves a corrupt backup masquerading as valid. Stale .partial files from prior crashes are swept on the next run
    • Symlinks inside the assets directory are skipped (security guard against link targets outside the dir)
    • Backups over 500 MB log a warning so operators notice unbounded asset growth before disk fills up
    • restart.py redirects spawned restart script stdout/stderr to restart.log and bails out early if the script is missing — silent failures used to vanish into a detached child (85da2e5)
    Spectrum-aperture icon set
    • Regenerated icon family from a single Pillow script: rounded-square aperture traced by a continuous RGB color-wheel stroke over a vignette canvas with chromatic bloom. 4× supersampled then downsampled per output for crispness
    • New 256 px transparent-background tray variant — taskbar icon reads cleanly against light themes instead of showing a dark tile
    • icon.ico now embeds 16/24/32/48/64/128/256 frames sourced from the transparent master (fixes the dark-square halo on light Windows themes)
    • Maskable 512 variant safe-area padded for PWA round-crops (3645216)

    Bug Fixes

    • Notification sound dropdowns: both the per-app override list and the main row now always render the EntitySelect (was silently inert before any sound assets were registered) and offer "no sound" as a first-class option via allowNone (1f95993)
    • CSS editor: notification_sound and notification_volume are now persisted on save — they were silently dropped from the payload before (66b85b0)
    • Python 3.13 ctypes: Win32 message-pump prototypes (GetMessageW / TranslateMessage / DispatchMessageW) now share a single LPMSG = POINTER(wintypes.MSG) class across WindowsShutdownGuard and PlatformDetector — fixes the expected LP_MSG instance instead of pointer to _MSG error and the resulting shutdown-guard / display-power-monitor failure on 3.13 (e4d24a0, 0d840ad)

    Development / Internal

    CI/Build

    • release.yml now creates the Gitea release as a draft and only flips draft=false once every build job (Windows, Linux, Docker) has uploaded its artifacts and sha256 sidecars — users never see a release page that's missing assets, which would have broken the in-app updater (bc42604)

    Refactoring

    • Shared API client + automations registry (audit M7, H8): new core/api-client.ts wraps fetchWithAuth with typed apiGet / apiPost / apiPut / apiPatch / apiDelete; 35 feature/core files migrated. FastAPI validation-array detail unwrap hardened. Automations editor's two hand-rolled RuleType dispatch ladders converted to Record<RuleType, ...> registries with an import-time exhaustiveness check (bb3a316)
    • types.ts split (audit H6): 1140 LOC types.ts split into 18 per-entity files under types/, original file kept as a pure re-export barrel — 102 type exports preserved with no import sites changed (49c35a2)

    Documentation

    • REVIEW_RECONCILE_NOTES.md — design doc for the dashboard innerHTML reconciliation work: bug-class analysis, latent-site inventory, decision ladder (helper / hand-rolled cells / Lit), and recommendation to migrate polling-heavy modules to Lit with entity-events.ts tab reconciliation sequenced first (10eb24b)

    All Commits (11)
    Hash Message Author
    0d840ad fix(ctypes): share wintypes.MSG with platform_detector to avoid argtype races alexei.dolgolyov
    1f95993 fix(notification): allow clearing the sound on per-app overrides and main row alexei.dolgolyov
    10eb24b docs: dashboard innerHTML reconciliation review notes alexei.dolgolyov
    66b85b0 fix(css-editor): persist notification_sound + notification_volume alexei.dolgolyov
    bc42604 ci(release): publish release only after every build job uploads assets alexei.dolgolyov
    3645216 feat(icons): spectrum aperture icon set + dedicated tray variant alexei.dolgolyov
    85da2e5 feat(backup): bundle assets in ZIP + partial-write hardening + restart log alexei.dolgolyov
    e4d24a0 fix(ctypes): pin LPMSG across MSG-pump prototypes for Python 3.13 alexei.dolgolyov
    bb3a316 refactor(frontend): shared API client + automations registry (audit M7, H8) alexei.dolgolyov
    49c35a2 refactor(frontend): split types.ts into 18 per-entity files (audit H6) alexei.dolgolyov
    ef1f9ea feat(android): production-readiness pass — security, perf, compat, UI/UX alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.8.0-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.8.0-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.8.0-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.8.0-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.8.0
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.8.0
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.7.0 8bdcc17799

    LedGrab v0.7.0
    Build Release / create-release (push) Successful in 3s
    Build Android APK / build-android (push) Failing after 11s
    Build Release / build-linux (push) Successful in 2m54s
    Build Release / build-docker (push) Successful in 3m50s
    Build Release / build-windows (push) Successful in 4m36s
    Stable

    alexei.dolgolyov released this 2026-05-26 00:35:38 +03:00 | 76 commits to master since this release

    v0.7.0 (2026-05-26)

    A device-support release: seven new device families, a unified pairing UX,
    a brand-new HTTP-endpoint output type, multi-broker MQTT + Zigbee2MQTT
    support, a major shutdown / data-safety fix, and a deep architectural
    refactor pass that landed registry patterns for every dispatch hot path.

    Features

    New device types

    • DDP — standalone Open-Pixel-Control-style target for Pixelblaze / ESPixelStick / xLights / Falcon endpoints, port 4048 (8f1140a)
    • Yeelight — Xiaomi/Yeelight bulbs and lightstrips over JSON-RPC on port 55443, SSDP discovery (4b65005)
    • WiZ Connected — Philips WiZ smart bulbs over UDP on port 38899, broadcast discovery (ede627b)
    • LIFX — LIFX bulbs and lightstrips over the binary LIFX LAN protocol on port 56700 (8f9d490)
    • Govee LAN — Govee Wi-Fi bulbs and ambient kits, multicast discovery (requires "LAN Control" enabled in the Govee Home app) (887131d)
    • Open Pixel Control (OPC) — Fadecandy boards, xLights/Falcon, OPC bridges, port 7890 with channel addressing (31c6c3a)
    • Nanoleaf — Light Panels / Canvas / Shapes / Lines / Elements over the documented HTTP REST API on port 16021 (426484a)

    New output type

    • HTTP endpoint output target — POST live strip frames to any user-configured HTTP endpoint, alongside WLED / MQTT / Hue. Full editor + storage + routes (d6cc800)

    Pairing flow

    • Generic pairing UX scaffold — 30-second SVG ring + countdown, instructions, retry/cancel. First concrete consumer is Nanoleaf; Tuya/Twinkly slot into the same shape later (2f31680)

    MQTT / Zigbee2MQTT

    • Multi-broker MQTT + new Zigbee2MQTT light output target sharing the HA-Light editor. Legacy single-broker YAML/env config auto-migrates to a "Default Broker" MQTTSource on startup (530316c)

    Editor experience

    • Live preview for color-strip sources of every type that can render without external calibration (audio, math_wave, weather, game_event, api_input, mapped, composite, processed) (337984c)
    • Expanded automations — new rule shapes + matching UI inputs + 285 lines of dispatch coverage (3fe66d8)
    • Expanded value sources — storage + schema + UI for the new value-source kinds the per-type factory refactor introduced (737fd72)
    • Card icon picker expanded from 44 → 120 icons across 5 new categories (weather, nature, controls, status, office) (cdf7d94)
    • closeIfPristine modal save-guard — editing an unchanged entity now silently closes the modal instead of firing a misleading "updated" toast (f03cb30)
    • New MiniSelect primitive for compact dropdowns that don't justify the full IconSelect grid; IconSelect gains a defence-in-depth XSS sanitiser on the icon channel (9ff83bd, 507e138)

    Updater

    • SSRF-validated redirect chain in the update service so a hostile mirror can't bounce the updater to a private IP. Stricter restart.ps1 argument handling + clearer logs (45d12b2)

    Bug Fixes

    • Survive PC restart — SQLite was running WAL with synchronous=NORMAL and Database.close() was never called, so an unclean Windows shutdown rolled the DB back to the last checkpoint and silently lost recent edits. Now uses synchronous=FULL + wal_autocheckpoint=100 + explicit wal_checkpoint(TRUNCATE) on close, and a hidden WM_QUERYENDSESSION / WM_ENDSESSION window keeps Windows from force-killing the process before the lifespan can finish (e24f9d3)
    • Devices PATCH preserves URL — PATCH-without-url (rename / icon-only) used to drop the address into the processor as None (0dd8d43)
    • HA Light brightness scale_send_entity_color was double-applying brightness_scale below 1 (quartered output for a half-scale) and skipping it above 1 (boost lost). Now one clamp(max(r,g,b) * bs * vs, 0, 255) pass with regression coverage (ad84b60)
    • Dashboard "MODIFIED" badge no longer fires retroactively on un-edited legacy layouts — userModified is now driven by actual edits, not deep-equal drift from defaults (e4bf58d)
    • Transport-bar uptime repaints on /health response instead of waiting up to ~10 s for the next poll (f1b0f0e)
    • Pre-merge device-support review passupdate_device no longer double-encrypts secrets in memory; GET /devices strips paired-only secrets behind boolean flags; SSRF validation on every new driver; corrupt-envelope decrypt returns "" instead of deleting the device row; update_device URL trim matches create; Govee discovery port-4002 collision serialised behind a module lock; Nanoleaf mDNS scan cleans up tasks on cancel; pair endpoint stops logging userinfo / exception bodies (0e3ae78)
    • value_source factory contract_build_game_event raises NotImplementedError (preserves the historical store contract) and create_source runs build_source before _check_name_unique so an invalid source_type raises the right error (c1aa2eb)
    • utils/url_scheme + utils/net_classify were referenced but untracked on a clean checkout — server failed to start with ModuleNotFoundError. Now committed (7736bc6)

    Performance

    • Capture hot paths vectorised — WGC swaps per-frame ~30 MB BGRA→RGB fancy-index allocations for cv2.cvtColor into a 3-slot pre-allocated pool; MSS uses screenshot.raw + cv2.cvtColor with 256-byte change-detection; DXcam/BetterCam fixes a silent name-mangling factory leak; dominant-colour reduction is ~10× faster via packed-RGB np.bincount (f184ef0)
    • Event-driven frame hand-offLiveStream gains a frame_id + Condition, consumers wait instead of polling, ring buffer grows 3 → 5 slots, _blend_u16 uses cv2.addWeighted. Up to one frame_time of glass-to-LED latency saved at matched FPS (ee4fa81)
    • WLED brightness threshold caches per-frame np.max keyed on frame identity instead of reducing the LED array every loop (6e4c1b6)
    • Dashboard FPS charts now diff target ids and only recreate added/removed/detached charts (skipping the history fetch when local samples already exist), and spark SVGs are mutated in place instead of innerHTML-rewritten every poll. Memoised patches/devices rendering by content signature so unchanged ticks no longer restart CSS animations (f6486f9)

    Development / Internal

    Architecture audit — registry patterns everywhere

    • Color-strip stream dispatchColorStripStreamManager.acquire() and ws_stream._create_stream() now share a STREAM_BUILDERS registry keyed by source type, with import-time coverage assertion against _SOURCE_TYPE_MAP. CSS response builder gets the same treatment (563cbac)
    • Value-source create / updateValueSourceStore.create_source shrinks from ~260 → ~25 lines via per-type builder/applier functions in a new storage.value_source_factories module (3b8f00e)
    • SystemMetricsValueStream — three parallel if/elif chains collapse into a MetricSpec(name, read_psutil, read_fallback, normalize, prime) registry in core.processing.metric_readers (9f3f346)
    • Automation engine — per-rule-type bodies become _handle_<kind> methods, dispatch table built once at class-creation, unknown-type fallback logs instead of silently returning False (98fb61d)
    • Effect renderer dispatch@_effect_renderer("fire") decorators + class-level _RENDERERS dict replace per-frame dict-rebuild + silent fire fallback (97dae2c)
    • Output-target response buildersisinstance ladder + silent fabricated-LED fallback replaced with _TARGET_RESPONSE_BUILDERS dict and a runtime RuntimeError for unknown subclasses (2f15fbb)
    • Versioned data migrations — replaces a naked blob.replace(...) migration with storage.data_migrations.MigrationRunner backed by a data_migrations audit table and atomic transactions (563cbac)

    Dedup / refactor

    • Edge-to-LED kernels in PixelMapper + AdvancedPixelMapper deduped into a shared core.capture.edge_interpolation module (5fec8db)
    • HA/Z2M _swap_color_source unified behind a shared light_target_helpers.swap_color_source helper (29bdacf)
    • Single-pixel _average_color lifted out of 6 LED drivers into core.devices.pixel_reduce.average_color (cc87fba)
    • Static → single rename for the color-strip source kind. Storage keeps backward-compatible serialisation (826e680)
    • Bindable types extracted into types/bindable.ts; the wider types.ts god-module split is staged for a follow-up frontend sprint (05f73ee)
    • WebSocket auth — 11 except Exception sites around handshake replaced with a narrow _WS_SEND_BENIGN_EXC tuple; receive path adds explicit observability (ea7ee88)
    • Backend hardening bundle — MQTT task tracking + drain resilience, credential encryption with auto-migration, devices watcher task tracking, WLED scheme inference at boundaries, streaming-upload caps, asyncio.gather(return_exceptions=True) on broadcast loops, WebSocket Origin allow-list, /docs auth-gate (898912f)
    • Frontend infra — inbound-event allowlist mirroring the server side, closeIfPristine adoption across editors, MiniSelect markup for filter pickers (ddae571)
    • PEP-604 union sweepruff --select UP007,UP045 --fix converted ~1760 sites from Optional[T] / Union[X, Y] to T | None / X | Y. Hooks bumped to ruff v0.15.12 to recognise UP045 (888f8fd)
    • Typed window globals — 59 (window as any).foo sites across 19 feature modules switched to typed window.foo against global-types.d.ts (0035172)
    • Processing magic numbers lifted to named module constants so tests can monkeypatch them (d38021f)
    • Database.ensure_open() — module-level singleton reopens cleanly across lifespan cycles, fixing 65 spurious sqlite3.ProgrammingError setup failures on Windows pytest aggregate runs (f591e25)

    Tests

    • WLED URL scheme integration + IPv6 regression coverage (907bdaf)
    • Lifespan reopen invariants on Database (f591e25)
    • Hundreds of new tests covering every registry / factory / migration introduced above

    Tooling / docs

    • .vex.toml makes vex the project's primary code-search backend with auto-update + semantic embeddings (06273ba)
    • REVIEW_TODO.md captures audit items deliberately deferred; TODO.md records the architecture-audit remainder (06273ba, 628c6b2)
    • Locale + CLAUDE.md upkeep alongside the new features (fd46c51, 48dbdb9, 17684af, 390d2b4)

    All Commits (55)
    Hash Message
    f591e25 fix(storage/database): reopen connection on lifespan restart
    f6486f9 perf(dashboard): diff FPS charts + cache spark SVG nodes; i18n perf strings
    48dbdb9 docs(review-todo): check off items addressed in 2026-05-23 autonomous pass
    0035172 refactor(types): migrate (window as any) statics to typed window globals
    888f8fd refactor(types): PEP-604 union sweep + UP007/UP045 enforcement
    ea7ee88 refactor(api/auth): narrow WS exception catches + observability log
    d38021f refactor(processing): hot-path magic numbers -> named module constants
    507e138 feat(ui/icon-select): defence-in-depth XSS sanitiser on icon channel
    907bdaf test(url-scheme): WLED route-level integration + IPv6 regression
    0dd8d43 fix(devices): preserve existing URL on PATCH-without-url
    fd46c51 docs: TODO + CLAUDE.md notes + locale keys for new features
    ddae571 chore(frontend-infra): inbound-event allowlist + storage/state touch-ups
    898912f chore(backend): MQTT/WLED/devices/capture/utils + api routes hardening
    45d12b2 feat(update-service): SSRF-validated redirects + restart hardening
    826e680 refactor(color-strip): rename static -> single + frontend follow-through
    737fd72 feat(value-sources): extend storage + schema + UI alongside new kinds
    3fe66d8 feat(automations): expand automation rules + UI + engine coverage
    f03cb30 feat(modal): closeIfPristine save-guard + per-editor adoption
    9ff83bd feat(ui): MiniSelect primitive + IconSelect XSS hardening + typed globals
    d6cc800 feat(http-endpoints): introduce HTTP endpoint output target stack
    06273ba chore(tooling): vex semantic-search config + REVIEW_TODO backlog
    628c6b2 docs: capture architecture-audit remainder for follow-up sessions
    2f15fbb refactor(output-targets): registry + coverage assertion for response builders
    c1aa2eb fix(value-source): preserve store contract for game_event + error precedence
    3b8f00e refactor(value-source): per-type factories for create / update dispatch
    05f73ee refactor(types): extract bindable primitives into types/bindable.ts (H6 partial)
    9f3f346 refactor(value-source): MetricSpec registry for SystemMetricsValueStream
    98fb61d refactor(automations): rule dispatch via class-level handler table
    5fec8db refactor(capture): lift duplicated edge-to-LED kernels into shared module
    97dae2c refactor(processing): replace inline effect dispatch with @_effect_renderer registry
    29bdacf refactor(processing): dedupe HA/Z2M _swap_color_source via shared helper
    563cbac refactor(storage,processing): kind registries + versioned data migrations
    e24f9d3 fix(shutdown): survive PC restart with WAL fsync + Win32 session-end guard
    e4bf58d fix(dashboard): stop showing perpetual MODIFIED for un-edited legacy layouts
    f1b0f0e fix(ui): repaint transport-bar uptime as soon as /health responds
    17684af docs: record review-fix pass in TODO.md
    0e3ae78 fix(devices): address pre-merge review findings
    7736bc6 fix(utils): commit url_scheme + net_classify dependencies
    390d2b4 docs: mark expand-device-support branch ready for merge
    cc87fba refactor(devices): extract _average_color to pixel_reduce
    426484a feat(devices): Nanoleaf OpenAPI target type + first pair-flow user
    2f31680 feat(devices): pairing-UX scaffold (Phase 2)
    31c6c3a feat(devices): Open Pixel Control (OPC) target type
    887131d feat(devices): Govee LAN target type
    8f9d490 feat(devices): LIFX LAN target type
    ede627b feat(devices): WiZ Connected LAN target type
    4b65005 feat(devices): Yeelight LAN target type
    8f1140a feat(devices): standalone DDP target type
    337984c feat(color-strips): in-editor live preview for all viable source types
    530316c feat(mqtt): multi-broker MQTT + Zigbee2MQTT light target
    6e4c1b6 perf(wled): cache per-frame max-pixel for brightness threshold
    ee4fa81 perf(processing): event-driven frame hand-off and scheduling fixes
    f184ef0 perf(capture): vectorize hot paths and fix engine bugs
    ad84b60 fix(ha-light): apply brightness_scale once and respect boost multipliers
    cdf7d94 feat(ui): expand card icon picker (44 -> 120 icons, +5 categories)

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.7.0-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.7.0-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.7.0-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.7.0-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.7.0
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.7.0
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.6.1 09792a9a05

    LedGrab v0.6.1
    Build Release / create-release (push) Successful in 4s
    Build Android APK / build-android (push) Failing after 9s
    Build Release / build-linux (push) Successful in 2m13s
    Build Release / build-docker (push) Successful in 3m9s
    Build Release / build-windows (push) Successful in 4m6s
    Stable

    alexei.dolgolyov released this 2026-05-10 23:57:47 +03:00 | 132 commits to master since this release

    v0.6.1 (2026-05-10)

    Features

    • Per-surface card presentation modes (C/M/D/R) for the UI (75ca487)
    • Customisable card icon for all entity types (0f5850e)
    • HA-Light: broadcast a single Color Value Source to all entities (a79f4bf)
    • Targets: customisable card icon plus HA-light stop action (ced72fc)
    • Customisable card icon plate for devices (49ddabb)

    Bug Fixes

    • Shutdown: apply target stop actions before tearing down HA/MQTT so devices end up in their configured state (6a07a6b)

    Development / Internal

    CI/Build

    • Android: fail-fast on missing release keystore before SDK setup (a026f0b)

    Chores

    • Clean up cfg abbreviation and stale TODO link (e65dcb4)

    All Commits
    Hash Message Author
    75ca487 feat(ui): per-surface card presentation modes (C/M/D/R) alexei.dolgolyov
    e65dcb4 chore: clean up cfg abbreviation and stale TODO link alexei.dolgolyov
    6a07a6b fix(shutdown): apply target stop actions before tearing down HA/MQTT alexei.dolgolyov
    0f5850e feat(ui): customisable card icon for all entity types alexei.dolgolyov
    a79f4bf feat(ha-light): broadcast a single Color Value Source to all entities alexei.dolgolyov
    ced72fc feat(targets): customisable card icon + HA-light stop action alexei.dolgolyov
    49ddabb feat(ui): customisable card icon plate for devices alexei.dolgolyov
    a026f0b ci(android): fail-fast on missing release keystore before SDK setup alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.6.1-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.6.1-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.6.1-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.6.1-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.6.1
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.6.1
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.6.0 5ef6ac1317

    LedGrab v0.6.0
    Build Release / create-release (push) Successful in 3s
    Build Android APK / build-android (push) Failing after 3m52s
    Build Release / build-linux (push) Successful in 5m20s
    Build Release / build-docker (push) Successful in 6m20s
    Build Release / build-windows (push) Successful in 7m7s
    Stable

    alexei.dolgolyov released this 2026-05-01 19:11:15 +03:00 | 141 commits to master since this release

    v0.6.0 (2026-05-01)

    This release adds device-event notifications (snack + Web Notifications), a daylight/timezone-aware streaming pipeline with a new camera engine, a redesigned Targets surface built on the dashboard's mod-card system, a tighter LED hot path with allocation-free per-frame work, and a revamped Release Notes overlay with clickable asset downloads. Plus a wide pass of modal, toolbar, and settings polish across the WebUI.

    Features

    • Device event notifications — configurable per-event channel matrix (none / snack / OS / both) for target online/offline, new WLED/serial discovery, and devices going missing. Backed by a long-running mDNS browser + 10 s serial poller, a startup-grace / flap-debounce / bulk-coalesce pipeline, and a new Notifications tab in Settings (en/ru/zh). (8aa3a32)
    • Daylight + timezone streaming — new daylight_settings module and daylight-tz frontend helper expand the daylight stream's behavior; capture path additions land alongside a new camera engine test suite. (fdac26b)
    • Targets cards migrated to the mod-card system — LED targets and HA Light targets now share the dashboard's instrument-readout vocabulary (mod-head / mod-leds / mod-metrics / mod-foot, kebab menu, badges, chips, patch indicator). LED preview, FPS sparkline, and pipeline metrics preserved via an extraHtml escape hatch. (233b463)
    • Target pipeline as a compact strip + chip row — drops the legacy "Pipeline details" collapsible block; an always-visible 4 px segmented timing bar (extract / map / smooth / send for video, read / fft / render / send for audio) sits above an inline chip row showing total ms / frames / keepalives, animating smoothly between samples. (51eebf2)
    • Targets metrics aligned with the dashboard — FPS sparkline now lives inside the FPS cell, Uptime gets a clock icon, Errors gets ok/warning by count, FPS readout adopts the dashboard current/target avg N.N shape, and the grid sizes so values like 1m 43s no longer truncate at typical desktop widths. (9067db2)
    • Release Notes overlay v2 — new masthead with display-font title, tag/published/pre-release chip strip, and close/external actions; markdown body fuzzy-matches <code> filenames to release assets and renders clickable download links with per-asset descriptions (Windows installer/portable/msi, Linux tarball/AppImage/deb/rpm, macOS dmg/pkg, Android apk/aab, iOS ipa). Checksum/signature side-files are hidden. (9d4a534)
    • Tutorials expansion — sub-tab switching, breadcrumb header, and prepare/switchSubTab hooks let tours open/close the dashboard customize panel and resolve targets behind sub-tabs; new steps for integrations, dashboard customize panel (presets / global / sections / perf cells), targets, scenes, and sync-clocks (en/ru/zh). (797b806)
    • Cards / settings / modal / toolbar polish — reworked mod-card colors, sections, channel-stripe styling, hairline borders, and signal-flow animation on running cards; multiselect bulk toolbar gets explicit Select-all / Deselect-all icons with luxury-gradient toolbar styling; Settings tabs are now icon-only (no overflow at any locale); modal exit animation gains symmetric fadeOut + slideDown keyframes with reduced-motion support; locale picker collapses to EN / RU / ZH; snack toast adopts a glass background with per-type accent. (a56569b)
    • Suppress browser auto-open on Windows login — when "Start with Windows" is enabled, the autostart shortcut now passes --autostart so the WebUI tab no longer pops on every login. Manual launches and the installer's "Launch LedGrab" finish-page action are unchanged. (de13f44)
    • Simpler segment payloadsSegmentPayload.start defaults to 0 and length defaults to "the rest of the strip from start". A single segment with only mode + color now fills the entire strip — no more length: 9999 magic value clients had to pass. (1c9acc5)
    • About panel now houses the author + contact details that previously lived in a global app footer, freeing up vertical space across every page (en/ru/zh donation.about_author key added). (816a27d)

    Performance

    • LED hot path is allocation-free per-frame: Adalight gets a dedicated single-worker tx executor, pre-allocated wire buffer, uint8 scratch, and a precomputed header struct; DDP gets a pre-built struct.Struct and memoryview emit path; calibration precomputes Phase 3 skip-LED resampling so per-frame work is now np.take + in-place blend; the WLED target processor gets a matching tightening. (797b806)

    Bug Fixes

    • Audio-source modal preserves device on refresh — refresh button moved into the label row (no more overflow past the Source panel edge); selection is restored by matching on (index, loopback) first with a trimmed-name fallback for OS-side reindexing; the EntitySelect trigger now syncs so the visible label matches the underlying <select> in edit mode. (0980cf4)
    • PWA meta tag — add the standard mobile-web-app-capable tag while keeping the Apple variant for iOS Safari, since Chrome deprecated apple-mobile-web-app-capable. (8e109f3)

    Development / Internal

    CI/Build

    • Add workflow_dispatch and skip lint/test on release commits (release.yml already runs in parallel; manual dispatch covers re-runs on demand). (033c1f6)

    Tests

    • New test_camera_engine suite covers the new capture path. (fdac26b)
    • Adalight + DDP tests cover header format, buffer reuse, non-contiguous input, brightness scaling, RGB/RGBW packets, sequence/PUSH semantics, and multi-packet fragmentation. (797b806)
    • 13 new tests for the device-event notifications backend (full suite still 899 passing). (8aa3a32)
    • conftest pre-creates the test DB so main.py's legacy-data migration no longer shovels the user's production DB into the test temp dir; test_preferences_notifications wipes its own setting at the start of the defaults test (was relying on isolation it never enforced). (9d4a534)

    Tooling

    • .mcp.json checked in with code-review-graph MCP server config so the graph tools are available out of the box. (797b806)

    All Commits
    Hash Message Author
    0980cf4 fix(ui): audio-source modal — preserve device on refresh, relocate refresh action alexei.dolgolyov
    fdac26b feat: daylight tz, camera engine, value stream + modal/UI polish alexei.dolgolyov
    816a27d refactor(ui): drop app footer, move author info to About panel alexei.dolgolyov
    797b806 feat: LED hot-path perf, tutorials expansion, modal markup polish alexei.dolgolyov
    9d4a534 feat(ui): release notes overlay v2 + settings/streams/dashboard polish alexei.dolgolyov
    51eebf2 feat(ui): redesign target pipeline as compact strip + chip row alexei.dolgolyov
    9067db2 feat(ui): align Targets metric cells with dashboard pattern alexei.dolgolyov
    233b463 feat(ui): migrate Targets cards to mod-card system alexei.dolgolyov
    de13f44 feat(autostart): suppress browser auto-open on Windows login alexei.dolgolyov
    1c9acc5 feat(api-input): make SegmentPayload start/length optional alexei.dolgolyov
    a56569b feat(ui): cards redesign + settings, modal, toolbar polish alexei.dolgolyov
    8aa3a32 feat(notifications): device event notifications (snack + Web Notifications) alexei.dolgolyov
    8e109f3 fix(pwa): add mobile-web-app-capable meta tag alexei.dolgolyov
    033c1f6 ci: add workflow_dispatch and skip lint/test on release commits alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.6.0-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.6.0-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.6.0-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.6.0-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.6.0
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.6.0
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.5.0 0804f54537

    LedGrab v0.5.0
    Build Release / create-release (push) Successful in 3s
    Build Android APK / build-android (push) Failing after 2m16s
    Build Release / build-linux (push) Successful in 3m54s
    Build Release / build-docker (push) Successful in 7m30s
    Build Release / build-windows (push) Successful in 8m37s
    Lint & Test / test (push) Successful in 8m45s
    Stable

    alexei.dolgolyov released this 2026-04-25 15:21:02 +03:00 | 157 commits to master since this release

    v0.5.0 (2026-04-25)

    This release ships the Lumenworks studio-console — a top-to-bottom WebUI redesign — plus a customizable per-account dashboard, a server-shutdown control, and a handful of dark/light/narrow-screen polish fixes.

    Features

    • Lumenworks studio-console WebUI redesign — new visual language across the entire WebUI: studio-console layout, refined typography, accent system, and motion. (539e431)
    • Extend the Lumenworks treatment to the Inputs, Integrations, and Graph tabs so the redesign is consistent across all top-level views. (b43e1cf)
    • Per-account customizable dashboard with a slide-in configuration panel — each user can pick their own widget layout, persisted per account. (56853b7)
    • Dashboard polish: richer performance strip, transport-bar controls, and additional readouts on the main view. (e5a2af9)
    • Item-card restyle with hover-driven performance tooltips and a configurable FPS ceiling. (70c95d1)
    • Live card-color picker — pick a custom color per card and see it apply instantly; default preset now uses the base palette. Monotonic uptime ticker no longer jitters on clock adjustments. (e0ff40f)
    • Server shutdown action exposed in the WebUI, backed by a public cancel_task lifecycle method so long-running tasks unwind cleanly. (3f80ef2)

    Bug Fixes

    • Channel stripe on item cards now only paints when the card has a custom color or is running — no more stray accents on idle defaults. (b1ee3c3)
    • Cards render correctly on pure black and pure white backgrounds, and are decoupled from the animated background so they stay legible regardless of the bg-anim setting. (dd415e2)
    • Single-row header layout and readable sidebar labels at narrow widths — fixes wrapping and label truncation on smaller windows. (2bae304)

    Development / Internal

    Chores

    • Harden test isolation, add .gitignore rule for stale src/data/, and mark the shutdown action done in the task tracker. (80f01d4)

    All Commits
    Hash Message Author
    80f01d4 chore: harden test isolation, gitignore stale src/data, mark shutdown action done alexei.dolgolyov
    b1ee3c3 fix(ui): channel stripe paints only on custom-color or running cards alexei.dolgolyov
    e0ff40f feat(ui): live card-color picker, monotonic uptime ticker tweaks, default preset uses base palette alexei.dolgolyov
    3f80ef2 feat: server shutdown action with public cancel_task lifecycle method alexei.dolgolyov
    2bae304 fix(ui): single-row header + readable sidebar labels at narrow widths alexei.dolgolyov
    dd415e2 fix(ui): cards on pure black/white, decoupled from bg-anim alexei.dolgolyov
    b43e1cf feat(ui): Lumenworks treatment for Inputs / Integrations / Graph tabs alexei.dolgolyov
    56853b7 feat(dashboard): per-account customizable dashboard with slide-in panel alexei.dolgolyov
    70c95d1 feat(ui): item-card restyle, perf hover tooltips, FPS ceiling alexei.dolgolyov
    e5a2af9 feat(ui): dashboard polish, richer perf strip, transport-bar controls alexei.dolgolyov
    539e431 feat(ui): Lumenworks studio-console WebUI redesign alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.5.0-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.5.0-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.5.0-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.5.0-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.5.0
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.5.0
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.4.2 c44bb38c43

    LedGrab v0.4.2
    Build Release / create-release (push) Successful in 3s
    Build Android APK / build-android (push) Failing after 2m5s
    Build Release / build-linux (push) Successful in 4m53s
    Build Release / build-docker (push) Successful in 5m39s
    Build Release / build-windows (push) Successful in 6m55s
    Lint & Test / test (push) Successful in 7m13s
    Stable

    alexei.dolgolyov released this 2026-04-22 20:20:30 +03:00 | 170 commits to master since this release

    v0.4.2 (2026-04-22)

    Bug Fixes

    • Ship previously-missing package assets in release artifacts — prebuilt notification sounds (alert, bell, chime, ping, pop) and game adapter YAMLs (minecraft, rocket_league, valorant). An unanchored data/ rule in .gitignore was matching server/src/ledgrab/data/, so these files never reached the tag or CI builds. Also bump the _FALLBACK_VERSION literal to 0.4.2 so the Windows installer (which strips .dist-info) reports the correct version in the WebUI instead of 0.3.0. Build scripts now patch this literal automatically to prevent future drift. (5db6edd)

    Features

    • Restyle the enhanced header locale picker as a LED-accent badge — 2-letter code in Orbitron, collapses to just the badge on narrow screens (9ce1dc3)

    Development / Internal

    CI/Build

    • Publish .sha256 sidecars alongside release assets for easier integrity verification (03d2e6b)

    Refactoring

    • Move the Key Colors test out of the lightbox and into the test-css-source modal where the rest of the source-render debug tools live (be2d5e1)

    All Commits
    Hash Message Author
    be2d5e1 refactor(color-strips): move Key Colors test from lightbox into test-css-source modal alexei.dolgolyov
    5db6edd fix(release): ship prebuilt assets and bump fallback version alexei.dolgolyov
    9ce1dc3 feat(ui): restyle enhanced header locale picker as LED-accent badge alexei.dolgolyov
    03d2e6b ci(release): publish .sha256 sidecars alongside release assets alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.4.2-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.4.2-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.4.2-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.4.2-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.4.2
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.4.2
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads
  • v0.4.1 c2c9af3c60

    LedGrab v0.4.1
    Build Release / create-release (push) Successful in 4s
    Build Android APK / build-android (push) Failing after 1m41s
    Build Release / build-linux (push) Successful in 3m3s
    Build Release / build-docker (push) Successful in 4m13s
    Lint & Test / test (push) Successful in 5m24s
    Build Release / build-windows (push) Successful in 5m33s
    Stable

    alexei.dolgolyov released this 2026-04-22 19:21:27 +03:00 | 176 commits to master since this release

    v0.4.1 (2026-04-22)

    Bug Fixes

    • Installer now bundles cryptography and just-playback, sets the TCL environment for Tk, and removes the stale debug.bat shim (4f7794c)

    Development / Internal

    CI/Build

    • Scope the Android keystore env correctly and fail loudly when a release build is attempted without a signing key (35b75a2)

    Documentation

    • Drop the stale WLED-rename task and document the Android signing secrets (a0d63a3)
    • Remove WLED-specific language from the auto-generated release notes template (4ed099d)

    All Commits
    Hash Message Author
    4f7794c fix(installer): bundle cryptography + just-playback, set TCL env, clean stale debug.bat alexei.dolgolyov
    a0d63a3 docs(release): drop stale WLED-rename task, document android signing secrets alexei.dolgolyov
    35b75a2 ci(android): fix keystore env scoping, fail loudly on release without key alexei.dolgolyov
    4ed099d docs(release): drop WLED-specific language from auto-generated release notes alexei.dolgolyov

    Downloads

    Platform File Description
    Windows (installer) LedGrab-v0.4.1-setup.exe Install with Start Menu shortcut, optional autostart, uninstaller
    Windows (portable) LedGrab-v0.4.1-win-x64.zip Unzip anywhere, run LedGrab.bat
    Linux LedGrab-v0.4.1-linux-x64.tar.gz Extract, run ./run.sh
    Android LedGrab-v0.4.1-android-release.apk Sideload on Android 7.0+ (API 24+) — TV boxes, Fire TV, phones, tablets. arm64-v8a / x86_64 / x86
    Docker See below docker pull + docker run

    After starting, open http://localhost:8080 in your browser.

    Docker

    docker pull git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.4.1
    docker run -d --name ledgrab -p 8080:8080 -v ledgrab-data:/app/data git.dolgolyov-family.by/alexei.dolgolyov/ledgrab:v0.4.1
    

    First-time setup

    1. Change the default API key in .
    2. Open http://localhost:8080 and add your LED devices.
    3. See for detailed configuration.
    Downloads