You can write a series of bash functions that can be called from either homebridge or Node-RED. Things to be aware of:
- When stopping any of the apps, you need to be sure to stop all of their child (grandchildren, etc) processes, so you should write a function to get all the PIDs of the entire "family" of processes.
- Starting Kodi and Raspbian (and openvpn) is straightforward from either homebridge or nodered. You start them the same way you would manually, but you must take some extra steps to start emulationstation from something that does not have an active connection to the vt (virtual terminal) that has control of the monitor.
- All the GUI apps should be started as background processes so that homebridge and Node-RED don't wait for them to finish. You do this by adding an ampersand after the command (e.g.
kodi &
)
I'll leave it to you to write the bash functions, but here are the commands you can use to start each app:
#kodi
kodi &
#emulationstation
export DISPLAY=":0"
sudo openvt -c 1 -s -f -- sudo -u pi emulationstation &
#raspbian
sudo startx &
#vpn
sudo openvpn --config config.ovpn &
Note, for emulationstation, sudo openvt -c 1 -s -f
means:
- Run openvt as the super user
- Connect to vt 1
- Switch to the indicated vt to run emulationstation
- Force the vt 1 connection even if vt 1 is already active
Everything after the --
is what will be run in vt 1. sudo -u pi emulationstation &
means:
- We're going to run the command using the super user account
- We're going to have the super user account run emulation station as the user named "pi" (use whichever user account you normally use to run emulationstation)
- We're going to run emulationstation in the background and not wait for it to exit.
We need the first sudo
to be able to call openvt, but emulationstation doesn't let you run it as the super user, so we need the second call to sudo to tell the system to run emulationstation as the pi
user. And that needs to be preceeded by --
so that openvt doesn't parse sudo's -u option as its own option.
Also (EDIT 5/21/2019: I discovered this today), you must export a DISPLAY
variable set to :0
. It seems the first time you run it, it will work without this being set, but subsequent launches will fail with errors about the display without it.
To stop each one of these apps, you should grab all the PIDs of it and its children/grandchildren/etc.. You can do this by using a combination of pgrep -f process_name
and a recursive loop of pgrep -P pid
(where you replace process_name with the name of the command (e.g. "kodi") and replace pid
with the process ID you get from pgrep -f...
). Each PID you get back must also be supplied to pgrep -P...
. You can do that in a for loop.
You should kill each process in reverse order and wait for each one to die cleanly before killing the next.
I have a series of functions I've written for these purposes and they seem to be working well, but I'm going to wait to post them after I've been able to thoroughly test them for a few weeks. But the basic idea seems to be sound and has been working for me for a few days now. I added them to my homebridge setup using homebridge-commander.
Note, one last tip is that you can write a function for homebridge-commander to report the run status of each app for its script.sh "device name" powerstatus get
call that does something like this:
STATUS=`ps -elf | grep -c kodi`
if [ $STATUS -get 0 ]; then
echo true
else
echo false
fi
If you do that when your script.sh
is called to get your "device status", your button in the home app will accurately reflect whether or not the app is running.