header image

Need a remote control for your physical servers but WOL (Wake-On-Lan) doesn't fit to your plans? Exactly my case!

In a case of emergency, such as a server not responding, I must have ability to control power states of my remote servers. Basic solution in such case is to physically reboot the server computer. But how to do it without physical access, and without WOL?

Table of Contents


Simple approach

Well, the solution for power control is to use another reliable helper computer which

  • can simulate server's power button press
  • is securely accessible via remote connection

This goal in mind, I implemented my own solution using, well what else than Raspberry Pi 3. I guess Arduino fits to plans, as well. Raspberry Pis can simulate power button press via GPIO pins. I ended up to use a Raspberry Pi 3 with 4 relay module, power button and green power led attached. Only the relay module is used to control server computer power state. In the picture above, blue (+) and black (GND) wires leaving from the relay module are connected to a server's motherboard corresponding power pins.

post image
Raspberry Pi 3 and relay module stack installed in a server computer case. The stack was mounted on a free 5.25” slot.

Raspberry Pi 3 is connected to WLAN. Necessary network configuration for remote access was carried out.

Leech power from the server

Raspberry Pi 3 needs to be powered on all the time server is running. Implementing a solution is very simple:

post image
Raspberry Pi 3 powered by server's PSU. Basically, Raspberry Pi 3 should be powered on when the server has idle power on it. The solution is very simple: make a USB power cable where one end is unmodified USB connector to your Raspberry Pi 3, and the other end has two wires: ground (GND) wire and +5V wire, attached to +5VSB (Voltage Standby) rail of the server's PSU. These wires are injected into PSU's main motherboard power cable as seen above. The brown cable is GND, the red one is connected to +5VSB socket.

Pins 9 (+5 VSB, purple; USB 5V+ red wire) and 5 (GND, black; USB GND brown wire) were used for Raspberry Pi 3 USB power cable, following the AllPinouts 24-pin power connector layout schema.

Details

Raspberry Pi 3 & relay module connections

The setup is very simple. You need to attach Raspberry Pi 5V GPIO pin to VCC pin of your relay module. Attach any Raspberry Pi's ground (GND) pin to a GND of the relay module. IN_x_ pins on the relay module must be attached to BCM pins of the Raspberry Pi. I ended up to use the following connection schema with 4 relay module:

Cable colorRelay module pinRaspberry Pi 3 GPIO pinpinout.xyz reference number
RedVCC5V2
BlackGNDGND6
WhiteIN1BCM1812
OrangeIN2BCM2316
YellowIN3BCM2418
BrownIN4BCM2522

NOTE: Only BCM18 (White) + 5V (Red) + GND (Black) are actually used in this configuration. Other BCM pins are attached for future needs.

NOTE: Be careful with your setup, as Raspberry Pi 3 has very limited capabilities of handling different voltages. You should read Raspberry Pi Stack Exchange question What are the min/max voltage/current values the gpio pins can handle? for more information.

You can use pinout.xyz website to find out GPIO pin roles on Raspberry Pis when configuring your setup.

Server computer & relay module connections

If you use relay module pin IN1 (or any IN_x_ pins), attach your server's power wires (+ and GND) to the corresponding relay channel sockets (~referring to those blue “boxes” and their screwable sockets (3 in each) on the relay chip). As I use _IN1_, I attach the server power wires as seen in the picture above. Once relay is activated by Raspberry Pi, it creates a short circuit between server's power GND and power + wires, resulting in powering up/down the server. Basically, we programmatically do just the same than you would otherwise do by hand.

The code

As you know, the mentioned setup doesn't work without code. On your Raspberry Pi 3, you need Python 3 and Python 3 Raspberry Pi GPIO libraries. Once installed, do the following.

On my configuration, I used Python 3 code developed by Samer Afach. As I use BCM18, my setup slightly differs, and the actual code I use is as follows:

> cat /usr/local/bin/server_powerswitch
 1#!/usr/bin/env python
 2# Source: https://blog.afach.de/?p=436
 3
 4import RPi.GPIO as GPIO
 5import time
 6import argparse
 7GPIO.setwarnings(False)
 8
 9#initialize GPIO pins
10GPIO.setmode(GPIO.BCM)
11
12#use command line arguments parser to decide whether switching should be long or short
13#The default port I use here is 18.
14parser = argparse.ArgumentParser()
15parser.add_argument("-port", "--portnumber", dest = "port", default = "18", help="Port number on GPIO of Raspberry Pi")
16
17#This option can be either long or short. Short is for normal computer turning on and off, and long is for if the computer froze.
18parser.add_argument("-len","--len", dest = "length", default = "short" , help = "Length of the switching, long or short")
19args = parser.parse_args()
20
21#initialize the port that you'll use
22GPIO.setup(int(args.port), GPIO.OUT)
23
24#switch relay state, wait some time (long or short) then switch it back. This acts like pressing the switch button.
25GPIO.output(int(args.port),False)
26if args.length == "long":
27    time.sleep(8)
28elif args.length == "short":
29    time.sleep(0.5)
30else:
31    print("Error: parameter -len can be only long or short")
32GPIO.output(int(args.port),True)

Naturally, you need to do chmod u+x /usr/local/bin/server_powerswitch after which the power switch command is available on your Raspberry Pi 3 as server_powerswitch and you can power on/off the server via Raspberry Pi 3. Use server_powerswitch --len long for hard power off in a case you have completely lost contact to the server (be aware of data corruption!).