Kioskinäytön käynnistys webbikameran avulla

Ohjaan Home Assistant -kodinohjausjärjestelmää keittiössä sijaitsevalla kosketusnäytöllisellä tietokoneella. Koneessa on Ubuntu 24.04 LTS, GNOME/Wayland ja Chromium-selain kioskitilassa.

Haluan näytön olevan sammuksissa silloin, kun kukaan ei käytä sitä. Näyttö pimenee GNOMEn normaalin idle-toiminnon avulla, ja webbikamera toimii liiketunnistimena: kun kamera havaitsee liikettä, järjestelmään lähetetään virtuaalinen näppäinpainallus, joka herättää näytön.

Näytön pimennys

Esimerkiksi 30 minuutin joutokäyntiajan voi asettaa komennolla:

gsettings set org.gnome.desktop.session idle-delay 1800

Kioskikoneessa näytön automaattinen lukitus kannattaa yleensä poistaa käytöstä:

gsettings set org.gnome.desktop.screensaver lock-enabled false

Näin näyttö sammuu 30 minuutin kuluttua, mutta herätessään palaa suoraan kioskinäkymään.

Motion-liiketunnistus

Asennetaan motion:

sudo apt update
sudo apt install motion

Konfiguraatio löytyy tiedostosta:

sudo nano /etc/motion/motion.conf

Olennaiset asetukset ovat esimerkiksi:

daemon off

video_device /dev/video0

width 640
height 480
framerate 15

threshold 1500
despeckle_filter EedDl
minimum_motion_frames 1
event_gap 60
pre_capture 3
post_capture 0

picture_output off
movie_output off

on_event_start /usr/bin/ydotool key 57:1 57:0

Kuvia tai videoita ei tarvitse tallentaa, koska kameraa käytetään tässä vain liikkeen havaitsemiseen.

event_gap ei määrää näytön sammumisaikaa. Näytön pimennyksen hoitaa GNOME. Motionin tehtävänä on ainoastaan generoida näppäinpainallus, kun liikettä havaitaan.

ydotool

Waylandissa perinteinen xdotool ei ole sopiva tähän tarkoitukseen, joten käytän ydotool:ia. Se generoi näppäin- ja hiiritapahtumia Linuxin uinput-rajapinnan kautta eikä tarvitse X11:tä.

Asennus:

sudo apt install ydotool

ydotool key käyttää Linuxin input-keycodeja. Välilyöntinäppäimen eli KEY_SPACE:n keycode on 57:

grep -w KEY_SPACE /usr/include/linux/input-event-codes.h

Tuloksena pitäisi näkyä:

#define KEY_SPACE        57

Näin ollen kokonainen välilyöntinäppäimen painallus ja vapautus on:

ydotool key 57:1 57:0

missä:

  • 57:1 = välilyönti painetaan alas
  • 57:0 = välilyönti vapautetaan

Tämä on tärkeä ero esimerkiksi X11:n keycodeihin nähden. Aiemmin käyttämäni numero 65 oli X11:n välilyönnin keycode eikä oikea arvo nykyiselle ydotool:lle.

Motion-konfiguraatiossa käytän siis:

on_event_start /usr/bin/ydotool key 57:1 57:0

ydotoold-palvelu ja käyttöoikeudet

ydotool-komento lähettää tapahtumat ydotoold-daemonille Unix-socketin kautta. Daemon tarvitsee oikeuden käyttää /dev/uinput-laitetta.

Motion-palvelu puolestaan ajetaan normaalisti omalla motion-käyttäjällään:

systemctl cat motion.service

Ubuntu 24.04 -järjestelmässäni palvelu on:

[Unit]
Description=Motion detection video capture daemon
Documentation=man:motion(1)

[Service]
Type=simple
User=motion
ExecStart=/usr/bin/motion

[Install]
WantedBy=multi-user.target

Motionia ei siis tarvitse ajaa rootina.

Sen sijaan ydotoold voidaan ajaa rootina ja antaa socketin käyttöoikeus erilliselle ydotool-ryhmälle.

Luodaan ryhmä ja lisätään siihen sekä motion– että kioski-käyttäjät:

sudo groupadd -f ydotool
sudo usermod -aG ydotool motion
sudo usermod -aG ydotool kioski

Ryhmän voi tarkistaa:

getent group ydotool

Esimerkiksi:

ydotool:x:1002:motion,kioski

Oma systemd-palveluni /etc/systemd/system/ydotoold.service on:

[Unit]
Description=Ydotool Daemon
After=network.target

[Service]
Type=simple
User=root
Group=ydotool
ExecStart=/usr/bin/ydotoold --socket-perm=0660
Restart=on-failure

[Install]
WantedBy=multi-user.target

Muutosten jälkeen:

sudo systemctl daemon-reload
sudo systemctl enable --now ydotoold
sudo systemctl restart motion

Socketin oikeudet voi tarkistaa:

ls -l /tmp/.ydotool_socket

Tavoitteena on:

srw-rw---- 1 root ydotool ... /tmp/.ydotool_socket

Tällöin motion-käyttäjä saa käyttää daemonia, mutta socket ei ole avoin kaikille järjestelmän käyttäjille.

Toiminnan voi testata Motionin käyttöoikeuksilla:

sudo -u motion ydotool key 57:1 57:0

Jos näyttö on sammuksissa, sen pitäisi herätä.

Ubuntu-päivityksen jälkeen ilmennyt ydotoold-ongelma

Ubuntu-päivityksen jälkeen järjestelmässä oli samanaikaisesti kaksi ydotoold-prosessia:

kioski ... /usr/bin/ydotoold
root   ... /usr/bin/ydotoold --socket-perm=0660

Kioskikäyttäjän prosessi tuli paketista löytyvästä käyttäjäkohtaisesta systemd-palvelusta:

/usr/lib/systemd/user/ydotool.service

Palvelu oli otettu käyttöön globaalisti kaikille käyttäjille, joten se käynnistyi automaattisesti kioski-käyttäjän GNOME-istunnon mukana.

Tilanteen pystyi näkemään esimerkiksi:

sudo -u kioski XDG_RUNTIME_DIR=/run/user/1000 \
    systemctl --user status ydotool.service

Koska käytän omaa system-tason ydotoold.service-palvelua, ylimääräinen user-service poistettiin globaalista autostartista:

sudo systemctl --global disable ydotool.service

Tarkistus:

systemctl --global is-enabled ydotool.service

Tuloksen pitäisi olla:

disabled

Mahdollisesti jo käynnissä oleva käyttäjäkohtainen palvelu voidaan pysäyttää:

sudo -u kioski XDG_RUNTIME_DIR=/run/user/1000 \
    systemctl --user stop ydotool.service

Tämän jälkeen:

ps -eo user,pid,ppid,cmd | grep '[y]dotoold'

pitäisi näyttää vain system-tason daemon:

root ... /usr/bin/ydotoold --socket-perm=0660

Tämä korjasi myös tilanteen, jossa Motionin lokiin tuli:

failed to connect socket `/tmp/.ydotool_socket': Permission denied

Motion-palvelu

Motion aktivoidaan ja käynnistetään:

sudo systemctl enable --now motion

Tilan voi tarkistaa:

systemctl status motion

Lokista voi tarkistaa, että liiketapahtumat eivät aiheuta ydotool-virheitä:

journalctl -u motion -n 50 --no-pager

Jos Motionin ryhmäjäsenyyksiä tai ydotoold:n socket-oikeuksia muutetaan, Motion kannattaa käynnistää uudelleen:

sudo systemctl restart motion

Kioskikäyttäjän automaattinen kirjautuminen

Kone kirjautuu automaattisesti käyttäjän kioski GNOME-istuntoon.

Tiedostossa:

/etc/gdm3/custom.conf

on:

[daemon]
AutomaticLoginEnable=true
AutomaticLogin=kioski

Autologin on kioskikoneessa kätevä, mutta sillä on yksi sivuvaikutus: käyttäjä ei anna kirjautumisen yhteydessä salasanaa, joten GNOME Keyringiä ei välttämättä pystytä avaamaan automaattisesti kirjautumissalasanalla.

Chromium kioskitilassa

Firefox osoittautui GNOME/Wayland-kioskikäytössä hankalaksi, joten selain on vaihdettu Chromiumiin.

Chromium käynnistyy käyttäjän GNOME-istunnossa kioskitilaan esimerkiksi:

/snap/bin/chromium \
    --kiosk \
    --no-first-run \
    --disable-infobars \
    --disable-session-crashed-bubble \
    --disable-features=TranslateUI \
    --enable-features=UseOzonePlatform \
    --ozone-platform=wayland \
    --force-device-scale-factor=0.95 \
    http://homeassistant.lan.ld:8123

Käynnistys voidaan tehdä esimerkiksi käyttäjän autostart-.desktop-tiedostosta.

Chromium Snap ja GNOME Keyring

Ubuntu-päivityksen jälkeen Chromium alkoi käynnistyessään näyttää ilmoituksen:

Authentication required

Enter password to unlock your login keyring
The password you use to log in to your computer no longer matches
that of your login keyring.

Kioskinäyttö toimi normaalisti, kun kysely peruttiin, mutta sama kysely tuli jokaisen rebootin jälkeen.

Syyksi osoittautui yhdistelmä:

  • GDM:n automaattinen kirjautuminen
  • GNOME Keyring
  • Chromium Snapin password-manager-service-liitäntä

Tilanteen voi tarkistaa:

snap connections chromium | grep password

Minulla tulos oli:

password-manager-service  chromium:password-manager-service  :password-manager-service  manual

Tällöin Chromiumilla on yhteys GNOME Keyringiin.

Koska tällä kioskikoneella Chromiumiin ei ole tarvetta tallentaa salasanoja GNOME Keyringin avulla, yhteyden voi katkaista:

sudo snap disconnect chromium:password-manager-service

Tämän jälkeen tarkistus näyttää:

password-manager-service  chromium:password-manager-service  -  -

Rebootin jälkeen Chromium ei enää yritä avata GNOME Keyringiä eikä salasanakyselyä tule.

Tarvittaessa liitännän saa takaisin:

sudo snap connect chromium:password-manager-service

Huomio: ilman GNOME Keyringiä Chromium ei tarjoa samaa suojattua paikallista salasanasäilytystä. Kioskikoneessa selaimeen ei siksi kannata tallentaa käyttäjätunnuksia tai salasanoja.

Kokonaisuus

Toimintaketju on siis:

  1. GDM kirjautuu automaattisesti kioski-käyttäjänä.
  2. Chromium käynnistyy Home Assistant -sivulle kioskitilassa.
  3. GNOME sammuttaa näytön 30 minuutin käyttämättömyyden jälkeen.
  4. Motion tarkkailee webbikameran kuvaa.
  5. Kun kamera havaitsee liikettä, Motion suorittaa:
/usr/bin/ydotool key 57:1 57:0
  1. ydotool lähettää näppäintapahtuman rootina toimivalle ydotoold-daemonille.
  2. /tmp/.ydotool_socket kuuluu ryhmälle ydotool, johon myös motion kuuluu.
  3. Virtuaalinen välilyöntinäppäimen painallus herättää GNOMEn sammuttaman näytön.
  4. Chromiumin Snap-paketin password-manager-service on irrotettu, jotta autologin ei aiheuta GNOME Keyring -salasanakyselyä.
  5. Paketista tuleva käyttäjäkohtainen ydotool.service on poistettu globaalista autostartista, jotta koneella ei käynnisty kahta keskenään kilpailevaa ydotoold-daemonia.