Speedtest der Internetverbindung mit openHAB regelmäßig durchführen

Ich wollte in unserem SmartHome einen regelmäßigen Speedtest unserer Internetverbindung regelmäßig durchführen lassen. Damit wollte ich herausfinden, ob die zugesicherten Bandbreiten unseres Glasfaser-Anschlusses immer eingehalten werden. Da in openHAB 3 automatisch alle Items persistiert werden, war das nach der Umstellung eine gute Möglichkeit.

Die Erste Idee für die Geschwindigkeitsmessung war das Network Binding. Das habe ich aber dann nicht verwendet, da dies eine ISO-Datei für den Test benötigt (das wollte ich so nicht umsetzen).

Im openHAB-Forum habe ich dann eine individuelle Scripting-Lösung auf Basis Speedtest CLI by Ookla gefunden.

Die Umsetzung war dort sehr gut dort beschrieben. Man muss nur die Systemvoraussetzungen beachten, nicht das hier etwas auf dem eigenen System fehlt (das kann zum Teil im Debugging des Scripts etwas aufwändiger sein).

Die Scripte stellen für mich eine sehr runde Lösung dar, die alle Informationen incl. graphischer Aufbereitung / Icons enthält. In openHAB 3.x werden die Daten automatisch persistiert und damit dann auch längerfristig auswertbar gespeichert.

Ein paar Anpassungen für openHAB 3.x mussten durchgeführt werden:

SpeedTest.items

Die Items werden wie folgt definiert:

Group gSpeedtest <"speedtest">
Group gSpeedChart
String SpeedtestCharts

String      SpeedtestSummary        "Speedtest [%s]"                                            <"speedtest_summary">   (gSpeedtest, gPersist)
Number      SpeedtestResultPing     "Ping [%.3f ms]"                                            <"speedtest_ping">      (gSpeedtest, gSpeedChart)
Number      SpeedtestResultDown     "Download [%.2f Mbit/s]"                                    <"speedtest_download">  (gSpeedtest, gSpeedChart)
Number      SpeedtestResultUp       "Upload [%.2f Mbit/s]"                                      <"speedtest_upload">    (gSpeedtest, gSpeedChart)
String      SpeedtestRunning        "Speedtest läuft ... [%s]"                                  <"speedtest_run">       (gSpeedtest)
Switch      SpeedtestRerun          "Manuell starten"                                           <"speedtest_reload">    (gSpeedtest)
DateTime    SpeedtestResultDate     "Letzte Ausführung [%1$td.%1$tm.%1$tY, %1$tH:%1$tM]"        <"speedtest_date">      (gSpeedtest, gPersist)
String      SpeedtestResultError    "Fehlermeldung [%s]"                                        <"speedtest_error">     (gSpeedtest, gPersist)
String      SpeedtestResultImage    "Bild"

SpeedTest.rules

Die Regel steuert dann die gesamte Logik an (hier ist eine automatischer und eine manueller Start möglich). Hier habe ich meine Anpassungen im Kommentar erfasst: 

val String ruleId = "Speedtest"
val Number calc = 125000 // Converting from bits to Mbits

rule "Speedtest init"
when
    System started
then
    createTimer(now.plusSeconds(195))
    [|
        if(SpeedtestRerun.state == NULL)
        {
            SpeedtestRerun.postUpdate(OFF)
        }
        if(SpeedtestRunning.state == NULL)
        {
            SpeedtestRunning.postUpdate("-")
        }
        if(SpeedtestSummary.state == NULL || SpeedtestSummary.state == "")
        {
            SpeedtestSummary.postUpdate("⁉ (unbekannt)")
        }
    ]
end
rule "Speedtest"
when
    // 1 x am Tag 4 Uhr früh
    Time cron "0 0 4 * * ?" or
    //Time cron "0 0/15 * * * ?" or     // alle 15 Minuten
    Item SpeedtestRerun changed from OFF to ON or
    Item SpeedtestRerun received command ON
then
    //logInfo(ruleId, "--> speedtest executed...")
    SpeedtestRunning.postUpdate("Messung läuft...")
    // execute the script, you may have to change the path depending on your system
    // Please use -f json and not -f json-pretty
    
    //val speedtestExecute = "speedtest -f json"
    // 13.02.2021 - Anpassung damit Lizenz akzeptiert wird
    //val speedtestExecute = "sudo -u openhab /usr/bin/speedtest -f json --accept-license --accept-gdpr"
    //val speedtestExecute = "speedtest -f json"
    
    //var speedtestCliOutput = executeCommandLine(speedtestExecute, 120*1000)
    
    // 13.02.2021 - Anpassung für openHAB 3
    var speedtestCliOutput = executeCommandLine(Duration.ofSeconds(120), "speedtest", "-f", "json")
    // for debugging:
    //var String speedtestCliOutput = "Ping: 43.32 ms\nDownload: 21.64 Mbit/s\nUpload: 4.27 Mbit/s"
    logInfo(ruleId, "--> speedtest output:\n" + speedtestCliOutput + "\n\n")
    SpeedtestRunning.postUpdate("Datenauswertung...")
    // starts off with a fairly simple error check, should be enough to catch all problems I can think of
    // 13.02.2021 - Anpassung notwendig zum Beispiel
    //if (speedtestCliOutput.startsWith("{\"type\":\"result\",") && speedtestCliOutput.endsWith("}}"))
    if (speedtestCliOutput.startsWith("{\"type\":\"result\","))
    {
        var ping = Float::parseFloat(transform("JSONPATH", "$.ping.latency", speedtestCliOutput))
        SpeedtestResultPing.postUpdate(ping)
        var float down = Float::parseFloat(transform("JSONPATH", "$.download.bandwidth", speedtestCliOutput))
        down = (down / calc)
        SpeedtestResultDown.postUpdate(down)
        var float up = Float::parseFloat(transform("JSONPATH", "$.upload.bandwidth", speedtestCliOutput))
        up = (up / calc)
        SpeedtestResultUp.postUpdate(up)
        var String url = transform("JSONPATH", "$.result.url", speedtestCliOutput)
        val img = url + ".png"
        SpeedtestResultImage.postUpdate(img)
        SpeedtestSummary.postUpdate(String::format("ᐁ  %.1f Mbit/s  ᐃ %.1f Mbit/s (%.0f ms)", down, up, ping))
        SpeedtestRunning.postUpdate("-")
        // update timestamp for last execution
        val DateTimeType ResultDate = DateTimeType.valueOf(transform("JSONPATH", "$.timestamp", speedtestCliOutput))
        SpeedtestResultDate.postUpdate(ResultDate)
    }
    else
    {
        SpeedtestResultPing.postUpdate(0)
        SpeedtestResultDown.postUpdate(0)
        SpeedtestResultUp.postUpdate(0)
        SpeedtestSummary.postUpdate("(unbekannt)")
        SpeedtestRunning.postUpdate("Fehler")
        logError(ruleId, "--> speedtest failed. Output:\n" + speedtestCliOutput + "\n\n")
    }
    SpeedtestRerun.postUpdate(OFF)
end

Sitemap

Die Visualisierung erfolgt dann in der Sitemap wie folgt:

        Text item=SpeedtestSummary icon="speedtest" {
            Frame label="Ergebnisse" {
                Text item=SpeedtestResultDown
                Text item=SpeedtestResultUp
                Text item=SpeedtestResultPing
            }
            Frame label="Steuerung" {
                Text item=SpeedtestResultDate
                Text item=SpeedtestRunning label="Speedtest [%s]" visibility=[SpeedtestRunning != "-"]
                Text item=SpeedtestResultError visibility=[SpeedtestRunning == "Fehler"]
                Switch item=SpeedtestRerun mappings=[ON="Start"]
            }
            Frame label="Statistik" {
                Switch item=Chart_Zeitraum_D_W_M_Y label="" mappings=[0="Woche", 1="Monat", 2="Jahr"]
                Chart item=gSpeedtest service="rrd4j" period=W refresh=15000 visibility=[Chart_Zeitraum_D_W_M_Y==0, Chart_Zeitraum_D_W_M_Y=="Uninitialized"]
                Chart item=gSpeedtest service="rrd4j" period=M refresh=15000 visibility=[Chart_Zeitraum_D_W_M_Y==1]
                Chart item=gSpeedtest service="rrd4j" period=Y refresh=15000 visibility=[Chart_Zeitraum_D_W_M_Y==2]
            }
        }

Fazit

Damit konnte ich recht einfach die Messung der Bandbreite bei uns zu Hause in openHAB integrieren. Eine schöne Erweiterung wäre noch die Verfügbarkeit des Internetzugangs regelmäßig zu protokollieren.

Wie messt Ihr in eurem SmartHome die Bandbreite eurer Internetverbindung? Habt Ihr eine bessere Variante als diese manuelle Scripting-Lösung?

2 Kommentare
  1. MoniS
    MoniS sagte:

    Hallo,
    durch Zufall bin ich auf diese Seite im Netz gestoßen und finde gerade den Bereich Smarthome bzw. Openhab sehr interessant. Aktuell messe ich die Geschwindigkeit über das Netzwerk Binding. Bei mir läuft OH 3.1 auf einer Synology DS918+ im Docker.
    Beim durchlesen des obigen Artikels frage ich mich, ob die oben beschriebene Speedtest Ookla Variante auch auf meinem System eingesetzt werden kann, oder muss zusätzlich noch etwas installiert werden? Wenn ich richtig recherchiert habe ist das Beispiel auf einem Raspi installiert und der Link bezieht sich auf OH2.5. Aus den Anpassungen geht leider nicht hervor, auf welchem Gerät bzw. unter welchen Voraussetzungen Speedtest Ookla bei dir läuft.
    Über eine Antwort würde ich mich sehr freuen.

    MoniS

  2. Reinhard
    Reinhard sagte:

    Hi MoniS,

    ich hatte diese “Scripting-Lösung” hier im openHAB-Forum gefunden: https://community.openhab.org/t/speedtest-cli-by-ookla-internet-up-downlink-measurement-integration/94447.

    Aktuell läuft bei mir ein openHAB 3.0.x auf einem RasPi. Ich musste auf meinem Linux-System das Paket “Speedtest CLI by Ookla” installieren. In dem vorherigen Link steht wie ich das installieren musste. Das macht ja in einem Docker-Container dann nicht so wirklich Sinn …

    Schöne Grüße,
    Reinhard

Hinterlasse einen Kommentar

An der Diskussion beteiligen?
Hinterlasse uns deinen Kommentar!

Schreibe einen Kommentar

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

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.