From deca8326c1d2cdb01474ae30e6f81d64bc475fcf Mon Sep 17 00:00:00 2001 From: Narvin Singh Date: Wed, 23 Dec 2020 23:48:59 -0500 Subject: [PATCH] Feat: status-bar Each panel of the status bar can be turned on or off and configured with an icon or no icon. - Loops every 2 seconds - Reports on: - CPU usage - Memory usage - Backlight brightness - Volume (requires amixer from alsa-utils) - Icon changes when volume is below 50%, at or above 50%, or muted - Battery percentage for each batter - Icon changes from batter to plug when on AC power - Date and time --- status-bar | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100755 status-bar diff --git a/status-bar b/status-bar new file mode 100755 index 0000000..f091bc9 --- /dev/null +++ b/status-bar @@ -0,0 +1,146 @@ +#!/bin/bash + +# Configurable variables +SEP=' | ' + +CPU_ON=1 +CPU_SYM= + +MEM_ON=1 +MEM_SYM= + +BL_ON=1 +BL_SYM= + +VOL_ON=1 +VOL_SYM_LOW= +VOL_SYM_HI= +VOL_SYM_MUTE= + +BAT_ON=1 +BAT_SYM= +BAT_SYM_PLG= +BAT_SYM_UNK= +BAT_CNT=1 + +DT_ON=1 +DT_SYM='' +DT_FMT='%a %d %I:%M%p' + +status_cpu() { + ps -ef | awk '{cpu = cpu + $4} END {print cpu "%"}' +} + +status_mem() { + printf '%.0f%%' "$(free -h | awk 'NR == 2 {print $3 * 100 / $2}')" +} + +status_bl () { + local bl + local max_bl + + printf -v bl '%s' \ + "$(find /sys/class/backlight/*/brightness | head -n 1 | xargs cat)" + printf -v max_bl '%s' \ + "$(find /sys/class/backlight/*/max_brightness | head -n 1 | xargs cat)" + # Multiply by 10^3 inside the arithemetic expansion so the integer arithmetic + # will preserve 3 digits after the decimal point. Applying e-3 would provide + # 3 decimal points for printf, but since we want the result scaled by 100, we + # only apply e-1. printf will round the result to the specified presion. + printf '%.0f%%' "$((bl * 1000 / max_bl))e-1" +} + +status_vol () { + printf '%s%%' \ + "$(amixer get Master | tail -n 1 | sed -E 's/.*\[(.*)%\].*/\1/')" +} + +status_vol_state() { + local -r vol="${1:-0}" + local state + + printf -v state '%s' \ + "$(amixer get Master | tail -n 1 | sed -E 's/.*\[(.*)\]/\1/')" + case "${state}" in + on) + if [[ "${vol}" -lt 50 ]]; then printf '%s' "${VOL_SYM_LOW}"; + else printf '%s' "${VOL_SYM_HI}"; fi + ;; + *) + printf '%s' "${VOL_SYM_MUTE}" + ;; + esac +} + +status_bat_cap () { + printf '%s' "$(find /sys/class/power_supply/BAT?/capacity \ + | head -n "${BAT_CNT}" | xargs cat | tr '\n' '% ' | sed 's/ *$//')" +} + +status_bat_state() { + local state + + printf -v state '%s' \ + "$(find /sys/class/power_supply/BAT?/status | head -n 1 | xargs cat)" + case "${state}" in + Discharging) + printf '%s' "${BAT_SYM}" + ;; + Charging|Full) + printf '%s' "${BAT_SYM_PLG}" + ;; + *) + printf '%s' "${BAT_SYM_UNK}" + ;; + esac +} + +status_dt () { + printf '%s' "$(date +"${DT_FMT}")" +} + +add_stat () { + local -r val="$1" + local -r sym="$2" + local sep + + # Skip the separator for the first status section + if [[ -n "${status}" ]]; then sep="${SEP}"; fi + + # Only output the status section if it has a value + if [[ -n "${val}" ]]; then + if [[ -n "${sym}" ]]; then status="${status}${sep}${sym} ${val}"; + else status="${status}${sep}${val}"; fi + fi +} + +while :; do + status='' + + if [[ "${CPU_ON}" -ne 0 ]]; then + add_stat "$(status_cpu)" "${CPU_SYM}" + fi + if [[ "${MEM_ON}" -ne 0 ]]; then + add_stat "$(status_mem)" "${MEM_SYM}" + fi + if [[ "${BL_ON}" -ne 0 ]]; then + add_stat "$(status_bl)" "${BL_SYM}" + fi + if [[ "${VOL_ON}" -ne 0 ]]; then + vol="$(status_vol)" + add_stat "${vol}" "$(status_vol_state "${vol:0:-1}")" + fi + if [[ "${BAT_ON}" -ne 0 ]]; then + add_stat "$(status_bat_cap)" "$(status_bat_state)" + fi + if [[ "${DT_ON}" -ne 0 ]]; then + add_stat "$(status_dt)" "${DT_SYM}" + fi + xprop -root -set WM_NAME " ${status} " + + # Sleep until the beginning of the next minute, this way when we are showing + # the time, the status updates on the minute + ## sleep $((60 - $(date +%S))) + sleep 2 +done +