Speedtest-cli Internet Up-/Downlink Measurement Integration

a lot is necessary to get it all to this stage

Would ne nice if you could Share this to the Community, I think further People are interested in the Solution…

TimeLine Speed Test Picker and Resultant graphing

this has been done on linux ubuntu, which may affect some of the paths and scripts ( speedtest )

This will have many edits, bear with me, I did not write hardly any code, just took
it all from this most excellent and helpful community

Items you will need working :

Timeline picker, Note Picker version ( there is a very useful Display only Version )

Persistence for the graphing,so the system can remember your data to graph and so many many other good things

https://www.openhab.org/addons/persistence/rrd4j

i will load my setups for everyone to see. it was only so he could check. as i also had a simple fault.
all that was wrong was the location in the rule . once he fixed that it worked 100%

Items file :

Group Speedtest <"network-icon"> (Home)

String      SpeedtestSummary        "Speedtest [%s]"                                       <"speedtest_network">       (gSpeedtest)
Number      SpeedtestResultPing     "Ping [%.3f ms]"                                       <"speedtest_next5">         (gSpeedtest)
Number      SpeedtestResultDown     "Downlink [%.2f Mbit/s]"                               <"speedtest_download">      (gSpeedtest)
Number      SpeedtestResultUp       "Uplink [%.2f Mbit/s]"                                 <"speedtest_upload">        (gSpeedtest)
String      SpeedtestRunning        "Speedtest running ... [%s]"                           <"speedtest_new">           (gSpeedtest)
Switch      SpeedtestRerun          "Start manually"                                       <"speedtest_reload2">       (gSpeedtest)
DateTime    SpeedtestResultDate     "Last executed [%1$td.%1$tm.%1$tY, %1$tH:%1$tM Uhr]"   <"speedtest_problem4">      (gSpeedtest)

Rule file :

val String filename = "speedtest.rules"

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("⁉ (unknown)")
    ]
end
rule "Speedtest"
when
    //Time cron "0 0 5,13 * * ?" or
    Time cron "0 0 * * * ?" or
    Item SpeedtestRerun received command ON
then
    logInfo(filename, "--> speedtest executed...")
    SpeedtestRunning.postUpdate("Measurement in progress...")

    // update timestamp for last execution
    SpeedtestResultDate.postUpdate(new DateTimeType())

    // execute the script, you may have to change the path depending on your system
    var String speedtestCliOutput = executeCommandLine("/usr/bin/speedtest-cli@@--simple", 120*1000)

    // for debugging:
    //var String speedtestCliOutput = "Ping: 43.32 ms\nDownload: 21.64 Mbit/s\nUpload: 4.27 Mbit/s"
    //logInfo(filename, "--> speedtest output:\n" + speedtestCliOutput + "\n\n")

    SpeedtestRunning.postUpdate("data analysis...")

    // starts off with a fairly simple error check, should be enough to catch all problems I can think of
    if (speedtestCliOutput.startsWith("Ping") && speedtestCliOutput.endsWith("Mbit/s")) {
        var String[] results = speedtestCliOutput.split("\\r?\\n")
        var float ping = new java.lang.Float(results.get(0).split(" ").get(1))
        var float down = new java.lang.Float(results.get(1).split(" ").get(1))
        var float up   = new java.lang.Float(results.get(2).split(" ").get(1))
        SpeedtestResultPing.postUpdate(ping)
        SpeedtestResultDown.postUpdate(down)
        SpeedtestResultUp.postUpdate(up)
        SpeedtestSummary.postUpdate(String::format("ᐁ  %.1f Mbit/s  ᐃ %.1f Mbit/s (%.0f ms)", down, up, ping))
        SpeedtestRunning.postUpdate("-")
        logInfo(filename, "--> speedtest finished.")
    } else {
        SpeedtestResultPing.postUpdate(0)
        SpeedtestResultDown.postUpdate(0)
        SpeedtestResultUp.postUpdate(0)
        SpeedtestSummary.postUpdate("(unknown)")
        SpeedtestRunning.postUpdate("Error during execution")
        logError(filename, "--> speedtest failed. Output:\n" + speedtestCliOutput + "\n\n")
    }
    SpeedtestRerun.postUpdate(OFF)
end

// vim: syntax=Xtend

you just need to check and change where you did the installation of speedtest-cli.

2 Likes

with openhabian 1.5 (Buster)
sudo easy_install speedtest-cli

gives me:
sudo easy_install: command not found

EDIT:

that worked! thanks

thanks that location change helped me too

var String speedtestCliOutput = executeCommandLine("/usr/bin/speedtest-cli@@--simple", 120*1000)
1 Like

Hey, when I execute the speed test from the UI it works fine and the result data is persisted to my influxdb:

09-Dec-2019 22:02:03.457 [INFO ] [.smarthome.model.core.internal.ModelRepositoryImpl] - Refreshing model 'speedtest.rules'
09-Dec-2019 22:02:18.020 [INFO ] [org.eclipse.smarthome.model.script.speedtest.rules] - --> speedtest executed...
09-Dec-2019 22:02:51.091 [INFO ] [org.eclipse.smarthome.model.script.speedtest.rules] - --> speedtest finished.

But when the scheduler executes the speed test (via rule) it runs into this exception:

09-Dec-2019 22:03:56.436 [ERROR] [org.quartz.core.JobRunShell                       ] - Job DEFAULT.2019-12-09T22:03:56.431+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@194c4ab
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@864925
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@c035ce
} ] threw an unhandled Exception: 
java.lang.NullPointerException: null
	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:66) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:865) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:224) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:768) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1116) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:992) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:226) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:458) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:244) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]
	at com.sun.proxy.$Proxy203.apply(Unknown Source) ~[?:?]
	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
09-Dec-2019 22:03:56.577 [ERROR] [org.quartz.core.ErrorLogger                       ] - Job (DEFAULT.2019-12-09T22:03:56.431+01:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@194c4ab
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@864925
  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@c035ce
} ] threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
	at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh240]
Caused by: java.lang.NullPointerException
	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:66) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:865) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:224) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:768) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:220) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1116) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:992) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:902) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:226) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:458) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:244) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:447) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:228) ~[?:?]
	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:204) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:190) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]
	at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]
	at com.sun.proxy.$Proxy203.apply(Unknown Source) ~[?:?]
	at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]
	... 1 more

Sadly the exception stack is not very helpful, at least not to me.
Help is appreciated.

Can the user openhab run script?

The speedtest-cli script you mean? Yes. It runs without any issues from the shell and from the Habmin-UI.

How do you run it from HABmin?
Post your whole rule so we can see the actual code you’re trying to run.
I don’t understand how you can run the test script and how it persists to influx. For me the test is “can the following run: /usr/local/bin/speedtest-cli@@–simple”

My whole rule, which runs without issue, is this:

rule "Speedtest"
when
    Item SpeedtestRerun received command ON
then
    logInfo(filename, "--> speedtest executed...")
    SpeedtestRunning.postUpdate("Measuring in progress...")

    // update timestamp for last execution
    SpeedtestResultDate.postUpdate(new DateTimeType())

    // execute the script, you may have to change the path depending on your system
    var String speedtestCliOutput = executeCommandLine("/usr/local/bin/speedtest-cli@@--simple", 120*1000)

    // for debugging:
    //var String speedtestCliOutput = "Ping: 43.32 ms\nDownload: 21.64 Mbit/s\nUpload: 4.27 Mbit/s"
    //logInfo(filename, "--> speedtest output:\n" + speedtestCliOutput + "\n\n")

    SpeedtestRunning.postUpdate("Analysing...")

    // starts off with a fairly simple error check, should be enough to catch all problems I can think of
    if (speedtestCliOutput.startsWith("Ping") && speedtestCliOutput.endsWith("Mbit/s")) {
        var String[] results = speedtestCliOutput.split("\\r?\\n")
        var float ping = new java.lang.Float(results.get(0).split(" ").get(1))
        var float down = new java.lang.Float(results.get(1).split(" ").get(1))
        var float up   = new java.lang.Float(results.get(2).split(" ").get(1))
        SpeedtestResultPing.postUpdate(ping)
        SpeedtestResultDown.postUpdate(down)
        SpeedtestResultUp.postUpdate(up)
        SpeedtestSummary.postUpdate(String::format("ᐁ  %.1f Mb/s  ᐃ %.1f Mb/s", down, up))
//        SpeedtestSummary.postUpdate(String::format("ᐁ  %.1f Mb/s  ᐃ %.1f Mb/s (%.0f ms)", down, up, ping))
        SpeedtestRunning.postUpdate("-")
        logInfo(filename, "--> speedtest finished.")
    } else {
        SpeedtestResultPing.postUpdate(0)
        SpeedtestResultDown.postUpdate(0)
        SpeedtestResultUp.postUpdate(0)
        SpeedtestSummary.postUpdate("(Unknown)")
        SpeedtestRunning.postUpdate("Error while checking")
        logError(filename, "--> speedtest failed. Output:\n" + speedtestCliOutput + "\n\n")
    }
    SpeedtestRerun.postUpdate(OFF)
end

I don’t know why and how, but I just came home from work to see it was executed nicely all day long. Didn’t do anything since yesterday. Seems to work for now. Thanks anyway.

Glad I could help :laughing:

1 Like

It works perfectly, thank you!

I have a question. When I start the system or reboot in my openhab.log an info message appears:

[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘speedtest.rules’, using it anyway:
The constructor Float(String) is deprecated
The constructor Float(String) is deprecated
The constructor Float(String) is deprecated

Does anyone know how to solve this?

I know it comes from this part of the rules but nothing else.

    if (speedtestCliOutput.startsWith("Ping") && speedtestCliOutput.endsWith("Mbit/s")) {
        var String[] results = speedtestCliOutput.split("\\r?\\n")
        var float ping = new java.lang.Float(results.get(0).split(" ").get(1))
        var float down = new java.lang.Float(results.get(1).split(" ").get(1))
        var float up   = new java.lang.Float(results.get(2).split(" ").get(1))
        SpeedtestResultPing.postUpdate(ping)
        SpeedtestResultDown.postUpdate(down)
        SpeedtestResultUp.postUpdate(up)
        SpeedtestSummary.postUpdate(String::format("ᐁ  %.1f Mbit/s  ᐃ %.1f Mbit/s (%.0f ms)", down, up, ping))
        SpeedtestRunning.postUpdate("-")
        logInfo(filename, "--> speedtest finished.")
    } 

Thanks

What i am missing, it works well from the CLI and getting this error from the Rule

image

how did you install speedtest with pip? the current user or sudo? Try the “other one”

C

This has just started happening to me too since updating to 2.5… upload speed is always showing as 2.3MBit whereas prior to upgrading it showed around 6 (which matched the upload speed in the other speedtest apps).

Download and ping are all working as expected.

Did you find out what was causing it for you?

Did you install the speedtest with apt install … ? and did you do an apt update/upgrade? If yes it is very likely that you installed version of speedtest has an error.

Just uninstall it and reinstall it using pip. That retrieved the lates version from github that should work properly. That solved my problem.

Thomas

1 Like

Awesome - that fixed it! Thanks so much.

1 Like

hi,
i have an issue withe the speedtest.exe running on my Windows 10 System.
The Speedtest works for 10 months and at the 31.12.2019 it stops.
In the Log i see this entry:
2020-01-14 09:00:18.631 [ERROR] [arthome.model.script.speedtest.rules] - --> speedtest failed. Output: 2020-01-14 09:00:00 +0100|18613|"TelemaxX Telekommunikation GmbH (Karlsruhe, Germany)"|32.00|54456|30773

thanks for your help

Did the output definition change? Maybe because of that openHAB cannot transform the output. Can you test on the commandline?

This is the log from the 24.12:
2019-12-24 02:00:15.229 [INFO ] [arthome.model.script.speedtest.rules] - --> speedtest output:
2019-12-24 02:00:00 +0100|18613|“TelemaxX Telekommunikation GmbH (Karlsruhe, Germany)”|26.90|55425|31153
i thing thats the same output.