Speedtest für ioBroker

Lesedauer: 5 Minuten

Für ioBroker gibt es aktuell 2 Speedtest Adapter, die bei vielen funktionieren – jedoch bei vielen eben auch nicht. Das ist besonders der Fall, wenn man einen Vodafone Cable Max 1000 (ehemals Unitymedia) Tarif hat. Ich habe noch nicht herausgefunden, wieso diese Speedtests nicht richtig laufen – jedoch habe ich mir selbst Abhilfe geschaffen, um hier auch selbst vernünftige Werte zu erhalten.

Vorbereitung

Damit der Speedtest richtig funktioniert, muss das Paket von Ookla (Speedtest.net) installiert werden. Dazu loggen wir uns auf dem Pi ein und führen folgende Befehle aus. Solltest Du bereits einen Speedtest installiert haben, der bspw. mit “speedtest-cli” aufgerufen wird, so ist dieser vorher zu entfernen.

Speedtest-CLI entfernen:

sudo apt-get remove speedtest-cli

Ookla Speedtest installieren – Automatischer Weg

curl -s https://install.speedtest.net/app/cli/install.deb.sh | sudo bash

Wichtig: Hier muss im Skript in Zeile 210 der Pfad geändert werden.

Von: var kommando = "/etc/speedtest/speedtest -f json --accept-license --accept-gdpr";

In: var kommando = "/usr/bin/speedtest -f json --accept-license --accept-gdpr";

Ookla Speedtest installieren – Manueller Weg

cd /etc/
mkdir speedtest
cd /etc/speedtest
wget https://install.speedtest.net/app/cli/ookla-speedtest-1.0.0-arm-linux.tgz

(Diese Version ggf. an Dein System anpassen -> https://www.speedtest.net/de/apps/cli – Diese Version hier ist für einen Raspberry Pi mit ARM System. Andere Systeme- gerade Virtualisierungen verwenden i386 oder ähnliche Dateien)

sudo tar -xvzf ookla-speedtest-1.0.0-arm-linux.tgz
rm ookla-speedtest-1.0.0-arm-linux.tgz

Datenpunkte

Das Skript füllt die eigenen Datenpunkte mit allen verfügbaren Rückgabewerten, die dieser Test zur Verfügung stellt. Des Weiteren sind die Datenpunkte strukturiert aufgebaut. Das heißt, der Datenpunkt Ergebnisse enthält alle Daten eines Test, wohingegen der Datenpunkt Test (mit Unterpunkten: Server und Daten) Informationen zu dem eigentlichen Test enthält. Auch gibt es einen Datenpunkt Server, welcher die Informationen zur Gegenstelle vorhält.

DatenpunktBeschreibung
JSON_OutputAusgabe der Konsole
PingPing in ms
JitterJitter in ms
Download_MBitDownload Geschwindigkeit in MBit/s
Upload_MBitUpload Geschwindigkeit in MBit/s
Download_MBDownload Geschwindigkeit in MB/s
Upload_MBUpload Geschwindigkeit in MB/s
OriginalDownloadDownload Geschwindigkeit in Byte/s
OriginalUploadUpload Geschwindigkeit in Byte/s
ISPInternet Service Provider
IPexterne IP
URLAdresse der Ergebnisse
IDID der Ergebnisse
ServerIDID des getesteten Servers
ServerIPIP des getesteten Servers
NameAnbieter des getesteten Servers
StadtStadt des getesteten Servers
LandLand des getesteten Servers
AdresseURL des getesteten Servers
DownloadDownload Daten in MB
UploadUpload Daten in MB
OriginalDownloadDownload Daten in Byte
OriginalUploadUpload Daten in Byte
DauerDownloadDauer des Download Test in Sekunden
DauerUploadDauer des Upload Test in Sekunden
Letzter_SpeedtestDatum und Uhrzeit des letzten Speedtest
Verfügbare Datenpunkte des Skripts

Skript

Nun erstellen wir in ioBroker ein neues Skript im common Bereich. Es bekommt den Namen “Speedtest”.

Der Aufruf erfolgt alle 60 Minuten und kann in der letzten Zeile angepasst werden. Auch lässt sich zur besseren Diagnose der eigenen Leitung ein fester Server in Zeile 32 eintragen. Eine Liste mit Servern in Deiner Umgebung gibt es hier:
https://www.speedtest.net/speedtest-servers.php

Hier schaust du am Ende nach der ID. Diese ID kommt dann in Zeile 32.

ID des Servers herausfinden
ID des Servers herausfinden

Soll das Skript immer den besten Server nehmen und automatisch entscheiden, so lasse diesen bei 0.

/*
 * @copyright 2020 Stephan Kreyenborg <stephan@kreyenborg.koeln>
 *
 * @author 2020 Stephan Kreyenborg <stephan@kreyenborg.koeln>
 *
 * Dieses Skript dient zur freien Verwendung in ioBroker zur Überprüfung Deiner Internetgeschwindkeit mit Hilfe von Speedtest.
 * Jegliche Verantwortung liegt beim Benutzer. Das Skript wurde unter Berücksichtigung der bestmöglichen Nutzung
 * und Performance entwickelt.
 * Der Entwickler versichert, das keine böswilligen Systemeingriffe im originalen Skript vorhanden sind.
 *
 * Sollte das Skript wider Erwarten nicht korrekt funktionieren, so hast Du jederzeit die Möglichkeit, Dich auf
 * https://www.kreyenborg.koeln
 * für Unterstützung zu melden. Jedes Skript besitzt seine eigene Kommentarseite, auf der,
 * nach zeitlicher Möglichkeit des Autors, Hilfe angeboten wird. Ein Anrecht hierauf besteht nicht!
 * 
 * Ansprüche gegenüber Dritten bestehen nicht. 
 * 
 * Skript Name:		Speedtest
 * Skript Version:	1.3
 * Erstell-Datum:	29. November 2021
 * 
 */

// Datenpunkte neu erstellen
var ueberschreiben = false;

// Hauptdatenpunkt unterhalb javascript
var datenpunkt = "Speedtest.";

// Favorisierter Server
// Liste: https://www.speedtest.net/speedtest-servers.php
var fav_server = 28602;

// Speedtest Objekte
var objekt = ["JSON_Output",
    "Ergebnisse.Ping",
    "Ergebnisse.Jitter",
    "Ergebnisse.Download_MBit",
    "Ergebnisse.Upload_MBit",
    "Ergebnisse.Download_MB",
    "Ergebnisse.Upload_MB",
    "Ergebnisse.OriginalDownload",
    "Ergebnisse.OriginalUpload",
    "ISP",
    "IP",
    "Ergebnisse.URL",
    "Ergebnisse.ID",
    "Test.Server.ServerID",
    "Test.Server.ServerIP",
    "Test.Server.Name",
    "Test.Server.Stadt",
    "Test.Server.Land",
    "Test.Server.Adresse",
    "Test.Daten.Download",
    "Test.Daten.Upload",
    "Test.Daten.OriginalDownload",
    "Test.Daten.OriginalUpload",
    "Test.Daten.DauerDownload",
    "Test.Daten.DauerUpload",
    "Test.Daten.Letzter_Speedtest"
];

// Beschreibung der Objekte
var beschreibung = ["JSON Ausgabe der Konsole",
    "Ping in ms",
    "Jitter in ms",
    "Download Geschwindigkeit in MBit/s",
    "Upload Geschwindigkeit in MBit/s",
    "Download Geschwindigkeit in MB/s",
    "Upload Geschwindigkeit in MB/s",
    "Download Geschwindigkeit in Byte/s",
    "Upload Geschwindigkeit in Byte/s",
    "Internet Service Provider",
    "externe IP",
    "Adresse der Ergebnisse",
    "ID der Ergebnisse",
    "ID des getesteten Servers",
    "IP des getesteten Servers",
    "Anbieter des getesteten Servers",
    "Stadt des getesteten Servers",
    "Land des getesteten Servers",
    "URL des getesteten Servers",
    "Download Daten in MB",
    "Upload Daten in MB",
    "Download Daten in Byte",
    "Upload Daten in Byte",
    "Dauer des Download Test",
    "Dauer des Upload Test",
    "Letzter Speedtest"
];

// Einheiten der Objekte
var einheiten = ["",
    "ms",
    "ms",
    "MBit/s",
    "MBit/s",
    "MB/s",
    "MB/s",
    "Byte/s",
    "Byte/s",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "MB",
    "MB",
    "Byte",
    "Byte",
    "s",
    "s",
    ""
];

// Typen der Objekte
var typen = ["string",
    "number",
    "number",
    "number",
    "number",
    "number",
    "number",
    "number",
    "number",
    "string",
    "string",
    "string",
    "string",
    "number",
    "string",
    "string",
    "string",
    "string",
    "string",
    "number",
    "number",
    "number",
    "number",
    "number",
    "number",
    "string"
];

// Rollen der Objekte
var rolle = ["json",
    "value",
    "value",
    "value",
    "value",
    "value",
    "value",
    "value",
    "value",
    "text",
    "text",
    "text",
    "text",
    "value",
    "text",
    "text",
    "text",
    "text",
    "text",
    "value",
    "value",
    "value",
    "value",
    "value",
    "value",
    "text"
];

// Schreibe Werte des JSON String in ein Array
function generiere_array(json_array) {
    var j = JSON.parse(json_array);
    var array_werte = [json_array,
        j.ping.latency,
        j.ping.jitter,
        parseFloat((j.download.bandwidth / 125000).toFixed(2)),
        parseFloat((j.upload.bandwidth / 125000).toFixed(2)),
        parseFloat((j.download.bandwidth / (1024 * 1024)).toFixed(2)),
        parseFloat((j.upload.bandwidth / (1024 * 1024)).toFixed(2)),
        j.download.bandwidth,
        j.upload.bandwidth,
        j.isp,
        j.interface.externalIp,
        j.result.url,
        j.result.id,
        j.server.id,
        j.server.ip,
        j.server.name,
        j.server.location,
        j.server.country,
        j.server.host,
        parseFloat((j.download.bytes / (1024 * 1024)).toFixed(2)),
        parseFloat((j.upload.bytes / (1024 * 1024)).toFixed(2)),
        j.download.bytes,
        j.upload.bytes,
        parseFloat((j.download.elapsed / 1000).toFixed(2)),
        parseFloat((j.upload.elapsed / 1000).toFixed(2)),
        hole_datum()
    ];
    return array_werte;
}

function speedtest() {
    // temporäre Variable für das Array
    var tmp_json;
    // Kommando für den Speedtest
    var kommando = "/etc/speedtest/speedtest -f json --accept-license --accept-gdpr";
    if (fav_server > 0) {
        kommando = kommando + " -s " + fav_server;
        log("Speedtest mit Server " + fav_server + " gestartet! Der Test dauert zwischen 10 - 20 Sekunden!");
    } else {
        log("Speedtest gestartet! Der Test dauert zwischen 10 - 20 Sekunden!");
    }
    exec(kommando,
        function (error, stdout) {
            if (error) {
                log('Speedtest konnte nicht ausgeführt werden! ' + error, 'error');
                return;
            } else {
                tmp_json = generiere_array(stdout);
                aktualisiere_datenpunkt(tmp_json);
                log('Speedtest durchgeführt. Ergebnisse: Download: ' + tmp_json[5] + ' MB/s | Upload: ' + tmp_json[6] + ' MB/s | Ping: ' + tmp_json[1] + 'ms');
            }
        });
}

function aktualisiere_datenpunkt(werte) {
    for (let i = 0; i < objekt.length; i++) {
        setState(datenpunkt + objekt[i], werte[i], true);
    }
}

// Erstelle die benötigten Datenpunkte
function datenpunkte_erstellen() {
    for (var i = 0; i < objekt.length; i++) {
        createState(datenpunkt + objekt[i], "", ueberschreiben, {
            name: beschreibung[i],
            desc: beschreibung[i],
            type: typen[i],
            role: rolle[i],
            unit: einheiten[i]
        });
    }

    // Alle Datenpunkte erstellt. Führe ersten Speedtest aus!
    log('Speedtest: Datenpunkte erstellt! Erster Speedtest wird in 30 Sekunden ausgeführt!');
    setTimeout(speedtest, 30000);
}

// Datum 
function hole_datum() {
    let datum = new Date();
    let tag = '0' + datum.getDate();
    let monat = '0' + (datum.getMonth() + 1);
    let jahr = datum.getFullYear();
    let stunde = '0' + datum.getHours();
    let minute = '0' + datum.getMinutes();
    let sekunde = '0' + datum.getSeconds();
    return tag.substr(-2) + '.' + monat.substr(-2) + '.' + jahr + ' ' + stunde.substr(-2) + ':' + minute.substr(-2) + ':' + sekunde.substr(-2);
}

function speedtest_erster_start() {
    log("Speedtest: Erster Start des Skriptes! Datenpunkte werden erstellt!");
    // Datenpunkte werden erstellt
    datenpunkte_erstellen();
}

// Erster Start und Initialisierung
speedtest_erster_start();

// Alle 60 Minuten einen Speedtest ausführen
schedule('*/60 * * * *', speedtest);

Um nun vielleicht Deine Speedtest-Verläufe in Grafana zu speichern, kann ich Dir folgende Vorlage empfehlen:

https://github.com/Seqway/Grafana-Dashboards/tree/main/dashboards/Speedtest

Wie hat Dir der Beitrag gefallen?
Bewertung: 5/5 - abgegebene Bewertungen: 3

81 Gedanken zu „Speedtest für ioBroker

  1. Anton Antworten

    Hallo Stephan.

    Ich habe dein Script lt.Anleitung installiert und es funktioniert auch.
    Nur leider, nur nachdem ich es das erste mal starte. Danach kommt folgende Felermeldung “Speedtest konnte nicht ausgeführt werden! Error: Command failed: /usr/bin/speedtest -f json –accept-license –accept-gdpr -s 28602”
    vielleicht hast du eine Lösung für mich?

    Lg. Tony

    • Stephan Autor des BeitragsAntworten

      Hallo Anton,
      Prüfe einmal mit einem whereis speedtest, wo installiert worden ist.

      Dann den Pfad im Skript in Zeile 216 anpassen.
      Der Pfad /usr/bin/ ist eigentlich falsch, wie er in deiner Fehlermeldung steht.

      Gruß,
      Stephan

      • Anton Antworten

        Hallo Stephan.
        Sorry, aber ich bin kein Profi. Also ich habe wie du mir geschrieben hast den Befehl “whereis speedtest” eingegeben und folgenden Pfad “usr/bin/speedtest /etc/speedtest /usr/share/man/man5/speedtest.5” in die Zeile 216 eingetragen.
        Nach dem Neustart des Scripts wurde mir folgende Fehlermeldung ausgegeben “script.js.common.07_Just_Smart.Speedtest: Speedtest konnte nicht ausgeführt werden! Error: Command failed: usr/bin/speedtest /etc/speedtest /usr/share/man/man5/speedtest.5 -s 28602/bin/sh: 1: usr/bin/speedtest: not found”.

        Bitte hilf mir da weiter 🙂

        lg. Anton

  2. DJSirius Antworten

    Hallo.

    Leider bekomme ich immer eine Fehlermeldung.

    Kann mir da jemand helfen?

    javascript.0 (23818) script.js.Speedtest: Speedtest konnte nicht ausgeführt werden! Error: Command failed: /etc/speedtest/speedtest -f json –accept-license –accept-gdpr -s
    44081 sh: 0: getcwd() failed: No such file or directory /bin/sh: 1: /etc/speedtest/speedtest: Exec format error

    Vielen Dank!

  3. nico Antworten

    Hi Stephan,

    kommen der Sache schon näher

    Log:

    pi@iobroker:~ $ sudo apt update
    Hit:1 https://deb.nodesource.com/node_16.x bullseye InRelease
    Ign:2 https://packagecloud.io/ookla/speedtest-cli/raspbian bullseye InRelease
    Hit:3 http://archive.raspberrypi.org/debian bullseye InRelease
    Hit:4 http://raspbian.raspberrypi.org/raspbian bullseye InRelease
    Err:5 https://packagecloud.io/ookla/speedtest-cli/raspbian bullseye Release
    404 Not Found [IP: 52.8.166.117 443]
    Reading package lists… Done
    E: The repository ‘https://packagecloud.io/ookla/speedtest-cli/raspbian bullseye Release’ does not have a Release file.
    N: Updating from such a repository can’t be done securely, and is therefore disabled by default.
    N: See apt-secure(8) manpage for repository creation and user configuration details.

    Wenn ich das richtig verstehe findet das update den speedtest-cli für raspbian bullseye nicht?

    MbG

  4. nico Antworten

    Hallo Stephan,

    habe dein Script ohne Probleme seit Monaten laufen bis ich Updates vom Iobroker und eben auch Raspi 4 OS auf bullseye gemacht habe

    cat /etc/os-release
    PRETTY_NAME=”Raspbian GNU/Linux 11 (bullseye)”
    NAME=”Raspbian GNU/Linux”
    VERSION_ID=”11″
    VERSION=”11 (bullseye)”
    VERSION_CODENAME=bullseye
    ID=raspbian
    ID_LIKE=debian
    HOME_URL=”http://www.raspbian.org/”
    SUPPORT_URL=”http://www.raspbian.org/RaspbianForums”
    BUG_REPORT_URL=”http://www.raspbian.org/RaspbianBugs”

    wenn nun dein speedtest läuft bekomme ich immer folgende Fehlermeldung:

    2022-10-17 19:19:32.506 – info: javascript.0 (785) script.js.common.Speedtest: Speedtest mit Server 18136 gestartet! Der Test dauert zwischen 10 – 20 Sekunden!
    2022-10-17 19:19:32.550 – error: javascript.0 (785) script.js.common.Speedtest: Speedtest konnte nicht ausgeführt werden! Error: Command failed: /etc/speedtest/speedtest -f json –accept-license –accept-gdpr -s 18136

    Hast du bitte eine Ahnung was da schief läuft

    Danke im Voraus,

    • Stephan Autor des BeitragsAntworten

      Hi Nico,
      ich denke, hier ist der Speedtest nicht mehr installiert?

      Du müsstest, so denke ich, das Repository für Bullseye anpassen.

      Gruß,
      Stephan

      • nico Antworten

        Hallo Stephan,

        Danke für deine Hilfe. Hier ist mal mein Log vom Raspi fürs Update vom Speedtest allerdings mit einer Fehlermeldung am Ende

        pi@iobroker:~ $ sudo apt-get remove speedtest-cli
        Reading package lists… Done
        Building dependency tree… Done
        Reading state information… Done
        Package ‘speedtest-cli’ is not installed, so not removed
        0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
        pi@iobroker:~ $ curl -s https://install.speedtest.net/app/cli/install.deb.sh | sudo bash
        This distribution version is not currently supported via package management, please use the direct download builds per architecture found at https://www.speedtest.net/apps/cli
        pi@iobroker:~ $ curl -s https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh | sudo bash
        Detected operating system as raspbian/bullseye.
        Checking for curl…
        Detected curl…
        Checking for gpg…
        Detected gpg…
        Detected apt version as 2.2.4
        Running apt-get update… done.
        Installing apt-transport-https… done.
        Installing /etc/apt/sources.list.d/ookla_speedtest-cli.list…done.
        Importing packagecloud gpg key… Packagecloud gpg key imported to /etc/apt/keyrings/ookla_speedtest-cli-archive-keyring.gpg
        done.
        Running apt-get update… done.

        The repository is setup! You can now install packages.
        pi@iobroker:~ $ sudo apt-get install speedtest
        Reading package lists… Done
        Building dependency tree… Done
        Reading state information… Done
        E: Unable to locate package speedtest

        Und nun?

        Thx

        • Stephan Autor des BeitragsAntworten

          Hallo,
          ich denke, Dir fehlt ein Zwischenschritt:

          sudo apt update
          sudo apt install speedtest

          Gruß,
          Stephan

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert