Search code examples
pythonsocket.iosubprocesssystemd

Running python-socketio with SystemD to play sounds at background


My SystemD service file looks like this:

[Unit]
Description=XXX
After=sound.target network.target
Wants=sound.target

[Service]
ExecStart=/usr/bin/python3 -u raspberry.py
WorkingDirectory=/home/pi/Desktop
Restart=always
User=pi
PrivateTmp=true

[Install]
Alias=XXX
WantedBy=multi-user.target

The python script is a classic python-socketio client which should listen for events like "listen" and "play". The main part of code looks like this:

import subprocess
import socketio

HOST = "https://XXX.ngrok.io"
sio = socketio.Client(engineio_logger=True)

...

@sio.on('play')
def play(data):
    print("play")
    subprocess.call(["espeak", "'Not working'"])

if __name__ == '__main__':
    subprocess.call(["espeak","'Initialized'"]) 
    sio.connect(HOST)
    sio.wait()

When I set up the service to run at booting, the first calling of espeak is executed and socket connection with my server is established but then if I send an event (through my server) the second calling of espeak is not working (there is no sound). If I look into logs through journalctl -u XXX I will see that the function is called because the print statement is executed.

What comes to my mind is that it is because of running the subprocess call from a different thread, but I am not sure.. any ideas?


Solution

  • The solution is related to my other question at Raspberry Pi forum. The main problem was the inability of root to play sounds. When I was debugging this problem, I found that because of User=pi the service is started as user pi. But when I call subprocess.call in @sio.on('play') part it was under called as user root. It was happening only in @sio.on('play') part. If I did it in if __name__ == '__main__': part, the calling was under pi user. Still don't know why it was happening but solution was not using AIY hat version of Raspbian but classic version Raspbian Stretch Lite.