OH3 and Speedtest Ookla

I’m sorry, Rich is one of the most active and as it happens the most liked user here in the forum. I’m afraid you are the arrogant one.
Please calm down a bit and take a step back and read again through this thread. You gave (and give) not the impression to have

  1. read the sources we gave you
  2. told us what you already tried - and failed to do
  3. told us, what obstacles you face

but: you have told us

  1. to solve your problem nevertheless
  2. even doubled down on your position - after being told so from multiple users here on the forum

:blush:

1 Like

You can close this topic

FYI there is a new binding getting reviewed here and the author supplied a jar file.

[speedtest] Binding for Ookla’s Speedtest - Initial contribution by bigbasec · Pull Request #9913 · openhab/openhab-addons (github.com)

Thank you, I have already found this version and saved it in the “Addons” folder. A recommended rule is installed to trigger the query. But it doesn’t work. (The Exec binding is also installed.)
I actually always take a lot of time when problems arise - that was also the case this time. Since I can’t get any further, I will forego the new binding and speed test.

Hi,
i want to share my current solution for the ookla docker container integration (based on Speedtest CLI by Ookla - Internet Up-/Downlink Measurement Integration):

  • I’m using the ookla docker image tamasboros/ookla-speedtest that is
  • writing the json output to /opt/openhab/userdata/tmp/ookla.json, this file is then
  • parsed by the speedtest rule (instead of executing the ookla speedtest and fetching the json like in the original rule). To do so, i added a try-catch block around, reading the file and convert the pretty json to a one-liner with 2 regex. (-> see MODIFICATION START / END)
  • cronjob is running the ookla speedtest container every minute.

speedtest.rules:

// MODIFICATION START
import java.nio.file.Files
import java.nio.file.Paths
// MODIFICATION END

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

    Time cron "0 0/15 * * * ?" or
    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 --accept-gdpr --accept-license -f json"
	var String speedtestCliOutput;
	// MODIFICATION START
	try {
        speedtestCliOutput = new String(Files.readAllBytes(Paths.get("/openhab/userdata/tmp/ookla.json")))
		speedtestCliOutput = speedtestCliOutput.replaceAll("\\s+", "").replaceAll("\\r\\n+","")
		// MODIFICATION END

		// for debugging:
		// var String speedtestCliOutput = "Ping: 43.32 ms\nDownload: 21.64 Mbit/s\nUpload: 4.27 Mbit/s"
		logInfo(ruleId, "--> speedtest output after readfile:\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
		if (speedtestCliOutput.startsWith("{\"type\":\"result\",") && speedtestCliOutput.endsWith("}}"))
		{
			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)
		
	// MODIFICATION START	
	} catch (IOException e){
		SpeedtestResultPing.postUpdate(0)
		SpeedtestResultDown.postUpdate(0)
		SpeedtestResultUp.postUpdate(0)
		SpeedtestSummary.postUpdate("(unbekannt)")
		SpeedtestRunning.postUpdate("File Error")

		logError(ruleId, "--> speedtest failed. Output:\nookla output reading failed!\n\n")
		
	}
        // MODIFICATION END
end

/etc/cron.d/docker
* * * * * docker /home/docker/docker_ookla.sh

/home/docker/docker_ookla.sh

docker run --rm --name ookla tamasboros/ookla-speedtest > /opt/openhab/userdata/tmp/ookla.json

I’m quite sure this is not the most beautiful solution, but due to lack of time my only one working :wink:

1 Like