After finishing with the hardware and software parts of my new NAS, I decided to append another little project which is aimed to provide a simplified control panel for macOS in the menu bar on the upper right of the screen.
Objective
What I wanted to achieve is a possibility to mount my various shares with one click as well as having controls for power on/off and SSH. Additionally the control should indicate whether the NAS is currently powered on or not.
BitBar
Realizing something like this in Objective-C or Swift would not be complicated but I decided to give BitBar a try. BitBar is basically a tool that loads all executable files at a given location, assumes that they provide a specific format on stdout and renders that as a menu bar app. This means that you can use almost any language including BaSH, Python, PHP, Perl, Ruby and much more to implement a menu bar app.
Installation
When using Homebrew, BitBar can be installed like this:
brew cask install bitbar
Otherwise just download it from https://getbitbar.com/.
Expected format
BitBar expects a executable printing something like the following structure to stdout:
{Text visible in the menu bar itself which can be clicked to open the menu}
---
{Text only}
{Function}|bash="uname -a" terminal=true
{Styled text}|color=red
This file should be located in the plugin folder that can be configured in the BitBar application itself. The filename also has to follow a specific convention:
<filename>.<refresh-time>.<ext>
So for my case this would be:
nas.2min.sh
2min
means that the script reloads itself every two minutes (which in my case is for checking if the NAS is still online).
Writing the script
The functiality should be pretty easy to implement so used a simple shell script. All I use in this script is ping
, ssh
, open
, osascript
and wakeonlan
.
Detect online status
This is usual unix stuff, so all I do is sending a single ICMP package using ping
to check if the system responds, throwing away all the output and saving the exit code in $RES
.
#!/bin/bash
ping -c 1 -t 1 {ip} > /dev/null 2>&1
RES=$?
Then I can just check if the exit status was 0
and paint the menu bar item either green or red according to the state.
if [ $RES -ne 0 ]; then
echo "NAS|color=red"
else
echo "NAS|color=green"
fi
When saving this and reloading BitBar (opening a BitBar menu item and press CMD+R for example), you should already see your menu bar app :-). Remember to chmod +x
the script.
Putting it all together
The following image shows how I implemented the formatted output and how it reflects on the UI:
And this is the whole script including all the functionality:
#!/bin/bash
#
# <bitbar.title>nas</bitbar.title>
# <bitbar.version>1.0</bitbar.version>
# <bitbar.author>David Prandzioch</bitbar.author>
# <bitbar.author.github></bitbar.author.github>
# <bitbar.desc></bitbar.desc>
# <bitbar.image></bitbar.image>
# <bitbar.abouturl></bitbar.abouturl>
#
if [[ "$1" = "mountstuff" ]]; then
open afp://192.168.0.21/Stuff
exit
fi
if [[ "$1" = "mountbackups" ]]; then
open afp://192.168.0.21/Backups
exit
fi
if [[ "$1" = "wake" ]]; then
/usr/local/bin/wakeonlan -i 192.168.0.255 xx:xx:xx:x:xx:xx
osascript -e 'display notification "NAS startup requested" with title "NAS"'
ssh nas "uname -a"
while test $? -gt 0
do
sleep 5
ssh nas "uname -a"
done
osascript -e 'display notification "NAS is online" with title "NAS"'
exit
fi
if [[ "$1" = "shutdown" ]]; then
ssh nas "shutdown -p now"
exit
fi
ping -c 1 -t 1 192.168.0.21 >/dev/null 2>&1
RES=$?
if [ $RES -ne 0 ]; then
echo "NAS|color=red"
else
echo "NAS|color=green"
fi
echo ---
if [ $RES -eq 0 ]; then
echo ---
echo "Shut down|bash=$0 param1=shutdown terminal=false refresh=true"
echo ---
echo "SSH|bash=\"ssh nas\" terminal=true"
echo ---
echo "Mount Stuff|bash=$0 param1=mountstuff terminal=false"
echo "Mount Backups|bash=$0 param1=mountbackups terminal=false"
else
echo "Wake|bash=$0 param1=wake terminal=false refresh=true"
fi