Skip to main content

Battery Power-Ups: Enhancing SketchyBar with "is"

·1042 words·5 mins·
is battery bash dotfiles cli Go macos sketchybar
Table of Contents
❤️ It's great to see you here! I'm currently available on evenings and weekends for consulting and freelance work. Let's chat about how I can help you achieve your goals.

is: the new subcommands
#

In my unrelenting quest to make useless barely useful software I recently added three new battery-related subcommands to is: an inspector for your environment.

  • is battery
  • is known battery
  • is known summary battery

These subcommands are a thin wrapper around distatus/battery, but they follow the patterns of the other is subcommands.

$ is battery --help
Usage: is battery <attribute> <op> <val>

Check battery attributes. e.g. "is battery state eq charging"

Arguments:
  <attribute>    [charge-rate|count|current-capacity|current-charge|design-capacity|design-voltage|last-full-capacity|state|voltage]
  <op>           [eq|ne|gt|gte|in|like|lt|lte|unlike]
  <val>

They allow you to do things like:

$ is known battery state
discharging

and

$ is battery count gt 0 && echo "we have 🔋"
we have 🔋

and

$ is known summary battery
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Attribute          ┃ Value         ┃
┣━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
┃ battery-number     ┃ 1┃ charge-rate        ┃ 0 mW          ┃
┃ count              ┃ 1┃ current-capacity   ┃ 76750.899 mWh ┃
┃ current-charge     ┃ 99 %          ┃
┃ design-capacity    ┃ 76498.56 mWh  ┃
┃ design-voltage     ┃ 13.281 mWh    ┃
┃ last-full-capacity ┃ 77534.478 mWh ┃
┃ state              ┃ discharging   ┃
┃ voltage            ┃ 13.281 V      ┃
┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛

and

is known summary battery --json
{
    "state": "discharging",
    "battery-number": 1,
    "count": 1,
    "charge-rate": 0,
    "current-capacity": 76750.899,
    "current-charge": 99,
    "design-capacity": 76498.56,
    "design-voltage": 13.281,
    "last-full-capacity": 77534.478,
    "voltage": 13.281
}

Now that we have some new tools at our disposal, what can we do with them?

SketchyBar (Before)
#

I’ve recently replaced the default macOS menu bar with SketchyBar. One segment of the menu bar displays the current status of my battery (if one is installed). Let’s have a look at my current menu bar.

My Desktop
#

As expected, my desktop doesn’t display a battery status.

desktop

My Laptop
#

My laptop, which (fortunately) has a battery, does display a battery status. Here we see the menu with the power supply plugged in and with the power supply removed.

laptop charging
laptop


I don’t love the default macOS menu bar. SketchyBar gives me portable way to have the same configuration on the various Macs that I use from day to day. It is configured via a collection of scripts and it ships with some nice default plugins. It even runs on 2017 Macs, which is what I’m slinging for my personal needs. Let’s dive right in and see how this helps with getting a battery icon into the status bar.

I started with this SketchyBar config. It allows me to configure which segments I want to appear in my menu bar and since this is basically a bash script, I can dynamically configure the menu bar based on my environment.

I want to add the battery to the menu bar conditionally, since in 50% of the cases, I won’t be on a laptop. I didn’t have a great way to see if I was using a laptop, so initially I would manually touch $PLUGIN_DIR/.laptop on the machines where I wanted to display a battery status. That worked fine as a stopgap.

if [ -f "$PLUGIN_DIR/.laptop" ]; then
    sketchybar --add item battery right \
        --set battery update_freq=120 script="$PLUGIN_DIR/battery.sh" "${button[@]}" \
        --subscribe battery system_woke power_source_change
fi

SketchyBar menu items are not only configured via scripts, they can also be updated via scripts. I started out using this script to find the current available charge in the battery as well as the charging state (is it charging right now?) The code to get those values was as follows:

PERCENTAGE="$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1)"
CHARGING="$(pmset -g batt | grep 'AC Power')"

If I’m honest, I didn’t write that code and it doesn’t really excite me. It has the potential to be brittle. Also, don’t ask me to explain it.

SketchyBar (After)
#

After installing the latest version of is, I’m able to make this a little nicer by no longer relying on a special file to exist. Here’s a diff:

-if [ -f "$PLUGIN_DIR/.laptop" ]; then
+if is battery count gt 0; then

That leaves us with:

if is battery count gt 0; then
    sketchybar --add item battery right \
        --set battery update_freq=120 script="$PLUGIN_DIR/battery.sh" "${button[@]}" \
        --subscribe battery system_woke power_source_change
fi

For the battery script itself, I can clean that up a little with this diff:

-PERCENTAGE="$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1)"
-CHARGING="$(pmset -g batt | grep 'AC Power')"
+PERCENTAGE="$(is known battery current-charge --round)"

-if [[ "$CHARGING" != "" ]]; then
+if is battery state eq charging; then

The current charge that I get back via distatus/battery is sometimes a few percentage points off from what pmset reports back. I don’t know if macOS performs some kind of smoothing, but for my purposes I’m not too concerned. I mostly care if the battery is fully charged, almost empty or has a reasonable amount of time left on it. Everything else is not that important.

One other consideration is that SketchyBar is installed via homebrew and launched via brew services, which doesn’t have the same $PATH as my user environment. I ended up adding the path to my is installation in both of the SketchyBar files that I need to maintain for this:

PATH=~/local/bin:"$PATH"

Summary
#

That’s basically it. My SketchyBar config is in my dot-files repo. The new is subcommands are well documented via --help and the README. If you can’t remember all of the available battery attributes (and why would you) the new is known summary battery subcommand can be very handy.

If you don’t currently have a battery, it’s pretty succinct:

$ is known summary battery
┏━━━━━━━━━━━┳━━━━━━━┓
┃ Attribute ┃ Value ┃
┣━━━━━━━━━━━╋━━━━━━━┫
┃ count     ┃ 0┗━━━━━━━━━━━┻━━━━━━━┛

Otherwise it can be quite verbose.

$ is known summary battery
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Attribute          ┃ Value         ┃
┣━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
┃ battery-number     ┃ 1┃ charge-rate        ┃ 0 mW          ┃
┃ count              ┃ 1┃ current-capacity   ┃ 76750.899 mWh ┃
┃ current-charge     ┃ 99 %          ┃
┃ design-capacity    ┃ 76498.56 mWh  ┃
┃ design-voltage     ┃ 13.281 mWh    ┃
┃ last-full-capacity ┃ 77534.478 mWh ┃
┃ state              ┃ discharging   ┃
┃ voltage            ┃ 13.281 V      ┃
┗━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┛

It’s also available as JSON.

is known summary battery --json
{
    "state": "discharging",
    "battery-number": 1,
    "count": 1,
    "charge-rate": 0,
    "current-capacity": 76750.899,
    "current-charge": 99,
    "design-capacity": 76498.56,
    "design-voltage": 13.281,
    "last-full-capacity": 77534.478,
    "voltage": 13.281
}

"Lightning" by nathan_lounds is marked with Public Domain Mark 1.0 .


Related

is: an inspector for your environment
·1273 words·6 mins
Go bash dotfiles is
Debounce All of the Things
·2073 words·10 mins
Go bash dotfiles
One Line Fuzzy Find for Git Worktree
·693 words·4 mins
fzf git awk bash