Internetgeschwindigkeit auf der Linuxkonsole messen

internetspeed“Bis zu 16.000 Kbit/s”, das Versprechen liest man bei nahezu jedem Anbieter. Doch auch wenn dieses Paket gebucht ist und die versprochene Leistung im DSL-Router angezeigt wird, liegen zwischen dieser Angabe und dem tatsächlichen Durchsatz meist Welten. Um diesen Verdacht auf den Grund zu gehen oder um den Verlauf der tatsächlichen Bandbreite zu verfolgen, bietet sich eine Möglichkeit an, die Geschwindigkeit auf der Linuxkonsole zu messen und die ermittelten Messwerte im Anschluss weiterzuverarbeiten. Möglich wäre beispielsweise die Speicherung in einer Datenbank und aus diesen Daten mit Drittprogrammen grafische Diagramme ausgeben zu lassen. Eine weitere Möglichkeit wäre die Einbindung in openHAB, um diese Diagramme gleich in der eigenen Hausautomatisierungsumgebung verfügbar zu haben.

In diesem Beitrag beschreibe ich die Installation sowie den Aufruf des Programms “speedtest-cli“. Im Anschluss zeige ich beispielhaft, wie die ermittelten Messwerte an openHAB übergeben werden können.

 

Installation

Zunächst aktualisieren wir unser System und bringen es damit auf den neusten, verfügbaren Stand (beispielhaft für eine Debian basierende Distribution):

apt-get update
apt-get upgrade

Im Anschluss installieren wir mit dem APT-Paketmanager weitere benötigte Pakete:

apt-get install wget curl

Nun kann das eigentliche Programm, um das es in diesem Beitrag geht, heruntergeladen werden. Wie immer speichere ich solche Scripte unter “/scripts/“.

cd /scripts/
wget -O speedtest-cli https://raw.githubusercontent.com/Michdo93/Python-speedtest-cli/master/speedtest_cli.py
chmod +x speedtest-cli
chown openhab: speedtest-cli

(Danke an Michael Dörflinger für den korrigierten Link)

Aufruf und Bedienung

Ein Aufruf des Programms in Form von

./speedtest-cli -h

zeigt uns an, wie dieses Programm zu verwenden ist und mit welchen Optionen es gestartet werden kann:

usage: speedtest-cli [-h] [--bytes] [--share] [--simple] [--list]
[--server SERVER] [--mini MINI] [--source SOURCE]
[--version]
Command line interface for testing internet bandwidth using speedtest.net.
--------------------------------------------------------------------------
https://raw.githubusercontent.com/Michdo93/Python-speedtest-cli/master/speedtest_cli.py

optional arguments:
  -h, --help show this help message and exit
  --bytes Display values in bytes instead of bits. Does not affect the image generated by --share
  --share Generate and provide a URL to the speedtest.net share results image
  --simple Suppress verbose output, only show basic information
  --list Display a list of speedtest.net servers sorted by distance
  --server SERVER Specify a server ID to test against
  --mini MINI URL of the Speedtest Mini server
  --source SOURCE Source IP address to bind to
  --version Show the version number and exit

Wie wir sehen, ist ein Bandbreitentest ohne große Konfiguration und ohne weiteren Angaben möglich. Die Ausführung von

./speedtest-cli

ergibt beispielhaft folgende Ausgabe:

root@linuxkiste:/scripts# ./speedtest-cli
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Klenzel Broadband ISP (123.123.123.123)...
Selecting best server based on latency...
Hosted by Haimspiel Media GmbH (Cologne) [20,73 km]: 107.561 ms
Testing download speed........................................
Download: 4.98 Mbits/s
Testing upload speed..................................................
Upload: 0.79 Mbits/s

Für die weitere Verwendung in Scripts empfiehlt sich jedoch der Aufruf mit der Option “–simple“. Dies beschränkt die Ausgabe der Testwerte auf das Nötigste.

./speedtest-cli --simple

Die Ausgabe könnte dann in etwa so aussehen:

root@linuxkiste:/scripts# ./speedtest-cli --simple
Ping: 153.986 ms
Download: 4.31 Mbits/s
Upload: 0.71 Mbits/s

 

Verwendung in einem Script

Die so erfolgte Ausgabe können wir nun in ihre Einzelteile zerlegen und für die spätere Verwendung aufbereiten. Im folgenden Script werden die von “speedtest-cli” ausgegebenen Werte an eine openHAB-Instanz gemeldet, denkbar wäre jedoch auch eine Speicherung in einer (My-)SQL-Datenbank.

#!/bin/bash
ping -c1 8.8.8.8 > /dev/null

if [ $? -ne 0 ]; then
        PING=0
        DOWN=0
        UP=0
        IP="Offline"
else
        /scripts/speedtest-cli --simple > /tmp/speedresult.txt
        PING=$(cat /tmp/speedresult.txt |grep Ping |cut -d " " -f 2)
        DOWN=$(cat /tmp/speedresult.txt |grep Download |cut -d " " -f 2)
        UP=$(cat /tmp/speedresult.txt |grep Upload |cut -d " " -f 2)
        IP=$(/usr/bin/curl -s https://klenzel.net/remoteip.php)
fi


/usr/bin/curl -s --header "Content-Type: text/plain" --request POST --data $PING http://IP_DER_OPENHAB_INSTANZ:PORT/rest/items/INET_PING
/usr/bin/curl -s --header "Content-Type: text/plain" --request POST --data $DOWN http://IP_DER_OPENHAB_INSTANZ:PORT/rest/items/INET_DOWN
/usr/bin/curl -s --header "Content-Type: text/plain" --request POST --data $UP http://IP_DER_OPENHAB_INSTANZ:PORT/rest/items/INET_UP
/usr/bin/curl -s --header "Content-Type: text/plain" --request POST --data $IP http://IP_DER_OPENHAB_INSTANZ:PORT/rest/items/INET_IP

rm -f /tmp/speedresult.txt

Erklärung des Scripts

  1. Die sogenannte Shebang
  2. Es wird mittels Ping geprüft, ob eine Internetverbindung vorhanden ist
  3. Das Programm “speedtest-cli” wird aufgerufen und die Ausgabe in die Datei “/tmp/speedresult.txt” umgeleitet
  4. Die Variable “PING” erhält den Wert der Latenz, gemessen in Millisekunden
  5. Die Variable “DOWN” erhält den Wert des Downstreams (Geschwindigkeit des Herunterladens), gemessen in Megabit pro Sekunde
  6. Die Variable “UP” erhält den Wert des Upstreams (Geschwindigkeit des Hochladens), ebenfalls gemessen in Megabit pro Sekunde
  7. Die Variable “IP” enthält die öffentliche IP des Internetanschlusses
  8. Der Inhalt der Variable “PING” wird mit dem Programm “curl” und der Methode “POST” an openHAB gesendet und dort in das Item “INET_PING” geschrieben
  9. Der Inhalt der Variable “DOWN” wird mit dem Programm “curl” und der Methode “POST” an openHAB gesendet und dort in das Item “INET_DOWN” geschrieben
  10. Der Inhalt der Variable “UP” wird mit dem Programm “curl” und der Methode “POST” an openHAB gesendet und dort in das Item “INET_UP” geschrieben
  11. Der Inhalt der Variable “IP” wird mit dem Programm “curl” und der Methode “POST” an openHAB gesendet und dort in das Item “INET_IP” geschrieben
  12. Die temporär erstellte Datei wird gelöscht

Dieses Script speichern wir für die weitere Verwendung in diesem Beitrag als “/scripts/speedtest.sh” und erlauben die Ausführung mit

chmod +x /scripts/speedtest.sh

 

Abschließend übertragen wir den Besitz der Datei an openhab durch

chown openhab: /scripts/speedtest.sh

 

CRON-Job anlegen

Damit unser Script in regelmäßigen Abständen ausgeführt wird, legen wir nun einen CRON-Job an. Dazu wechseln wir in den Kontext des Nutzers “openhab” durch

su openhab

und öffnen die Cron-Tabelle mittels

crontab -e

Wir fügen folgende Zeile ein, wenn wir dieses Script halbstündlich durchführen lassen wollen:

*/30 * * * * /scripts/speedtest.sh > /dev/null 2>&1

Alternativ besteht die Möglichkeit, openHAB das Script in regelmäßigen Abständen ausführen zu lassen. Dies wird weiter unten in diesem Beitrag erläutert. Den Nutzerkontext von “openhab” verlassen wir anschließend durch

exit

 

Um in den Nutzerkontext von “openhab” wechseln zu können, wird vorausgesetzt, dass für diesen Nutzer ein Passwort sowie eine Shell eingerichtet wurde. Dies wird in diesem Beitrag beschrieben.

 

Integration in openHAB

Die aus dem Script ermittelten Werte werden, wie bereits erwähnt, in das angegebene Item gesetzt. Dazu ist es vorab notwendig, in der Item-Beschreibungsdatei (zumeist default.items) Dummy-Schalter mit der entsprechenden Bezeichnung anzulegen:

Number INET_PING "Ping [%.1f ms]"
Number INET_DOWN "Download [%.1f Mbit/s]"
Number INET_UP "Upload [%.1f Mbit/s]"
String INET_IP "akt. IP-Adresse: [%s]"

Der Logstream von openHAB meldet nach erfolgreicher Durchführung des oben gezeigten Scripts die Aktualisierung der drei Items:

13:58:56.977 INFO runtime.busevents[:26] -INET_PING state updated to 153.986
13:58:56.977 INFO runtime.busevents[:26] -INET_DOWN state updated to 4.31
13:58:56.977 INFO runtime.busevents[:26] -INET_UP state updated to 0.71
13:58:56.977 INFO runtime.busevents[:26] -INET_IP state updated to 12.34.56.78

Eine Darstellung muss in der jeweiligen Konfiguration eingetragen werden (zumeist default.sitemap). Beispielhaft kann dies wie folgt umgesetzt werden:

Text item=INET_PING icon="ping"
Text item=INET_DOWN icon="download"
Text item=INET_UP icon="upload"
Text item=INET_IP icon="ipaddr"

Die angegebenen Icons “ping“, “download“, “upload” und “ipaddr” stammen nicht aus der Grundinstallation von openHAB sondern wurden nachträglich in das Verzeichnis “/usr/share/openhab/webapps/images/” eingefügt. Dabei sollten die Icons 16×16 Pixel groß sein und im Format “.png” vorliegen.

Sinnvoll wäre es zudem natürlich, die Messwerte über einen bestimmten Zeitraum zu speichern und daraus Diagramme erstellen und anzeigen zu lassen.

Dazu bedarf es seitens openHAB einer Datenbankanbindung, ich verwende hierfür RRD4J. Die Installation wird in diesem Beitrag ausführlich beschrieben.

 

Nun erstellen wir ein weiteres Dummy-Item in der Datei “default.items“:

Number CHART_PERIOD

und erweitern unsere Sitemap-Definition von oben wir folgt:

Text label="Internetgeschwindigkeit" icon="gauge" {
   Text item=INET_PING icon="ping"
   Text item=INET_DOWN icon="download"
   Text item=INET_UP icon="upload"
   Text item=INET_IP icon="gauge"
   Switch item=CHART_PERIOD label="Zeitspanne" mappings=[0="Stunde", 1="Tag", 2="Woche"]
   Chart item=INET_PING period=h refresh=300 visibility=[CHART_PERIOD==0, CHART_PERIOD=="Uninitialized"]
   Chart item=INET_PING period=D refresh=1800 visibility=[CHART_PERIOD==1]
   Chart item=INET_PING period=W refresh=3600 visibility=[CHART_PERIOD==2]
   Chart item=INET_DOWN period=h refresh=300 visibility=[CHART_PERIOD==0, CHART_PERIOD=="Uninitialized"]
   Chart item=INET_DOWN period=D refresh=1800 visibility=[CHART_PERIOD==1]
   Chart item=INET_DOWN period=W refresh=3600 visibility=[CHART_PERIOD==2]
   Chart item=INET_UP period=h refresh=300 visibility=[CHART_PERIOD==0, CHART_PERIOD=="Uninitialized"]
   Chart item=INET_UP period=D refresh=1800 visibility=[CHART_PERIOD==1]
   Chart item=INET_UP period=W refresh=3600 visibility=[CHART_PERIOD==2]
}

 

Erklärung:

Zunächst wird in der Hausübersicht nur die Zeile “Internetgeschwindigkeit” dargestellt. Klickt oder drückt man auf diese, gelangt man in das definierte Untermenü. Dort werden in den ersten drei Zeilen zunächst die aktuellen Messwerte dargestellt. Im unteren Bereich werden drei Diagramme, für jeden Messwert eins, angezeigt. Zudem ist es nun möglich, über drei Buttons den angezeigten Darstellungszeitraum zu wechseln.

Dies könnte im Endeffekt so aussehen:

 

openhab-speed

 

 

Wenn für das Script, welches wir oben erstellt haben, kein CRON-Job angelegt wurde, besteht auch die Möglichkeit, das Script durch openHAB in regelmäßigen Abständen ausführen zu lassen, sofern es auf dem gleichen Rechner wie openHAB vorliegt.

Dazu erstellen wir in einer Regelbeschreibungsdatei (zumeist default.rules) eine CRON-Regel:

rule "Cron 30 Minuten"
  when
  Time cron "0 /30 * * * ?"
  then
    executeCommandLine("/scripts/speedtest.sh", 60000)
end