Browse Source

Added the i3 battery popup

Samuel W. Flint 8 years ago
parent
commit
306a4891b2
1 changed files with 182 additions and 0 deletions
  1. 182 0
      i3-battery-popup

+ 182 - 0
i3-battery-popup

@@ -0,0 +1,182 @@
+#! /bin/bash
+
+################################################################################
+# A script that shows a battery warning on i3wm                                #
+#                                                                              #
+# It supports multiple batteries                                               #
+# (like my thinkpad T450s has)                                                 #
+#                                                                              #
+# When tcl/tk (wish) is installed, it shows a nice popup                       #
+# Which you can configure to show on all workspaces                            #
+# by adding the following to your i3 config:                                   #
+# "for_window [title="Battery Warning"] sticky enable"                         #
+#                                                                              #
+# By default, the script will show two messages:                               #
+# One at 10% and one at 5% battery                                             #
+#                                                                              #
+# The script takes the following options:                                      #
+# -L : The percentage at which the first popup shows (default: 10)             #
+#                                                                              #
+# -l : The percentage at which the second popup shows                          #
+#      Default: half of the percentage given by -L                             #
+#                                                                              #
+# -m : The message to show to the User                                         #
+#                                                                              #
+# -t : The time interval the script waits before checking the battery again.   #
+#      Give this a value in seconds: 5s, 10s, or in minutes: 5m                #
+#      Default: 5m                                                             #
+#                                                                              #
+# -n : Don't use Tcl/Tk dialog. Use i3-nagbar.                                 #
+#                                                                              #
+# By R-J Ekker, 2016                                                           #
+################################################################################
+
+error () {
+    echo $1 >&2
+    echo "Exiting" >&2
+    exit $2
+}
+
+while getopts 'L:l:m:t:F:n' opt; do
+    case $opt in
+        L)
+            [[ $OPTARG =~ ^[0-9]+$ ]] || error "${opt}: ${OPTARG} is not a number" 2
+            UPPER_LIMIT="${OPTARG}"
+            ;;
+        l)
+            [[ $OPTARG =~ ^[0-9]+$ ]] || error "${opt}: ${OPTARG} is not a number" 2
+            LOWER_LIMIT="${OPTARG}"
+            ;;
+        m)
+            MESSAGE="${OPTARG}"
+            ;;
+        n)
+            DONT_USE_WISH="-n"
+            ;;
+        t)
+            [[ $OPTARG =~ ^[0-9]+[ms]?$ ]] || error "${opt}: ${OPTARG} is not a valid period" 2
+            SLEEP_TIME="${OPTARG}"
+            ;;
+        F)
+            LOGFILE="${OPTARG}"
+            ;;
+        :)
+            error "Option -$OPTARG requires an argument." 2
+            ;;
+        \?)
+            exit 2
+            ;;
+    esac
+done
+
+# This function returns an awk script
+# Which prints the battery percentage
+# It's an ugly way to include a nicely indented awk script here
+
+get_awk_source() {
+    cat <<EOF
+BEGIN {
+    FS="=";
+}
+\$1 ~ /ENERGY_FULL_DESIGN$/ {
+    f += \$2;
+}
+\$1 ~ /ENERGY_NOW\$/ {
+    n += \$2;
+}
+END {
+    print int(100*n/f);
+}
+EOF
+}
+
+is_battery_discharging() {
+    cat $BATTERIES | grep Charging && return 1
+    return 0
+} >/dev/null
+
+get_battery_perc() {
+    cat $BATTERIES | awk -f <(get_awk_source)
+}
+
+show_popup() {
+    # WISH_SCRIPT="wm state . withdrawn; tk_messageBox -icon warning -title \"Battery Warning\" -message \"${MESSAGE}\"; exit"
+    # echo "$WISH_SCRIPT" | wish
+    notify-send --urgency=critical --icon=warning "Battery Warning" "${MESSAGE}"
+}
+
+show_nagbar(){
+    /usr/bin/i3-nagbar -m "${MESSAGE}"
+}
+
+show_message(){
+    echo "showing warning" >&2
+    # if [[ -z $DONT_USE_WISH ]] && which wish; then
+    show_popup
+    # else
+    #     show_nagbar
+    # fi
+}
+
+main (){
+    # Setting defaults
+    UPPER_LIMIT="${UPPER_LIMIT:-10}"
+    UPPER_HALF=$(( $UPPER_LIMIT / 2 ))
+    LOWER_LIMIT=${LOWER_LIMIT:-$UPPER_HALF}
+    MESSAGE="${MESSAGE:-Warning: Battery is getting low}"
+    SLEEP_TIME="${SLEEP_TIME:-5m}"
+
+    BATTERIES=/sys/class/power_supply/BAT*/uevent
+
+    echo "Upper ${UPPER_LIMIT}; Lower ${LOWER_LIMIT}; sleep ${SLEEP_TIME}"
+    echo "Current: $(get_battery_perc)%"
+
+    LIMIT="${UPPER_LIMIT}"
+    # This will be set to "y" after first click
+    # So we know when to stop nagging
+    POPUP_CLICKED=""
+
+    while true; do
+        echo -n "Checking.. "
+
+        PERC=$(get_battery_perc)
+        echo "got ${PERC}%"
+
+        if is_battery_discharging; then
+            if [[ $PERC -lt $LIMIT ]]; then
+                show_message
+
+                if [[ -z $POPUP_CLICKED ]]; then
+                    # first click; set limit lower
+                    POPUP_CLICKED="y"
+                    LIMIT=${LOWER_LIMIT}
+                else
+                    # We clicked twice; No more popups
+                    LIMIT=0
+                fi
+            fi
+        else
+            echo "Battery Charging"
+            # restart messages, reset limits
+            POPUP_CLICKED=""
+            if [[ $PERC -gt $UPPER_LIMIT ]]; then
+                LIMIT=${UPPER_LIMIT}
+            else
+                LIMIT=${LOWER_LIMIT}
+            fi
+        fi
+        echo "sleeping ${SLEEP_TIME}; current limit ${LIMIT}%; ${POPUP_CLICKED:+Popup was clicked}"
+        sleep "${SLEEP_TIME}"
+    done
+} >&2
+
+LOCK_FILE="${HOME}/.battery_state.lock"
+(
+    if [[ -n $LOGFILE ]]; then
+        exec >>$LOGFILE 2>&1
+    fi
+
+    flock -xn 200 || error "Cannot acquire lock ${LOCK_FILE}" 3
+
+    main
+) 200>"${LOCK_FILE}"