Change button background color if...

Hi there,
I got my battery status as widget in the touch bar. It would be great, if the color (now black) would change to red as soon as the battery level is < 10%.

Found this code for Apple Script but I can't find out what the "then" part should be:

set batteryPercent to word 6 of paragraph 2 of (do shell script "pmset -g batt")

if batteryPercent < 10 then

I don't even understand the first part haha

Thanks for your advices!

Here is the completed version:

set batteryPercent to word 6 of paragraph 2 of (do shell script "pmset -g batt")

if batteryPercent < 10 then
	return "{\"text\":\"" & (batteryPercent as string) & "\", \"font_color\": \"255,0,0,255\"}"
else
	return "{\"text\":\"" & (batteryPercent as string) & "\", \"font_color\": \"0,0,0,255\"}"
end if

You can set other things such as icon, background color, font size:

Hi @buseco, thanks for the code.

I tried it on 2 different ways:

  1. I created the battery percentage widget and added a second action with your code.
  2. I directly pasted the code as action to the widget.
    I also restarted BTT.

Both ways don't work and I don't know what I'm doing wrong.

I ran the script in this editor and the result is just fine, but the color in the touchbar doesn't change.
Any guesses what I'm doing wrong?

Thank you!

That's where you should assign the action. You also have there the option to execute the script every X seconds. Don't forget to name it.

You can use this, works fine for me:

{
  "BTTWidgetName" : "Battery Percentage",
  "BTTTriggerType" : 639,
  "BTTTriggerTypeDescription" : "Apple Script Widget",
  "BTTTriggerClass" : "BTTTriggerTypeTouchBar",
  "BTTPredefinedActionType" : -1,
  "BTTPredefinedActionName" : "No Action",
  "BTTEnabled2" : 1,
  "BTTUUID" : "6A30B5CB-A8FA-4541-BD70-41E0D917AC13",
  "BTTEnabled" : 1,
  "BTTModifierMode" : 0,
  "BTTOrder" : 59,
  "BTTDisplayOrder" : 0,
  "BTTMergeIntoTouchBarGroups" : 0,
  "BTTTriggerConfig" : {
    "BTTScriptType" : 0,
    "BTTTouchBarButtonColor" : "75.323769, 75.323769, 75.323769, 255.000000",
    "BTTTouchBarItemIconWidth" : 22,
    "BTTTouchBarButtonFontSize" : 16,
    "BTTTouchBarItemPlacement" : 1,
    "BTTTouchBarAlternateBackgroundColor" : "75.323769, 75.323769, 75.323769, 255.000000",
    "BTTTouchBarButtonCornerRadius" : 6,
    "BTTTouchBarScriptUpdateInterval" : 20,
    "BTTTouchBarAppleScriptString" : "set batteryPercent to word 6 of paragraph 2 of (do shell script \"pmset -g batt\")\r\rif batteryPercent < 10 then\r\treturn \"{\\\"text\\\":\\\"\" & (batteryPercent as string) & \"\\\", \\\"font_color\\\": \\\"255,0,0,255\\\"}\"\relse\r\treturn \"{\\\"text\\\":\\\"\" & (batteryPercent as string) & \"\\\", \\\"font_color\\\": \\\"255,255,255,255\\\"}\"\rend if",
    "BTTTouchBarAppleScriptStringRunOnInit" : false,
    "BTTTouchBarButtonName" : "Battery Percentage",
    "BTTTouchBarAppleScriptUsePath" : 0,
    "BTTTouchBarFreeSpaceAfterButton" : 5,
    "BTTTouchBarItemIconHeight" : 22,
    "BTTTouchBarItemPadding" : 0
  }
}
1 Like

Hi @buseco
thanks again for the explanation.
These are my settings now and as you can see in the results field the result returns the "else".

I*m a little bit into coding, but here I'm really struggeling with debugging.

Oh my bad haven't noticed this earlier. You should change this line:

set batteryPercent to word 6 of paragraph 2 of (do shell script "pmset -g batt") 

to

set batteryPercent to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number

Notice the as number at the end. The problem was that batteryPercent was taken as text when compared in the if condition with an integer, that's why it failed.

1 Like

Thanks so much, this works now. Really really nice of you for helping me out here.
I guess I can find AppleScript references anywhere in the internet for further stuff and hope that I can share my knowledge then, too.
What about if you would write this as a tutorial here in the forum?

Bye

@buseco I am working on this to add conditional icons as well. So when my mac is charging, it shows the charging battery. There is also a 100/80/50/30 icon that displays the battery that full. Is there a library or tool i could use to see how to add that?

You can use the following code, but bear in mind that it will work only if you have a folder called "battery" on Desktop, having icons called as so: b1, b2, b3, b4, bCharging.

I've attached the icon resources I've used battery.zip (16.5 KB) so you can simply unzip it on Desktop. You can change the icons but don't forget to change the path in the code.

set batteryPercentage to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number

set title to "\"text\":\"" & (batteryPercentage as string) & "%\""

if batteryPercentage < 10 then
	set fontColor to "\"font_color\":\"255,0,0,255\""
else
	set fontColor to "\"font_color\":\"255,255,255,255\""
end if

try
	do shell script "pmset -g batt | grep -wci \"charging\""
	set isCharging to true
on error errmsg number errnr
	set isCharging to false
end try

if isCharging then
	set icon to "\"icon_path\":\"~/Desktop/battery/bCharging.png\""
else if batteryPercentage > 75 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b4.png\""
else if batteryPercentage > 50 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b3.png\""
else if batteryPercentage > 25 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b2.png\""
else
	set icon to "\"icon_path\":\"~/Desktop/battery/b1.png\""
end if

return "{" & title & "," & fontColor & "," & icon & "}"

In order to determine wether the laptop is charging or not I've used pmset -g batt and notice it displays wether it is "charging" or "discharging", and with a simple grep we can look after that text. Note that grep will have a non zero exit code if no matches are found, so the shell script call is wrapped on a try clause.

You can adjust the intervals after your needs. Hope this helps you.

Note: I've got the battery status icons from https://www.flaticon.com/packs/battery-status

@buseco This is great!! Last question, what would I add in to display the time remaining (similar to the stock Golden Chaos battery widget)?

You can use the same command, pmset -g batt. You can grep after the remaining time with something like this:

pmset -g batt | grep -o "[0-9]\{1,2\}:[0-9]\{1,2\}"

You will have the exact value, for instance 3:17 and then you can add it to your text. Note though that grep might come empty when the time isn't estimated yet so don't forget to wrap the script execution in try-on error.

1 Like

Using that one gives me

Expected end of line but found “[”.

Am i nesting that line alone in the following code or should it go somewhere specific?

    set batteryPercentage to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number

set title to "\"text\":\"" & (batteryPercentage as string) & "%\""

if batteryPercentage < 10 then
	set fontColor to "\"font_color\":\"255,0,0,255\""
else if batteryPercentage < 30 then
	set fontColor to "\"font_color\":\"255,140,0\""
else
	set fontColor to "\"font_color\":\"255,255,255,255\""
end if

try
	do shell script "pmset -g batt | grep -wci \"charging\""
	set isCharging to true
on error errmsg number errnr
	set isCharging to false
end try

if isCharging then
	set icon to "\"icon_path\":\"~/Desktop/battery/bCharging.png\""
else if batteryPercentage > 75 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b4.png\""
else if batteryPercentage > 50 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b3.png\""
else if batteryPercentage > 25 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b2.png\""
else
	set icon to "\"icon_path\":\"~/Desktop/battery/b1.png\""
end if

return "{" & title & "," & fontColor & "," & icon & "}"

When using do shell script "script goes here" you need to escape some characters, such as " or \. In this case, it would consider the script content over right before the [ character. Here's how it should look:

set batteryPercentage to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number

try
	set remainingTime to do shell script "pmset -g batt | grep -o \"[0-9]\\{1,2\\}:[0-9]\\{1,2\\}\""
	set title to "\"text\":\"" & (batteryPercentage as string) & "% (" & remainingTime & ")\""
on error errmsg number errnr
	set title to "\"text\":\"" & (batteryPercentage as string) & "%\""
end try


if batteryPercentage < 10 then
	set fontColor to "\"font_color\":\"255,0,0,255\""
else
	set fontColor to "\"font_color\":\"255,255,255,255\""
end if

try
	do shell script "pmset -g batt | grep -wci \"charging\""
	set isCharging to true
on error errmsg number errnr
	set isCharging to false
end try

if isCharging then
	set icon to "\"icon_path\":\"~/Desktop/battery/bCharging.png\""
else if batteryPercentage > 75 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b4.png\""
else if batteryPercentage > 50 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b3.png\""
else if batteryPercentage > 25 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b2.png\""
else
	set icon to "\"icon_path\":\"~/Desktop/battery/b1.png\""
end if

return "{" & title & "," & fontColor & "," & icon & "}"
1 Like

Perfect! This is the final code im using in the widget that allows 20% increments and switched up the icons as well (battery-pjw.zip) as the text colors for <30% and <5%:

set batteryPercentage to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number

try
	set remainingTime to do shell script "pmset -g batt | grep -o \"[0-9]\\{1,2\\}:[0-9]\\{1,2\\}\""
	set title to "\"text\":\"" & (batteryPercentage as string) & "% (" & remainingTime & ")\""
on error errmsg number errnr
	set title to "\"text\":\"" & (batteryPercentage as string) & "%\""
end try

if batteryPercentage < 10 then
	set fontColor to "\"font_color\":\"255,0,0,255\""
else if batteryPercentage < 30 then
	set fontColor to "\"font_color\":\"255,140,0\""
else
	set fontColor to "\"font_color\":\"255,255,255,255\""
end if

try
	do shell script "pmset -g batt | grep -wci \"charging\""
	set isCharging to true
on error errmsg number errnr
	set isCharging to false
end try

if isCharging then
	set icon to "\"icon_path\":\"~/Desktop/battery/bCharging.png\""
else if batteryPercentage > 80 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b5.png\""
else if batteryPercentage > 60 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b4.png\""
else if batteryPercentage > 40 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b3.png\""
else if batteryPercentage > 20 then
	set icon to "\"icon_path\":\"~/Desktop/battery/b2.png\""
else
	set icon to "\"icon_path\":\"~/Desktop/battery/b1.png\""
end if

return "{" & title & "," & fontColor & "," & icon & "}"

I can't thank you enough for your help @buseco!

2 Likes

Thank you both for figuring this out - works lovely for me (tho, I dropped the icons to ~/Documents/ instead as I like to keep my Desktop clean :wink:

  • any way of dropping the "remainingTime" display to the second line? (underneath the "xx%" battery percentage?)