Windows PC Wake up / Shut down - Automated
Problem:
I've just got an Amazon Echo. As the previous post suggests I've got it talking to Jenkins, so anything that can be done in Jenkins Alexa can now call, which is rather awesome.
This being said, I wanted to get Alexa to turn on and off my PC, which I didn't think was too unreasonable.
Solution:
There's a couple of parts to this, the turning on and the turning off. Both have to use different mechanisms.
Turning On:
Best option here I could think of was the good old Wake on LAN packet. I have a Gigabyte H81M-DS2V motherboard. It took me a long long time to get this to work (which is slightly embarrassing given the simplicity of the solution).
First getting into the BIOS was hard enough, given the boot speed of the SSD! I had to unplug the thing...got it all working, plugged the SSD back in and booted into windows, after shutting down it stopped working!
Turns out all I had to do (right from the beginning as well) was to update the Realtek driver for the NIC. You can find the driver I used here:
http://www.realtek.com.tw/Downloads/downloadsView.aspx?Langid=1&PNid=13&PFid=5&Level=5&Conn=4&DownTypeID=3&GetDown=false
Obviously you'll need to actually enable Wake On LAN within windows, but there's plenty of articles on how to do that out there. Here's a good article for that:
http://www.sysadminshowto.com/how-to-configure-wake-on-lan-in-windows-10-and-windows-8-1/
Now Wake on LAN actually works - how do we get this working with Alexa? Obviously our good friend the HA-Bridge comes into play, but do we need Jenkins?
Turns out, no! Initially I had this working by using Jenkins to spin up a temporary docker container which has a Wake on LAN application in and passing the MAC of my PC to it etc etc...this worked quite well, but took a few seconds to activate, especially if the container had to be pulled down. There is a better way!
HA-Bridge can send UDP packets. They have to be crafted in raw hex, but given the simplicity of a Wake on LAN packet, this is pretty easy.
The packet structure is as follows: 6 bytes of FF followed by 16 copies of the MAC you want to wake up, you can then send this to the network broadcast address on UDP port 9. Using HA-Bridge you can specify a UDP destination so if you had the following MAC: 00:11:22:33:44:55 and your PC sat on the 10.10.10.0/24 network the URL you need to use is the following:
udp://10.10.10.255:9/0xFFFFFFFFFFFF001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455001122334455
This is much faster than using some other tool, and you can confirm that it's being sent by listening on any machine on that network with wireshark as it should be received as a broadcast.
Turning Off:
First, we need a Linux machine with the samba-common toolset. I use an existing machine and my Jenkins server can just SSH to it. So we're set there.
Now we need to allow the windows machine to actually be controlled. You can do this by using the registry editor and navigating to the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Then create a new 32 bit DWORD entry with the following name: LocalAccountTokenFilterPolicy and set the value to 1
You can now turn off the machine (providing you don't have a firewall in the way) using the following command:
net rpc -S ipaddress -U 'username%password' shutdown -t 1 -f
This was a prime example of something that actually worked straight away, and I couldn't help but laugh at how seemingly easy it was.
I bunged this into Jenkins as an SSH job (so it SSH's to my linux host and runs this command) and used the credential manager built into Jenkins to store the username and password for the machine.