Speedtest-cli Internet Up-/Downlink Measurement Integration

This is not a typo and is correct and appropriate as written. Use “val” when you have a variable that should never be reassigned. In this case filename is a constant so val is appropriate.

It’s unnecessary. The timer is never referenced again. It is never checked and never cancelled so there is no need to assign it to a variable. You can if you want to be it doesn’t do anything for you.

1 Like

yup thanks Rich :slight_smile:

@mboremski if you are interested check out:

i need to cheer for your willingness to contribute, not many do that. My examples are far from perfect and if you ever find room for improvement, shoot :wink:

2 Likes

Thanks, yes thats probably a better solution for checking more often.

And no, dont really want to run the speedtest every 5min :wink:

In fact, as I run Openhab on a Pi3 I might need to move the speedtest off openhab (still feed the data into the db) as it only has a 100mbit ethernet (I have, or should have, a 250/100 link).

Sorry, I’m just learning. Tell me please where to copy the code below?

Rule (Linux speedtest.rules)

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("⁉ (unbekannt)")
    ]
end

I recommend the Beginner’s Tutorial, and the User’s Guide in the docs site. There will almost certainly be other similar fundamental questions you will face soon.

To answer your specific question, if you installed on Linux using apt or yum the file goes in /etc/openhab2/rules.

If installed manually or on another OS it goes in the conf/rules folder under wherever you unzipped OH to.

1 Like

Thank you! It turns out it’s not two different files (two blocks of code as the author of the article showed), but one file. I put it in the rules folder and it all worked. But unfortunately the data record does not work in influxdb (collectd works) and openhab does not transfer data to the database. The empty database is created from scratch and a separate openhab user is created for it, all privileges are set for both writing and reading.

Sys: Ubuntu Server 16.04.3 X64
openhab: 2.1.0

Openhab2:
1. Install influxdb persistence

2. The data in the file is filled: influxdb.cfg

url=http://127.0.0.1:8086
user=openhab
password=mypass
db=openhab
retentionPolicy=autogen

3. influxdb.persist:

    Strategies {
        everyMinute : "0 * * * * ?"
        everyHour   : "0 0 * * * ?"
        everyDay    : "0 0 0 * * ?"
        default = everyMinute
    }

    Items {
        gInfluxDB* : strategy = everyChange, everyMinute
        Presence_Phone : strategy = everyChange
    }

4. SpeedTest.items

Group gSpeedtest <"network-icon"> (Whg)

String      SpeedtestSummary        "Ск.Инта: [%s]"             <"speedtest_network">       (gSpeedtest, gInfluxDB)
Number      SpeedtestResultPing     "Ping [%.3f ms]"             <"speedtest_next5">         (gSpeedtest, gInfluxDB)
Number      SpeedtestResultDown     "Downlink [%.2f Mbit/s]"     <"speedtest_download">      (gSpeedtest, gInfluxDB)
Number      SpeedtestResultUp       "Uplink [%.2f Mbit/s]"       <"speedtest_upload">        (gSpeedtest, gInfluxDB)
String      SpeedtestRunning        "Speedtest запущен ... [%s]" <"speedtest_new">           (gSpeedtest)
Switch      SpeedtestRerun          "Ручной запуск"              <"speedtest_reload2">       (gSpeedtest)
DateTime    SpeedtestResultDate     "История: [%1$td.%1$tm.%1$tY в %1$tH:%1$tM]"   <"speedtest_problem4">      (gSpeedtest, gInfluxDB)

5. sudo systemctl status influxdb:

No data db openhab:

root@edgi-server:/etc/openhab2/items# influx
Connected to http://localhost:8086 version 1.4.0~n201709010800
InfluxDB shell version: 1.4.0~n201709010800
> auth
username: openhab
password:
> use openhab
Using database openhab
> show measurements
>
>
>

nothing no data from openhab

First make sure to reboot OH. There is some weird behavior right now with groups where changes in group membership are not picked up properly until a reboot.

no work. reboot OH did not help
there are more ideas? can provide some more data? I need very much what would have worked, I have been fighting for many days.

I’m no expert on this stuff. I’m out of ideas.

Hey @edgi I noticed that you have quotation marks inside categories/icons section here.

Instead of

String      SpeedtestSummary        "Ск.Инта: [%s]"             <"speedtest_network">       (gSpeedtest, gInfluxDB)
Number      SpeedtestResultPing     "Ping [%.3f ms]"             <"speedtest_next5">         (gSpeedtest, gInfluxDB)

you should probably write

String      SpeedtestSummary        "Ск.Инта: [%s]"             <speedtest_network>       (gSpeedtest, gInfluxDB)
Number      SpeedtestResultPing     "Ping [%.3f ms]"            <speedtest_next5>         (gSpeedtest, gInfluxDB)

Cheers

Thank you! My icons work with both quotation marks and without quotes. It did not affect the record in the database. It is not written. Empty. And rebooting the demons did not help either.

Is anyone running this on a separate computer/server and importing the information into the openhab server?

Hey @lysol, I do not but let me know what’s your actual question and we can probably work something out.

The easiest is probably to install a small openHAB instance on the second device, then send data over to the main instance. Another option would be to write a small script executed on the second device, that would then send data to the main openHAB system via openHAB REST API or MQTT. You’d need to write a small script for that yourself.

1 Like

I used to use sensorReporter with the execActuator. But my connection was super stable so I stopped running it as it didn’t provide any benefit.

I can dig up my old configs and scripts if you would like.

This is basically @ThomDietrich’s second option, only you wouldn’t need to write it yourself since I already have. :slight_smile:

1 Like

Don’t really have another question. Was curious as one of my HABpanel dashboards is sort of a “Home Status” page that I can get uncommon information related to the status/health of our “home”. While it’s not that big of a deal in a home environment, I like to practice separation of roles. In this sense, having this on a separate (and more powerful) server would make sense to me. I’ll mess around with it when I get time and see what I can come up with.

Thanks! I’ll take a look at it.

OK, I had a look and I set it up before I started running OH in Docker so I was using the executeCommandLine to run the program. So here is a quick set of configs that should get you close. I’m just typing these in so there will likely be errors.

sensorReporter.ini

NOTE: This is just the config for the execActuator, you will need to include all the other config sections as well.

[Actuator1]
Class: execActuator.execActuator
Type: Exec
Connection: MQTT
Poll: 0
Command: /usr/local/bin/speedtest-cli --simple
CMDTopic: scripts/speedtest-cli/cmd
ResultTopic: scripts/speedtest-cli/results

I’m pretty sure that the code will not time out as speedtest takes awhile to run. If it does timeout let me know and I’ll update the code.

Items
NOTE: the below Items use an overly complicated naming scheme I used to use. Ignore the N_V crap.
NOTE2: Change the mqtt configs below to match yours

    String      RunSpeedTest     { mqtt="<[broker:scripts/speedtest-cli/cmd:*:default]" } // Strings passed to this Item are command line arguments to speedtest_cli
    String      SpeedTestResults { mqtt="<[broker:scripts/speedtest-cli/results:command:default]" }

    String		N_V_Speedtest_Summary		"Speedtest [%s]"				<network>
    Number		N_V_Speedtest_Ping			"Ping [%.3f msec]"				<network> (gChart)
    Number		N_V_Speedtest_Download		"Download [%.2f Mb/s]"			<network> (gChart)
    Number		N_V_Speedtest_Upload		"Upload [%.2f Mb/s]"			<network> (gChart)
    String		N_V_Speedtest_Running		"Speedtest running ... [%s]"	<network>
    Switch 		T_C_Speedtest_Start			"Start Speedtest"				<network>
    DateTime	N_V_Speedtest_Lastupdate	"Last Speedtest [%1$tm/%1$td/%1$tY %1$tT]" <clock>

Rules

rule "Initialize Speedtest"
when
    System started
then
    if(N_V_Speedtest_Summary.state == NULL || N_V_Speedtest_Summary.state == "") N_V_Speedtest_Summary.postUpdate("NA")
end

rule "Run Speedtest"
when
    Time cron "0 0 */1 * * ?" or // not sure about this cron expression, I had it set to run every 15 minutes in my last version
    Item T_C_Speedtest_Start received command
then
    RunSpeedTest.sendCommand("")
    N_V_Speedtest_Running.postUpdate("Running...")
end

rule "Process Speedtest Results"
when
    Item SpeedTestResults received update
then
    N_V_Speedtest_LastUpdate.postUpdate(new DateTimeType())
    
    val results = SpeedTestResults.state.toString
    if(results != "" && results.length >= 3 && results != "ERROR") {
        val parts = results.split("\n")
        val float ping = Float::parseFloat(parts.get(0).split(" ").get(1))  // I would do this differently these days, see the Type Conversions thread for details
        val float down = Float::parseFloat(parts.get(1).split(" ").get(1))
        val float up   = Float::parseFloat(parts.get(2).split(" ").get(1))

        N_V_Speedtest_Ping.postUpdate(ping)
        N_V_Speedtest_Download.postUpdate(down)
        N_V_Speedtest_Upload.postUpdate(up)
        N_V_Speedtest_Summary.postUpdate(String::format("ᐁ  %.1f Mbit/s  ᐃ %.1f Mbit/s (%.0f ms)", down, up, ping))
    }
    else if(results == "ERROR"){
        logError("Speedtest", "speedtest-cli returned an error code, see sensorReporter logs for details")
        N_V_Speedtest_Summary.postUpdate("ERROR")
    }
    else {
        logError("Speedtest", "Failed to parse results from speedtest-cli: " + results)
        N_V_Speedtest_Summary.postUpdate("Failed to Parse")
    }
    
    N_V_Speedtest_Running.postUpdate("-")
end
1 Like

Thanks a lot for this tutorial. Worked flawlessly.
One thing which is a bit unrelated but as it happens here I’m wondering if anybody knows a nice solution.
Now in the Android app on the phone in landscape mode the item overflows the text “Speedtest” and the results while in wider UIs or in landscape it looks perfectly fine. Does OpenHAB have any way to avoid that or is this an issue which would need to be handled in the app?

Hello!

As far as I know, that’s the problem in HABDroid. I’m having it with a speedtest, but also with a longer TV Shows and Movies name when using Plex binding. You could add \n at the begining, so it would start a new line, but it is useful only for a text that could fit in one line itself - in case a length of caption + item text is too long.

Best regards,
Davor

This is a bug with the android app. It should be able to handle longer strings, e.g. by wrapping and scrolling it. Would you please comment and ask for a solution here: https://github.com/openhab/openhab.android/issues/169