Internet Speedtest

Aus wiki.frank-wulf.de
Zur Navigation springen Zur Suche springen

Shell script /usr/bin/fwspeedtest

#!/bin/bash
#
# Author:  Frank Wulf
# Version: 1.6 (2024-10-01)
#
# This script measures the internet speed by using Ookla speedtest tool.
#
# In regards to the conversion rules described in
# https://help.speedtest.net/hc/en-us/articles/360039162713-What-do-mbps-and-kbps-mean-
# the following calculations are used:
# 1 kilobit = 1000 bits
# 1 megabit = 1000 kilobits
# 1 Mbyte   = 8 megabits
#
# Version history:
# 1.0   2020-04-11   Initial release
# 1.1   2020-04-18   Changed to best-of-three mode
# 1.2   2020-04-24   Extended time between tests to 15 minutes
# 1.3   2020-06-08   Fixed issue when "packet loss" is not available
# 1.4   2020-06-10   Adjusted conversion rules
# 1.5   2020-12-23   Added parameter "accept-gdpr" to Ookla speedtest call
# 1.6   2024-10-01   VPN service name is now dynamic

runs=2
#tarif="Telekom Zuhause L"
#tarif="o2 Testkarte Online"
tarif="freenet FUNK unlimited"
#vpn_service="openvpn"
vpn_service="wg-quick@wg0"
exclude=0
comment=""
out=/tmp/fwspeedtest.out

if [ -f "$out" ]; then
  rm $out 1>/dev/null 2>&1
fi

# Run the speedtest <runs> times without VPN connection
for i in `eval echo {1..$runs}`
do
  # Check if VPN connection is active
  systemctl status $vpn_service 1>/dev/null 2>&1
  if [ $? -eq 0 ]; then
    vpn_active=1
    # Stop VPN connection
    systemctl stop $vpn_service
    sleep 5
  else
    vpn_active=0
  fi

  # Fill timestamp field
  timestamp[$i]=`date +'%Y-%m-%d %H:%M:%S'`

  # Run speedtest
  /usr/bin/speedtest speedtest --accept-gdpr --format=csv >>$out
  retcode=$?

  if [ $vpn_active -eq 1 ]; then
    # Start VPN connection
    systemctl start $vpn_service
  fi

  if [ "$retcode" -ne 0 ]; then
    exit 1
  fi

  if [ $i -lt $runs ]; then
    # Wait 15 seconds between two speedtests
    sleep 15
  fi
done

download_max=0
i=0

while read line; do
  i=$((i+1))
  download_new=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $7 }'`
  if [ $download_new -gt $download_max ]; then
    # Download rate is faster than previous ones
    download=$download_new
    server_id=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $3 }'`
    server_name=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $2 }'`
    latency=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $4 }'`
    jitter=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $5 }'`
    packet_loss=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $6 }'`
    download=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $7 }'`
    upload=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $8 }'`
    download_used=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $9 }'`
    upload_used=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $10 }'`
    url=`echo "$line"|awk -F '^ *"|" *, *"|" *$' '{ print $11 }'`
    download_max=$download
    row=$i
  fi

  if [ $i -eq $runs ]; then
    # Round values for latency. jitter and packet_loss
    latency=`echo "scale=2; ($latency + 0.005) / 1" | bc`
    jitter=`echo "scale=2; ($jitter + 0.005) / 1" | bc`
    if [ $packet_loss == "N/A" ]; then
      packet_loss=0
    else
      packet_loss=`echo "scale=1; ($packet_loss + 0.05) / 1" | bc`
    fi

    # Convert download/upload speed from bytes per second to Mbps and round values
    download=`echo "scale=8; $download * 8 / 1000000" | bc`
    download=`echo "scale=2; ($download + 0.005) / 1" | bc`
    upload=`echo "scale=8; $upload * 8 / 1000000" | bc`
    upload=`echo "scale=2; ($upload + 0.005) / 1" | bc`

    # Convert used bytes to MBytes and round values
    download_used=`echo "scale=8; $download_used / 1000000" | bc`
    download_used=`echo "scale=1; ($download_used + 0.05) / 1" | bc`
    upload_used=`echo "scale=8; $upload_used / 1000000" | bc`
    upload_used=`echo "scale=1; ($upload_used + 0.05) / 1" | bc`

    vpn_active=0

    # Fill timestamp field
    timestamp=${timestamp[$row]}

    # Insert data into database
    sql="INSERT INTO fw_speedtest (timestamp,server_id,server_name,latency,"
    sql+="jitter,packet_loss,download,upload,download_used,upload_used,"
    sql+="vpn_active,tarif,exclude,comment,url) VALUES ("
    sql+="\"$timestamp\", \"$server_id\", \"$server_name\", \"$latency\", "
    sql+="\"$jitter\", \"$packet_loss\", \"$download\", \"$upload\", "
    sql+="\"$download_used\", \"$upload_used\", \"$vpn_active\", "
    sql+="\"$tarif\", \"$exclude\", \"$comment\",\"$url\")"

    mysql --login-path=fwsysmon -D fwsysmon -e "$sql"

  fi

done <<<`cat $out`

exit 0

Scheduling Speedtest with systemd

  • Service Unit file /lib/systemd/system/fwspeedtest.service
[Unit]
Description=Internet speedtest

[Service]
Type=oneshot
ExecStart=/usr/bin/fwspeedtest
User=root
Group=root
  • Timer Unit file /lib/systemd/system/fwspeedtest.timer
[Unit]
Description=Run Internet speedtest

[Timer]
OnCalendar=*-*-* 18:00
RandomizedDelaySec=12h
Persistent=true

[Install]
WantedBy=timers.target