Internetgeschwindigkeit auf der Linuxkonsole messen
„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
- Die sogenannte Shebang
- Es wird mittels Ping geprüft, ob eine Internetverbindung vorhanden ist
- Das Programm „speedtest-cli“ wird aufgerufen und die Ausgabe in die Datei „/tmp/speedresult.txt“ umgeleitet
- Die Variable „PING“ erhält den Wert der Latenz, gemessen in Millisekunden
- Die Variable „DOWN“ erhält den Wert des Downstreams (Geschwindigkeit des Herunterladens), gemessen in Megabit pro Sekunde
- Die Variable „UP“ erhält den Wert des Upstreams (Geschwindigkeit des Hochladens), ebenfalls gemessen in Megabit pro Sekunde
- Die Variable „IP“ enthält die öffentliche IP des Internetanschlusses
- 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
- 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
- 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
- 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
- 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:
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
Daniel Wenzel
12.01.2016 @ 16:38
Hallo und vielen Dank für die Hinweise. Den „Speeed“ habe ich soeben korrigiert. So wie es aussieht, scheint ifconfig.me jedoch die richtige Seite zu sein, da ipconfig.me nur auf diese umleitet. Aber wenn dadurch das Script besser funktioniert, ist es auch OK ;)
Anonymous
12.01.2016 @ 15:31
Hallo,
erstmal vielen Dank für die tollen Tutorials hier. Klasse Arbeit.
Ich habe hier im Internetgeschwindigkeits-Tutorial zwei kleine Fehler gefunden:
Im bash script steht einmal ifconfig. Ich habe ’ne Weile nach Fehlern bei mir gesucht bis ich das fand… Richtig ist ipconfig und dann läuft es super.
IP=$(/usr/bin/curl -s http://ipconfig.me/ip)
Der Befehl für den Speercheck ist nicht ./speeedtest-cli sondern ./speedtest-cli
Ich habe die Daten für upload und download in einen Graph kombiniert. Sieht auch sehr gut aus.
Daniel Wenzel
30.12.2015 @ 07:02
Danke für den Tipp. Um es in den Anleitungen einfach wie möglich zu halten, hat openHAB meist root-Rechte.
Nicht schön, aber in einem internen Netzwerk auch kein Weltuntergang. Nach außen hin sollte man seine Netzwerkkomponenten eh nicht erreichen.
Sascha
30.12.2015 @ 02:09
Der Benutzer openhab hat bei mir keine Berechtigung einen ping Befehl auszuführen (Raspian jessie lite, openhab installiert via apt -> siehe oHwiki)
Um es allen Benutzern zu ermöglichen folgenden Befehl in der konsole eintippen
sudo chmod u+s `which ping`
Jetzt werden bei mir endlich keine nullen mehr an openhab gesendet ;)
LG Sascha
Broadband monitoring tools | Michiel's 0s & 1s
06.04.2015 @ 22:32
[…] It should be possible to use the aforementioned speedtest CLI tool, cron, and some graphing utilities together with a server running speedtest-mini to graph the available bandwidth over time as well. Daniel Wenzel has documented one way of achieving this. […]
Dominic
27.02.2015 @ 15:10
Die permissions sind okay. hab es nun mit wget gelöst, scheinbar liefert der ping einen falschen errorlevel zurück.
$WGET -q –tries=2 –timeout=10 http://www.google.com -O /tmp/google.idx &> /dev/null
if [ ! -s /tmp/google.idx ]
#Down
else
#on
fi
Daniel Wenzel
27.02.2015 @ 04:23
Hallo,
ich lasse openHAB das Script halbstündlich ausführen. Damit dein Nutzer openhab die Scripte ausführen darf, kann ich mir zwei Lösungen vorstellen:
1) Dem Nutzer openhab den Besitz der Dateien übergeben:
chown openhab: /scripts/speedtest-cli /scripts/scripts.log /scripts/speedtest.sh
2) Allen Nutzern das Recht des Ausführens der Scripte zuweisen:
chmod o+rx /scripts/speedtest-cli /scripts/speedtest.sh
chmod o+rw /scripts/scripts.log
Für die im Script verwendeten Programme und Befehle sehe ich die Berechtigungen unkritisch, das sollte jeder Systembenutzer ausführen dürfen. Woran genau bzw. an welchen fehlendem Recht scheitert es denn bei dir?
Dominic
26.02.2015 @ 23:45
Benutzt du du den system cron?
Führe ich das skript als user openhab aus so fehlt dem user wohl einiges an berechtigungen. Als root funkt es, würde ich jedoch gerne umgehen. :)
LG
Dominic
Anonymous
26.02.2015 @ 13:02
Hallo Daniel,
ich muss schon sagen, deine Lösung ist strukturierter, als die meinige.Nun werden alle vier values per curl übertragen. Bei mir kam die IP per Echo. ifconfig.me war mir außerdem nicht geläufig, aber prizipiell wäre wieistmeineip.de natürlich ähnlich.
Cooler Blog, du darfst gerne weitermachen :)
Daniel Wenzel
26.02.2015 @ 05:44
Hallo Dominic,
danke für deine wertvollen Tipps, ich habe versucht, das Script entsprechend umzugestalten und die Änderungen im Artikel eingepflegt.
Mit diesen Änderungen sollte nun auch deine Frage beantwortet sein, denn das Script prüft nun vorab, ob eine Internetverbindung vorhanden ist, bevor getestet wird. Sollte dem nicht so sein, werden nur Nullwerte an openHAB übermittelt.
Dominic
25.02.2015 @ 23:05
Hey, danke für deinen Denkanstoß. Bei mir ist dieses Tool wirklich von nöten. Unitymedia macht aktuell wirklich was sie wollen.
Habe das Skript um eine Überprüfung der IP Adresse erweitert, diese wird nach der Ausführung in Openhab direkt zurückgeliefert. Die Werte vom Speedtest gehen über curl (hier ist es sinnvoll den silent mode zu aktivieren)
Außerdem kann man UP/Down in einem Graph erfassen :D
Habe nun eine Frage, was ist denn, wenn der Speedtest nicht erfolgreich war?
Wäre doch sinnvoll dann 0 Mbit zurückzugeben. Ich habe im Rahmen der Downtime heute 6 Stunden keine weiteren Messwerte somit gilt natürlich der zuletzt übertragene wert.
Viele Grüße
Dominic