One of the worst things about the Apple Magic mouse is the fact that the OS doesn't give you any kind of low battery alert until it hits 2% battery. Maybe mine is defective, but that's not enough to get through a full work day. This wouldn't be so bad if not for the worst thing about the magic mouse:
You can't charge it and use it at the same time....thanks Apple.
This details a very basic work around. We're going to add a cron job that runs every 15min that will check the battery level and show a notification if its below a certain threshold.
Setup your script
- Open a new terminal window
- enter the following commands, I'll explain what they all are later down
- mkdir bin
- cd bin
- touch mouseCheck.sh
- chmod a+x mouseCheck.sh
Copy all of this black text
#!/bin/bash
# Edit cron tab
# env EDITOR=nano crontab -e
# */15 * * * * ~/bin/mouseCheck.sh
#
#
BATT=`ioreg -c AppleDeviceManagementHIDEventService -r -l | grep -i mouse -A 20 | grep BatteryPercent | cut -d= -f2 | cut -d' ' -f2`
KEY_BATT=`ioreg -c AppleDeviceManagementHIDEventService -r -l | grep -i "Magic Keyboard" -A 20 | grep BatteryPercent | cut -d= -f2 | cut -d' ' -f2`
# defaults to warn at 12%; accepts other number as 1st argument (useful for testing)
COMPARE=${1:-12}
#COMPARE=101
if [ -z "$BATT" ]; then
echo 'No mouse found.'
exit 0
fi
if (( BATT < COMPARE )); then
osascript -e "display notification \"Mouse battery is at ${BATT}%.\" with title \"Mouse Battery Low\""
fi
if [ -z "$KEY_BATT" ]; then
echo 'No Keyboard found.'
exit 0
fi
if (( KEY_BATT < COMPARE )); then
osascript -e "display notification \"Keyboard battery is at ${KEY_BATT}%.\" with title \"Keyboard Battery Low\""
fi
- Go back to your terminal and type the following:
- cat > mouseCheck.sh
- Paste the above CMD + V
- Hit CMD + D to return to terminal prompt.
Set up the cronjob
- Type the following into the same terminal(capitals are important):
- env EDITOR=nano crontab -e
You should something that looks like this:
paste the following into it:
*/15 * * * * ~/bin/mouseCheck.sh
- Hit Ctrl + x
- Hit y
- Hit Enter
You might get a warning saying 'Terminal wants to administer' your computer, Click Ok.
Thats it! If you battery or keyboard get below 12% you should get an alert like this in the top right. I've found 12% is more than enough to get me through 2 days in case I forget after the first one.
Mine are higher because when writing this article I changed the alert level to get a screen shot.
Stick around and I'll explain what everything does if you're curious and what you can change on your own.
Commands explained:
-
mkdir bin
- create a folder called bin. This is typically where executables go. -
cd bin
- change current directory to be bin -
touch mouseCheck.sh
- create an empty file called mouseCheck.sh The .sh means this is a shell script, or will be at least. -
cat > mouseCheck.sh
write something to mouseCheck.sh - in this case we don't tell it what to write, so it will prompt us for input afterwards, until it sees the End of File character (EoF) -
ctrl + D
send the EoF character to close input.
At this point you can see whats in the file with the command: cat mouseCheck.sh
cat is the basic command to read text files.
-
env EDITOR=nano crontab -e
- Open the cron tab for editing. we need to add theenv EDITOR=nano
before hand because it lets us make a temporary change to the ENVIRONMENT VARIABLES just for this command. It's a good idea to not change things unless we specifically mean to.- If you used lower case editor, or left it out you'll end up in the default text editor VIM, which is a very powerful editor but has a very steep learning curve and is famous for not being able to be easily quit.
- If you end up here by accident you can either:
- Close your terminal and start over (remember to cd bin)
- Attempt to exit vim by:
- Hitting
esc
then type:q
and hit enter
- If you used lower case editor, or left it out you'll end up in the default text editor VIM, which is a very powerful editor but has a very steep learning curve and is famous for not being able to be easily quit.
-
Crontab syntax isn't very complicated but its unique and weird the first time you see it, if you're interested I found this was a good read on it: https://www.geeksforgeeks.org/crontab-in-linux-with-examples/
-
*/15 * * * * ~/bin/mouseCheck.sh
translates to run the script mouseCheck.sh located in the bin directory/folder in my home directory (~) every 15 minutes.
-
Script Explained
#!/bin/bash
This tells the program where to find the program to run this script. In our case we're using the shell bash
thats in the /bin
directory. This is different from the bin we put our script in.
# Edit cron tab
# env EDITOR=nano crontab -e
# */15 * * * * ~/bin/mouseCheck.sh
Honestly this isn't needed...the # at the beginning tell bash to ignore these lines, but I leave this here because I can never remember how to get to the cron editor.
BATT=`ioreg -c AppleDeviceManagementHIDEventService -r -l | grep -i mouse -A 20 | grep BatteryPercent | cut -d= -f2 | cut -d' ' -f2`
KEY_BATT=`ioreg -c AppleDeviceManagementHIDEventService -r -l | grep -i "Magic Keyboard" -A 20 | grep BatteryPercent | cut -d= -f2 | cut -d' ' -f2`
This sets up 2 variables, one for mouse battery and one for keyboard battery by running several commands each. Each time you see a | its taking the output from one command and using it as the input for the next one.
# defaults to warn at 12%; accepts other number as 1st argument (useful for testing)
COMPARE=${1:-12}
#COMPARE=101
if [ -z "$BATT" ]; then
echo 'No mouse found.'
exit 0
fi
if (( BATT < COMPARE )); then
osascript -e "display notification \"Mouse battery is at ${BATT}%.\" with title \"Mouse Battery Low\""
fi
if [ -z "$KEY_BATT" ]; then
echo 'No Keyboard found.'
exit 0
fi
if (( KEY_BATT < COMPARE )); then
osascript -e "display notification \"Keyboard battery is at ${KEY_BATT}%.\" with title \"Keyboard Battery Low\""
fi
I've run out of time, but if you're very interested in the rest of these commands drop a comment and I can fill the rest in.
Cheers.
Thank you for posting this! So annoying Apple hasn't built in their own warning. One typo though: Hit CMD + D to return to terminal prompt should be CTR + D (control).