Waking My Computer from Afar
bernsteinbear.com
bernsteinbear.com
Apart from working on my PC, this is also quite nice as it gives you a way to force-power-off remotely if necessary.
I wanted to wake my laptop via wifi. There's no way to do it using WoL with the laptop's wifi card.
For some reason the laptop's wifi card won't be powered during sleep or never responds to WoL packets, but the USB port is powered during sleep.
I got an ESP32-S3 which has built-in USB. I cobbled together the examples from the ESP-IDF framework. Using one wifi example I got the ESP32 to detect WoL packets sent to it, and the other example was the USB HID example that acts like a mouse and moves the cursor around.
So now I can send a WoL request to the ESP32, and it will then "move the mouse" and wake the laptop. It worked like a charm and only took me about 2 evenings to put together.
Power outages and therefore undesired activation are extremely rare where I live. Probably less than one in five years.
There's a BliKVM "card" which also looks interesting and I'd probably use if I did it again because I was trying to fit the card above the GPU and it took some modding.
So turning the smart plug on my phone on would start the computer. I use it for my backup server with a JBOD that is only turned on when I need it. You can also schedule on/off time on the app. And if you want to programmatically turn it on/off you can setup Home Assistant with the plug.
As you're launching from systemd anyway, I'd try something like `AmbientCapabilities=CAP_NET_BIND_SERVICE` in the unit file (caveat: untested). Then it's scoped to that unit, where it's (1) needed and (2) clear why it's needed. Instead of the busybox executable that (1) likely is used in a bunch of places where that's unneeded and (2) may get reinstalled by the package manager without this perm, quietly breaking your setup.
systemd also supports binding the port for you, but afaict from a quick skim, Busybox httpd doesn't support accepting the socket from systemd, so that wouldn't be as easy a change.
import subprocess
[...]
result = subprocess.run(["wakeonlan", "MY:MA:CA:DD:RE:SS"], capture_output=True)
The magic packet could be built and broadcast in pure python, without introducing a dependency on an external binary.For example, one could take inspiration from the code at https://github.com/remcohaszing/pywakeonlan/blob/main/wakeon...
#!/usr/bin/env bash
config_sys="${config_sys:-/etc/wol}"
config_user="${config_user:=$HOME/.config/wol}"
PORT="${PORT:-9999}"
cat <<EOF
WoL Wake-On-LAN Magic Packet transmitter
Copyright 2023 Tj <hacker@iam.tj>
Licensed on the terms of the GNU General Public Licence version 3.
EOF
ls() {
shopt -s nullglob
for f in $@; do
printf "%s\n" "${f##*/}"
done
}
if [ -z "$1" ]; then
cat <<-EOF
Please specify the hostname. Currently defined:
System ($config_sys/): $(ls "$config_sys/*" 2>/dev/null)
User ($config_user/): $(ls "$config_user/*" 2>/dev/null)
Config files should be named for the target host
Content is shell variable definitions
Required: IP= and MAC=
Optional: PORT= (default is ${PORT})
E.g:
MAC="60:45:cb:9f:42:fb"
IP="fddc:7e00:e001:ee80::2"
EOF
exit 1
fi
for conf in "$config_sys" "$config_user"; do
if [[ -r "$conf/$1" ]]; then
. "$conf/$1"
# don't break; allow user override
fi
done
if [[ -z "$IP" ]] || [[ -z "$MAC" ]]; then
>&2 printf "Error: required configuration missing IP='%s' MAC='%s'\n" "$IP" "$MAC"
exit 2
fi
target="/dev/udp/$IP/$PORT"
hex2char() # $1 = 2 hex digits
{
case "${#1},${1,,}" in
(2,*[!0-9a-f]*) return 2 ;;
(2,*) printf '%b' "\x$1" ;;
(*) return 1 ;;
esac
}
make_payload() # $1 = Ethernet MAC address with ":" separators
{
IFS=":" read -r -a mac < <(echo "$1")
for h in "${mac[@]}"; do
magic="$magic$(hex2char "$h")"
done
payload=""
ff="$(hex2char "ff")"
for ((i=0; i < 6; i++)); do
payload="${payload}${ff}"
done
for ((i=0; i < 16; i++)); do
payload="${payload}${magic}"
done
}
printf "Sending magic packet to %s (%s port %s [MAC %s])\n" "$1" "$IP" "$PORT" "$MAC"
make_payload "$MAC"
printf "%s" "$payload" > "$target" || printf "error: failed to send (error %s)\n" "$?"I had a quick look at Tailscale and it seems to be a VPN network that you get to manage? So it's still a VPN just with convenience functions to make adding devices easy is that about right? Where does the DNS for this exist, is it on Tailscale's own servers. There must be some purpose to having to login. Does Tailscale also hold some connection open to figure out which devices are on or not.
In a way this reminds me of AWS SSM Agent. I think it's talking to some central Amazon servers and I don't need to open a port on an EC2.
And yes, Tailscale keeps a connection open to its servers to allow other devices to reach you when you're behind a firewall and direct connections can't be established.
You login to Tailscale from each device in order for the central Tailscale control plane to authenticate the device and for it to distribute that device's public Wireguard key out to the rest of the mesh.
https://www.arduino.cc/reference/en/libraries/ethernetwebser...
Or it could employ some sort of port knocking on the uC+Eth board so that it wakes up the main system only when the right sequence is used. The advantage of using a uC, lower power draw aside, is that micro SD cards (and their sockets) are less reliable than internal flash.
[1] https://ntfy.sh/
I eventually replaced it with an aliexpress tuya pcie power switch. I just wish I'd gotten the zigbee version. Homeassistant with local tuya wifi devices is quite janky.
If you're imagining you just forward the port to your computers IP address... no that doesn't work. Because while your computer is asleep it doesn't have an IP address. What you need to do is configure the router to forward broadcast packets to the local subnet. Something like that anyway, I can't remember the exact details.
Maybe some have the feature if you're forwarding a port, it will send a wakeonlan packet if it detects traffic on that port.
Lets let a for-profit third party dictate and manage your network. What could possibly go wrong?
b) I don't have to think about doing systems administration on the very resource-limited stripped-down OpenWRT device
c) It's probably marginally more secure
Security-wise I prefer the port forwarding because there is no third party involved and less complexity in general, but sure, you can find pros and cons here and there.
Are there places in the world where people have to actually care about the power consumption of their computer so much that this is a thing? Any examples?
From a hardware perspective, it seems to be high temperature for a long time (>70C, >55C if it's passively cooled) and thermal cycling are the two mechanisms that cause hardware to fail. Neither of these are true for a computer left on when idling.
Where I am from, 1 W 24/7/365 is approximately one dollar per year (~10 cents per kWh). I have a Mac Mini M1, now, but I used to have an Intel MacBook Pro and before that, a 300W workstation.
The MacBook Pro took about 30 watts idling, so about two dollars a month. I probably lose more than that on exchange rate fluctuations.
The 300W workstation took about 300 watts idling, so about 20 dollars a month. This is rightfully significant, and due to this concern, that computer was replaced. However, if I did not have the option, 20 dollars a month is a perfectly reasonable price to pay considering the hundreds of tabs, programs, daemons, and other misc things that I always had going on. I treated the computer as an extension of my mind that doesn't sleep, and I would pay $20 gladly for this feature.
Now I have a Mac Mini M1. I haven't measured the wall power but "powermetrics" says the CPU, which is the only actual part in the computer, taking 600 mW (0.6W) idling. Absolutely no reason to shut this down ever. Why would I even consider that.
Unless you have a GPU, and a relatively modern system, most desktop PCs (dell, etc) probably take about 15-20W to run. A GPU adds about 20-30W of idle drain. Depending on what you do with your computer, the question is simple: Would I pay $1/W/24/7/365 per year to keep all my stuff open? If it's too high, can you reduce the idle power consumption?
with average california cost/kwh (.35)
raspberry pi ~ $1/month
200w server ~ $50/month
also, more time on might mean more disk wear and greater chance of hardware failure. (there is probably some sort of heat shock, so leaving things on might be good too)
I live in California. Electricity is not free, or even cheap.
I have 4 computers. 1 out in the garage that's my "off-site" backup system, complete with LTO tape drive. It's also got an 8 drive RAID10 array. I don't need it running 24/7. I need it on when I have a backup job for it to do, and off when I don't need it on.
I have a workstation that I only use when I'm developing personal code. I don't need it running 24/7. It also has 8 spinning disks, video card, and a massive CPU. It consumes about 300W of power, so that adds up.
My laptop is off when I'm not using it, but even that I wake remotely from time to time when I'm out in the garage and need a file from it.
I have 1 server that runs 24/7 and handles Plex, security cameras, and 6 virtual machines. It's a workhorse, but it's got a 65W CPU in it and barely uses the video card.
My electric bill is $600/month in the summer months, mostly due to AC but I don't need to make it any worse by running 4 computers continuously when I don't need to.