Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for Big Sur/Monterey. Supports Apple Silicon. #12

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
# Battery

> For Apple M1 chip users: https://github.com/BenziAhamed/alfred-battery/issues/11#issue-812562822

![Logo](info.png)

An Alfred workflow to display battery information of your Apple laptop.

Is activated by the keyword "battery". The new gradient icon set is the default, but if
you like the old set better, just use the optional keyword "reg", like thus: "battery reg"
and it will revert to the old set.

Gradient Icons:
Thanks to their respective authors on FlatIcon.

Icon Attribution List:

Temperature icons created by Muhammad Ali
Serial icons created by Creatype
Battery icons created by Freepik
Ui icons created by pictranoosa
Health icons created by CLARY K
Ui icons created by Us and Up
Clock icons created by redempticon
Mouse icons created by Ilham Fitrotul Hayat
Panel icons created by Pixel perfect
Computer peripheral icons created by lakonicon
Macbook icons created by bqlqn
Scan icons created by Pause08
Hospital icons created by bearicons
196 changes: 122 additions & 74 deletions src/battery.sh
Original file line number Diff line number Diff line change
@@ -1,117 +1,165 @@
#!/usr/bin/env bash
#!/bin/bash

INFO=$(ioreg -l -n AppleSmartBattery -r)
ioreg -l -n AppleSmartBattery -r > info.txt

# Charge and time remaining
CURRENT_CAPACITY=$(echo "$INFO" | grep CurrentCapacity | awk '{printf $3; exit}')
MAX_CAPACITY=$(echo "$INFO" | grep MaxCapacity | awk '{printf $3; exit}')
CHARGE=$((CURRENT_CAPACITY * 100 / MAX_CAPACITY))
CELLS=$(python -c "f='●'*($CHARGE/10) + '○'*(10-$CHARGE/10); print f")
STATUS_INFO=Draining...
if [ "$1" = "reg" ]; then
ICON_SET="icons"
else
ICON_SET="gradient-icons"
fi

CHARGING=$(echo "$INFO" | grep -i ischarging | awk '{printf("%s", $3)}')
TIME_TO_EMPTY=$(echo "$INFO" | grep -i AvgTimeToEmpty | awk '{printf("%s", $3)}')
TIME_LEFT=Calculating…
RAW_CURRENT_CAPACITY=$(cat info.txt | grep -e \"AppleRawCurrentCapacity\" | awk '{printf ("%i", $3)}')
RAW_MAX_CAPACITY=$(cat info.txt | grep -e \"AppleRawMaxCapacity\" | awk '{printf ("%i", $3)}')
# MAX_CAPACITY=$(cat info.txt | grep -e \"MaxCapacity\" | | awk -F',' '{printf ("%s", $45)}' | awk -F'=' '{printf ("%i", $2)}')
DESIGN_CAPACITY=$(cat info.txt | grep -e \"DesignCapacity\" | awk '{printf ("%i", $3)}')
TEMPERATURE=$(cat info.txt | grep -e "\"Temperature\"" | awk '{printf ("%.1f", $3/100.00)}')
MANUFACTURE_DATE=$(cat info.txt | grep -e \"ManufactureDate\" | awk -F',' '{printf ("%s", $56)}' | awk -F'=' '{printf ("%i", $2)}')
CHARGING=$(cat info.txt | grep -e \"IsCharging\" | awk '{printf("%s",$3)}')


SERIAL=$(cat info.txt | grep -e \"Serial\" | awk -F',' '{printf ("%s", $40)}' | awk -F'=' '{printf ("%s", $2)}' | tr -d '"')
SERIAL="${SERIAL%\"}"

if [ "$TIME_TO_EMPTY" -lt 15000 ]; then
TIME_LEFT=$(echo "$INFO" | grep -i AvgTimeToEmpty | awk '{printf("%i:%.2i", $3/60, $3%60)}')
HEALTH=$(echo $RAW_MAX_CAPACITY $DESIGN_CAPACITY | awk '{printf ("%i", $1/$2 * 100)}')
CHARGE=$(echo $RAW_CURRENT_CAPACITY $RAW_MAX_CAPACITY | awk '{printf ("%i", $1/$2 * 100)}')
CELLS=$(/usr/bin/python3 -c "f='●'*(int($CHARGE/9)) + '○'*(int(10-$CHARGE/9));print(f)")

CYCLE_COUNT=$(cat info.txt | grep -e '\"CycleCount\" =' | awk '{printf ("%i", $3)}')

TIME_TO_EMPTY=$(cat info.txt | grep -e \"AvgTimeToEmpty\" | awk '{printf("%s", $3)}')
TIME_LEFT=Calculating…
if [ $TIME_TO_EMPTY -lt 15000 ]; then
TIME_LEFT=$(cat info.txt | grep -e \"AvgTimeToEmpty\" | awk '{printf("%i:%.2i", $3/60, $3%60)}')
fi

if [ "$CHARGING" == Yes ]; then
TIME_FULL=$(echo "$INFO" | grep -i AvgTimeToFull | tr '\n' ' | ' | awk '{printf("%i:%.2i", $3/60, $3%60)}')
TIME_INFO=$(echo "$TIME_FULL" until full)
STATUS_INFO=Charging...
BATT_ICON=charging.png
TIME_INFO=n
STATUS_INFO=Draining
BATT_ICON="$ICON_SET/draining.png"

if [ $CHARGING == Yes ]; then
TIME_FULL=$(cat info.txt | grep -e \"AvgTimeToFull\" | tr '\n' ' | ' | awk '{printf("%i:%.2i", $3/60, $3%60)}')
TIME_INFO=$(echo $TIME_FULL until full)
STATUS_INFO=Charging
BATT_ICON="$ICON_SET/charging.png"
else
FULLY_CHARGED=$(echo "$INFO" | grep -i FullyCharged | awk '{printf("%s", $3)}')
EXTERNAL=$(echo "$INFO" | grep -i ExternalConnected | awk '{printf("%s", $3)}')
if [ "$FULLY_CHARGED" == Yes ]; then
if [ "$EXTERNAL" == Yes ]; then
TIME_INFO="On AC power"
STATUS_INFO="Fully Charged"
BATT_ICON=power.png
CHARGE="100"
CELLS="●●●●●●●●●●"
else
TIME_INFO=$TIME_LEFT
BATT_ICON=full.png
fi
else
TIME_INFO=$TIME_LEFT
BATT_ICON=critical.png
if [ "$CHARGE" -gt 80 ]; then
BATT_ICON=full.png
elif [ "$CHARGE" -gt 50 ]; then
BATT_ICON=medium.png
elif [ "$CHARGE" -gt 10 ]; then
BATT_ICON=low.png
fi
fi
FULLY_CHARGED=$(cat info.txt | grep -e \"FullyCharged\" | awk '{printf("%s",$3)}')
EXTERNAL=$(cat info.txt | grep -e \"ExternalConnected\" | awk '{printf("%s",$3)}')
if [ $FULLY_CHARGED == Yes ]; then
if [ $EXTERNAL == Yes ]; then
TIME_INFO=$(echo On AC power)
STATUS_INFO=$(echo Fully Charged)
BATT_ICON="$ICON_SET/power.png"
else
TIME_INFO=$(echo $TIME_LEFT)
BATT_ICON="$ICON_SET/full.png"
fi
else
TIME_INFO=$(echo $TIME_LEFT)
BATT_ICON="$ICON_SET/critical.png"
if [ $CHARGE -gt 80 ]; then
BATT_ICON="$ICON_SET/full.png"
elif [ $CHARGE -gt 50 ]; then
BATT_ICON="$ICON_SET/medium.png"
elif [ $CHARGE -gt 10 ]; then
BATT_ICON="$ICON_SET/low.png"
fi
fi
fi

# Temperature
TEMPERATURE=$(echo "$INFO" | grep Temperature | awk '{printf ("%.1f", $3/10-273)}')
let "MANUFACTURE_DATE=MANUFACTURE_DATE-0x0000303030303030"
let "MANUFACTURE_DATE=(MANUFACTURE_DATE & 0x000000FF00FF00FF) * 10 + ((MANUFACTURE_DATE & 0x0000FF00FF00FF00) >> 8) + 1992"

# Cycle count
CYCLE_COUNT=$(echo "$INFO" | grep -e '"CycleCount" =' | awk '{printf ("%i", $3)}')
let "year=(MANUFACTURE_DATE >> 0) & 0xFFFF"
let "month=(MANUFACTURE_DATE >> 16) & 0xFFFF"
let "day=(MANUFACTURE_DATE >> 32) & 0xFFFF"

# Battery health
# ref: https://github.com/BenziAhamed/alfred-battery/issues/10#issuecomment-745541202
DESIGN_CAPACITY=$(echo "$INFO" | grep DesignCapacity | awk '{printf ("%.i", $3)}')
HEALTH=$((MAX_CAPACITY * 100 / DESIGN_CAPACITY))
AGE=$(python3 -c "from datetime import date as D; d1=D.today(); d2=D($year, $month, $day); print ( (d1.year - d2.year)*12 + d1.month - d2.month )")

if [ "$HEALTH" -gt 100 ]; then
HEALTH=100
TRACKPAD_ICON="$ICON_SET/trackpad.png"
# trackpad
TrackpadPercent=`ioreg -c AppleDeviceManagementHIDEventService | grep -se \"Magic Trackpad\" -A8 | grep -se \"BatteryPercent\" | sed 's/[a-z,A-Z, ,|,\",=]//g' | tail -1 | awk '{print $1}'`
if [ ${#TrackpadPercent} = 0 ]
then
TrackpadTitle="Not connected"
else
TrackpadSlug=$(python -c "f='●'*(int($TrackpadPercent/10)) + '○'*(int(10-$TrackpadPercent/10));print(f)")
TrackpadTitle="$TrackpadPercent% $TrackpadSlug"
fi

# Serial
SERIAL=$(echo "$INFO" | grep BatterySerialNumber | awk '{printf ("%s", $3)}' | tr -d '"')
MOUSE_ICON="$ICON_SET/mouse.png"
# mouse
MousePercent=`ioreg -c AppleDeviceManagementHIDEventService | grep -se \"Magic Mouse\" -A8 | grep -se \"BatteryPercent\" | sed 's/[a-z,A-Z, ,|,\",=]//g' | tail -1 | awk '{print $1}'`
if [ ${#MousePercent} = 0 ]
then
MouseTitle="Not connected"
else
MouseSlug=$(python -c "f='●'*(int($MousePercent/10)) + '○'*(int(10-$MousePercent/10));print(f)")
MouseTitle="$MousePercent% $MouseSlug"
fi

# Battery age
MANUFACTURE_DATE=$(echo "$INFO" | grep ManufactureDate | awk '{printf ("%i", $3)}')
day=$((MANUFACTURE_DATE&31))
month=$(((MANUFACTURE_DATE>>5)&15))
year=$((1980+(MANUFACTURE_DATE>>9)))
AGE=$(python -c "from datetime import date as D; d1=D.today(); d2=D($year, $month, $day); print ( (d1.year - d2.year)*12 + d1.month - d2.month )")
KEYBOARD_ICON="$ICON_SET/keyboard.png"
# keyboard
KeyboardPercent=`ioreg -c AppleDeviceManagementHIDEventService | grep -se \"Magic Keyboard\" -A8 | grep -se \"BatteryPercent\" | sed 's/[a-z,A-Z, ,|,\",=]//g' | tail -1 | awk '{print $1}'`
if [ ${#KeyboardPercent} = 0 ]
then
KeyboardTitle="Not connected"
else
KeyboardSlug=$(python -c "f='●'*(int($KeyboardPercent/10)) + '○'*(int(10-$KeyboardPercent/10));print(f)")
KeyboardTitle="$KeyboardPercent% $KeyboardSlug"
fi

# Alfred feedback
cat << EOB
<?xml version="1.0"?>
<items>
<item>
<title>$CHARGE% $CELLS</title>
<subtitle>$STATUS_INFO</subtitle>
<icon>icons/$BATT_ICON</icon>
<subtitle>$STATUS_INFO</subtitle>
<icon>$BATT_ICON</icon>
</item>
<item>
<title>$TIME_INFO</title>
<subtitle>Time Left</subtitle>
<icon>icons/clock.png</icon>
<subtitle>Time Left</subtitle>
<icon>$ICON_SET/clock.png</icon>
</item>
<item>
<title>$TEMPERATURE °C</title>
<subtitle>Temperature</subtitle>
<icon>icons/temp.png</icon>
<title>${TEMPERATURE} °C</title>
<subtitle>Temperature</subtitle>
<icon>$ICON_SET/temp.png</icon>
</item>
<item>
<title>$CYCLE_COUNT</title>
<subtitle>Charge Cycles Completed</subtitle>
<icon>icons/cycles.png</icon>
<subtitle>Charge Cycles Completed</subtitle>
<icon>$ICON_SET/cycles.png</icon>
</item>
<item>
<title>$HEALTH%</title>
<subtitle>Health</subtitle>
<icon>icons/health.png</icon>
<subtitle>Health</subtitle>
<icon>$ICON_SET/health.png</icon>
</item>
<item>
<title>$MouseTitle</title>
<subtitle>Magic Mouse</subtitle>
<icon>$MOUSE_ICON</icon>
</item>
<item>
<title>$KeyboardTitle</title>
<subtitle>Magic Keyboard</subtitle>
<icon>$KEYBOARD_ICON</icon>
</item>
<item>
<title>$TrackpadTitle</title>
<subtitle>Magic TrackPad</subtitle>
<icon>$TRACKPAD_ICON</icon>
</item>
<item>
<title>$SERIAL</title>
<subtitle>Serial</subtitle>
<icon>icons/serial.png</icon>
<icon>$ICON_SET/serial.png</icon>
</item>
<item>
<title>$AGE months</title>
<subtitle>Age</subtitle>
<icon>icons/age.png</icon>
<icon>$ICON_SET/age.png</icon>
</item>
</items>
EOB
Binary file added src/gradient-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/charging.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/clock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/critical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/cycles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/draining.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/health.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/keyboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/low.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/medium.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/mouse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/power.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/serial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/temp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/gradient-icons/trackpad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/icons/keyboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/icons/mouse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/icons/trackpad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added workflow/Notify.tgz
Binary file not shown.
108 changes: 108 additions & 0 deletions workflow/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env python
# encoding: utf-8
#
# Copyright (c) 2014 Dean Jackson <deanishe@deanishe.net>
#
# MIT Licence. See http://opensource.org/licenses/MIT
#
# Created on 2014-02-15
#

"""A helper library for `Alfred <http://www.alfredapp.com/>`_ workflows."""

import os

# Workflow objects
from .workflow import Workflow, manager
from .workflow3 import Variables, Workflow3

# Exceptions
from .workflow import PasswordNotFound, KeychainError

# Icons
from .workflow import (
ICON_ACCOUNT,
ICON_BURN,
ICON_CLOCK,
ICON_COLOR,
ICON_COLOUR,
ICON_EJECT,
ICON_ERROR,
ICON_FAVORITE,
ICON_FAVOURITE,
ICON_GROUP,
ICON_HELP,
ICON_HOME,
ICON_INFO,
ICON_NETWORK,
ICON_NOTE,
ICON_SETTINGS,
ICON_SWIRL,
ICON_SWITCH,
ICON_SYNC,
ICON_TRASH,
ICON_USER,
ICON_WARNING,
ICON_WEB,
)

# Filter matching rules
from .workflow import (
MATCH_ALL,
MATCH_ALLCHARS,
MATCH_ATOM,
MATCH_CAPITALS,
MATCH_INITIALS,
MATCH_INITIALS_CONTAIN,
MATCH_INITIALS_STARTSWITH,
MATCH_STARTSWITH,
MATCH_SUBSTRING,
)


__title__ = 'Alfred-Workflow'
__version__ = open(os.path.join(os.path.dirname(__file__), 'version')).read()
__author__ = 'Dean Jackson'
__licence__ = 'MIT'
__copyright__ = 'Copyright 2014-2019 Dean Jackson'

__all__ = [
'Variables',
'Workflow',
'Workflow3',
'manager',
'PasswordNotFound',
'KeychainError',
'ICON_ACCOUNT',
'ICON_BURN',
'ICON_CLOCK',
'ICON_COLOR',
'ICON_COLOUR',
'ICON_EJECT',
'ICON_ERROR',
'ICON_FAVORITE',
'ICON_FAVOURITE',
'ICON_GROUP',
'ICON_HELP',
'ICON_HOME',
'ICON_INFO',
'ICON_NETWORK',
'ICON_NOTE',
'ICON_SETTINGS',
'ICON_SWIRL',
'ICON_SWITCH',
'ICON_SYNC',
'ICON_TRASH',
'ICON_USER',
'ICON_WARNING',
'ICON_WEB',
'MATCH_ALL',
'MATCH_ALLCHARS',
'MATCH_ATOM',
'MATCH_CAPITALS',
'MATCH_INITIALS',
'MATCH_INITIALS_CONTAIN',
'MATCH_INITIALS_STARTSWITH',
'MATCH_STARTSWITH',
'MATCH_SUBSTRING',
]
Loading