1

I have 3 GUI apps on my RPi:

  1. Raspbian
  2. Retro Pie
  3. Kodi

and I have both Node Red and homebridge always running in the background. NOOBS is my boot manager.

I would like to be able to tell Siri (using homebridge) to "Turn on Retro Pie|Kodi|Raspbian" and have the following happen:

  1. Determine which (if any) of the apps is currently running and if one is (and it's not the requested one), kill/quit it
  2. Run the requested app

Additionally, as a bonus, if I select Kodi, I'd like to check to make sure that there's an active VPN connection (using openvpn) before running Kodi. And if Kodi is the currently running GUI app and I'm switching apps to something else, disconnect the VPN.

I'm not sure how much bandwidth the VPN client takes up, so perhaps I should just make sure that's running all the time...

One last thing: I know someone will want to suggest I get an additional RPi for all these functions. Maybe one day, but for now, everything runs great together and I usually am only using one at a time anyway.

1 Answer 1

1

You can write a series of bash functions that can be called from either homebridge or Node-RED. Things to be aware of:

  1. 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.
  2. 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.
  3. 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:

  1. Run openvt as the super user
  2. Connect to vt 1
  3. Switch to the indicated vt to run emulationstation
  4. 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:

  1. We're going to run the command using the super user account
  2. 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)
  3. 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.