Run networkQuality, append results to a CSV history file, and render download/upload waveform charts in Terminal Widget. Add medium widgets with ids "download" and "upload".
Schedule with launchd (example interval: every 60 minutes).
Script
Run networkQuality, append results to a CSV history file, and render download/upload waveform charts in Terminal Widget. Add medium widgets with ids "download" and "upload".
Schedule with launchd (example interval: every 60 minutes).
#!/usr/bin/env bash
# Uses networkQuality, update terminal-widgets, output up/down speeds
set -e
LOGDIR="$HOME/logs"
LOGFILE="$LOGDIR/speed.csv"
mkdir -p "$LOGDIR"
widget_id_upload="upload"
widget_id_download="download"
chart_format="waveform"
NQ_OUT=$(networkQuality -s 2>&1)
STATUS=$?
if [[ $STATUS -ne 0 ]]; then
echo "networkQuality failed: $NQ_OUT" >&2
exit $STATUS
fi
DOWNLOAD=$(echo "$NQ_OUT" | awk -F: '/Downlink capacity/ {print int($2+0)}')
UPLOAD=$(echo "$NQ_OUT" | awk -F: '/Uplink capacity/ {print int($2+0)}')
TIMESTAMP=$(date -Iseconds)
echo "$TIMESTAMP,$DOWNLOAD,$UPLOAD" >>"$LOGFILE"
tmpfile=$(mktemp)
tail -n 100 "$LOGFILE" >"$tmpfile"
mv "$tmpfile" "$LOGFILE"
DOWN_VALS=($(tail -n 96 "$LOGFILE" | awk -F, '{print $2}'))
UP_VALS=($(tail -n 96 "$LOGFILE" | awk -F, '{print $3}'))
/opt/homebrew/bin/terminal-widget --base-zero --target ${widget_id_download} --text 'Download Speeds' --chart - --chart-format ${chart_format} --bg ffffff --fg 'rgb(237, 78, 195)' --text-color 222222 --caption --caption-color 888888 <<<"${DOWN_VALS[*]}" || true
/opt/homebrew/bin/terminal-widget --base-zero --target ${widget_id_upload} --text 'Upload Speeds' --chart - --chart-format ${chart_format} --bg ffffff --fg 'rgb(78, 155, 237)' --text-color 222222 --caption --caption-color 888888 <<<"${UP_VALS[*]}" || true
echo "⬇️ $DOWNLOAD"
echo "⬆️ $UPLOAD"
exit 0
Suggested interval: 1 hour (StartInterval = 3600 seconds).
Save the script from this recipe to ~/bin/network-speed-waveform.sh, then create a Launch Agent plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.terminalwidget.network-speed-waveform</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>~/bin/network-speed-waveform.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>3600</integer>
<key>StandardOutPath</key>
<string>/tmp/com.terminalwidget.network-speed-waveform.log</string>
<key>StandardErrorPath</key>
<string>/tmp/com.terminalwidget.network-speed-waveform.err</string>
</dict>
</plist>
From Terminal:
mkdir -p ~/bin ~/Library/LaunchAgents
# Save your script to ~/bin/network-speed-waveform.sh
cat > ~/Library/LaunchAgents/com.terminalwidget.network-speed-waveform.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.terminalwidget.network-speed-waveform</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>~/bin/network-speed-waveform.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>3600</integer>
<key>StandardOutPath</key>
<string>/tmp/com.terminalwidget.network-speed-waveform.log</string>
<key>StandardErrorPath</key>
<string>/tmp/com.terminalwidget.network-speed-waveform.err</string>
</dict>
</plist>
EOF
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/com.terminalwidget.network-speed-waveform.plist
For a GUI editor and troubleshooting, see LaunchControl from soma-zone.