Script per Autostart starten

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Blitzkid
User
Beiträge: 10
Registriert: Mittwoch 10. April 2019, 18:13

Hi :)

Ich habe ein Problem, ein Pythonscript per Autostart laufen zu lassen. Ich habe das Ganze über systemd realisiert.

Anbei folgende Schritte, wie ich das Ganze realisiert habe.

1. Neuer Service erstellt:

Code: Alles auswählen

sudo nano /lib/systemd/system/audiobutton.service
2. Folgendes in die Service-Datei eingetragen:

Code: Alles auswählen

#audiobutton.service
	
[Unit]
Description=start audiobutton
After=multi-user.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/Desktop/audiobutton.py

[Install]
WantedBy=multi-user.target
3. Service-Datei gespeichert

4. Service vom System erkennen lassen:

Code: Alles auswählen

sudo systemctl daemon-reload
5. Service bootfähig gemacht:

Code: Alles auswählen


sudo systemctl enable audiobutton.service
6. Reboot durchgeführt:

Code: Alles auswählen


sudo reboot
Nach dem Neustart wurde allerdings mein audiobutton.py Script nicht ausgeführt, als ich es testen wollte. Anbei das Script:

Code: Alles auswählen

#audiobutton.py

import pygame
from gpiozero import Button
import time

pygame.init()

def play_shots():
    print ("Shots!")
    shots.play()
    time.sleep(18)
    
    
btn_audio = Button(23)
shots = pygame.mixer.Sound('/home/pi/Music/Shots/Shots.wav')

btn_audio.when_pressed = play_shots
Also habe ich mir das Log mal angeschaut und dort gesehen, dass der Service wohl gestartet wird, allerdings direkt nach einer Sekunde wieder beendet wird.
Liegt mein Problem am Python-Script oder an der Service-Datei?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

An deinem Skript. Ich bin mir sicher die Beispiele die du genutzt hast machen am Ende noch etwas Entscheidendes.

Und wie ich sehe sind ja plötzlich doch Klammern beim play.
Blitzkid
User
Beiträge: 10
Registriert: Mittwoch 10. April 2019, 18:13

Ja ich hatte wohl vor dem kopieren aus irgendwelchen Gründen die Klammern gelöscht...

Muss ich dem Skript wohl sagen, dass es sich nicht einfach schließen, sondern geöffnet bleiben soll. Mal schauen was sich da machen lässt...
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie gesagt, die Quellen, aus denen du das hast, die haben da 100%ig etwas getan, das du vergessen hast.

Und es ist darum auch immer eine gute Idee ein Skript NICHT nur in der IDE auszufuehren. Denn die laesst den Python Interpreter einfach weiterlaufen.
Blitzkid
User
Beiträge: 10
Registriert: Mittwoch 10. April 2019, 18:13

Also ich hab das Skript etwas angepasst:

Code: Alles auswählen

#audiobutton.py
import pygame
from gpiozero import Button
from signal import pause 	#<- Neu eingefügt
import time

pygame.init()

def play_shots():
    print ("Shots!")
    shots.play()
    time.sleep(18)
    
    
btn_audio = Button(23)
shots = pygame.mixer.Sound('/home/pi/Music/Shots/Shots.wav')

btn_audio.when_pressed = play_shots

pause() 			#<- Neu eingefügt
Wenn ich jetzt das Log anschaue, steht dort lediglich, dass der Service gestartet wurde und nicht beendet. Wenn ich aber den Status vom Service anschaue, steht dieser auf "Active: inactive (dead)"

Das bedeutet, der Service ist zwar funktionsfähig, aber das Skript möchte trotzdem nicht laufen.... Ich bin mittlerweile echt ratlos :?: :?: :?:
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kannst du das Skript in der Kommandozeile starten? Und was sagt das syslog?
Blitzkid
User
Beiträge: 10
Registriert: Mittwoch 10. April 2019, 18:13

Ja in der Kommandozeile starten ist kein Problem.

Meinst du das Syslog unter /var/log/syslog?

Da steht nur drinnen, wann ich per VNC connectet bin, aber nichts bezüglich bootbezogenen Diensten....
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kannst du den service von Hand starten? Also systemtctl <service> start oder wie auch genau das geht? Wenn das nicht geht, oder der schnell abbricht, sollte da eigentlich was im log erscheinen.
Benutzeravatar
noisefloor
User
Beiträge: 3853
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

`After=multi-user.target` und `WantedBy=multi-user.target` widerspricht sich eigentlich. Entweder oder.

Eigene Units gehören auch eigentlich nach `/etc/systemd/system` oder `/etc/systemd/user` (je nach dem, wann bzw. vom wem die Unit gestartet werden soll).

Im Skript fehlt das `signal.pause()` am Ende. So läuft das Skript 1x durch und macht nichts. Schau mal in den gpiozero Doku.
EDIT: letzten Satz streichen, hatte den 2. Code übersehen.

Gruß, noisefloor
Zuletzt geändert von noisefloor am Donnerstag 11. April 2019, 19:46, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

@noisefloor: die pause ist drin.
Benutzeravatar
noisefloor
User
Beiträge: 3853
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

funktioniert `signal.pause()` in Units überhaupt? Letztendlich stimmt es ja, was systemd sagt: das Skript ist inaktiv, eben wegen dem `pause`.
Keine Ahnung, wie systemd mit so Prozessen verfährt.

Stell' das Skript doch mal testweise auf polling um, auch wenn das stilistisch nicht wertvoll ist.

Gruß, noisefloor
Benutzeravatar
noisefloor
User
Beiträge: 3853
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@__deets__ ich verstehe deinen Post nicht im Zusammenhang mit meiner Frage "funktioniert `signal.pause()` in Units überhaupt?"

Funktioniert soll hier heissen, dass das Skript so funktioniert, wie ausserhalb von systemd. Das `signal.pause()` grundsätzlich funktioniert ist klar.

Gruß, noisefloor
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist ein Systemcall, der äquavilent zu einem ewig langen sleep ist, nur das halt kein Timer rumlungert. Einen Event Loop zu treiben gibt es auch nicht. Es gibt keinen Grund, warum der als sytemd unit nicht funktionieren sollte. Das zu ändern wird also keinen Unterschied machen.

Wenn würde eine Unit durch rechteprobleme oder eben genau zu lange Laufzeit (passiert mir gelegentlich in udev regeln) aus dem Rennen geworfen. Da ist es aber irrelevant, ob du nun einen systemcall machst, oder 30 mit 3 Sekunden Pause - nach 90 Sekunden (oder so) wirst du terminiert.
Blitzkid
User
Beiträge: 10
Registriert: Mittwoch 10. April 2019, 18:13

Ich hab das Ganze jetzt über ein Shellskript gelöst, welches den Autostart der Datei einleitet. Danke für ganzen Tipps :)
Antworten