Homebridge Start und Status in FHEM: Unterschied zwischen den Versionen

Aus FHEMWiki
K (Typos/Spelling)
 
(43 dazwischenliegende Versionen von 9 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Der Artikel befindet sich noch im Aufbau.
Um nicht bei jeder Änderung, welche die Homebridge betrifft, diese über die Console manuell neustarten zu müssen zeigt diese Lösung wie dies bequem aus FHEMWEB erfolgen kann. In den nachfolgenden Abschnitten sind die einzelnen Schritte dazu erläutert.


Achtung: Die Code Zeilen sind direkt der FHEM Config Datei entnommen.
== Vorwort ==
Die im weiteren genutzten Bezeichnungen von Dummys, Scriptdateinamen o.ä. können geändert werden. Die Änderungen müssen jedoch auch an allen entsprechenden Stellen vorgenommen werden.
Genannte IP Adressen, Benutzernamen und Passwörter sind auf die eigenen Gegebenheiten anzupassen. Die Berechtigungen des Benutzers müssen zur Ausführung der Scripte geprüft und ggf. angepasst werden. Entsprechende Linux Kenntnisse sollten vorhanden sein. Dieser Artikel berücksichtigt dass FHEM und Homebridge nicht zwingend auf dem selben System laufen. Die hier gezeigte Lösung kann für beide Varianten genutzt werden, FHEM und Homebridge auf dem gleichen System oder auf getrennten Systemen.


Ich war es leid bei jeder Änderung die Homebridge betrifft immer wieder auf die Console zu müssen um den Dienst neu zustarten.
== Umsetzung ==
Hier aus ist dann das folgenden entstanden.
Was noch nicht geht ist die Erkennung wenn Homebridge abgeschmiert ist.
Dies wird nach möglichleit zu einem späterem Zeitpunkt umgesetzt.


Grundlage ist das Script von meintechblog.de für das Auto Backup sowie das Startscript im Artikel Homebridge einrichten
=== Status- und Kontroll-Dummy ===
[[Datei:HomebridgeDummy.PNG|mini|550px|Status- bzw. Kontroll-Dummy]]


== Status Dummy anlegen ==
Es wird ein Dummy benötigt, welcher den Status des Homebridge-Dienstes anzeigt und über den dieser Dienst gesteuert werden kann. Das nötige Script um die Homebridge als Dienst zu starten wird weiter unten in diesem Artikel erstellt.
1. Anlegen einen Dummies um den Status in FHEM zu sehen:
<source lang="bash" style="width:100%;">
define FHEM.Homebridge.Status dummy
attr FHEM.Homebridge.Status room 9.03_Tech
</source>


== Start Script anlegen ==
<syntaxhighlight lang="bash" style="width:100%;">
2. Script im Verzeichnis /etc/init.d/ erstellen
define SYS_Homebridge dummy
attr SYS_Homebridge devStateIcon .*on:general_an .*off:general_aus .*:audio_rec
attr SYS_Homebridge eventMap status:status start:start stop:stop restart:restart
attr SYS_Homebridge icon it_router
attr SYS_Homebridge room System
attr SYS_Homebridge userReadings OnStateChange:(start|stop|restart|status) {  system ("sudo service homebridge ".ReadingsVal($NAME,"state","restart")." &" );;  }
attr SYS_Homebridge webCmd status:start:stop:restart
</syntaxhighlight>


Wenn die Datei noch nicht angelegt ist auf der Console mit folgenden Befehl erstellen.
Der Dummy wird durch Setzen von "start", "stop", "restart" oder "status" jeweils das userReading ausführen und somit letztendlich den homebridge Dienst steuern.
<source lang="bash" style="width:100%;">
 
=== Start Script anlegen ===
Nun ist das Startscript für die Homebridge anzulegen. Mittels des folgenden Befehls wird (wenn noch nicht vorhanden) das homebridge Script angelegt und im Editor geöffnet.
 
<syntaxhighlight lang="bash" style="width:100%;">
sudo nano /etc/init.d/homebridge
sudo nano /etc/init.d/homebridge
</source>
</syntaxhighlight>
Wenn die Homebridge nicht auf dem selben System läuft wie FHEM muss dieser Schritt auf dem Homebridge System ausgeführt werden.
 
Das nun folgende Script kann in die homebridge Datei, die im Nano Editor geöffnet ist, rein kopiert werden.


== Start Script befüllen ==
'''Achtung''': die Variablen ''homeBridgeUser'', ''fhemHost'' und ''fhemHostTelnetPort'' sind ggf. auf die eigenen Gegebenheiten anzupassen.
<source lang="bash" style="width:100%;">
 
<syntaxhighlight lang="bash" style="width:100%;">
#!/bin/sh
#!/bin/sh
### BEGIN INIT INFO
### BEGIN INIT INFO
Zeile 39: Zeile 49:
export PATH=$PATH:/usr/local/bin
export PATH=$PATH:/usr/local/bin
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules
PID=`pidof homebridge`
PID=`pidof homebridge`
homeBridgeUser="fhem"
fhemHost=127.0.0.1          #FHEM Server (Masterinstanz)
fhemHostTelnetPort=7072    #TelnetPort der FHEM Instanz
fhemDefine="SYS_Homebridge"
case "$1" in
case "$1" in
start)
start)
if ps -p $PID > /dev/null 2>&1; then
if ps -p $PID > /dev/null 2>&1; then
         echo "Homebridge is already running"
         echo "Homebridge is already running"
         perl /opt/fhem/fhem.pl 7072 "setreading FHEM.Homebridge.Status info Homebridge is allready running"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is already running"
        perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge.Status on"
        perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge off"
else
else
         su - "hs-server-admin" -c "homebridge > /dev/null 2>&1 &"
         su - $homeBridgeUser -c "homebridge > /dev/null 2>&1 &"
         echo "Homebridge starting"
         echo "Homebridge starting"
$0 status
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge starting"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine on"
        sleep 2
        $0 status
fi
fi
;;
;;
Zeile 56: Zeile 73:
if ! ps -p $PID > /dev/null 2>&1; then
if ! ps -p $PID > /dev/null 2>&1; then
         echo "Homebridge is not running"
         echo "Homebridge is not running"
         perl /opt/fhem/fhem.pl 7072 "setreading FHEM.Homebridge.Status info Homebridge is not running"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is not running"
        perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge.Status off"
        perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge off"
else
else
         kill $PID
         kill $PID
         echo "Homebridge closed"
         echo "Homebridge stopping"
         perl /opt/fhem/fhem.pl 7072 "setreading FHEM.Homebridge.Status info Homebridge closed"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge stopping"
         perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge.Status off"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine off"
         perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge off"
         sleep 2
        $0 status
fi
fi
;;
;;
Zeile 78: Zeile 94:
if ps -p $PID > /dev/null 2>&1; then
if ps -p $PID > /dev/null 2>&1; then
         echo "Homebridge is running PID $PID"
         echo "Homebridge is running PID $PID"
         perl /opt/fhem/fhem.pl 7072 "setreading FHEM.Homebridge.Status info Homebridge running as PID $PID"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge running as PID $PID"
         perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge.Status on"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine on"
        perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge off"
else
else
         echo "Homebridge is not running"
         echo "Homebridge is not running"
         perl /opt/fhem/fhem.pl 7072 "setreading FHEM.Homebridge.Status info Homebridge is not running"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is not running"
         perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge.Status off"
         perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine off"
        perl /opt/fhem/fhem.pl 7072 "set FHEM.Homebridge off"
fi
fi
;;
;;
Zeile 94: Zeile 108:
esac
esac
exit 0
exit 0
</source>


== Start Script Autostart einrichten==
</syntaxhighlight>
Autostart aktivieren:
 
<source lang="bash" style="width:100%;">
Das Script setzt in dem bereits angelegten Dummy ein Reading ''info'' in dem der Ausführungsstatus des Scripts wiedergegeben wird. Das Reading ''state'' wir auf on oder off gesetzt. ''On'' bedeutet dass die Homebridge gestartet ist, ''off'' dass die Homebridge nicht ausgeführt wird.
 
 
Damit die Homebridge auch mit Start des Systems gestartet wird sind die folgenden zwei Schritte notwendig
 
<syntaxhighlight lang="bash" style="width:100%;">
sudo chmod 755 /etc/init.d/homebridge
sudo chmod 755 /etc/init.d/homebridge
sudo update-rc.d homebridge defaults
</syntaxhighlight>


sudo update-rc.d homebridge defaults
Zum Testen kann der Dienst nun mit dem Befehl
</source>


== Homebridge Start per Konsole==
<syntaxhighlight lang="bash" style="width:100%;">
Nun kann man mit
<source lang="bash" style="width:100%;">
sudo service homebridge start
sudo service homebridge start
</source>
</syntaxhighlight>
bzw.
bzw.
<source lang="bash" style="width:100%;">
<syntaxhighlight lang="bash" style="width:100%;">
sudo /etc/init.d/homebridge start
sudo /etc/init.d/homebridge start
</source>
</syntaxhighlight>
den Dienst starten
 
gestartet werden. In dem angelegten Dummy werden zwei Readings erzeugt mit den entsprechenden Rückmeldungen aus dem Script. Die Readings werden erst angezeigt wenn die bereits geöffnete Detailseite des Dummys neu geladen wird.


== Homebridge Start per FHEM==
=== Testlauf / Fertig ===
Nun können die einzelnen Aktionen über den Dummy ausgeführt werden. Dabei wird jeweils der eingerichtete Dienst angesteuert und eine (mit kurzer Verzögerung) Rückmeldung gegeben.


== Homebridge Start Dummy einrichten==
== Sonstiges ==
<source lang="bash" style="width:100%;">
define FHEM.Homebridge dummy
attr FHEM.Homebridge event-on-change-reading state
attr FHEM.Homebridge room 9.03_Tech
attr FHEM.Homebridge webCmd status:start:stop:restart
</source>


== Homebridge Start DOIF einrichten==
=== FHEM Benutzer Zugriff auf Script gewähren ===
<source lang="bash" style="width:100%;">
define FHEM.Homebridge.DOIF DOIF ([FHEM.Homebridge] eq "start") ({system ("sudo /etc/init.d/homebridge start")})\
DOELSEIF ([FHEM.Homebridge] eq "stop") ({system ("sudo /etc/init.d/homebridge stop")})\
DOELSEIF ([FHEM.Homebridge] eq "restart") ({system ("sudo /etc/init.d/homebridge restart")})\
DOELSEIF ([FHEM.Homebridge] eq "status") ({system ("sudo /etc/init.d/homebridge status")})
attr FHEM.Homebridge.DOIF room 9.03_Tech
</source>


== Homebridge FHEM Zugriff auf Script gewähren==
Damit aus FHEM das Script ausgeführt werden kann benötigt dieser Benutzer entsprechende Berechtigungen. Dazu ist in der sudoers ein Eintrag zu ergänzen.
Dazu wird die sudoers Datei im Nano Editor geöffnet


<source lang="bash" style="width:100%;">
<syntaxhighlight lang="bash" style="width:100%;">
sudo nano /etc/sudoers
sudo nano /etc/sudoers
</source>
</syntaxhighlight>
Beispiel Zeile
 
<source lang="bash" style="width:100%;">
Dort sollte im Abschnitt ''# User privilege specification'' die folgende Zeile ergänzt werden
 
<syntaxhighlight lang="bash" style="width:100%;">
fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge
fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge
</source>
</syntaxhighlight>
 
bzw. unter Raspbian Jessie (vgl.: [https://forum.fhem.de/index.php/topic,66841.msg581747.html#msg581747 Forenbeitrag]):


Beispiel Datei:
<syntaxhighlight lang="bash" style="width:100%;">
<source lang="bash" style="width:100%;">
fhem ALL=(ALL) NOPASSWD:/usr/sbin/service
</syntaxhighlight>
'''Achtung!''' Sollte FHEM nicht unter dem Benutzer ''fhem'' laufen ist dies an den entsprechenden Stellen anzupassen.
 
Beispielinhalt der sudoers:
<syntaxhighlight lang="bash" style="width:100%;">
#
#
# This file MUST be edited with the 'visudo' command as root.
# This file MUST be edited with the 'visudo' command as root.
Zeile 166: Zeile 182:
# User privilege specification
# User privilege specification
root ALL=(ALL:ALL) ALL
root ALL=(ALL:ALL) ALL
fhem ALL=(ALL) NOPASSWD:/opt/fhem/FHEM/backup.sh, /etc/init.d/homebridge
fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge


# Members of the admin group may gain root privileges
# Members of the admin group may gain root privileges
Zeile 177: Zeile 193:


#includedir /etc/sudoers.d
#includedir /etc/sudoers.d
</source>
</syntaxhighlight>
 
[[Kategorie:HOWTOS]]
 
=== Anpassung wenn FHEM und Homebridge auf getrennten Systemen laufen ===
Unter dem Kapitel [[Umsetzung]] wurde bereits alles vorbereitet um mit wenigen Änderungen eine Homebridge zu starten die nicht auf dem selben System läuft wie FHEM. Es sind nur 2 Änderungen notwendig.
Die erste Änderung betrifft den eingerichteten Dummy. Hier ist das vorhandene ''userReadings'' wie folgt abzuändern
 
<syntaxhighlight lang="bash" style="width:100%;">
attr SYS_Homebridge userReadings OnStateChange:(start|stop|restart|status) { system ("sudo /opt/fhem/FHEM/homebridgeserviceremote.sh ".ReadingsVal($NAME,"state","restart")." &" );; }
</syntaxhighlight>
 
Dadurch wird, durch die Aktionen des Dummys, ein weiteres Script angesprochen.
 
Nun wird dieses Script mit hilfe des Nano Editor angelegt
 
<syntaxhighlight lang="bash" style="width:100%;">
sudo nano /opt/fhem/FHEM/homebridgeserviceremote.sh
</syntaxhighlight>
 
und mit dem folgenden Inhalt befüllt.
 
'''Achtung''': die Variablen ''remoteUser'', ''remotePasswort'' und ''remoteHost'' sind ggf. auf die eigenen Gegebenheiten der entfernt laufenden Homebridge anzupassen. Der hier genannte Benutzer muss natürlich berechtigt sein die Homebridge starten zu können. Es sollte auch nicht der root User verwendet werden, sondern ein eigens dafür angelegter und in den Berechtigungen eingeschränkter Benutzer verwendet werden.
Wer zur Fehleranalyse etwas mehr sehen möchte ändert den Wert von ''debug'' auf 1.
 
<syntaxhighlight lang="bash" style="width:100%;">
#!/bin/bash
debug=0
remoteUser="root"
remotePasswort="root"
remoteHost="192.168.1.111"
remoteService="homebridge"
fhemHostTelnetPort=7072          #TelnetPort der FHEM Instanz
 
# Voraussetzungen prüfen
if [ $(dpkg-query -W -f='${Status}' sshpass 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
if [ "$debug" = "1" ]; then
echo "sshpass wird benötigt. Installation beginnt";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] sshpass wird benötigt. Installation beginnt\"}";
fi
apt-get install sshpass
if [ "$debug" = "1" ]; then
echo "sshpass wurde installiert";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] sshpass wurde installiert\"}";
fi
fi
###################################
 
# Befehl ausführen
case "$1" in
start)
if [ "$debug" = "1" ]; then
echo "Ausführen von 'sudo service $remoteService start' auf '$remoteHost' als '$remoteUser'";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService start' auf '$remoteHost' als '$remoteUser'\"}";
fi
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService start"
if [ "$debug" = "1" ]; then
echo "Ausführung beendet";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
fi
;;
stop)
if [ "$debug" = "1" ]; then
echo "Ausführen von 'sudo service $remoteService stop' auf '$remoteHost' als '$remoteUser'";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService stop' auf '$remoteHost' als '$remoteUser'\"}";
fi
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService stop"
if [ "$debug" = "1" ]; then
echo "Ausführung beendet";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
fi
;;
restart)
if [ "$debug" = "1" ]; then
echo "Ausführen von 'sudo service $remoteService restart' auf '$remoteHost' als '$remoteUser'";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService restart' auf '$remoteHost' als '$remoteUser'\"}";
fi
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService restart"
if [ "$debug" = "1" ]; then
echo "Ausführung beendet";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
fi
 
;;
status)
if [ "$debug" = "1" ]; then
echo "Ausführen von 'sudo service $remoteService status' auf '$remoteHost' als '$remoteUser'";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService status' auf '$remoteHost' als '$remoteUser'\"}";
fi
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService status"
if [ "$debug" = "1" ]; then
echo "Ausführung beendet";
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
fi
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
exit 0
###################################
</syntaxhighlight>
 
Das Script macht nicht sehr viel. Es verbindet sich über ssh mit dem entfernten System und startet (stopt, etc.) den Homebridge Dienst. Hinweis: es wird sshpass benötigt, welches das Script bei Bedarf versucht zu installieren.
 
 
HINWEIS: Statt wie hier sshpass zu verwenden ist es besser ssh korrekt für zertifikatbasierten Zugriff zu konfigurieren.
 
== Dankeschön ==
Ein Dankeschön geht an die Entwicklergemeinde rund um Homebridge und dem FHEM Plugin für die Homebridge.
 
Ein besonderes Dankeschön an ''No Legend'' der die zugrunde liegende Idee und Lösung in diesem Artikel beschrieben hat.

Aktuelle Version vom 6. Januar 2019, 21:59 Uhr

Um nicht bei jeder Änderung, welche die Homebridge betrifft, diese über die Console manuell neustarten zu müssen zeigt diese Lösung wie dies bequem aus FHEMWEB erfolgen kann. In den nachfolgenden Abschnitten sind die einzelnen Schritte dazu erläutert.

Vorwort

Die im weiteren genutzten Bezeichnungen von Dummys, Scriptdateinamen o.ä. können geändert werden. Die Änderungen müssen jedoch auch an allen entsprechenden Stellen vorgenommen werden. Genannte IP Adressen, Benutzernamen und Passwörter sind auf die eigenen Gegebenheiten anzupassen. Die Berechtigungen des Benutzers müssen zur Ausführung der Scripte geprüft und ggf. angepasst werden. Entsprechende Linux Kenntnisse sollten vorhanden sein. Dieser Artikel berücksichtigt dass FHEM und Homebridge nicht zwingend auf dem selben System laufen. Die hier gezeigte Lösung kann für beide Varianten genutzt werden, FHEM und Homebridge auf dem gleichen System oder auf getrennten Systemen.

Umsetzung

Status- und Kontroll-Dummy

Status- bzw. Kontroll-Dummy

Es wird ein Dummy benötigt, welcher den Status des Homebridge-Dienstes anzeigt und über den dieser Dienst gesteuert werden kann. Das nötige Script um die Homebridge als Dienst zu starten wird weiter unten in diesem Artikel erstellt.

define SYS_Homebridge dummy
attr SYS_Homebridge devStateIcon .*on:general_an .*off:general_aus .*:audio_rec
attr SYS_Homebridge eventMap status:status start:start stop:stop restart:restart
attr SYS_Homebridge icon it_router
attr SYS_Homebridge room System
attr SYS_Homebridge userReadings OnStateChange:(start|stop|restart|status) {  system ("sudo service homebridge ".ReadingsVal($NAME,"state","restart")." &" );;  }
attr SYS_Homebridge webCmd status:start:stop:restart

Der Dummy wird durch Setzen von "start", "stop", "restart" oder "status" jeweils das userReading ausführen und somit letztendlich den homebridge Dienst steuern.

Start Script anlegen

Nun ist das Startscript für die Homebridge anzulegen. Mittels des folgenden Befehls wird (wenn noch nicht vorhanden) das homebridge Script angelegt und im Editor geöffnet.

sudo nano /etc/init.d/homebridge

Wenn die Homebridge nicht auf dem selben System läuft wie FHEM muss dieser Schritt auf dem Homebridge System ausgeführt werden.

Das nun folgende Script kann in die homebridge Datei, die im Nano Editor geöffnet ist, rein kopiert werden.

Achtung: die Variablen homeBridgeUser, fhemHost und fhemHostTelnetPort sind ggf. auf die eigenen Gegebenheiten anzupassen.

#!/bin/sh
### BEGIN INIT INFO
# Provides: homebridge
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time for homebridge
# Description: Enable service provided by daemon.
### END INIT INFO
export PATH=$PATH:/usr/local/bin
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules

PID=`pidof homebridge`
homeBridgeUser="fhem"
fhemHost=127.0.0.1          #FHEM Server (Masterinstanz)
fhemHostTelnetPort=7072     #TelnetPort der FHEM Instanz
fhemDefine="SYS_Homebridge"

case "$1" in
start)
if ps -p $PID > /dev/null 2>&1; then
        echo "Homebridge is already running"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is already running"			
else
        su - $homeBridgeUser -c "homebridge > /dev/null 2>&1 &"
        echo "Homebridge starting"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge starting"	
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine on"
        sleep 2
        $0 status
fi
;;
stop)
if ! ps -p $PID > /dev/null 2>&1; then
        echo "Homebridge is not running"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is not running"
else
        kill $PID
        echo "Homebridge stopping"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge stopping"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine off"
        sleep 2
        $0 status		
fi
;;
restart)
if ! ps -p $PID > /dev/null 2>&1; then
        $0 start
else
        $0 stop
        $0 start
fi
;;
status)
if ps -p $PID > /dev/null 2>&1; then
        echo "Homebridge is running PID $PID"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge running as PID $PID"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine on"
else
        echo "Homebridge is not running"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is not running"
        perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine off"
fi
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
exit 0

Das Script setzt in dem bereits angelegten Dummy ein Reading info in dem der Ausführungsstatus des Scripts wiedergegeben wird. Das Reading state wir auf on oder off gesetzt. On bedeutet dass die Homebridge gestartet ist, off dass die Homebridge nicht ausgeführt wird.


Damit die Homebridge auch mit Start des Systems gestartet wird sind die folgenden zwei Schritte notwendig

sudo chmod 755 /etc/init.d/homebridge
sudo update-rc.d homebridge defaults

Zum Testen kann der Dienst nun mit dem Befehl

sudo service homebridge start

bzw.

sudo /etc/init.d/homebridge start

gestartet werden. In dem angelegten Dummy werden zwei Readings erzeugt mit den entsprechenden Rückmeldungen aus dem Script. Die Readings werden erst angezeigt wenn die bereits geöffnete Detailseite des Dummys neu geladen wird.

Testlauf / Fertig

Nun können die einzelnen Aktionen über den Dummy ausgeführt werden. Dabei wird jeweils der eingerichtete Dienst angesteuert und eine (mit kurzer Verzögerung) Rückmeldung gegeben.

Sonstiges

FHEM Benutzer Zugriff auf Script gewähren

Damit aus FHEM das Script ausgeführt werden kann benötigt dieser Benutzer entsprechende Berechtigungen. Dazu ist in der sudoers ein Eintrag zu ergänzen. Dazu wird die sudoers Datei im Nano Editor geöffnet

sudo nano /etc/sudoers

Dort sollte im Abschnitt # User privilege specification die folgende Zeile ergänzt werden

fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge

bzw. unter Raspbian Jessie (vgl.: Forenbeitrag):

fhem ALL=(ALL) NOPASSWD:/usr/sbin/service

Achtung! Sollte FHEM nicht unter dem Benutzer fhem laufen ist dies an den entsprechenden Stellen anzupassen.

Beispielinhalt der sudoers:

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults	env_reset
Defaults	mail_badpass
Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root	ALL=(ALL:ALL) ALL
fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge

# Members of the admin group may gain root privileges
%admin  ALL = (ALL) NOPASSWD: ALL

# Allow members of group sudo to execute any command
%sudo	ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

Anpassung wenn FHEM und Homebridge auf getrennten Systemen laufen

Unter dem Kapitel Umsetzung wurde bereits alles vorbereitet um mit wenigen Änderungen eine Homebridge zu starten die nicht auf dem selben System läuft wie FHEM. Es sind nur 2 Änderungen notwendig. Die erste Änderung betrifft den eingerichteten Dummy. Hier ist das vorhandene userReadings wie folgt abzuändern

attr SYS_Homebridge userReadings OnStateChange:(start|stop|restart|status) { system ("sudo /opt/fhem/FHEM/homebridgeserviceremote.sh ".ReadingsVal($NAME,"state","restart")." &" );; }

Dadurch wird, durch die Aktionen des Dummys, ein weiteres Script angesprochen.

Nun wird dieses Script mit hilfe des Nano Editor angelegt

sudo nano /opt/fhem/FHEM/homebridgeserviceremote.sh

und mit dem folgenden Inhalt befüllt.

Achtung: die Variablen remoteUser, remotePasswort und remoteHost sind ggf. auf die eigenen Gegebenheiten der entfernt laufenden Homebridge anzupassen. Der hier genannte Benutzer muss natürlich berechtigt sein die Homebridge starten zu können. Es sollte auch nicht der root User verwendet werden, sondern ein eigens dafür angelegter und in den Berechtigungen eingeschränkter Benutzer verwendet werden. Wer zur Fehleranalyse etwas mehr sehen möchte ändert den Wert von debug auf 1.

#!/bin/bash
debug=0
remoteUser="root"
remotePasswort="root"
remoteHost="192.168.1.111"
remoteService="homebridge"
fhemHostTelnetPort=7072           #TelnetPort der FHEM Instanz

# Voraussetzungen prüfen
if [ $(dpkg-query -W -f='${Status}' sshpass 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
	if [ "$debug" = "1" ]; then 
		echo "sshpass wird benötigt. Installation beginnt"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] sshpass wird benötigt. Installation beginnt\"}";
	fi
	apt-get install sshpass
	if [ "$debug" = "1" ]; then 
		echo "sshpass wurde installiert";
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] sshpass wurde installiert\"}";		
	fi
fi
###################################

# Befehl ausführen
case "$1" in
start)
	if [ "$debug" = "1" ]; then 
		echo "Ausführen von 'sudo service $remoteService start' auf '$remoteHost' als '$remoteUser'"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService start' auf '$remoteHost' als '$remoteUser'\"}";
	fi
	sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService start"
	if [ "$debug" = "1" ]; then 
		echo "Ausführung beendet"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
	fi
;;
stop)
	if [ "$debug" = "1" ]; then 
		echo "Ausführen von 'sudo service $remoteService stop' auf '$remoteHost' als '$remoteUser'"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService stop' auf '$remoteHost' als '$remoteUser'\"}";
	fi
	sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService stop"
	if [ "$debug" = "1" ]; then 
		echo "Ausführung beendet"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
	fi
;;
restart)
	if [ "$debug" = "1" ]; then 
		echo "Ausführen von 'sudo service $remoteService restart' auf '$remoteHost' als '$remoteUser'"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService restart' auf '$remoteHost' als '$remoteUser'\"}";
	fi
	sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService restart"
	if [ "$debug" = "1" ]; then 
		echo "Ausführung beendet"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
	fi

;;
status)
	if [ "$debug" = "1" ]; then 
		echo "Ausführen von 'sudo service $remoteService status' auf '$remoteHost' als '$remoteUser'";
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService status' auf '$remoteHost' als '$remoteUser'\"}";		
	fi
	sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService status"
	if [ "$debug" = "1" ]; then 
		echo "Ausführung beendet"; 
		perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";
	fi
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
exit 0
###################################

Das Script macht nicht sehr viel. Es verbindet sich über ssh mit dem entfernten System und startet (stopt, etc.) den Homebridge Dienst. Hinweis: es wird sshpass benötigt, welches das Script bei Bedarf versucht zu installieren.


HINWEIS: Statt wie hier sshpass zu verwenden ist es besser ssh korrekt für zertifikatbasierten Zugriff zu konfigurieren.

Dankeschön

Ein Dankeschön geht an die Entwicklergemeinde rund um Homebridge und dem FHEM Plugin für die Homebridge.

Ein besonderes Dankeschön an No Legend der die zugrunde liegende Idee und Lösung in diesem Artikel beschrieben hat.