#!/bin/bash INTERFACE="br0" TEMP_FILE="/tmp/waybar_network_$INTERFACE" MAX_AGE=10 # Function to format bytes/s to human readable with max 2 digits format_rate() { local rate=$1 local unit="K" local value # Convert to KB/s first value=$(( (rate * 10) / 1024 )) # If KB/s would be >= 1000 (100.0K), convert to MB/s if [ $value -ge 1000 ]; then unit="M" value=$(( (rate * 10) / 1048576 )) # 1024*1024 # If MB/s would be >= 1000 (100.0M), convert to GB/s if [ $value -ge 1000 ]; then unit="G" value=$(( (rate * 10) / 1073741824 )) # 1024*1024*1024 fi fi # Split into whole and decimal parts local whole=$((value / 10)) local decimal=$((value % 10)) # Format with appropriate spacing if [ $whole -lt 10 ]; then printf "%d.%d%s" "$whole" "$decimal" "$unit" else printf "%2d%s" "$whole" "$unit" fi } # Check if interface exists if [ ! -d "/sys/class/net/$INTERFACE" ]; then echo '{"text":"󰈀 No Interface","tooltip":"Interface '$INTERFACE' not found"}' exit 1 fi # Get current values RX_BYTES=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes) TX_BYTES=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes) CURRENT_TIME=$(date +%s) # Check if temp file exists and is recent TEMP_FILE_VALID=0 if [ -f "$TEMP_FILE" ]; then read PREV_RX PREV_TX PREV_TIME < "$TEMP_FILE" TIME_DIFF=$((CURRENT_TIME - PREV_TIME)) # Accept temp file if it's recent (0 seconds is OK, negative or too old is not) if [ $TIME_DIFF -ge 0 ] && [ $TIME_DIFF -le $MAX_AGE ]; then TEMP_FILE_VALID=1 fi fi # If no valid temp file, initialize if [ $TEMP_FILE_VALID -eq 0 ]; then echo "$RX_BYTES $TX_BYTES $CURRENT_TIME" > "$TEMP_FILE" echo '{"text":"'${INTERFACE}' ↑0.0K ↓0.0K","tooltip":"Upload: 0.0 KB/s\\nDownload: 0.0 KB/s"}' exit 0 fi # If TIME_DIFF is 0, return the last calculated result without updating temp file if [ $TIME_DIFF -eq 0 ]; then # Try to read cached result from a secondary file CACHE_FILE="/tmp/waybar_network_cache_$INTERFACE" if [ -f "$CACHE_FILE" ]; then cat "$CACHE_FILE" exit 0 else # No cache, show 0.0K echo '{"text":"'${INTERFACE}' ↑0.0K ↓0.0K","tooltip":"Upload: 0.0 KB/s\\nDownload: 0.0 KB/s"}' exit 0 fi fi # Calculate rates (bytes per second) RX_RATE=$(( (RX_BYTES - PREV_RX) / TIME_DIFF )) TX_RATE=$(( (TX_BYTES - PREV_TX) / TIME_DIFF )) # Handle negative values (counter reset) or unrealistic high values if [ $RX_RATE -lt 0 ] || [ $RX_RATE -gt 1073741824 ]; then RX_RATE=0; fi if [ $TX_RATE -lt 0 ] || [ $TX_RATE -gt 1073741824 ]; then TX_RATE=0; fi # Format rates with auto-scaling TX_FORMATTED=$(format_rate $TX_RATE) RX_FORMATTED=$(format_rate $RX_RATE) # Calculate tooltip values (always in KB/s for consistency) RX_KB_TENTHS=$(( (RX_RATE * 10) / 1024 )) TX_KB_TENTHS=$(( (TX_RATE * 10) / 1024 )) RX_WHOLE=$((RX_KB_TENTHS / 10)) RX_DECIMAL=$((RX_KB_TENTHS % 10)) TX_WHOLE=$((TX_KB_TENTHS / 10)) TX_DECIMAL=$((TX_KB_TENTHS % 10)) # Format output with auto-scaled units RESULT=$(printf '{"text":"'${INTERFACE}' ↑%4s ↓%4s","tooltip":"Upload: %d.%d KB/s\\nDownload: %d.%d KB/s"}' \ "$TX_FORMATTED" "$RX_FORMATTED" \ "$TX_WHOLE" "$TX_DECIMAL" "$RX_WHOLE" "$RX_DECIMAL") echo "$RESULT" # Store current values for next iteration AND cache the result echo "$RX_BYTES $TX_BYTES $CURRENT_TIME" > "$TEMP_FILE" echo "$RESULT" > "/tmp/waybar_network_cache_$INTERFACE"