Skip to content

Instantly share code, notes, and snippets.

@o9-9
Created August 18, 2025 22:29
Show Gist options
  • Select an option

  • Save o9-9/46f23f38074d73f54eee81ca9fe853e0 to your computer and use it in GitHub Desktop.

Select an option

Save o9-9/46f23f38074d73f54eee81ca9fe853e0 to your computer and use it in GitHub Desktop.

Revisions

  1. o9-9 created this gist Aug 18, 2025.
    14 changes: 14 additions & 0 deletions Dockerfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    FROM rust:1.31

    WORKDIR /usr/src
    RUN git clone https://github.com/nelsonjchen/speedtest-rs
    WORKDIR ./speedtest-rs

    RUN cargo install --path .

    ADD entrypoint.sh /opt/speedtest2mqtt.sh
    RUN apt-get update && \
    apt-get install -y mosquitto-clients && \
    chmod 777 /opt/speedtest2mqtt.sh

    CMD ["/opt/speedtest2mqtt.sh"]
    38 changes: 38 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    Build and fire up the container stack with `docker-compose up --build -d`.

    Configuration can be done through `environment` variables in `docker-compose.yml`:

    * `MQTT_HOST` - mqtt server, defaults to `localhost`
    * `MQTT_ID` - id to use for connecting to mqtt server, defaults to `speedtest`
    * `MQTT_TOPIC` - topic to push data to, defaults to `speedtest/status`
    * `MQTT_OPTIONS` - additional mqtt options, defaults to `-V mqttv311`
    * `MQTT_USER` - user for mqtt server
    * `MQTT_PASS` - password for mqtt server
    * `SPEEDTEST_OPTIONS` - additional options for `speedtest-rs`
    * `SPEEDTEST_INTERVAL` - interval in which to run speedtest, in seconds, defaults to 60

    Configuration of sensors in Home Assistant:

    ``` yaml
    sensor:
    - platform: mqtt
    state_topic: speedtest/status
    unit_of_measurement: ms
    icon: mdi:speedometer
    name: Speedtest Ping
    value_template: "{{ value_json.ping }}"

    - platform: mqtt
    state_topic: speedtest/status
    unit_of_measurement: Mbit/s
    icon: mdi:speedometer
    name: Speedtest Download
    value_template: "{{ value_json.download }}"

    - platform: mqtt
    state_topic: speedtest/status
    unit_of_measurement: Mbit/s
    icon: mdi:speedometer
    name: Speedtest Upload
    value_template: "{{ value_json.upload }}"
    ```
    8 changes: 8 additions & 0 deletions docker-compose.yml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    version: '2.1'

    services:
    speedtest-rust:
    build: .
    container_name: speedtest-rust
    environment:
    - SPEEDTEST_INTERVAL=1200
    48 changes: 48 additions & 0 deletions entrypoint.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    #!/bin/sh

    MQTT_HOST=${MQTT_HOST:-localhost}
    MQTT_ID=${MQTT_ID:-speedtest}
    MQTT_TOPIC=${MQTT_TOPIC:-speedtest/status}
    MQTT_OPTIONS=${MQTT_OPTIONS:-"-V mqttv311"}
    MQTT_USER=${MQTT_USER:-""}
    MQTT_PASS=${MQTT_PASS:-""}

    SPEEDTEST_OPTIONS=${SPEEDTEST_OPTIONS:-""}
    SPEEDTEST_INTERVAL=${SPEEDTEST_INTERVAL:-60}

    SPEEDTEST_CMD="/usr/local/cargo/bin/speedtest-rs $SPEEDTEST_OPTIONS"
    MQTT_CMD="/usr/bin/mosquitto_pub"

    while true; do
    echo "Running $SPEEDTEST_CMD..."
    output=$($SPEEDTEST_CMD)

    echo "--- Output: -------------------------------------------------"
    echo $output
    echo "-------------------------------------------------------------"

    download=$(echo $output | sed -n -r 's/.*Download: ([0-9]+\.[0-9]+).*/\1/p')
    upload=$(echo $output | sed -n -r 's/.*Upload: ([0-9]+\.[0-9]+).*/\1/p')
    ping=$(echo $output | sed -n -r 's/.*Hosted by .*: ([0-9]+\.[0-9]+) ms.*/\1/p')
    payload="{\"upload\": $upload, \"download\": $download, \"ping\": $ping}"

    echo
    echo "--- Parsed result -------------------------------------------"
    echo "Ping: $ping ms"
    echo "Download: $download MBit/s"
    echo "Upload: $upload MBit/s"
    echo "-------------------------------------------------------------"
    echo "Payload: $payload"
    echo "-------------------------------------------------------------"

    echo
    echo "Sending data to MQTT @ $MQTT_HOST/$MQTT_TOPIC..."

    echo $payload | $MQTT_CMD -h ${MQTT_HOST} -i ${MQTT_ID} -l -t ${MQTT_TOPIC} ${MQTT_OPTIONS} -u ${MQTT_USER} -P ${MQTT_PASS}

    echo
    echo "Sleeping $SPEEDTEST_INTERVAL seconds..."
    echo

    sleep $SPEEDTEST_INTERVAL
    done