Saving Energy with Wake-On-LAN

Published on

Having home servers for dev and management of family data is fantastic. But there is one downside that doesn't really get talked about that much, and that is power consumption as your home lab/network grows in size.

In this article, I'm going to take a look at tackling the challenge of reducing power consumption, doing my little bit to help save the environment and my wallet from energy bills by scheduling shutdowns and starting them up in the morning via a Raspberry.

The Setup

I have a Raspberry Pi 3 Model B+ lying around not currently doing anything which draws a couple watts when idle - I intend to run this 24/7 to start both my servers up first thing in the morning.

I have two servers, one HP ProLiant MicroServer Gen8 which is a Windows Server and serves AD/DHCP/DNS for the network as well as a backup for critical data on my other server. This server draws around 30-40 watts.

My other server is a Dell PowerEdge T430 running Proxmox for all other services I require. This server draws around 160 watts.

The Plan

The plan is to leverage Etherwake in a simple Python script which will run as a service.

The Process

After installing Raspberry Pi OS Lite, as a GUI is not needed for this headless setup, I set to work getting everything set up and ready.

First was making sure the system is up to date:

$ sudo apt update
$ sudo apt upgrade -y

Next I could install Etherwake and Python:

$ sudo apt install etherwake
$ sudo apt install python3
$ sudo apt install python3-pip

Before we start writing our Python script, we will want to install a couple packages:

  • schedule - enables us to fluently schedule operations
  • pytz - enables scheduling to handle timezone/daylight savings
$ sudo apt install etherwake
$ sudo apt install python3
$ sudo apt install python3-pip
$ cd ~/
$ mkdir wake-on-lan
$ cd wake-on-lan
$ python -m venv ./python
$ ./python/bin/python -m pip install --upgrade pip
$ ./python/bin/pip install schedule
$ ./python/bin/pip install pytz
$ nano ~/wol.py

Now we're ready to start writing our script

Our script will look something like this:

import schedule
import subprocess
import time

def _main():
    print('Starting WoL scheduler...')

    # Startup servers a 06:00 every day
    schedule.every().day.at('06:00', 'Europe/London').do(startup)

    while 1:
        n = schedule.idle_seconds()
        if n is None:
            # No more jobs
            break
        elif n > 0:
            # Sleep until the next scheduled job
            time.sleep(n)
        schedule.run_pending()

def startup():
    # Server 1
    startup_server(ip='192.168.0.1', macaddress='<MACADDRESS>')
    # pve1
    startup_server(ip='192.168.0.2', macaddress='<MACADDRESS>')

def startup_server(ip, macaddress):
    is_alive = subprocess.call(['ping', '-c', '1', ip], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) == 0
    if not is_alive:
        print('Sending wake-up packet to ' + ip)
        subprocess.Popen('/usr/sbin/etherwake -b ' + macaddress, shell=True, stdout=subprocess.PIPE)
    else:
        print (ip + ' is already running...')

if __name__ == '__main__':
    _main()

The core of this python script is that it will create a schedule every day at 6AM Europe/London time. It will run infinitely but sleep during the time remaining until the next scheduled job. When a schedule is up, it sends a ping to the device to determine if it's already on, or sends an etherwake packet to start it.

Finally, we want to get this running as a service on the Pi.
To do this, we're going to create a systemd service and configure it to run.

$ sudo nano /etc/systemd/system/wake-on-lan.service

In this file, we're going to configure the service like so:

[Unit]
Description=Server starter

[Service]
User=root
Group=root
ExecStart=/home/<USERNAME>/wake-on-lan/python/bin/python /home/<USERNAME>/wake-on-lan/wol.py
Restart=on-failure

[Install]
WantedBy=multi-user.target

Finally, we can enable and start the service.

$ sudo systemctl enable wake-on-lan
$ sudo systemctl start wake-on-lan

And we're done! The Pi should now be sending wake requests to my two servers at 6AM every morning. All that's left to do is configure the servers to auto shut down at 11 at night.

Summary

In this post I took you through my means of saving myself a little money by using a Raspberry Pi 3 Model B+ to allow me to set my servers to automatically switch off at night while still being woken up in the morning.