Script-Time: Auto-(Un-)lock-Service

Anwesenheitsprüfung als Service auf einem Linux-System

Script-Time: Auto-(Un-)lock-Service
Photo by Mohammad Rahmani / Unsplash

Ich hatte in einem früheren Post bereits ein Script erstellt, mit dem sich die Nähe des Benutzers feststellen lässt. Dieses Script soll nun nicht mehr per Cron jede Minute gestartet werden, sondern als Service im Hintergrund aufpassen. Meine Erwartung ist, dass die Reaktionszeit und Zuverlässigkeit deutlich verbessert wird.

Script-Time: Auto-(Un-)Lock Laptop
Wäre es nicht angenehm, wenn der Rechner “unlocked” ist, solange man davor sitzt? Und wenn man den Raum verlässt wäre es gut, er wäre “locked” und der Bildschirm aus? Und wenn jetzt der Rechner noch aufpassen würde, falls jemand sich an meinen Arbeitsplatz setzt? Ich habe das für mich mit

Das Script

Das Script soll nun permanent laufen. Es prüft jeden einzelnen Versuch mein Smartphone zu erreichen. Dabei werden die Fehlversuche gezählt. Sollten zu viele Versuche erfolglos gewesen sein, wird der Rechner gesperrt und der Bildschirm ausgeschaltet. Auch die Kameraüberwachung wird wieder scharf gestellt. Der Fantasie sind keine Grenzen gesetzt. Es sieht jetzt so aus:

#!/bin/bash
###############################################################################
###                           check_presence                               ###
###  Prüft über Bluetooth, ob das Phone MM-Phone in Reichweite ist.        ###
###  Falls der Bildschirm nicht ausgeht, als normaler User                 ###
###  `xhost +SI:localuser:root` eingeben.                                    ###
###  Dieser Befehl kann auch in der ~/.xprofile hinterlegt und permanent   ###
###  gemacht werden.                                                        ###
###  Das Skript überprüft alle 10 Sekunden, ob das Gerät erreichbar ist.   ###
###  Bei Nichterreichbarkeit wird der Bildschirm ausgeschaltet und         ###
###  die Sitzung nach 20 erfolglosen Versuchen gesperrt.                    ###
###############################################################################

# Pfad zur Flag-Datei, die den Zustand speichert
FLAG=/tmp/present.flag

# MAC-Adresse des Telefons (Bluetooth)
PHONEMAC="ba:09:87:65:43:21"

# Ermitteln des Hauptbenutzers mit den meisten Sessions
MAINUSER=$(who | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 1 | awk '{print $2}')

# Maximale Anzahl an Versuchen ohne Antwort
MAXNORESPONSES=20
# Zähler für fehlgeschlagene Versuche
NORESPONSES=0

# Bluetooth-Adapter aktivieren
hciconfig hci0 up

# Endlosschleife, die den Zustand überprüft
while true; do
    # Überprüfen, ob das Telefon per Bluetooth erreichbar ist
    if l2ping -c 1 -t 3 $PHONEMAC > /dev/null 2>&1; then
        # Gerät ist erreichbar
        NORESPONSES=0  # Zähler zurücksetzen

        # Wenn die Flag-Datei noch nicht existiert, dann anzeigen und den Bildschirm aktivieren
        if [ ! -e $FLAG ]; then
            echo "MM in der Nähe" > $FLAG
            export DISPLAY=:0
            xset dpms force on  # Bildschirm einschalten
            # Optional: Ton abspielen (falls gewünscht, auskommentiert)
            # su -c 'play -q /path/to/sound.wav' $MAINUSER
            killall motion  # Alle laufenden Motion-Instanzen stoppen
            loginctl unlock-sessions  # Sitzungen entsperren
        fi
    else
        # Gerät ist nicht erreichbar
        if [ $NORESPONSES -ge $MAXNORESPONSES ]; then
            # Wenn zu viele fehlgeschlagene Versuche, dann Bildschirm ausschalten und Sitzung sperren
            if [ -e $FLAG ]; then
                loginctl lock-sessions  # Sitzungen sperren
                sleep 5  # Warten, bevor der Bildschirm ausgeschaltet wird
                export DISPLAY=:0
                xset dpms force off  # Bildschirm ausschalten
                motion  # Motion wieder starten
                rm $FLAG  # Flag-Datei löschen
            fi
        fi
        # Zähler für fehlgeschlagene Versuche erhöhen
        ((NORESPONSES++))
    fi

    # Alle 10 Sekunden erneut prüfen
    sleep 10
done

Das Script habe ich unter /usr/local/bin/presencecheck gespeichert. Motion ist bei mir so konfiguriert, dass nach Aufzeichnung eines Videos dieses an mein Smartphone geschickt wird, falls die Datei größer als 1MB ist. Kleinere Dateien enthalten bei mir erfahrungsgemäß nur das Einschalten des Lichtes im Büro oder andere kurzzeitige Veränderungen. Ich denke darüber nach, ob ich Motion durch Frigate ersetze. Denn es interessiert nur, wenn sich ein Mensch an meinem Rechner zu schaffen macht.

KI: Kleine Fortschritte auf meinem Weg...
Frigate: Intelligente Objekterkennung für private Haussicherheit und Automatisierung mit ioBroker Nachdem ich nun von Hand meine KI trainiert habe und die Trainingsdaten auf Videostreams angewendet habe, habe ich jetzt auch fertige Tools gefunden, die sich leicht in die Automation einbinden lassen.…

Service erstellen

Jetzt müssen wir dem systemd noch erklären, dass wir dieses Script permanent in Betrieb haben wollen. Das mache ich in der Datei /etc/systemd/system/presencecheck.service:

[Unit]
Description=Bluetooth Unlock Service
After=bluetooth.target
 	 	 	 	 	 	 	 	 	 	
[Service]
ExecStart=/usr/local/bin/presencecheck
Restart=always
 	 	 	 	 	 	 	 	 	 	
[Install]
WantedBy=default.target

Mit chmod 644 habe ich die richtigen Rechte zugewiesen. Als nächstes muss systemd noch mitgeteilt werden, dass ein neuer Service erschienen ist. Das mache ich mit folgendem Befehl:

systemctl daemon-reload

Damit sind alle Vorbereitungen abgeschlossen.

Service starten

Mit systemctl start presencecheck kann der Dienst nun gestartet werden. Damit er auch direkt beim Booten mitgestartet wird geben wir systemctl enable presencecheck ein. Ich erledige beide Schritte gleichzeitig mit folgendem Befehl:

systemctl enable --now presencecheck

Funktion prüfen

Da die Anwesenheitskontrolle nun ein normaler Systemdienst ist, kann er auch genauso geprüft und gestoppt werden.

Ob der Dienst läuft, erfahren wir so:

# systemctl status presencecheck

● presencecheck.service - Bluetooth Unlock Service
     Loaded: loaded (/etc/systemd/system/presencecheck.service; enabled; preset: disabled)
     Active: active (running) since Sat 2024-01-13 19:57:01 CET; 54min ago
   Main PID: 70579 (check_presence)
      Tasks: 2 (limit: 18846)
     Memory: 916.0K (peak: 1.9M)
        CPU: 1.397s
     CGroup: /system.slice/presencecheck.service
             ├─70579 /bin/bash /usr/local/bin/presencecheck
             └─78215 sleep 10

Jan 13 19:57:01 michael systemd[1]: Started Bluetooth Unlock Service.

Wir sehen also leicht, dass der Dienst aktiv ist und läuft. Er ist auch enabled, sodass er beim nächsten Systemstart wieder gestartet werden wird.

Fazit

Die Umstellung von Cron- auf Servicebetrieb hat die Fehlauslösungen auf Null gebracht. Meine Laptops erkennen jetzt meine Anwesenheit deutlich schneller.

Ich hatte die Befürchtung, daß die häufigen Bluetoothabfragen negative Auswirkungen auf die Akkulaufzeit haben. Da das Script lange Intervalle nutzt, solange das Smartphone antwortet, ist dies nicht der Fall. Erst wenn das Phone nicht erreichbar ist, werden die Intervalle stark verkürzt. Aber davon bekommt das Telefon ja nichts mit 😉