1###########################################
2# Battery plugin for oh-my-zsh            #
3# Original Author: Peter hoeg (peterhoeg) #
4# Email: peter@speartail.com              #
5###########################################
6# Author: Sean Jones (neuralsandwich)     #
7# Email: neuralsandwich@gmail.com         #
8# Modified to add support for Apple Mac   #
9###########################################
10# Author: J (927589452)                   #
11# Modified to add support for FreeBSD     #
12###########################################
13# Author: Avneet Singh (kalsi-avneet)     #
14# Modified to add support for Android     #
15###########################################
16
17if [[ "$OSTYPE" = darwin* ]]; then
18  function battery_is_charging() {
19    ioreg -rc AppleSmartBattery | command grep -q '^.*"ExternalConnected"\ =\ Yes'
20  }
21  function battery_pct() {
22    pmset -g batt | grep -Eo "\d+%" | cut -d% -f1
23  }
24  function battery_pct_remaining() {
25    if battery_is_charging; then
26      echo "External Power"
27    else
28      battery_pct
29    fi
30  }
31  function battery_time_remaining() {
32    local smart_battery_status="$(ioreg -rc "AppleSmartBattery")"
33    if [[ $(echo $smart_battery_status | command grep -c '^.*"ExternalConnected"\ =\ No') -eq 1 ]]; then
34      timeremaining=$(echo $smart_battery_status | command grep '^.*"AvgTimeToEmpty"\ =\ ' | sed -e 's/^.*"AvgTimeToEmpty"\ =\ //')
35      if [ $timeremaining -gt 720 ]; then
36        echo "::"
37      else
38        echo "~$((timeremaining / 60)):$((timeremaining % 60))"
39      fi
40    else
41      echo "∞"
42    fi
43  }
44  function battery_pct_prompt () {
45    local battery_pct color
46    if ioreg -rc AppleSmartBattery | command grep -q '^.*"ExternalConnected"\ =\ No'; then
47      battery_pct=$(battery_pct_remaining)
48      if [[ $battery_pct -gt 50 ]]; then
49        color='green'
50      elif [[ $battery_pct -gt 20 ]]; then
51        color='yellow'
52      else
53        color='red'
54      fi
55      echo "%{$fg[$color]%}[${battery_pct}%%]%{$reset_color%}"
56    else
57      echo "∞"
58    fi
59  }
60
61elif [[ "$OSTYPE" = freebsd* ]]; then
62  function battery_is_charging() {
63    [[ $(sysctl -n hw.acpi.battery.state) -eq 2 ]]
64  }
65  function battery_pct() {
66    if (( $+commands[sysctl] )); then
67      sysctl -n hw.acpi.battery.life
68    fi
69  }
70  function battery_pct_remaining() {
71    if ! battery_is_charging; then
72      battery_pct
73    else
74      echo "External Power"
75    fi
76  }
77  function battery_time_remaining() {
78    local remaining_time
79    remaining_time=$(sysctl -n hw.acpi.battery.time)
80    if [[ $remaining_time -ge 0 ]]; then
81      ((hour = $remaining_time / 60 ))
82      ((minute = $remaining_time % 60 ))
83      printf %02d:%02d $hour $minute
84    fi
85  }
86  function battery_pct_prompt() {
87    local battery_pct color
88    battery_pct=$(battery_pct_remaining)
89    if battery_is_charging; then
90      echo "∞"
91    else
92      if [[ $battery_pct -gt 50 ]]; then
93        color='green'
94      elif [[ $battery_pct -gt 20 ]]; then
95        color='yellow'
96      else
97        color='red'
98      fi
99      echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
100    fi
101  }
102elif [[ "$OSTYPE" = linux-android ]] && (( ${+commands[termux-battery-status]} )); then
103  function battery_is_charging() {
104    termux-battery-status 2>/dev/null | command awk '/status/ { exit ($0 ~ /DISCHARGING/) }'
105  }
106  function battery_pct() {
107    # Sample output:
108    # {
109    #   "health": "GOOD",
110    #   "percentage": 93,
111    #   "plugged": "UNPLUGGED",
112    #   "status": "DISCHARGING",
113    #   "temperature": 29.0,
114    #   "current": 361816
115    # }
116    termux-battery-status 2>/dev/null | command awk '/percentage/ { gsub(/[,]/,""); print $2}'
117  }
118  function battery_pct_remaining() {
119    if ! battery_is_charging; then
120      battery_pct
121    else
122      echo "External Power"
123    fi
124  }
125  function battery_time_remaining() { } # Not available on android
126  function battery_pct_prompt() {
127    local battery_pct color
128    battery_pct=$(battery_pct_remaining)
129    if battery_is_charging; then
130      echo "∞"
131    else
132      if [[ $battery_pct -gt 50 ]]; then
133        color='green'
134      elif [[ $battery_pct -gt 20 ]]; then
135        color='yellow'
136      else
137        color='red'
138      fi
139      echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
140    fi
141  }
142elif [[ "$OSTYPE" = linux*  ]]; then
143  function battery_is_charging() {
144    if (( $+commands[acpitool] )); then
145      ! acpitool 2>/dev/null | command grep -qE '^\s+Battery.*Discharging'
146    elif (( $+commands[acpi] )); then
147      ! acpi 2>/dev/null | command grep -v "rate information unavailable" | command grep -q '^Battery.*Discharging'
148    fi
149  }
150  function battery_pct() {
151    if (( $+commands[acpitool] )); then
152      # Sample output:
153      #   Battery #1     : Unknown, 99.55%
154      #   Battery #2     : Discharging, 49.58%, 01:12:05
155      #   All batteries  : 62.60%, 02:03:03
156      local -i pct=$(acpitool 2>/dev/null | command awk -F, '
157        /^\s+All batteries/ {
158          gsub(/[^0-9.]/, "", $1)
159          pct=$1
160          exit
161        }
162        !pct && /^\s+Battery/ {
163          gsub(/[^0-9.]/, "", $2)
164          pct=$2
165        }
166        END { print pct }
167        ')
168      echo $pct
169    elif (( $+commands[acpi] )); then
170      # Sample output:
171      # Battery 0: Discharging, 0%, rate information unavailable
172      # Battery 1: Full, 100%
173      acpi 2>/dev/null | command awk -F, '
174        /rate information unavailable/ { next }
175        /^Battery.*: /{ gsub(/[^0-9]/, "", $2); print $2; exit }
176      '
177    fi
178  }
179  function battery_pct_remaining() {
180    if ! battery_is_charging; then
181      battery_pct
182    else
183      echo "External Power"
184    fi
185  }
186  function battery_time_remaining() {
187    if ! battery_is_charging; then
188      acpi 2>/dev/null | command grep -v "rate information unavailable" | cut -f3 -d ','
189    fi
190  }
191  function battery_pct_prompt() {
192    local battery_pct color
193    battery_pct=$(battery_pct_remaining)
194    if battery_is_charging; then
195      echo "∞"
196    else
197      if [[ $battery_pct -gt 50 ]]; then
198        color='green'
199      elif [[ $battery_pct -gt 20 ]]; then
200        color='yellow'
201      else
202        color='red'
203      fi
204      echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
205    fi
206  }
207else
208  # Empty functions so we don't cause errors in prompts
209  function battery_is_charging { false }
210  function battery_pct \
211    battery_pct_remaining \
212    battery_time_remaining \
213    battery_pct_prompt { }
214fi
215
216function battery_level_gauge() {
217  local gauge_slots=${BATTERY_GAUGE_SLOTS:-10}
218  local green_threshold=${BATTERY_GREEN_THRESHOLD:-$(( gauge_slots * 0.6 ))}
219  local yellow_threshold=${BATTERY_YELLOW_THRESHOLD:-$(( gauge_slots * 0.4 ))}
220  local color_green=${BATTERY_COLOR_GREEN:-%F{green}}
221  local color_yellow=${BATTERY_COLOR_YELLOW:-%F{yellow}}
222  local color_red=${BATTERY_COLOR_RED:-%F{red}}
223  local color_reset=${BATTERY_COLOR_RESET:-%{%f%k%b%}}
224  local battery_prefix=${BATTERY_GAUGE_PREFIX:-'['}
225  local battery_suffix=${BATTERY_GAUGE_SUFFIX:-']'}
226  local filled_symbol=${BATTERY_GAUGE_FILLED_SYMBOL:-'▶'}
227  local empty_symbol=${BATTERY_GAUGE_EMPTY_SYMBOL:-'▷'}
228  local charging_color=${BATTERY_CHARGING_COLOR:-$color_yellow}
229  local charging_symbol=${BATTERY_CHARGING_SYMBOL:-'⚡'}
230
231  local -i battery_remaining_percentage=$(battery_pct)
232  local filled empty gauge_color
233
234  if [[ $battery_remaining_percentage =~ [0-9]+ ]]; then
235    filled=$(( ($battery_remaining_percentage * $gauge_slots) / 100 ))
236    empty=$(( $gauge_slots - $filled ))
237
238    if [[ $filled -gt $green_threshold ]]; then
239      gauge_color=$color_green
240    elif [[ $filled -gt $yellow_threshold ]]; then
241      gauge_color=$color_yellow
242    else
243      gauge_color=$color_red
244    fi
245  else
246    filled=$gauge_slots
247    empty=0
248    filled_symbol=${BATTERY_UNKNOWN_SYMBOL:-'.'}
249  fi
250
251  local charging=' '
252  battery_is_charging && charging=$charging_symbol
253
254  # Charging status and prefix
255  print -n ${charging_color}${charging}${color_reset}${battery_prefix}${gauge_color}
256  # Filled slots
257  [[ $filled -gt 0 ]] && printf ${filled_symbol//\%/\%\%}'%.0s' {1..$filled}
258  # Empty slots
259  [[ $filled -lt $gauge_slots ]] && printf ${empty_symbol//\%/\%\%}'%.0s' {1..$empty}
260  # Suffix
261  print -n ${color_reset}${battery_suffix}${color_reset}
262}
263