Speedtest-cli Internet Up-/Downlink Measurement Integration

Thanks, wasn’t in my mind…

And did it work?

Yes, perfectly

1 Like

just figured out that the path is wrong if i installed speedtest with apt-get, can somebody tell me whats the right path for the rule

2019-08-18 22:00:00.050 [INFO ] [arthome.model.script.speedtest.rules] - --> speedtest executed...

2019-08-18 22:00:00.128 [WARN ] [lipse.smarthome.io.net.exec.ExecUtil] - Execution failed (Exit value: -559038737. Caused by java.io.IOException: Cannot run program "/usr/local/bin/speedtest-cli" (in directory "."): error=2, No such file or directory)

2019-08-18 22:00:00.166 [ERROR] [arthome.model.script.speedtest.rules] - --> speedtest failed. Output:

If i do sudo speedtest-cli its works in the command interface

[sudo] password for openhabian:
Retrieving speedtest.net configuration...
Testing from O2 Deutschland (77.13.178.38)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by SysEleven GmbH (Berlin) [2.81 km]: 8.717 ms
Testing download speed................................................................................
Download: 94.17 Mbit/s
Testing upload speed......................................................................................................
Upload: 3.80 Mbit/s

On Debian10 Buster this worked for me:

sudo apt-get install python3-pip
sudo pip3 install speedtest-cli

I use speed test like this

2 Likes

Looks very nice!
Do you dare publishing your code?

Hi there,

today i have a little question that is a bit off topic.

After updating my speedtest server to Debian Buster i got a strange behaviour. The download rates are in the same range as before. The upload rates are dropped significat to about 3 MBit from aboz 25MBit. i tried this on different Buster installations, but this is always the same. On a Debian Stretch installation i measure the full power.

Does anyone else has the same problem?

Thanks Thomas

Thats pretty. Can you share sitemap and graph? :slight_smile:

Hi Allen,
I’ve got the same problem with the speedtest. Could you give me a little bit more information how you fixed this? I’m using shelly and a vpn to ssh into the ubuntu machine with openhab.(when i’am not at home, normally using terminal at home on the mac)

Best regards😁

sent you a message.
will share my files that i used and it works like that for me ?
if you can give me that details i might be able to help.
i use mac and teamviewer if i am of site to connect to my ubuntu server at home.

Regards

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