Add the official speedtest cli

Thanks to everyone for their assistance, I have it working on my RPi4 now. Summary of steps I used (for others on same platform, assume you have Terminal installed and Samba for a connected Windows 10/11 PC, with a drive mapped for \config):

On PC:

  1. Download compressed .tgz image from Speedtest CLI: Internet speed test for the command line, which for the RPi4 is under “Linux download / aarch64”.
  2. Open image (content is a .tar file).
  3. Connect to your HASSOS RPi, and under \config create folders \3rdparty\speedtest.
  4. Extract .tar file contents (3 files, speedtest.*) to the new directory \config\3rdparty\speedtest .

On HA, use Terminal:

  1. I had to make speedtest executable using chmod +x speedtest .
  2. Execute speedtest (to accept licences, typing “YES”) using ./speedtest .

Using HA File Editor, add all YAML config as shown in @ptr727’s post above Add the official speedtest cli - #27 by ptr727.

Lastly, restart HASSOS then add the new entities (I use dashboard option to locate “Unused entities”) to a card.

3 Likes

Glad you got it working, I updated my post with more details on how to download and extract the binary, and to pick the right platform.

Thank for your solution, it’s working great for me. I do have questions:
How to get the value for the server id and the last time of execution.
I’m also trying to get speedtest on demand working using a call-service link to this

shell_command:
   launch_speedtest_cli: /config/shell_commands/speedtest --format=json --accept-license --accept-gdpr

it seem to call the service but doesn’t update the sensors

  json_attributes:
    - 'download'
    - 'upload'
    - 'server_name'
    - 'isp'

- sensor:
  - name: Speedtest Download
    state: '{{ state_attr("sensor.speedtest_ping", "download") | round(2) }}'
    unit_of_measurement: Mbit/s
  - name: Speedtest Upload
    state: '{{ state_attr("sensor.speedtest_ping", "upload") | round(2) }}'
    unit_of_measurement: Mbit/s

In sensor, how to get a sensor for

    - 'server_name'
    - 'isp'

Thank you

Here it is:

  - name: Speedtest ISP
    state: '{{ state_attr("sensor.speedtest_ping", "isp") }}'
  - name: Speedtest Server Name
    state: '{{ state_attr("sensor.speedtest_ping", "server_name") }}'

Thank you,
That work perfectly but both return values were the same so I had to change a line in:
Speed Test Results - (from returned JSON string)
FROM: server_name = st_results[“server”][“name”]
TOL server_name = st_results[“server”][“location”]

ISP is your internet provider and server name is the one you are using to test the speed. Some providers also host speedtest servers so might be the same in your case.

In case anyone is interested I’ve created a wrapper to run official speedtest.net cli and post results to HA via MQTT with auto discovery. No configuration on HA side needed.
https://hub.docker.com/rep…/docker/adorobis/speedtest2mqtt
and here the repo:
https://github.com/adorobis/speedtest-CLI2mqtt
Feel free to comment and contribute :slight_smile:

2 Likes

Thanks for sharing it helped a lot

This looks promising. I need to run it on a different box that has a faster nic then my HA setup, how can I send the results to mqtt on my HA box?

n/m figured it out. Thanks, this is awesome!

1 Like

Ok, I’ve managed to install the docker container via Portainer and its running but how do I call the test to run from within HA ? Do I need to call a Python script to get it to run ?

Just came across this as I was looking to do the same! Thanks for the good work - it works flawlessly!

mb

1 Like

You don’t call it, you have to configure the parameters of your mqtt broker in the config.ini file as well as some other parameters and it will run at the frequency you specify. See some example file in the repo:

1 Like

Thank you, All sorted now.

Would that be worth adding to your GH repo to advise others ?

1 Like

Of course! Will do it in free time but feel free to contribute. You have it fresh :blush:

Hi, something happened on latest docker version. It nomore starts:

Successfully connected to MQTT broker
Running Speedtest
Traceback (most recent call last):
  File "/usr/src/app/./speedtest.py", line 308, in <module>
    run_speedtest()
  File "/usr/src/app/./speedtest.py", line 67, in run_speedtest
    process = subprocess.Popen([SPEEDTEST_PATH,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/subprocess.py", line 1024, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.11/subprocess.py", line 1901, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'speedtest'
Successfully connected to MQTT broker
Running Speedtest
Traceback (most recent call last):
  File "/usr/src/app/./speedtest.py", line 308, in <module>
    run_speedtest()
  File "/usr/src/app/./speedtest.py", line 67, in run_speedtest
    process = subprocess.Popen([SPEEDTEST_PATH,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/subprocess.py", line 1024, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/lib/python3.11/subprocess.py", line 1901, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'speedtest'

I’m trying to create the docker container locally from Dockerfile and try to use it…

EDIT:
Ok I figured it out: latest commit changed the SPEEDTEST_PATH value on config.ini and this is a breaking change!

image

1 Like

Indeed, latest docker image is based on alpine therefore 2.5 times smaller but it required the parameter change. Need to figure out how to automate it in the Docker file (if possible) Any fresh deployment will take correct ini file.

I tried doing this in August 2023. and it failed.i tried quite a few things, and basically “sensors.yaml” isn’t being read, maybe i don’t understand that. so i tried putting it in configuration.yaml, that gave me errors. and i realized i needed to reformat the command_line scenario. so here is what i now have as my code, this all goes inside the configuration.yaml. I took @ptr727 's post, but got it working again

The second half of this is exactly the same, it’s just the top half (the command_line portion)

# SpeedTest.net CLI
# this section runs the command every 20 minutes
# https://www.speedtest.net/apps/cli
# Template sensors are in configuration.yaml
# Download and test, use binary matching platform, e.g. for x86_64
# wget -qO- https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-x86_64.tgz | tar xvz
# ./speedtest --accept-license --accept-gdpr
# Copy binary to desired HA config folder
# mkdir -p /config/3rdparty/speedtest
# cp ./speedtest /config/3rdparty/speedtest/
command_line:
  - sensor:
      command: '/config/3rdparty/speedtest/speedtest --format=json'
      name: SpeedTest CLI Data
      unique_id: speedtest_cli_data
      command_timeout: 60
      scan_interval: 1200
      value_template: >-
        {{
          {
            "ping": value_json.ping.latency,
            "download": value_json.download.bandwidth,
            "upload": value_json.upload.bandwidth
          }
          | to_json
        }}


# SpeedTest.net CLI
# this section converts the data to sensors for adding to the dashboard.
# https://www.speedtest.net/apps/cli
# Command_line sensor is in sensors.yaml
template:
  - sensor:
    - name: 'SpeedTest CLI Ping'
      unique_id: speedtest_cli_ping
      icon: mdi:speedometer
      # TIME_MILLISECONDS: Final = "ms"
      unit_of_measurement: ms
      state_class: measurement
      state: "{{ (states('sensor.speedtest_cli_data') | from_json).ping | round(2) }}"
    - name: 'SpeedTest CLI Download'
      unique_id: speedtest_cli_download
      icon: mdi:speedometer
      # DATA_RATE_MEGABITS_PER_SECOND: Final = "Mbit/s"
      unit_of_measurement: Mbit/s
      state_class: measurement
      state: "{{ ((states('sensor.speedtest_cli_data') | from_json).download * 8 / 1000 / 1000) | round(2) }}"
    - name: 'SpeedTest CLI Upload'
      unique_id: speedtest_cli_upload
      icon: mdi:speedometer
      unit_of_measurement: Mbit/s
      state_class: measurement
      state: "{{ ((states('sensor.speedtest_cli_data') | from_json).upload * 8 / 1000 / 1000) | round(2) }}"

FYI: Their version of 1.2.0 is still the latest. you can validate what version by going here…
https://www.speedtest.net/apps/cli
Then going down to “download speedtest-cli” and clicking linux. you will then click the version you need. for me it was x86_64 as i’m on an intel processor laptop. but if you’re using Raspberry Pi i believe you want armel but i would double check. - a post above says raspi 4 uses aarch64

still works as of 2023.9.0

1 Like

Hello

I have some problems on deploying the container.

Tried it on Debian 12 and Alpine 3.18.

speedtest:/speedtest# docker-compose up speedtest
[+] Running 1/0
 ✔ Container speedtest  Created                                                                                        0.0s 
Attaching to speedtest
speedtest  | Traceback (most recent call last):
speedtest  |   File "/usr/src/app/./speedtest.py", line 22, in <module>
speedtest  |     refresh_interval = int(config['DEFAULT']['REFRESH_INTERVAL']) # Interval in seconds at which speedtest will be run
speedtest  |                            ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
speedtest  |   File "/usr/local/lib/python3.12/configparser.py", line 1222, in __getitem__
speedtest  |     raise KeyError(key)
speedtest  | KeyError: 'REFRESH_INTERVAL'
speedtest exited with code 0

my docker-compose.yml:

speedtest:/speedtest# cat docker-compose.yml 
services:
  speedtest:
    container_name: speedtest
    image: adorobis/speedtest2mqtt:latest
    restart: unless-stopped
    volumes:
      - /speedtest/config:/usr/src/config

Any ideas?