enne2 db47640846 Nome stabile della seriale via udev e note sull'indicatore di cattura
- udev/99-ambilight.rules: symlink /dev/ambilight ancorato alla porta USB fisica
  (il CH340 clone non ha iSerial, quindi by-id non e' univoco), ID_MM_DEVICE_IGNORE,
  TAG+=uaccess
- setup-udev.sh: rileva VID/PID/porta, installa la regola, verifica il symlink
- backend: fallback di porta (config -> /dev/ambilight -> /dev/ttyUSB0) e campo 'dev'
  nello stato D-Bus
- README: tabella dei percorsi, prove sull'indicatore di condivisione schermo e le
  tre alternative (portal, KWin ScreenShot2, kmsgrab)
2026-11-01 13:16:08 +01:00

ambilight-plasmoid

Ambilight per KDE Plasma 6: cattura il bordo superiore dello schermo su Wayland (portal ScreenCast + PipeWire), calcola il colore medio di 47 zone e pilota una striscia WS2812B collegata a un ESP8266 (Wemos D1 mini) con firmware Adalight via seriale. Il controllo sta in un plasmoide nel vassoio di sistema, con popup per luminosità, contrasto, saturazione e banda campionata.

schermo ──portal──▶ ambilightd ──Adalight/seriale──▶ ESP8266 ──▶ striscia
                        ▲
                        │ D-Bus org.enne2.Ambilight
                        │
                ambilight-ctl  ◀── plasmoide (Plasma 6, QML)

Componenti

File Ruolo
backend/ambicapture.py negoziazione ScreenCast portal + pipeline GStreamer (pipewiresrc)
backend/ambilightd.py demone: cattura, calcolo zone, luminosità/contrasto/saturazione, invio Adalight, servizio D-Bus
backend/ambilight-ctl CLI che parla col demone e stampa JSON (usata dal plasmoide)
backend/ambilight.service unit systemd --user (avvio automatico al login)
package/org.enne2.ambilight/ plasmoide Plasma 6 (icona nel vassoio + popup con slider)
install.sh / uninstall.sh installazione e rimozione, senza root

Hardware

  • ESP8266 Wemos D1 mini (clone), firmware Adalight-FastLED con PIN_DATA 5 (= D1/GPIO5), Num_Leds = dimensione buffer (256): il numero reale di LED lo decide il software che invia i frame.
  • Striscia WS2812B 47 LED sul solo bordo superiore.
  • Cablaggio: D1 → 470 Ω → DIN, alimentatore 5 V separato (~60 mA/LED), massa comune, 1000 µF sull'alimentazione; level shifter 74AHCT125 se il filo dati è lungo.

Installazione

./install.sh          # backend + servizio utente + plasmoide

Al primo avvio il desktop chiede il permesso di condividere lo schermo: va concesso una volta (viene memorizzato in ~/.cache/ambilight/restore_token).

Il plasmoide appare nel vassoio come Ambilight (icona TV); clic per il popup.

Uso da terminale

ambilight-ctl state                     # JSON con tutto lo stato
ambilight-ctl start | stop | toggle
ambilight-ctl set brightness 0.8         # brightness|contrast|saturation|band|reverse|leds
ambilight-ctl get fps
systemctl --user status ambilight.service

Configurazione

~/.config/ambilight/config.json (scritto dal demone a ogni modifica):

chiave range default note
brightness 0.05 – 2.0 1.0 moltiplicatore
contrast 0.5 – 2.0 1.0 pivot sul grigio 128
saturation 0.0 – 2.0 1.0 0 = bianco e nero
band 0.02 – 0.5 0.12 frazione di altezza campionata
reverse bool true LED 0 sul lato destro (verificato a schermo)
leds 1 – 256 47 LED della striscia
port, baud – /dev/ttyUSB0, 115200 seriale
side top/bottom top bordo campionato
auto_start bool true streaming attivo all'avvio del demone

Prestazioni misurate

  • 47 LED, Adalight a 115200: ~78 fps (limite teorico della seriale per 147 byte/frame).
  • Cattura: portal + PipeWire, pipeline ridotta a 47×4 × 72 px RGB → costo CPU trascurabile.

Nome stabile del dispositivo seriale

La scheda (CH340, 1a86:7523) non espone un iSerial: verificato con cat /sys/bus/usb/devices/1-2/serial → vuoto. Di conseguenza:

percorso valore su questa macchina unico?
/dev/ttyUSB0 assegnato in ordine di enumerazione no
/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 derivato da ID_SERIAL=1a86_USB_Serial no (due cloni identici collidono)
/dev/serial/by-path/pci-0000:65:00.3-usb-0:2:1.0-port0 legato alla porta USB fisica sì
/dev/ambilight (regola udev) symlink creato da noi sì

Installa la regola (richiede sudo, una volta):

sudo ./setup-udev.sh /dev/ttyUSB0     # rileva la porta fisica e scrive /etc/udev/rules.d/99-ambilight.rules
ambilight-ctl set port /dev/ambilight
systemctl --user restart ambilight.service

La regola aggancia KERNELS=="<porta>" + VID/PID (non il numero ttyUSB), crea /dev/ambilight, aggiunge ID_MM_DEVICE_IGNORE (ModemManager smette di sondare la porta) e TAG+="uaccess" (accesso ACL all'utente attivo). Se sposti la scheda su un'altra porta USB il nome non segue: rilancia setup-udev.sh.

Il demone comunque ripiega su /dev/ambilight e poi /dev/ttyUSB0 se il percorso configurato non esiste, e riporta il dispositivo realmente aperto nel campo dev di ambilight-ctl state.

L'indicatore di condivisione schermo nel vassoio

Con la cattura via portal ScreenCast, KDE mostra nel vassoio un pallino rosso finché la sessione di condivisione è attiva. Verificato su questa macchina:

  • compare/scompare insieme allo streaming (diff di due screenshot: cambia solo quella regione del vassoio, ~1.500 px in 172x22);
  • non è un plasmoide di sistema (/usr/share/plasma/plasmoids non contiene nulla di simile) e non compare in knownItems/extraItems del vassoio, quindi non esiste la voce "Configure System Tray → Entries" per nasconderlo: è un indicatore di stato del shell, per scelta di KDE.

Le alternative per non averlo:

  1. KWin ScreenShot2 (nessun portal, nessun indicatore): KWin autorizza solo i processi con un .desktop che dichiara X-KDE-DBUS-Restricted-Interfaces=org.kde.KWin.ScreenShot2. Provato con un .desktop utente (Exec=/usr/bin/python3 e python3.14) + kbuildsycoca6: risponde ancora org.kde.KWin.ScreenShot2.Error.NoAuthorized. Non provato l'entry in /usr/local/share/applications (richiede sudo). Se funziona, la cattura è un CaptureArea della sola fascia (nessun indicatore, ma costo CPU per frame).
  2. kmsgrab (ffmpeg -f kmsgrab) da un servizio privilegiato con CAP_SYS_ADMIN: nessun portal e nessun indicatore, ma cattura DRM grezza (piano/format legati alla GPU) e un servizio di sistema: più fragile.
  3. Tenere il portal: costo GPU minimo, ~78 fps, indicatore visibile.

Note

  • Il firmware Adalight manda Ada\n una volta al secondo quando non riceve frame: è l'heartbeat del protocollo, non un errore.
  • Il demone tiene la seriale in esclusiva: Prismatik (o altri programmi Adalight) vanno chiusi.
  • ModemManager su Fedora può contendere /dev/ttyUSB0: se la porta risulta occupata serve una regola udev con ID_MM_DEVICE_IGNORE.

Licenza

GPL-3.0-or-later (come i componenti KDE con cui interagisce).

S
Description
Ambilight per KDE Plasma 6: demone Adalight (ESP8266/WS2812B) + applet nel vassoio con slider luminosita, contrasto, saturazione
Readme
113 KiB
Languages
Python 62.7%
QML 22.1%
Shell 15.2%