I purchased a Logitech/Saitek PZ55 Flight Switch Panel recently and set it up so I could control my computer:
It can now do the following:
- Start my gaming PC via Wake-On-Lan.
- Open Task Manager.
- Open explorer.exe.
- Start Firefox, Discord, Steam, Spotify, Blender.
- Start my favourite game.
- Start a Chrome session with Special Business™ tabs already open.
Switch Controller
The switch is connected to a Raspberry Pi 4B which runs a Python script as a SystemD service.
A prototype version of the script worked as follows:
import hid
import requests
vid = 0x06a3
pid = 0x0d67
with hid.Device(vid, pid) as h:
while True:
fip = h.read(3)
print(fip[0])
if fip[0] == 4:
x = requests.get('http://10.0.0.100:5120/')
Using the pyhidapi
package, we open a connection to the PZ55 Flight Switch Panel and keep reading every time a new USB HID event is emitted. If a particular switch is set, it’ll call out to an API endpoint on a local network web server.
A more recent verison of the code uses a global state, so that flicking a switch either way will call out to the same endpoint, and also added a bunch of different endpoints.
Receiving Webserver
I set up a very basic C# ASP.NET web app, with a controller that listens for specific endpoints (the ones used by the switch). Depending on the endpoint selected, it calls out to PSExec and tells it to run that particular application. An example controller:
public string Inquisitor()
{
ExecuteCommand.Run("PsExec.exe -d -i $(query session | select -skip 2 | %{$_.Split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)} | select -skip 2)[0] explorer 'steam://rungameid/527430'");
return "Starting Inquisitor: Martyr.";
}
In this case, ExecuteCommand.Run()
is a helper function I’ve created that starts a process, runs a background PowerShell prompt, and then executes that command through it:
public static void Run(string Command)
{
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("powershell.exe", "/c " + Command);
Process = Process.Start(ProcessInfo);
}
That PowerShell command gets the current active sessions, finds the first user session, and then runs PSExec against it so that we can enable GUI applications remotely.
It’s not super complicated, it’s very hacky, but it works and it’s designed for use only on my home setup. Do not do something like this in an official environment.
I used NSSM to install it as a Windows Service that logs on with my account when I start up the PC and gives it Administrator level permissions to allow it to start applications in my active desktop.
Why?
The modern personal computer usually consists of a keyboard with a bunch of buttons and a mouse or trackpad with a couple more.
But computers used to be all about the switches. Take for examble, the venerable PDP-11/70 front panel below:
But what if we added physical switches to personal computing?
I love the idea of a console like the Serenity from Firefly:
Or the complexity of aircraft control panels like the A-10C Warthog:
I know what I’m doing isn’t super practical when all of the functionality is available in menus accessible via my keyboard or mouse, but I think personal computing should be more personal, more fun, and I’m aiming to enable that for myself.