Is This Thing On?
5 minute readQuestioning my hatred of LEDs.
One of the most difficult problems I’ve had with using this machine headless, is knowing whether it’s turned on or not. Seriously.
If I connect the external monitor (ok, not headless in that case), no image on the screen might mean:
- The Macbook is not turned on
- The Macbook is asleep
- There is a problem with the monitor or connection (eg bad cable)
If I try to connect over NoMachine or VNC and fail, that might mean:
- The Macbook is not turned on
- The Macbook is asleep
- The Macbook is not connected to the network
- NoMachine/VNC is not started on the Macbook
- I’ve configured something wrongly with NoMachine/VNC
I really dislike the millions of blinking LEDs designers love to stick on electronic devices. They constantly nag or distract, I think they are bad. But I’d kill for one one this Macbook!
Things I’ve tried
I have a small USB-C SD card reader. It has a red LED which lights up when it is receiving power. For a while I used this, but it’s impractical. Although it’s small, it still sticks out to be breakage risk. A nice bit of leverage on the USB port, just waiting to wrench it off if it catches on something (a bit like the 1st-gen Apple Pencil when it was charging).
At some point I noticed that the caps lock
button on the keyboard had an LED which lit when caps was locked. And (remembering I’d usually be using a Bluetooth keyboard and pointing device), the caps lock could be applied to the built-in keyboard without affecting the Bluetooth keyboard. I could just leave caps lock on and the LED would stay lit.
The showstopper problem with both of the above ideas was that they both only worked when the Macbook was fully booted and ready to rock. I guess the ports and caps lock LED are powered off at other times. Most of my periods of confusion as to whether it was powered on or not were happening when it was half-on, during boot, sleep, shutdown etc.
My current-best solution
I noticed that my router, in its list of ‘attached clients’ was providing relatively quick/up-to-date information about whether the Macbook was connected or not. It seemed to connect to Wi-Fi quite early in the boot process, and disconnect soon after I initiated a shutdown.
Following on from that, I started ping
ing the Macbook in a terminal window, which I could keep nearby while I worked. This was getting close enough for my purposes.
The obvious next step was to script it properly. My aim was to get a brief status line telling me if the Macbook was connected or not, and its battery charge level. The following script did the job:
#!/bin/bash
# Ping a Mac on the LAN
# If it's alive, check its battery level using a seperate script `battery-check` (present on the
# Mac)
# Return the result with coloured text to indicate off/on status, and rough battery level
# Loop repeatedly, overwriting the results text each time onto the same single line
ip_to_check=192.168.8.123
hostname=AIR
wht='\033[1;15m'
red='\033[1;31m'
ylw='\033[1;33m'
ong='\033[38;5;208m'
grn='\033[1;32m'
nc='\033[0m' # No Colour
update_battery () {
# Log in with SSH and call script to get battery charge info.
battery_check_output=$(ssh AIR "bash --login -c battery-check")
# `battery-check` returns a string like `battery: 18%`, we want to extract the number.
percentage=$(echo "${battery_check_output}" | tr -dc '0-9')
if [[ $percentage -lt 15 ]]; then
battcolor=$red
elif [[ $percentage -lt 30 ]]; then
battcolor=$ong
elif [[ $percentage -lt 80 ]]; then
battcolor=$ylw
else
battcolor=$grn
fi
}
# Hide cursor
tput civis
update_battery
sleep 1
update_battery
sleep 1
i=0
while :
do
# -c 1 ... count 1 (only ping once)
if ping -c 1 ${ip_to_check} &> /dev/null; then
# Temporarily go white to indicate battery has just been checked/updated (2 * 5 = 10secs)
if [[ $i -lt 2 ]]; then
color=$wht
else
color=$battcolor
fi
echo -ne " ${hostname} ${grn} ON ${nc}${color}${percentage}%${nc}\r"
# i ends up incrementing every 5secs or so
((i++))
# Increment and every n counts update battery
# 5sec * 36 = 180secs = 3mins
if [[ $i -eq 36 ]]; then
i=0
update_battery
fi
else
echo -ne " ${hostname} ${red} OFF ${nc}\r"
fi
sleep 5
done
I already had a little script on the Mac to report the battery level (a very simple wrapper around a Mac built-in system_profiler
, just to shorten the output).
#!/bin/sh
percent=$(system_profiler SPPowerDataType | grep "State of Charge (%)" | awk '{print $5}')
echo "battery: ${percent}%"
Then I wanted to be able to float the mac-get-status
script in a tiny window.
This next script opens up a terminal in a new window, gives it a specific title macmonitor
, and runs mac-get-status
:
#!/bin/bash
$TERMINAL --title macmonitor -e "mac-get-status" &
Then I tell my window manager (DWM) to apply a special rule to windows with that specific title. This is how it’s done in DWM but other window managers may have ways of achieving the same thing.
static const Rule rules[] = {
// If an Xfce4-terminal window has title 'macmonitor':
// - Make it float
// - Make its dimensions 150px x 22px
{"Xfce4-terminal", NULL, "macmonitor", 0, 1, -1, 0, 0, 150, 22, 1},
// other rules...
};