You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

97 lines
3.0 KiB

#!/usr/bin/env bash
# Get the default interface used for routing
INTERFACE=$(ip route 2>/dev/null | grep '^default' | awk '{print $5}' | head -1)
if [ -z "$INTERFACE" ]; then
echo '{"text": "󰖪 No net", "tooltip": "No network connection"}'
exit 0
fi
# Get IPv4 address of the interface
IP=$(ip -4 addr show "$INTERFACE" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)
if [ -z "$IP" ]; then
echo '{"text": "󰖪 No IP", "tooltip": "Interface '"$INTERFACE"' has no IP"}'
exit 0
fi
# Determine interface type and set appropriate icon
if [[ "$INTERFACE" =~ ^(wlan|wlp) ]]; then
ICON="󰲝" # generic network icon (nerd font)
TYPE="WiFi"
elif [[ "$INTERFACE" =~ ^(eth|enp|eno|ens) ]]; then
ICON="󰲝" # generic network icon (nerd font)
TYPE="Ethernet"
else
ICON="󰲝" # generic network icon (nerd font)
TYPE="$INTERFACE"
fi
# --- Transfer rate calculation ---
# Path to sysfs statistics
RX_FILE="/sys/class/net/$INTERFACE/statistics/rx_bytes"
TX_FILE="/sys/class/net/$INTERFACE/statistics/tx_bytes"
STATE_FILE="/tmp/waybar-network-stats-$INTERFACE"
# Read current byte counters
NOW_RX=$(cat "$RX_FILE" 2>/dev/null)
NOW_TX=$(cat "$TX_FILE" 2>/dev/null)
NOW_TS=$(date +%s%N) # nanoseconds for precision
# Helper: format bytes/sec to human-readable
format_rate() {
local bytes_per_sec="$1"
if [ "$bytes_per_sec" -lt 0 ]; then
bytes_per_sec=0
fi
if [ "$bytes_per_sec" -ge 1073741824 ]; then
awk -v n="$bytes_per_sec" 'BEGIN { printf "%.1fG", n / 1073741824 }'
elif [ "$bytes_per_sec" -ge 1048576 ]; then
awk -v n="$bytes_per_sec" 'BEGIN { printf "%.1fM", n / 1048576 }'
elif [ "$bytes_per_sec" -ge 1024 ]; then
awk -v n="$bytes_per_sec" 'BEGIN { printf "%.1fK", n / 1024 }'
else
awk -v n="$bytes_per_sec" 'BEGIN { printf "%.1fB", n }'
fi
}
RATE_DOWN=""
RATE_UP=""
if [ -f "$STATE_FILE" ]; then
# Read previous values: rx tx timestamp_ns
read -r PREV_RX PREV_TX PREV_TS < "$STATE_FILE"
if [ -n "$PREV_RX" ] && [ -n "$PREV_TX" ] && [ -n "$PREV_TS" ]; then
# Calculate time delta in seconds (nanosecond difference)
DELTA_NS=$((NOW_TS - PREV_TS))
if [ "$DELTA_NS" -gt 0 ]; then
DELTA_RX=$((NOW_RX - PREV_RX))
DELTA_TX=$((NOW_TX - PREV_TX))
# bytes per second = delta_bytes / (delta_ns / 1e9)
RX_BPS=$(awk -v rx="$DELTA_RX" -v ns="$DELTA_NS" 'BEGIN { printf "%.0f", rx * 1000000000 / ns }')
TX_BPS=$(awk -v tx="$DELTA_TX" -v ns="$DELTA_NS" 'BEGIN { printf "%.0f", tx * 1000000000 / ns }')
if [ -n "$RX_BPS" ] && [ -n "$TX_BPS" ]; then
RATE_DOWN=$(format_rate "$RX_BPS")
RATE_UP=$(format_rate "$TX_BPS")
fi
fi
fi
fi
# Save current state for next run
echo "$NOW_RX $NOW_TX $NOW_TS" > "$STATE_FILE"
# --- Build output ---
if [ -n "$RATE_DOWN" ] && [ -n "$RATE_UP" ]; then
RATE_STR="${RATE_DOWN}${RATE_UP}"
else
RATE_STR=""
fi
echo "{\"text\": \"<span size='x-large' rise='-1500'>$ICON</span> $INTERFACE $IP${RATE_STR}\", \"tooltip\": \"$TYPE: $INTERFACE$IP | ↓ ${RATE_DOWN:-?}/s ↑ ${RATE_UP:-?}/s\"}"