openHAB: Put Mac to sleep
Einige von euch kennen das Problem sicherlich auch: du hast dich gerade gemütlich ins Bett gelegt (oder auch das Haus verlassen), und dann fällt dir ein, dass du den Rechner nicht in den Sleep-Mode geschickt hast.
Man hat diverse Möglichkeiten:
- Aufstehen bzw. umkehren. Die unattraktivste Option, das steht außer Frage.
- Sich per SSH einloggen und die Kiste schlafen schicken; das erfordert aber, dass auf dem Rechner der SSH-Port offen und der Rechner – gegebenenfalls auch von außen – erreichbar ist. Das ist nicht in jeder Umgebung gewünscht beziehungsweise möglich.
-
Mail.app missbrauchen. In den Mail-Filtern von Mail.app kann man sich eine Regel definieren, die beim Eintreffen einer Mail mit spezifischem Subject, beispielsweise „Put me to sleep, darling“, ein AppleScript ausführt, das den Rechner in den Sleep-Mode versetzt. Erfordert lediglich ein laufendes Mail.app, das in regelmäßigen Abständen Mails checkt. Da ich inzwischen aber auf allen Maschinen auf
mutt
umgestiegen bin (vgl. hier und hier), kam auch das für mich nicht in Frage. - Es gibt lustige Ansätze mit Hazel, Dropbox und AppleScript – fragt mal Google, ich hab diesen Weg nicht getestet.
- Und wenn sowieso schon ein openHAB läuft, kann man auch dieses zu dem Zweck heranziehen.
Um diesen Weg zu gehen, sind sowohl exec binding als auch network health binding in addons/
benötigt. Für die Demo lege ich eine eigene rechner.items nach configurations/items
.
Group:Switch:OR(ON, OFF) Rechner "Rechner [(%d)]" <network> (All)
Switch Petzi
"Petzi (MacPro)"
(Rechner)
{ nh="petzi", exec="OFF:ssh spillerm@petzi osascript -e 'tell application \"System Events\" to sleep'" }
Switch Pingo
"Pingo (iMac)"
(Rechner)
{ nh="pingo", exec="OFF:ssh mane@pingo osascript -e 'tell application \"System Events\" to sleep'" }
Was passiert hier? Ich definiere mir eine Gruppe namens „Rechner“, die in meiner Sitemap angezeigt werden soll. In der Übersicht wird die Anzahl der aktiven Hosts angezeigt werden ([(%d)]
), mit einem möglichst passenden Symbol (<network>
). Meine Gruppe hat derzeit zwei Items (Switch Petzi und Switch Pingo), deren Netzwerkstatus in regelmäßigen Abständen geprüft wird (nh="hostname"
). Meine Rechner haben jeweils eine feste IP, und hier läuft ein interner bind
, der für die Namensauflösung zuständig ist. Alternativ könnte man die Hosts auf der openHAB-Schüssel in die /etc/hosts
eintragen beziehungsweise IP-Adressen in der openHAB-Konfiguration verwenden.
Für die Demo bauen wir uns dann noch eine rechner.sitemap und legen diese nach configurations/sitemaps
. Aufrufen können wir das Ganze nun per http://$SERVERNAME:8080/openhab.app?sitemap=rechner
. Reagiert der Host auf die nh
-Überprüfung, springt der Switch auf ON
:
12:01:31.826 [DEBUG] [o.o.b.n.i.NetworkHealthBinding:75 ] - established connection [host 'pingo' port '0' timeout '5000']
12:01:31.848 [INFO ] [runtime.busevents :26 ] - Pingo state updated to OFF
12:02:34.871 [DEBUG] [o.o.b.n.i.NetworkHealthBinding:75 ] - established connection [host 'petzi' port '0' timeout '5000']
12:02:34.915 [INFO ] [runtime.busevents :26 ] - Petzi state updated to ON
Setzt man den Switch Petzi nun im Webinterface auf OFF
, so wird das hinterlegte Kommando ausgeführt:
$ ssh spillerm@petzi osascript -e 'tell application \"System Events\" to sleep'
Erforderlich ist hierzu, dass sich der User spillerm
auf petzi
einloggen darf, ohne ein Passwort eingeben zu müssen – ich habe den passenden SSH-Key hinterlegt. Nun kann ich, egal wo ich bin, meinen Rechner einschlafen lassen. Aufwecken wäre sicherlich auch möglich, aber damit habe ich mich nicht weiter beschäftigt, da ich das nicht möchte – die Rechner müssten auf Wake on LAN konfiguriert werden, und das verursacht hier üblicherweise Stress.
Gerade der Pro zickt ganz gerne mal und will partout nicht schlafen; zur Eingrenzung, was da gerade quersteckt, ist das folgende Kommando recht hilfreich:
$ pmset -g assertions
27/02/15 12:50:21 GMT+1
Assertion status system-wide:
BackgroundTask 0
PreventDiskIdle 0
ApplePushServiceTask 0
UserIsActive 1
PreventUserIdleDisplaySleep 1
InteractivePushServiceTask 0
PreventSystemSleep 0
ExternalMedia 1
PreventUserIdleSystemSleep 1
NetworkClientActive 0
Listed by owning process:
pid 16(powerd): [0x000000090000012e] 04:28:33 ExternalMedia named: "com.apple.powermanagement.externalmediamounted"
pid 208(coreaudiod): [0x000000010000033e] 01:17:27 NoIdleSleepAssertion named: "com.apple.audio.'AppleHDAEngineOutput:1B,0,1,2:0'.noidlesleep"
pid 86(hidd): [0x0000000a0000033c] 01:17:29 UserIsActive named: "com.apple.iohideventsystem.queue.tickle"
Timeout will fire in 1143 secs Action=TimeoutActionRelease
pid 291(iTunes): [0x000000010000033f] 01:17:27 PreventUserIdleSystemSleep named: "com.apple.iTunes.playback"
pid 291(iTunes): [0x000000050000033d] 01:17:27 PreventUserIdleDisplaySleep named: "Nameless (via IOPMAssertionCreate)"
Kernel Assertions: 0xc=USB,BT-HID
id=500 level=255 0x4=USB mod=27/02/15 08:25 description=EHCI owner=AppleUSBEHCI
id=503 level=255 0x4=USB mod=27/02/15 08:37 description=UHC3 owner=AppleUSBUHCI
id=505 level=255 0x8=BT-HID mod=01/01/70 01:00 description=com.apple.driver.IOBluetoothHIDDriver owner=BNBMouseDevice
id=506 level=255 0x8=BT-HID mod=01/01/70 01:00 description=com.apple.driver.IOBluetoothHIDDriver owner=BNBTrackpadDevice
Und damit verabschiede ich mich ins Wochenende und wünsche euch eine tolle Zeit :)
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten