-
LedGrab v0.9.0
StableBuild Release / create-release (push) Successful in 4sBuild Android APK / build-android (push) Failing after 22sBuild Release / build-linux (push) Successful in 2m54sBuild Release / build-windows (push) Successful in 4m50sBuild Release / build-docker (push) Successful in 6m34sBuild Release / publish-release (push) Successful in 4sreleased this
2026-06-23 14:48:51 +03:00 | 0 commits to master since this releasev0.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 ahue_gradient_modetoggle (39b0554) - Nanoleaf extControl v2 per-panel UDP streaming (
per_panelmode) (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_docsflag (default off) to view/docs,/redoc, and
/openapi.jsonwithout 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-safeget_statscopy, MQTT discovery
lock,reactive_modeLiteral, 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.9.0-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.9.0-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.9.0-android-release.apkSideload 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.0First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
- Persistent activity/audit log: storage model with migration, recorder with
-
LedGrab v0.8.2
StableBuild Release / create-release (push) Successful in 3sBuild Android APK / build-android (push) Failing after 11sBuild Release / build-docker (push) Successful in 3m14sBuild Release / build-linux (push) Successful in 4m3sBuild Release / build-windows (push) Successful in 4m25sBuild Release / publish-release (push) Successful in 1sreleased this
2026-06-08 20:18:46 +03:00 | 22 commits to master since this releasev0.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
/snapshotresponse (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/settingsroute (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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.8.2-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.8.2-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.8.2-android-release.apkSideload 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.2First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
-
LedGrab v0.8.1
StableBuild Android APK / build-android (push) Failing after 11sBuild Release / create-release (push) Successful in 6sBuild Release / build-docker (push) Successful in 2m57sBuild Release / build-linux (push) Successful in 1m49sBuild Release / build-windows (push) Successful in 3m35sBuild Release / publish-release (push) Successful in 2sreleased this
2026-05-28 23:36:03 +03:00 | 62 commits to master since this releasev0.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_idis now threaded end-to-end throughDeviceCreate/DeviceUpdate/DeviceResponseand 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/graphreturns the full nodes + edges + validation topology, andGET /api/v1/graph/dependents/{kind}/{id}reports what references an entity (a5effba)
Aggregated snapshot endpoint
- New
GET /api/v1/snapshotreturns 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_deviceno longer masks an intentional 4xx (e.g. an unknownmqtt_source_idor 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.
homeassistantvsandroid). 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_iddevice 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.8.1-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.8.1-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.8.1-android-release.apkSideload 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.1First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
- The device editor now shows an MQTT broker picker for
-
LedGrab v0.8.0
StableBuild Release / create-release (push) Successful in 3sBuild Android APK / build-android (push) Failing after 8sBuild Release / build-linux (push) Successful in 3m8sBuild Release / build-docker (push) Successful in 4m11sBuild Release / build-windows (push) Successful in 4m55sBuild Release / publish-release (push) Successful in 1sreleased this
2026-05-28 17:48:18 +03:00 | 64 commits to master since this releasev0.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 toelapsedRealtimeNanoswith 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|specialUsewith properServiceCompat.startForegroundpromotion; Ethernet > Wi-Fi > VPN > cellular selection inNetworkUtils; Android 15 predictive-back viaenableOnBackInvokedCallback; 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:
processLockserialises EOF respawn vsstop()to prevent orphaned screenrecord; publish-before-start under@SynchronizedinCaptureService.restartRootPipelinecloses the orphan window during watchdog restarts; watchdog give-up bound corrected (ef1f9ea)
Backup format — bundled DB + assets ZIP
- Auto-backups now produce a
.zipcontainingledgrab.dbplus every file from the assets directory underassets/— matching the manualGET /api/v1/system/backupdownload. Restore accepts both.zipand legacy.dbinterchangeably - Partial-write hardening: writes stage to
<name>.partialthenos.replaceinto place — a crash mid-write never leaves a corrupt backup masquerading as valid. Stale.partialfiles 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.pyredirects spawned restart script stdout/stderr torestart.logand 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.iconow 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_soundandnotification_volumeare 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 singleLPMSG = POINTER(wintypes.MSG)class acrossWindowsShutdownGuardandPlatformDetector— fixes theexpected LP_MSG instance instead of pointer to _MSGerror and the resulting shutdown-guard / display-power-monitor failure on 3.13 (e4d24a0, 0d840ad)
Development / Internal
CI/Build
release.ymlnow creates the Gitea release as a draft and only flipsdraft=falseonce 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.tswrapsfetchWithAuthwith typedapiGet/apiPost/apiPut/apiPatch/apiDelete; 35 feature/core files migrated. FastAPI validation-array detail unwrap hardened. Automations editor's two hand-rolledRuleTypedispatch ladders converted toRecord<RuleType, ...>registries with an import-time exhaustiveness check (bb3a316) - types.ts split (audit H6): 1140 LOC
types.tssplit into 18 per-entity files undertypes/, 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 withentity-events.tstab 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.8.0-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.8.0-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.8.0-android-release.apkSideload 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.0First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
- 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
-
LedGrab v0.7.0
StableBuild Release / create-release (push) Successful in 3sBuild Android APK / build-android (push) Failing after 11sBuild Release / build-linux (push) Successful in 2m54sBuild Release / build-docker (push) Successful in 3m50sBuild Release / build-windows (push) Successful in 4m36sreleased this
2026-05-26 00:35:38 +03:00 | 76 commits to master since this releasev0.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.ps1argument handling + clearer logs (45d12b2)
Bug Fixes
- Survive PC restart — SQLite was running WAL with
synchronous=NORMALandDatabase.close()was never called, so an unclean Windows shutdown rolled the DB back to the last checkpoint and silently lost recent edits. Now usessynchronous=FULL+wal_autocheckpoint=100+ explicitwal_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_colorwas double-applyingbrightness_scalebelow 1 (quartered output for a half-scale) and skipping it above 1 (boost lost). Now oneclamp(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 —
userModifiedis now driven by actual edits, not deep-equal drift from defaults (e4bf58d) - Transport-bar uptime repaints on
/healthresponse instead of waiting up to ~10 s for the next poll (f1b0f0e) - Pre-merge device-support review pass —
update_deviceno longer double-encrypts secrets in memory;GET /devicesstrips paired-only secrets behind boolean flags; SSRF validation on every new driver; corrupt-envelope decrypt returns""instead of deleting the device row;update_deviceURL 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_eventraisesNotImplementedError(preserves the historical store contract) andcreate_sourcerunsbuild_sourcebefore_check_name_uniqueso an invalidsource_typeraises the right error (c1aa2eb) utils/url_scheme+utils/net_classifywere referenced but untracked on a clean checkout — server failed to start withModuleNotFoundError. Now committed (7736bc6)
Performance
- Capture hot paths vectorised — WGC swaps per-frame ~30 MB BGRA→RGB fancy-index allocations for
cv2.cvtColorinto a 3-slot pre-allocated pool; MSS usesscreenshot.raw + cv2.cvtColorwith 256-byte change-detection; DXcam/BetterCam fixes a silent name-mangling factory leak; dominant-colour reduction is ~10× faster via packed-RGBnp.bincount(f184ef0) - Event-driven frame hand-off —
LiveStreamgains aframe_id+Condition, consumers wait instead of polling, ring buffer grows 3 → 5 slots,_blend_u16usescv2.addWeighted. Up to oneframe_timeof glass-to-LED latency saved at matched FPS (ee4fa81) - WLED brightness threshold caches per-frame
np.maxkeyed 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 dispatch —
ColorStripStreamManager.acquire()andws_stream._create_stream()now share aSTREAM_BUILDERSregistry keyed by source type, with import-time coverage assertion against_SOURCE_TYPE_MAP. CSS response builder gets the same treatment (563cbac) - Value-source create / update —
ValueSourceStore.create_sourceshrinks from ~260 → ~25 lines via per-type builder/applier functions in a newstorage.value_source_factoriesmodule (3b8f00e) - SystemMetricsValueStream — three parallel
if/elifchains collapse into aMetricSpec(name, read_psutil, read_fallback, normalize, prime)registry incore.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_RENDERERSdict replace per-frame dict-rebuild + silent fire fallback (97dae2c) - Output-target response builders —
isinstanceladder + silent fabricated-LED fallback replaced with_TARGET_RESPONSE_BUILDERSdict and a runtimeRuntimeErrorfor unknown subclasses (2f15fbb) - Versioned data migrations — replaces a naked
blob.replace(...)migration withstorage.data_migrations.MigrationRunnerbacked by adata_migrationsaudit table and atomic transactions (563cbac)
Dedup / refactor
- Edge-to-LED kernels in
PixelMapper+AdvancedPixelMapperdeduped into a sharedcore.capture.edge_interpolationmodule (5fec8db) - HA/Z2M
_swap_color_sourceunified behind a sharedlight_target_helpers.swap_color_sourcehelper (29bdacf) - Single-pixel
_average_colorlifted out of 6 LED drivers intocore.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 widertypes.tsgod-module split is staged for a follow-up frontend sprint (05f73ee) - WebSocket auth — 11
except Exceptionsites around handshake replaced with a narrow_WS_SEND_BENIGN_EXCtuple; 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,/docsauth-gate (898912f) - Frontend infra — inbound-event allowlist mirroring the server side,
closeIfPristineadoption across editors, MiniSelect markup for filter pickers (ddae571) - PEP-604 union sweep —
ruff --select UP007,UP045 --fixconverted ~1760 sites fromOptional[T]/Union[X, Y]toT | None/X | Y. Hooks bumped to ruff v0.15.12 to recognise UP045 (888f8fd) - Typed window globals — 59
(window as any).foosites across 19 feature modules switched to typedwindow.fooagainstglobal-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 spurioussqlite3.ProgrammingErrorsetup 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.tomlmakes vex the project's primary code-search backend with auto-update + semantic embeddings (06273ba)REVIEW_TODO.mdcaptures audit items deliberately deferred;TODO.mdrecords 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.7.0-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.7.0-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.7.0-android-release.apkSideload 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.0First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
-
LedGrab v0.6.1
StableBuild Release / create-release (push) Successful in 4sBuild Android APK / build-android (push) Failing after 9sBuild Release / build-linux (push) Successful in 2m13sBuild Release / build-docker (push) Successful in 3m9sBuild Release / build-windows (push) Successful in 4m6sreleased this
2026-05-10 23:57:47 +03:00 | 132 commits to master since this releasev0.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
cfgabbreviation 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.6.1-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.6.1-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.6.1-android-release.apkSideload 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.1First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
-
LedGrab v0.6.0
StableBuild Release / create-release (push) Successful in 3sBuild Android APK / build-android (push) Failing after 3m52sBuild Release / build-linux (push) Successful in 5m20sBuild Release / build-docker (push) Successful in 6m20sBuild Release / build-windows (push) Successful in 7m7sreleased this
2026-05-01 19:11:15 +03:00 | 141 commits to master since this releasev0.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_settingsmodule anddaylight-tzfrontend 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
extraHtmlescape 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.Nshape, and the grid sizes so values like1m 43sno 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
--autostartso 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 payloads —
SegmentPayload.startdefaults to 0 andlengthdefaults to "the rest of the strip from start". A single segment with onlymode+colornow fills the entire strip — no morelength: 9999magic 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_authorkey 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.Structand memoryview emit path; calibration precomputes Phase 3 skip-LED resampling so per-frame work is nownp.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-capabletag while keeping the Apple variant for iOS Safari, since Chrome deprecatedapple-mobile-web-app-capable. (8e109f3)
Development / Internal
CI/Build
- Add
workflow_dispatchand skip lint/test on release commits (release.yml already runs in parallel; manual dispatch covers re-runs on demand). (033c1f6)
Tests
- New
test_camera_enginesuite 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)
conftestpre-creates the test DB somain.py's legacy-data migration no longer shovels the user's production DB into the test temp dir;test_preferences_notificationswipes its own setting at the start of the defaults test (was relying on isolation it never enforced). (9d4a534)
Tooling
.mcp.jsonchecked 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.6.0-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.6.0-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.6.0-android-release.apkSideload 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.0First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
-
LedGrab v0.5.0
StableBuild Release / create-release (push) Successful in 3sBuild Android APK / build-android (push) Failing after 2m16sBuild Release / build-linux (push) Successful in 3m54sBuild Release / build-docker (push) Successful in 7m30sBuild Release / build-windows (push) Successful in 8m37sLint & Test / test (push) Successful in 8m45sreleased this
2026-04-25 15:21:02 +03:00 | 157 commits to master since this releasev0.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_tasklifecycle 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
.gitignorerule for stalesrc/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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.5.0-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.5.0-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.5.0-android-release.apkSideload 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.0First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
-
LedGrab v0.4.2
StableBuild Release / create-release (push) Successful in 3sBuild Android APK / build-android (push) Failing after 2m5sBuild Release / build-linux (push) Successful in 4m53sBuild Release / build-docker (push) Successful in 5m39sBuild Release / build-windows (push) Successful in 6m55sLint & Test / test (push) Successful in 7m13sreleased this
2026-04-22 20:20:30 +03:00 | 170 commits to master since this releasev0.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 unanchoreddata/rule in.gitignorewas matchingserver/src/ledgrab/data/, so these files never reached the tag or CI builds. Also bump the_FALLBACK_VERSIONliteral to0.4.2so the Windows installer (which strips.dist-info) reports the correct version in the WebUI instead of0.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
.sha256sidecars alongside release assets for easier integrity verification (03d2e6b)
Refactoring
- Move the Key Colors test out of the lightbox and into the
test-css-sourcemodal 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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.4.2-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.4.2-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.4.2-android-release.apkSideload 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.2First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
- Ship previously-missing package assets in release artifacts — prebuilt notification sounds (
-
LedGrab v0.4.1
StableBuild Release / create-release (push) Successful in 4sBuild Android APK / build-android (push) Failing after 1m41sBuild Release / build-linux (push) Successful in 3m3sBuild Release / build-docker (push) Successful in 4m13sLint & Test / test (push) Successful in 5m24sBuild Release / build-windows (push) Successful in 5m33sreleased this
2026-04-22 19:21:27 +03:00 | 176 commits to master since this releasev0.4.1 (2026-04-22)
Bug Fixes
- Installer now bundles
cryptographyandjust-playback, sets theTCLenvironment for Tk, and removes the staledebug.batshim (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.exeInstall with Start Menu shortcut, optional autostart, uninstaller Windows (portable) LedGrab-v0.4.1-win-x64.zipUnzip anywhere, run LedGrab.bat Linux LedGrab-v0.4.1-linux-x64.tar.gzExtract, run ./run.sh Android LedGrab-v0.4.1-android-release.apkSideload 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.1First-time setup
- Change the default API key in .
- Open http://localhost:8080 and add your LED devices.
- See for detailed configuration.
Downloads
- Installer now bundles