Yes, typo on my part above
Maybe someone has a good idea for the following question.
I would like to have a rule that is able to send different messages for thresholds.
My ISP has three levels of bandwidth: Maximum, Usually and Minimum
So i´ve got six states, Upload (Min,Normal,Max) and Download (Min,Normal,Max), to measure.
I already made the checks but i´m not sure what would be a good way to write a rule for this.
Edit: Ok so here´s what i did. I´m pretty sure there´s a “better” or much simplier way to do this and i´m happy if someone has a optimized version.
Code in the first post
Ok clearly, not being a programmer I’ve done something wrong, I thought I copied and pasted the code ok, and the command line speedtest creates no issues but I get a Java error
2020-03-17 17:21:11.343 [vent.ItemStateChangedEvent] - SpeedtestRunning changed from Data Analysis... to Measurement in progress...
2020-03-17 17:21:11.358 [vent.ItemStateChangedEvent] - SpeedtestResultDate changed from 2020-03-17T17:20:12.257-0400 to 2020-03-17T17:21:11.340-0400
2020-03-17 17:21:20.575 [vent.ItemStateChangedEvent] - SpeedtestRunning changed from Measurement in progress... to Data Analysis...
2020-03-17 17:21:20.577 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Speedtest': For input string: "{"type":"result","timestamp":"2020-03-17T21:21:20Z","ping":{"jitter":0.070000000000000007,"latency":4.0490000000000004},"download":{"bandwidth":10542780,"bytes":38014560,"elapsed":3610},"upload":{"bandwidth":11753696,"bytes":42415200,"elapsed":3610},"packetLoss":0,"isp":"Bell Canada","interface":{"internalIp":"192.168.1.34","name":"eth0","macAddr":"B8:27:EB:1E:8B:85","isVpn":false,"externalIp":"216.209.224.196"},"server":{"id":12159,"name":"LARG*net","location":"London, ON","country":"Canada","host":"speedtest.largnet.ca","port":8080,"ip":"198.20.48.134"},"result":{"id":"841f35c7-9e7a-4989-8a4d-d5f280f6c97b","url":"https://www.speedtest.net/result/c/841f35c7-9e7a-4989-8a4d-d5f280f6c97b"}}"
2020-03-17 17:23:27.252 [ERROR] [org.quartz.core.JobRunShell ] - Job DEFAULT.Timer 11 2020-03-17T17:23:27.248-04:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
org.eclipse.xtext.xbase.impl.XIfExpressionImpl@11d0ff7 (conditionalExpression: false)
org.eclipse.xtext.xbase.impl.XIfExpressionImpl@1f5aac8 (conditionalExpression: false)
org.eclipse.xtext.xbase.impl.XIfExpressionImpl@1905992 (conditionalExpression: false)
} ] threw an unhandled Exception:
java.lang.NullPointerException: null
at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:65) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:954) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:235) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:857) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:231) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1205) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1135) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:1081) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:237) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:469) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:255) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:458) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:239) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:201) ~[?:?]
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.$Proxy177.apply(Unknown Source) ~[?:?]
at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:48) ~[?:?]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [bundleFile:?]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [bundleFile:?]
2020-03-17 17:23:27.309 [ERROR] [org.quartz.core.ErrorLogger ] - Job (DEFAULT.Timer 11 2020-03-17T17:23:27.248-04:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
org.eclipse.xtext.xbase.impl.XIfExpressionImpl@11d0ff7 (conditionalExpression: false)
org.eclipse.xtext.xbase.impl.XIfExpressionImpl@1f5aac8 (conditionalExpression: false)
org.eclipse.xtext.xbase.impl.XIfExpressionImpl@1905992 (conditionalExpression: false)
} ] threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [bundleFile:?]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [bundleFile:?]
Caused by: java.lang.NullPointerException
at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:65) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:954) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:235) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:857) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:231) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1205) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1135) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:1081) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:237) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:469) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:255) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:458) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:239) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:201) ~[?:?]
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.$Proxy177.apply(Unknown Source) ~[?:?]
at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:48) ~[?:?]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]
... 1 more
'''
Please put all your code between ```php
and ```
Currently i don´t see a speedtest error.
Sorry can never remember how to get the text in those scrollable windows
Code:
// Global Variables
//
val String filename = "speedtest.rules"
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("⁉ (unknown)")
]
end
//
rule "Speedtest"
when
Time cron "0 0 7/4 1/1 * ?" or //every 4hrs from 7am
Item SpeedtestRerun changed from OFF to ON 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/local/bin/speedtest-cli@@--simple", 120*1000)
// val speedtestExecute = "speedtest -f json -s 1061"
val speedtestExecute = "speedtest -f json"
var speedtestCliOutput = executeCommandLine(speedtestExecute, 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...")
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 String ResultDate = "" + new DateTimeType()
SpeedtestResultDate.postUpdate(ResultDate)
}
else
{
SpeedtestResultPing.postUpdate(0)
SpeedtestResultDown.postUpdate(0)
SpeedtestResultUp.postUpdate(0)
SpeedtestSummary.postUpdate("(unknown)")
SpeedtestRunning.postUpdate("Failure")
logError(ruleId, "--> speedtest failed. Output:\n" + speedtestCliOutput + "\n\n")
}
SpeedtestRerun.postUpdate(OFF)
end
As I said I cut and paste it
what file is this copied from? If it’s the rule…it;s missing a large part of it from the top.
The error’s straight from my log openhabIP:9001
The code from the speedtest.rules
The code you copied is only part of the rules file…you are missing quite a bit of it from the top. You need to make sure you got it all when you copied and pasted.
Squid
Not missing just didn’t copy it. (edited) I put logInfo’s in to see where the code was stopping, code falls through until the "first var ping = "
I think your cron part is not correct.
Please try it without the cron part and if that‘s working check the cron part.
If you are going to ask for help…you’ve got to give us the full picture…
Cron is ok, literally I used my old speedtest-cli script and it always worked
Anyway this is manually running I’m testing and you can see it runs from the original log output
2020-03-17 17:21:11.343 [vent.ItemStateChangedEvent] - SpeedtestRunning changed from Data Analysis... to Measurement in progress...
2020-03-17 17:21:11.358 [vent.ItemStateChangedEvent] - SpeedtestResultDate changed from 2020-03-17T17:20:12.257-0400 to 2020-03-17T17:21:11.340-0400
2020-03-17 17:21:20.575 [vent.ItemStateChangedEvent] - SpeedtestRunning changed from Measurement in progress... to Data Analysis...
2020-03-17 17:21:20.577 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Speedtest': For input string: "{"type":"result","timestamp":"2020-03-17T21:21:20Z","ping":{"jitter":0.070000000000000007,"latency":4.0490000000000004},"download":{"bandwidth":10542780,"bytes":38014560,"elapsed":3610},"upload":{"bandwidth":11753696,"bytes":42415200,"elapsed":3610},"packetLoss":0,"isp":"Bell Canada","interface":{"internalIp":"192.168.1.34","name":"eth0","macAddr":"B8:27:EB:1E:8B:85","isVpn":false,"externalIp":"216.209.224.196"},"server":{"id":12159,"name":"LARG*net","location":"London, ON","country":"Canada","host":"speedtest.largnet.ca","port":8080,"ip":"198.20.48.134"},"result":{"id":"841f35c7-9e7a-4989-8a4d-d5f280f6c97b","url":"https://www.speedtest.net/result/c/841f35c7-9e7a-4989-8a4d-d5f280f6c97b"}}"
Ok, because i only see this kind of errors when something with timers or cron isn‘t correct.
I‘m not sure what openHAB wants to tell you with this line:
I just opened this in Visual Studio Code again and now I get this error
"Type mismatch: cannot convert from BigDecimal to float",
It seems to be complaining about the calculations
down = (down / calc) & up = (up / calc)
Should calc be defined as a Float?
Ok, there is something fundamentally different with my system, I deleted my speedtest.rules and only used your code and same result.
I’ll need to delve deeper…
I played around with the values a lot before posting my solution and this was the only working combination.
Edit: I changed the timestamp update to use the timestamp from the json instead of an now
function.
Make sure you installed the JSONPath transformation.
If th eJSONPath transform is not installed openhab throws this error, because the rule engine can’t handle the input string.
Edit: @Bredmich you should add the requirement of having the JSONPath transform installed.
Thanks for the hint!
I didn´t know that the JSONPath Transformation wasn´t part of the base installation of oH.
Edit: Added JSONPath Transformation to the requirements
Regarding --accept-license --accept-gdpr
I think some people may have problems because OH runs it as ‘openhab’ user.
Solution would be sudo -u openhab speedtest
and then accept agreements.
Then there should be no issue with it. I hope it may help someone.
Thanks for the info!
I added a note to use the openhab user for the initial speedtest.