Controller an, Schreibtisch aus — der schwierige Teil war das Nein
An meinem Rechner hängen zwei Arbeitsmonitore und, quer durchs Zimmer, ein Fernseher. Es gab schon ein Skript, das auf Knopfdruck von einem auf den anderen umschaltet: Monitore aus, Fernseher an, Ton auf den Fernseher, Steam im Wohnzimmer-Modus. Jetzt sollte der Controller das auslösen — einschalten, hinsetzen, fertig. Das Erkennen des Controllers war der kleinere Teil. Die eigentliche Arbeit steckte in einer Frage, die ich anfangs gar nicht gestellt hatte: Wie widerspricht man einer Automatik, die gerade dabei ist, den eigenen Bildschirm abzuschalten?
Der Ausgangspunkt war bequem. Ein Eintrag im Menü, ein Klick, und der Schreibtisch wird zur Konsole. Beide Monitore gehen aus, der Fernseher wacht mit der richtigen Bildwiederholrate auf, der Ton wandert auf den Fernseher-Anschluss, und Steam startet neu in dem Modus, den man mit einem Controller bedienen kann. Schließt man diesen Modus wieder, kommt alles von selbst zurück.
Nur: Bis zu diesem Klick muss man noch am Schreibtisch sitzen. Wer schon auf dem Sofa liegt, steht wieder auf. Der Controller sollte das übernehmen.
Der naheliegende Weg ist der falsche
Wenn ein Controller sich per Funk verbindet, taucht er im Linux-System als neues Eingabegerät auf — so, wie es eine frisch eingesteckte Tastatur täte. Dafür gibt es einen Mechanismus, der auf genau solche Ereignisse reagiert, und der war mein erster Gedanke.
Er ist die falsche Ebene. Dieser Mechanismus läuft tief im System, außerhalb jeder Benutzersitzung — er weiß nichts von meinem Bildschirm, meinem Ton und meinen Fenstern. Alles, was hier passieren soll, gehört aber genau dorthin. Man müsste die Meldung also erst wieder von unten nach oben durchreichen, und das ist umständlicher, als es klingt.
Der bessere Weg liegt eine Etage höher: Der Dienst, der die Funkverbindungen verwaltet, meldet jede Verbindung und jede Trennung ohnehin an alle, die zuhören wollen — und man darf als normaler Benutzer zuhören, aus der eigenen Sitzung heraus, mit allem Zugriff auf Bildschirm und Ton. Kein Abfragen im Sekundentakt, keine Rechte, die man sich nicht sowieso schon hat.
Das war der Teil, der schnell ging.
Die Taste kennt den Unterschied nicht
Ein Xbox-Controller verbindet sich, wenn man die große Taste in der Mitte drückt. Das tut man auf dem Sofa, bevor man spielt. Man tut es aber auch am Schreibtisch, um kurz zu sehen, ob der Akku noch reicht — oder weil man den Controller beim Aufräumen in der Hand hatte.
Für die Automatik sieht beides identisch aus. Ohne Vorkehrung heißt das: Ich hebe mitten in der Arbeit einen Controller hoch, und beide Monitore werden schwarz, während der Fernseher im Nebenzimmer angeht und Steam neu startet.
Das ist keine theoretische Sorge. Es ist mir beim ersten echten Test genau so passiert — der Beweis steht unten im Protokoll.
Also bekommt die Automatik eine Wartezeit. Zwischen „Controller verbunden“ und „Schreibtisch aus“ liegen fünfzehn Sekunden, in denen eine Meldung mit einem Abbrechen-Knopf auf dem Bildschirm steht. Wer nichts tut, bekommt den Wohnzimmer-Modus. Wer widerspricht, arbeitet weiter.
Klingt nach einer Kleinigkeit. Es sind drei Entscheidungen, die alle auf dieselbe Frage hinauslaufen: Wann gilt Schweigen als Zustimmung?
Erstens: Der Countdown braucht seine eigene Uhr
Solche Meldungen haben von Haus aus eine Anzeigedauer. Es liegt nahe, die einfach als Countdown zu benutzen: Meldung für fünfzehn Sekunden einblenden, und wenn sie verschwindet, umschalten.
Das geht schief, weil die Anzeigedauer ein Wunsch ist, kein Vertrag. Welches Programm die Meldungen auf dem Bildschirm darstellt, ist unter Linux frei wählbar, und die gängigen Varianten gehen unterschiedlich damit um — manche halten sich daran, manche ignorieren den Wunsch, manche lassen wichtige Meldungen grundsätzlich stehen. Eine Automatik, die ihre Uhr aus der Bildschirmanzeige bezieht, läuft auf dem einen Rechner nach fünfzehn Sekunden und auf dem nächsten gar nicht.
Also zählt die Automatik selbst. Die Meldung ist nur noch das Gesicht des Countdowns, nicht sein Uhrwerk.
Zweitens: Wegwischen heißt nein, Ignorieren heißt ja
Wenn so eine Meldung vom Bildschirm verschwindet, bekommt das auslösende Programm eine Nachricht — und darin steht auch, warum sie verschwunden ist. Die Zeit war um. Der Benutzer hat sie weggewischt. Oder das Programm hat sie selbst geschlossen.
Diese Unterscheidung ist die ganze Miete. „Zeit war um“ heißt: Der Mensch hat die Meldung gesehen und nichts unternommen — das ist Zustimmung. „Weggewischt“ heißt: Der Mensch hat sie in die Hand genommen und beiseitegeschoben — das ist eine bewusste Geste, und die soll den Vorgang abbrechen, auch ohne dass jemand den Abbrechen-Knopf trifft.
Wer diese beiden Fälle zusammenwirft, baut eine Automatik, die entweder nie auslöst oder sich nicht abwimmeln lässt.
Drittens: Wer nicht fragen kann, handelt nicht
Und wenn die Meldung sich überhaupt nicht anzeigen lässt? Weil gerade keine grafische Sitzung läuft, weil das zuständige Programm abgestürzt ist, weil der Rechner ohne Bildschirm hochgefahren wurde?
Zwei Haltungen sind denkbar. „Dann eben ohne Rückfrage“ — oder „dann lieber gar nicht“. Ich habe mich für das Zweite entschieden, und zwar als Grundeinstellung. Eine Rückfrage, die niemand sehen kann, ist keine Rückfrage. Sie so zu behandeln, als hätte jemand zugestimmt, ist schlimmer, als gar nicht erst zu fragen: Die Automatik tut dann genau in dem Moment etwas Einschneidendes, in dem ihr niemand widersprechen könnte.
Wer das anders sieht — etwa auf einem Rechner ohne Bildschirm, wo die Rückfrage nie ankommen kann und trotzdem gehandelt werden soll —, kann es umstellen. Aber man muss es ausdrücklich tun.
Nur der Übergang zählt
Ein letzter Fallstrick, den man erst beim zweiten Anmelden bemerkt: Beim Start liest die Automatik, welche Geräte gerade verbunden sind. Täte sie das nicht, würde sie bei jedem Anmelden feststellen „der Controller ist verbunden“ und den Wohnzimmer-Modus starten. Gemeint ist aber nicht der Zustand „verbunden“, sondern der Übergang von getrennt zu verbunden. Der Anfangszustand wird deshalb gemerkt, aber nicht beantwortet.
Ein Fehler, den erst der Test gezeigt hat
Weil das Werkzeug allgemein werden sollte, kann es auch auf das Trennen reagieren — etwa: Wenn das Telefon den Raum verlässt, sperre den Bildschirm. Nur trennt sich Bluetooth dauernd für ein paar Sekunden, und ein Controller, der nach einer Viertelstunde Ruhe einschläft, hat den Raum nicht verlassen. Dagegen gibt es eine Schonfrist: Erst wenn das Gerät nach der eingestellten Zeit immer noch weg ist, passiert etwas. Kommt es zurück, wird abgeblasen.
Genau das tat es nicht. Ich hatte die Prüfungen in der falschen Reihenfolge: Erst wurde aussortiert, welche Regeln sich überhaupt für dieses Ereignis interessieren — und eine Regel, die auf das Trennen hört, interessiert sich definitionsgemäß nicht für das Verbinden. Damit flog ausgerechnet das Ereignis raus, das die Schonfrist hätte abblasen sollen. Die Schonfrist lief also immer ab, und das Abblasen war totes Gewicht. Der Fehler war in der Logik unsichtbar und im Test sofort zu sehen: Gerät trennen, eine Sekunde warten, Gerät zurückholen — und die Sperre kam trotzdem.
Dabei fiel ein zweiter auf. Die laufenden Schonfristen waren nur nach dem Namen der Regel abgelegt, nicht nach dem Gerät. Bei einer Regel, die für mehrere Geräte gilt, hätte die Rückkehr des einen die Schonfrist des anderen mit abgeblasen. Beides ist repariert und mit Tests abgesichert, die genau diese Fälle durchspielen.
Was am Ende dabei herauskam
Ein kleines Werkzeug, das Bluetooth-Geräte mit Befehlen verbindet — und das man sich vor allem deshalb angeschaut haben sollte, weil es widersprechen lässt. Eine Regel besteht aus: welches Gerät, verbinden oder trennen, welcher Befehl, wie lange Bedenkzeit, und optional zwei Bedingungen, die den Auslöser abwürgen (bei mir: nur wenn der Fernseher überhaupt angeschlossen ist, und nicht wenn der Modus schon läuft).
Der erste echte Durchlauf steht im Protokoll: Um 17:00:18 verbindet sich der Controller, um 17:00:34 startet der Umschalter — sechzehn Sekunden später, also genau nach der Bedenkzeit. Eine Sekunde danach sind beide Monitore aus. Um 17:01:06 kommen sie zurück, weil ich von Hand zurückgeschaltet habe: Ich saß ja am Schreibtisch und hatte den Abbrechen-Knopf nicht getroffen. Der Test hat damit beides bewiesen — dass es funktioniert, und dass die Bedenkzeit kein Zierrat ist.
Für alle, die das nachbauen wollen
Die Begriffe in echt: Der Verwaltungsdienst für Funkverbindungen heißt
BlueZ und meldet sich über den systemweiten Nachrichtenbus
D-Bus; das Signal, auf das man hört, ist
PropertiesChanged auf der Eigenschaft Connected. Der
Mechanismus für Geräteereignisse, den ich verworfen habe, ist udev.
Die Bildschirmmeldungen laufen über org.freedesktop.Notifications;
die Begründung, warum eine Meldung verschwunden ist, kommt im Signal
NotificationClosed — 1 für abgelaufen, 2
für weggewischt, 3 für selbst geschlossen. Das Werkzeug läuft als
systemd-Dienst der Benutzersitzung, nicht des Systems.
bluetoothctl devices Paired # Adressen der gekoppelten Geräte
bt-trigger list # dasselbe, plus Name und Verbindungszustand
bt-trigger monitor # Ereignisse live mitlesen, ohne etwas auszulösen
bt-trigger dry-run couch-mode # Countdown zeigen, Befehl nur ausgeben
journalctl --user -u bt-trigger -f
Und die Regel selbst, vollständig:
[rule:couch-mode]
device = AA:BB:CC:11:22:33
event = connect
confirm = 15
command = ~/.local/bin/tv-game-mode on
when = ~/.local/bin/tv-game-mode available
unless = ~/.local/bin/tv-game-mode status --quiet
Das Werkzeug liegt unter der MIT-Lizenz auf GitHub: maTzko13/bt-trigger. Das Umschalt-Skript für Monitore, Ton und Steam liegt als Beispiel dabei — es ist auf meinen Rechner zugeschnitten und als Vorlage gedacht, nicht zur Installation. Seine Kommentare enthalten die vier Dinge, die mich beim Bauen Zeit gekostet haben, darunter die unangenehmste: Warum man Steam nicht in das übliche Spiele-Hilfsprogramm einwickeln darf — der dabei gesetzte Ladetrick wird an jeden Hilfsprozess vererbt, und die sterben reihenweise daran.
Was ich daraus mitgenommen habe
- Bei Automatik ist das Auslösen der einfache Teil. Die Arbeit steckt in der Frage, wie ein Mensch widerspricht — und was passiert, wenn er es nicht kann.
- Ein Countdown darf seine Zeit nicht von der Anzeige beziehen, die ihn darstellt. Sonst hängt das Verhalten davon ab, welches Programm die Meldungen zeichnet.
- „Ignoriert“ und „weggewischt“ sind nicht dasselbe. Die eine Geste ist Zustimmung, die andere ein Nein — und diese Information wird tatsächlich mitgeliefert.
- Wenn die Rückfrage nicht ankommen kann, ist Nichtstun die richtige Vorgabe. Zustimmung zu unterstellen, weil niemand widersprochen hat, ist genau dann falsch, wenn niemand widersprechen konnte.
- Zustand und Übergang auseinanderhalten. „Ist verbunden“ und „hat sich gerade verbunden“ sehen im Code fast gleich aus und verhalten sich bei jedem Anmelden völlig verschieden.
- Die Reihenfolge von Prüfungen ist Logik, nicht Formsache. Meine Schonfrist ließ sich nicht abbrechen, weil das rettende Ereignis eine Zeile zu früh aussortiert wurde.
Dieselbe Frage stellt sich bei jeder Automatisierung, die im Betrieb etwas Sichtbares tut — ein Skript, das Rechner abends herunterfährt, eine Regel, die Postfächer umleitet, ein Wartungsfenster, das sich selbst startet: Wer merkt es rechtzeitig, und wie sagt er Nein? Wenn Sie so etwas planen, schreiben Sie mir.
Transparenz: Diese Notiz ist mit KI-Unterstützung geschrieben — auf Basis meiner eigenen Aufzeichnungen und Systeme, inhaltlich von mir geprüft. Die redaktionelle Verantwortung liegt bei mir.
Die Konfigurationen hier stammen aus meinem privaten Homelab. Das Umschalten von Bildschirmen greift tief in die Sitzung ein — bauen Sie sich einen Rückweg, der ohne den gerade abgeschalteten Bildschirm funktioniert, bevor Sie so etwas scharf schalten.