Fhem.service (systemd unit file): Unterschied zwischen den Versionen
(→Hinweise und Tipps: Abschnitt zu RestartSec eingefügt) |
(→Start von anderen Services abhängig machen: Hinweis mit network-online eingetragen) |
||
(13 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 5: | Zeile 5: | ||
</syntaxhighlight>Stand Mai 2020 hat die Datei folgenden Inhalt: | </syntaxhighlight>Stand Mai 2020 hat die Datei folgenden Inhalt: | ||
=== Inhalt fhem.service === | === Inhalt /etc/systemd/system/fhem.service === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# $Id: fhem.service 19235 2019-04-21 13:26:17Z betateilchen $ | # $Id: fhem.service 19235 2019-04-21 13:26:17Z betateilchen $ | ||
Zeile 50: | Zeile 50: | ||
=== unit file bearbeiten === | === unit file bearbeiten === | ||
<syntaxhighlight lang="bash"> | Dieser Befehl editiert die (fhem.service) unit Datei mit dem Standard Editor (z.B. nano) und führt zum Abschluss auch ein daemon-reload durch.<syntaxhighlight lang="bash"> | ||
sudo systemctl edit --full fhem | sudo systemctl edit --full fhem | ||
</syntaxhighlight> | </syntaxhighlight>Tipp: Datei speichern '''ctrl+s''' und Editor verlassen '''ctrl+x''' | ||
Tipp: Datei speichern '''ctrl+s''' und Editor verlassen '''ctrl+x''' | |||
== Prozesse vor dem FHEM Start ausführen == | == Prozesse vor dem FHEM Start ausführen == | ||
Ziel ist es sicherzustellen, dass für den Start von FHEM alle Voraussetzungen erfüllt sind, z.B. | Ziel ist es sicherzustellen, dass für den Start von FHEM alle Voraussetzungen erfüllt sind, z.B. | ||
* Hardware aktiviert ( [[COC]], [[FHEM_auf_Raspberry_PI_mit_COC_betreiben]], | * Hardware aktiviert ([[COC]], [[FHEM_auf_Raspberry_PI_mit_COC_betreiben]], {{Link2Forum|Topic=106060|Message=1003767|LinkText=SCC Busware}}, [[HM-CFG-USB USB Konfigurations-Adapter|HM-CFG-USB]]) | ||
* Datenbank gestartet | * Datenbank gestartet | ||
* Systemprozess läuft (z.B. | * Systemprozess läuft (z.B. {{Link2Forum|Topic=110716|LinkText=Bluetooth gestartet}} | ||
* eigenen Prozessen ist gestartet | * eigenen Prozessen ist gestartet | ||
* [[DWD OpenData|Sprache einstellen]] | * [[DWD OpenData|Sprache einstellen]] | ||
Zeile 74: | Zeile 72: | ||
Das Beispiel hier in einem allgemeinerem Pfad:<syntaxhighlight lang="bash"> | Das Beispiel hier in einem allgemeinerem Pfad:<syntaxhighlight lang="bash"> | ||
sudo nano / | sudo nano /usr/local/bin/EnableXX.sh | ||
</syntaxhighlight>Den Code (Beispiele am Ende) hier einfügen und die Datei speichern und Editor verlassen (ctrl+s ctrl+x). | </syntaxhighlight>Den Code (Beispiele am Ende) hier einfügen und die Datei speichern und Editor verlassen (ctrl+s ctrl+x). | ||
Zeile 91: | Zeile 89: | ||
[Service] | [Service] | ||
Type=oneshot | Type=oneshot | ||
ExecStart=bash / | ExecStart=bash /usr/local/bin/EnableXX.sh | ||
StandardOutput=journal | StandardOutput=journal | ||
Zeile 120: | Zeile 118: | ||
ExecStartPre= bash /opt/fhem/ExecStartPre.sh | ExecStartPre= bash /opt/fhem/ExecStartPre.sh | ||
ExecStart=... | ExecStart=... | ||
</syntaxhighlight>Die beiden Zeilen User und Group muss man auskommentieren, da die Unit sonst mit dem User fhem ausgeführt wird. | </syntaxhighlight> | ||
Die beiden Zeilen User und Group muss man auskommentieren, da die Unit sonst mit dem User fhem ausgeführt wird. | |||
{{Randnotiz|RNTyp=Fehl|RNText=Achtung: Die Gruppenmitgliedschaft des Users fhem (z.B. gpio) ist beim Systemstart an der Stelle noch nicht wirksam.}} | |||
#User=fhem | |||
#Group=dialout | |||
'''3. Änderungen aktivieren''' | '''3. Änderungen aktivieren''' | ||
Zeile 136: | Zeile 136: | ||
Wants=xxx.service | Wants=xxx.service | ||
After=xxx.service | After=xxx.service | ||
</syntaxhighlight>Insbesondere empfiehlt es sich auf den kompletten Start des Netzwerkes zu warten, vor allem wenn beim Start von FHEM Netzwerkressourcen online sein müssen (Netzlaufwerke, Dienste wie ser2net usw.).<syntaxhighlight lang="bash"> | |||
Wants=network-online.target | |||
After=network-online.target | |||
</syntaxhighlight>Man kann auch erzwingen, dass FHEM nicht startet falls die Voraussetzungen nicht erfüllt sind. Dafür muss anstatt Wants= Requires= verwendet werden. | </syntaxhighlight>Man kann auch erzwingen, dass FHEM nicht startet falls die Voraussetzungen nicht erfüllt sind. Dafür muss anstatt Wants= Requires= verwendet werden. | ||
== Einstellungen dies und das == | |||
=== Start verzögern === | |||
Es ist immer besser eine direkte Abhängigkeit zu definieren. In unklaren Situationen oder als erste Abhilfe kann es notwendig sein, einfach den FHEM Start zu verzögern. | |||
Der default Wert für ''TimeoutStartSec='' liegt bei 90 sec. Anzeige mit <code>systemctl show fhem.service -p TimeoutStartUSec</code> | |||
Soll die Startverzögerung länger sein, muss dieser Wert zusätzlich gesetzt werden. Ansonsten wird der Start mit einer Fehlermeldung abgebrochen. | |||
<syntaxhighlight lang="text"> | |||
[Service] | |||
... | |||
ExecStartPre=/bin/sleep 10 | |||
#TimeoutStartSec= # default 90, set for larger sleep time | |||
</syntaxhighlight> | |||
=== Restart verzögern === | === Restart verzögern === | ||
Sollte man z.B. bei einem Neustart über die FHEM Oberfläche (shutdown restart) zwei Starts innerhalb von 1 Sekunde im Logfile beobachten, kann man den Neustart im unit file mit einem Parameter 2 Sekunden verzögern:<syntaxhighlight> | Sollte man z.B. bei einem Neustart über die FHEM Oberfläche (shutdown restart) zwei Starts innerhalb von 1 Sekunde im Logfile beobachten, kann man den Neustart im unit file mit einem Parameter um 2 - 10 Sekunden ({{Link2Forum|Topic=93870|Message=924833|LinkText=siehe auch diesen Forenbeitrag}}) verzögern: | ||
<syntaxhighlight lang="text"> | |||
[Service] | [Service] | ||
... | ... | ||
Zeile 148: | Zeile 167: | ||
== Hinweise und Tipps == | == Hinweise und Tipps == | ||
=== Startreihenfolge beeinflussen === | |||
Wie man erzwingen kann, dass FHEM '''nach''' hciuart (Bluetooth Service) startet, ist in {{Link2Forum|Topic=110716|LinkText=diesem Forenbeitrag}} beschrieben. | |||
=== Ausgaben im Script === | === Ausgaben im Script === | ||
Ausgaben mit echo landen im /var/log/syslog. Das Log kann man mit diesem Befehl anzeigen. Ist das Logfile zu unübersichtlich kann man sich auch z.B. nur 15 Zeilen nach systemd Ausgabe des unit files anzeigen lassen.<syntaxhighlight lang="bash"> | Ausgaben mit echo landen im /var/log/syslog. Das Log kann man mit diesem Befehl anzeigen. Ist das Logfile zu unübersichtlich kann man sich auch z.B. nur 15 Zeilen nach systemd Ausgabe des unit files anzeigen lassen. | ||
<syntaxhighlight lang="bash"> | |||
cat /var/log/syslog | cat /var/log/syslog | ||
cat /var/log/syslog|grep -A 15 "FHEM Home" | cat /var/log/syslog|grep -A 15 "FHEM Home" |
Aktuelle Version vom 17. November 2024, 15:10 Uhr
Die Datei fhem.service ist ein systemd unit file und wird bei der debian Installation von FHEM mit ausgeliefert. Änderungen an dieser Datei sind normalerweise nicht notwendig. Man sollte zumindest genau wissen was man tut! Der Artikel soll die Datei etwas beschreiben und ein paar Fälle behandeln die ein Anpassung notwendig machen.
Unit File - ein paar kurze Erklärung
Den aktuellen Inhalt kann man jederzeit anschauen:
systemctl cat fhem
Stand Mai 2020 hat die Datei folgenden Inhalt:
Inhalt /etc/systemd/system/fhem.service
# $Id: fhem.service 19235 2019-04-21 13:26:17Z betateilchen $
[Unit]
Description=FHEM Home Automation
Wants=network.target
After=network.target
#Requires=postgresql.service
#After=postgresql.service
#Requires=mysql.service
#After=mysql.service
[Service]
Type=forking
User=fhem
Group=dialout
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl fhem.pl fhem.cfg
#ExecStart=/usr/bin/perl fhem.pl configDB
Restart=always
[Install]
WantedBy=multi-user.target
Erklärung ausgewählter Parameter
Wants= die angegebene Services werden benötigt, fhem startet aber trotzdem falls die Services nicht gestartet werden können.
Requires= wenn der Service nicht gestartet werden kann, wird fhem nicht gestartet.
After= bewirkt, dass fhem nach dem Service (der Gruppe) gestartet wird.
Das ist wichtig damit Services die für fhem notwendig sind schon gestartet sind. Benötig fhem z.B. Datenbanken sind die entsprechenden Zeilen einzubauen oder durch entfernen des Kommentarzeichens (#) zu aktivieren.
User=fhem bewirkt das der Services mit user fhem gestartet wird. Falls fhem mit dem user root gestartet wird, startet fhem.pl einen neuen Prozess unter dem User fhem.
Group=dialout Es wird die Gruppe dialout zum Start benutzt.
Beide Zeilen können für den normalen Start von FHEM auch auskommentiert werden.
Zusätzlicher Parameter
ExecStartPre= Hier kann ein Shell Befehl stehen, der vor dem Start des eigentlichen Service (ExecStart=) ausgeführt wird.
unit file bearbeiten
Dieser Befehl editiert die (fhem.service) unit Datei mit dem Standard Editor (z.B. nano) und führt zum Abschluss auch ein daemon-reload durch.
sudo systemctl edit --full fhem
Tipp: Datei speichern ctrl+s und Editor verlassen ctrl+x
Prozesse vor dem FHEM Start ausführen
Ziel ist es sicherzustellen, dass für den Start von FHEM alle Voraussetzungen erfüllt sind, z.B.
- Hardware aktiviert (COC, FHEM_auf_Raspberry_PI_mit_COC_betreiben, SCC Busware, HM-CFG-USB)
- Datenbank gestartet
- Systemprozess läuft (z.B. Bluetooth gestartet
- eigenen Prozessen ist gestartet
- Sprache einstellen
Dazu gibt es mehrere Lösungswege:
- die Datei fhem.service modifizieren
- einen separaten Service implementieren
- Abhängigkeiten definieren
Ein Script mit separater service unit starten
Wir erstellen quasi einen eigenen Service - Vorteil: Die fhem.service braucht man nicht verändern.
1. Script bereitstellen
Das Beispiel hier in einem allgemeinerem Pfad:
sudo nano /usr/local/bin/EnableXX.sh
Den Code (Beispiele am Ende) hier einfügen und die Datei speichern und Editor verlassen (ctrl+s ctrl+x).
Hier kann meist der Original Scriptcode verwendet werden, der früher in das init.d Script eingefügt werden sollte.
2. unit file erzeugen
Man erstellt eine neues unit file.
sudo systemctl edit --full --force enablexx.service
Mit folgendem Inhalt
[Unit]
Description=EnableXX
Before=fhem.service
#After=network.target
[Service]
Type=oneshot
ExecStart=bash /usr/local/bin/EnableXX.sh
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Die Zeile Before=fhem.service stellt sicher, dass der Start vor FHEM erfolgt. 3. Service aktivieren
#sudo systemctl daemon-reload # nur notwendig wenn nicht systemctl edit verwendet wurde
sudo systemctl enable enablexx
sudo systemctl start enablexx
Den Erfolg auch nach einem komplette Neustart testen!
Ein Script zusammen mit FHEM starten
1. Script bereitstellen
Dazu wird eine Scriptdatei erzeugt, Beispiel:
sudo nano /opt/fhem/ExecStartPre.sh
Den Code (Beispiele am Ende) hier einfügen und die Datei speichern und Editor verlassen (ctrl+s ctrl+x).
2. ExecStartPre aktivieren
Um ein Script mit root Rechten in der fhem.service unit auszuführen, müssen drei Zeilen in der Datei geändert werden (siehe oben).
Vor der Zeile ExecStart= wir diese Zeile eingefügt:
[Service]
...
ExecStartPre= bash /opt/fhem/ExecStartPre.sh
ExecStart=...
Die beiden Zeilen User und Group muss man auskommentieren, da die Unit sonst mit dem User fhem ausgeführt wird.
#User=fhem #Group=dialout
3. Änderungen aktivieren
Die Änderungen werden erst nach einem daemon-reload aktiv und nach einem restart wirksam.
#sudo systemctl daemon-reload # nur notwendig wenn nicht systemctl edit verwendet wurde
sudo systemctl restart fhem
Den Erfolg auch nach einem komplette Neustart testen!
Start von anderen Services abhängig machen
In der fhem.service unit kann man sicherstellen, dass ein Service fertig gestartet wurde bevor fhem startet. Dazu kann man im unit Abschnitt zwei Zeilen einfügen (bzw. Kommentar entfernen):
Wants=xxx.service
After=xxx.service
Insbesondere empfiehlt es sich auf den kompletten Start des Netzwerkes zu warten, vor allem wenn beim Start von FHEM Netzwerkressourcen online sein müssen (Netzlaufwerke, Dienste wie ser2net usw.).
Wants=network-online.target
After=network-online.target
Man kann auch erzwingen, dass FHEM nicht startet falls die Voraussetzungen nicht erfüllt sind. Dafür muss anstatt Wants= Requires= verwendet werden.
Einstellungen dies und das
Start verzögern
Es ist immer besser eine direkte Abhängigkeit zu definieren. In unklaren Situationen oder als erste Abhilfe kann es notwendig sein, einfach den FHEM Start zu verzögern.
Der default Wert für TimeoutStartSec= liegt bei 90 sec. Anzeige mit systemctl show fhem.service -p TimeoutStartUSec
Soll die Startverzögerung länger sein, muss dieser Wert zusätzlich gesetzt werden. Ansonsten wird der Start mit einer Fehlermeldung abgebrochen.
[Service]
...
ExecStartPre=/bin/sleep 10
#TimeoutStartSec= # default 90, set for larger sleep time
Restart verzögern
Sollte man z.B. bei einem Neustart über die FHEM Oberfläche (shutdown restart) zwei Starts innerhalb von 1 Sekunde im Logfile beobachten, kann man den Neustart im unit file mit einem Parameter um 2 - 10 Sekunden (siehe auch diesen Forenbeitrag) verzögern:
[Service]
...
Restart=...
RestartSec=2
...
Hinweise und Tipps
Startreihenfolge beeinflussen
Wie man erzwingen kann, dass FHEM nach hciuart (Bluetooth Service) startet, ist in diesem Forenbeitrag beschrieben.
Ausgaben im Script
Ausgaben mit echo landen im /var/log/syslog. Das Log kann man mit diesem Befehl anzeigen. Ist das Logfile zu unübersichtlich kann man sich auch z.B. nur 15 Zeilen nach systemd Ausgabe des unit files anzeigen lassen.
cat /var/log/syslog
cat /var/log/syslog|grep -A 15 "FHEM Home"
Beispielcode
Diese Codebeispiel ist auf dem Raspberry Pi ausführbar und lässt vor dem Start von FHEM die grüne LED (ACT) blinken.
Beispiel 1: 3 mal kurz und 3 mal lang
# Lass die ACT LED (grün) am Pi 3 mal kurz und 3 mal lang blinken
ANZAHL=3
#Status (Standard [mmc0] )sichern
trigger=$(cat /sys/class/leds/led0/trigger|grep -o "\[.*\]"|tr -d [+])
#umschalten auf manuell
echo "none" >/sys/class/leds/led0/trigger
#blinken
for ((i=1 ; i<=$(( $ANZAHL * 2 )) ; i++ )); do
echo $(( $i % 2 )) >/sys/class/leds/led0/brightness
sleep 0.3
done
for ((i=1 ; i<=$(( $ANZAHL * 2 )) ; i++ )); do
echo $(( $i % 2 )) >/sys/class/leds/led0/brightness
sleep 1
done
#Status wieder herstellen
echo $trigger >/sys/class/leds/led0/trigger