Fhem.service (systemd unit file): Unterschied zwischen den Versionen

Aus FHEMWiki
K (→‎Hinweise und Tipps: Link ins Forum eingefügt)
(→‎Start von anderen Services abhängig machen: Hinweis mit network-online eingetragen)
 
(11 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 56: Zeile 56:
== 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]], [https://forum.fhem.de/index.php/topic,106060.msg1003767.html#msg1003767 SCC Busware], [[HM-CFG-USB USB Konfigurations-Adapter|HM-CFG-USB]])
* 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. [https://forum.fhem.de/index.php/topic,110716.msg1048536.html#msg1048536 Bluetooth gestartet])
* 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 72: Zeile 72:


Das Beispiel hier in einem allgemeinerem Pfad:<syntaxhighlight lang="bash">
Das Beispiel hier in einem allgemeinerem Pfad:<syntaxhighlight lang="bash">
sudo nano /user/local/bin/EnableXX.sh
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 89: Zeile 89:
[Service]
[Service]
Type=oneshot
Type=oneshot
ExecStart=bash /user/local/bin/EnableXX.sh
ExecStart=bash /usr/local/bin/EnableXX.sh
StandardOutput=journal
StandardOutput=journal


Zeile 118: 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 lang="bash">
</syntaxhighlight>
#User=fhem
Die beiden Zeilen User und Group muss man auskommentieren, da die Unit sonst mit dem User fhem ausgeführt wird.
#Group=dialout
{{Randnotiz|RNTyp=Fehl|RNText=Achtung: Die Gruppenmitgliedschaft des Users fhem (z.B. gpio) ist beim Systemstart an der Stelle noch nicht wirksam.}}
</syntaxhighlight>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 134: 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 ==
== 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 ===
=== Hinweise aus dem Forum ===
Wie man erzwingen kann, dass FHEM '''nach''' hciuart (Bluetooth Service) startet, ist in {{Link2Forum|Topic=110716|LinkText=diesem Forenbeitrag}} beschrieben.
FHEM nach HCIUART starten: [https://forum.fhem.de/index.php/topic,110716.msg1048536.html#msg1048536]


=== 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.

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.

X mark.svgAchtung: Die Gruppenmitgliedschaft des Users fhem (z.B. gpio) ist beim Systemstart an der Stelle noch nicht wirksam.
#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