aboutsummaryrefslogtreecommitdiff
path: root/hypr/.config/hypr/waybar-alt-2/scripts/network_traffic.sh
diff options
context:
space:
mode:
Diffstat (limited to 'hypr/.config/hypr/waybar-alt-2/scripts/network_traffic.sh')
-rwxr-xr-xhypr/.config/hypr/waybar-alt-2/scripts/network_traffic.sh110
1 files changed, 110 insertions, 0 deletions
diff --git a/hypr/.config/hypr/waybar-alt-2/scripts/network_traffic.sh b/hypr/.config/hypr/waybar-alt-2/scripts/network_traffic.sh
new file mode 100755
index 0000000..ac63d01
--- /dev/null
+++ b/hypr/.config/hypr/waybar-alt-2/scripts/network_traffic.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+
+# network_traffic.sh [-tPOLLING_INTERVAL] [NETWORK_INTERFACE...]
+
+getopts t: __ && shift
+isecs=${OPTARG:-1}
+ifaces=($@)
+: ${rate_max:=1000000} # maximum transfer rate for {percent}, can be overridden setting the env var
+
+# `snore` adapted from https://blog.dhampir.no/content/sleeping-without-a-subprocess-in-bash-and-how-to-sleep-forever
+# without MacOS workaround, TODO: with _snore_fd initialized separatedly, also i dont touch IFS so dont bother with it
+snore() {
+ local IFS
+ [[ -n "${_snore_fd:-}" ]] || { exec {_snore_fd}<> <(:); } 2>/dev/null
+ read ${1:+-t "$1"} -u $_snore_fd || :
+}
+
+human_readable() {
+ local hrunits=( B K M G T P )
+ local ndigits=${#1}
+ local idxunit=$(( (2 + ndigits) / 3 - 1))
+ local lentrim=$(( ndigits - (idxunit * 3 ) ))
+ echo ${1::$lentrim}${hrunits[$idxunit]}
+}
+
+exit_err() {
+ printf '{"text": "⚠ %s", "tooltip": "%s", "class": "error"}\n' "$@"
+ exit
+}
+
+if test ${#ifaces[@]} -gt 0; then
+# sanity check the interface names
+ for iface in ${ifaces[@]}; do
+ test -h "/sys/class/net/${iface}" || exit_err "${iface}" "${iface} is not an existing network interface name"
+ done
+else
+# default to all interfaces except `lo`
+ ifaces=(/sys/class/net/*)
+ ifaces=(${ifaces[@]##*/})
+ ifaces=(${ifaces[@]//lo/})
+# TODO: check that filtering out `lo` is enough, else `^(eth|wlan|enp|wlp)` as suggested
+fi
+
+# sanity check polling interval
+if test ${isecs} -lt 1; then
+ exit_err "${isecs}" "${isecs} is not a valid polling interval"
+fi
+# NOTE: `snore` would take a decimal interval but bash arithmetic does not
+#if test $(echo "${isecs} >= 0.2" |bc) -eq 0; then
+# exit_err "${isecs}" "${isecs} is not a valid polling interval"
+#fi
+
+# NOTE: `/proc/net/dev` format is:
+# interface:
+# RX bytes packets errs drop fifo frame compressed multicast
+# TX bytes packets errs drop fifo colls carrier compressed
+
+# NOTE: array items are:
+# 0=rx_bytes 1=rx_packets 2=rx_errs 3=rx_drop
+# 4=tx_bytes 5=tx_packets 6=tx_errs 7=tx_drop
+for iface in ${ifaces[@]} aggregate; do
+ declare -a traffic_prev_${iface} traffic_curr_${iface} traffic_delt_${iface}
+ declare -n traffic_prev=traffic_prev_${iface}
+ declare -n traffic_curr=traffic_curr_${iface}
+ declare -n traffic_delt=traffic_delt_${iface}
+ traffic_prev=( 0 0 0 0 0 0 0 0 )
+ traffic_curr=( 0 0 0 0 0 0 0 0 )
+ traffic_delt=( 0 0 0 0 0 0 0 0 )
+done
+
+# TODO: rearrange the loop, do not show bogus on first iteration
+while snore ${isecs} ;do
+ tooltip=""
+ traffic_delt_aggregate=( 0 0 0 0 0 0 0 0 )
+
+ readarray -s2 proc_net_dev </proc/net/dev
+ while read -a data; do
+ iface=${data[0]%:}
+ test "${ifaces[*]}" = "${ifaces[*]//${iface}/}" && continue
+ declare -n traffic_prev=traffic_prev_${iface}
+ declare -n traffic_curr=traffic_curr_${iface}
+ declare -n traffic_delt=traffic_delt_${iface}
+ traffic_curr=(${data[@]:1:4} ${data[@]:9:4})
+ #FIXME: tooltip is delayed one iteration wrt main display (but why?)
+ #printf -v tooltip_hr_rx '%4s⇣' $(human_readable ${traffic_delt[0]})
+ #printf -v tooltip_hr_tx '%4s⇡' $(human_readable ${traffic_delt[4]})
+ #tooltip="${tooltip:+${tooltip}\r}${iface}\t${tooltip_hr_rx}\t${tooltip_hr_tx}"
+ for i in {0..7}; do
+ (( traffic_delt[i] = ( traffic_curr[i] - traffic_prev[i] ) / isecs ))
+ (( traffic_delt_aggregate[i] += traffic_delt[i] ))
+ done
+ traffic_prev=(${traffic_curr[@]})
+ done <<<"${proc_net_dev[@]}"
+
+ printf '{"text": "%4s⇣ %4s⇡", "tooltip": "%s", "percentage": %d}\n' \
+ $(human_readable ${traffic_delt_aggregate[0]}) \
+ $(human_readable ${traffic_delt_aggregate[4]}) \
+ "${tooltip}" \
+ $(( ( traffic_delt_aggregate[0] + traffic_delt_aggregate[4] ) / rate_max ))
+ #printf '{"text": "%5s⇣ %5s⇡", "alt": "%s", "tooltip": "%s", "class": "%s", "percentage": %d }\n' $(human_readable ${traffic_delt[0]}) $(human_readable ${traffic_delt[4]}) '_alt' '_tooltip' '_class' 0
+done
+
+
+# NOTE: in waybar config (do NOT use "interval"):
+# "custom/network_traffic": {
+# "exec": "~/.config/waybar/scripts/network_traffic.sh",
+# "return-type": "json",
+# "format": "Speed: {}", // optional
+# },
+