Powerbutton over the Network

· seth's blog


It's early 2020, at the start of the pandemic for me. My job sent me home indefinitely. And I'm trying to find projects to do. I was really into playing PC games on my TV, and I liked the idea of playing it on my Steamlink. But how do I do that without getting up to turn on the silly thing? Enter a Raspberry Pi project.

The hardware #

The beast

What you're looking at is the end product. It was not very good looking, and I ended up cutting into the computer case. The important thing here was the breadboard with the I think 1000ohm resistor on it? That probably should've been a diode (not simply a resistor) to prevent electricity at all from coming back to the Pi. But I digress.

The software #

The automation had three levels of tools with it. It had a function to check if the PC was on, to power on the PC, and to power it off.

Python code for the power button #

The first function here was to do a simple ping against my PC's static IP address to see if it was running or not. If I got a response, I would say that it's up. If I didn't I will say it's down. That'll help me decide whether or not to poweron/poweroff.

checkpc.py

from contextlib import contextmanager
import sys, os

@contextmanager
def suppress_stdout():
    with open(os.devnull, "w") as devnull:
                old_stdout = sys.stdout
                sys.stdout = devnull
                try:  
                    yield
                finally:
                    sys.stdout = old_stdout

with suppress_stdout():
     hostname = "192.168.0.2" #example
     response = os.system("ping -c 1 " + hostname)

#and then check the response...
if response == 0:
    print("Gaming PC is up!")
else:
    print("Gaming PC is down!")

The next function was to turn it on. It looks like I shot everything through the #11 GPIO pin as stated before since the other cable was attached to ground. Reading the code, it looks like I send a pulse out for like 2 seconds straight, before turning it off. There is a loop to go through it 50 times but I think that was for debugging.

poweronpc.py

#import the GPIO and time package
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
# loop through 50 times, on/off for 1 second
#for i in range(50):
GPIO.output(11,True)
time.sleep(2)
GPIO.output(11,False)
time.sleep(1)
GPIO.cleanup()
print("Gaming PC powered on")

The last function was to turn it off once I was done with it...or if to turn off the PC if it was frozen or something.

poweroffpc.py

#import the GPIO and time package
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
# loop through 50 times, on/off for 1 second
#for i in range(50):
GPIO.output(11,True)
time.sleep(5)
GPIO.output(11,False)
time.sleep(1)
GPIO.cleanup()
print("Gaming PC powered off")

iOS Shortcuts #

All of this software was great, but I wasn't going to SSH into my Raspberry Pi every time I want to turn on my gaming PC.

At least on my computer. If I can just yell at my phone to turn on the computer, I don't care if it ends up doing SSH to run the script! And that's exactly what I did here for all three automations:

FIRST PART OF SHORTCUT #

shortcut 1

SECOND PART OF SHORTCUT #

shortcut 2

And that's it! Depending on what shortcut I called on, I would turn on/turn off my gaming PC.

Summary and what can be done better #

This solution worked well, and I was pretty happy with the results. If I had to do it over now, I probably would go for at least a diode and some more robust electrical protections for the connectino between the Pi and the PC (rather than just exposed wire).

I would probably combine all of the Python code into a single script, define each function, and then call what I'm trying to do with an argument vs. what I did back then. I do not have a gaming computer like this anymore, so I can't turn around and test that theory today. But please feel to take this code and make it better!