DSL Speedtest manuell in Home Assistant einbinden

DSL Speedtest manuell in Home Assistant einbinden

In meiner Home Assistant Installation habe ich Sensoren für die Messung meiner DSL Download- und Upload-Geschwindigkeit definiert. Dazu habe ich bisher die Integration für Speedtest.net verwendet. Die Ausführung der Messung innerhalb von Home Assistant hat in meinen Augen einen entscheidenden Nachteil: läuft HA z.B. wie bei mir in einer virtuellen Maschine, kann die Virtualisierung die gemessene Geschwindigkeit negativ beeinflussen. So habe ich regelmäßig unrealistische Werte bekommen.

Daher wollte ich die Messung nicht mehr innerhalb einer virtuellen Maschine ausführen und ich habe die Messung direkt auf dem Proxmox Host eingerichtet. Die gemessenen Daten werden dann per MQTT an Home Assistant übermittelt. Natürlich kann auch ein beliebiger anderer Rechner, der permanent aktiv ist, verwendet werden.

Voraussetzungen

Zunächst einmal braucht man einen MQTT-Broker, z.B. Mosquitto. Dieser kann z.B. als Add-On innerhalb von Home Assistant installiert werden. Ich gehe darauf nicht weiter ein, da es dazu genügenden Tutorien gibt.

Auf dem Proxmox Host werden zwei zusätzliche Komponenten benötigt: der Speedtest-Client und ein MQTT-Client zum Senden der gemessenen Daten.

Speedtest-Client

Die Installation des Speedtest-Clients ist sehr einfach und auf der Webseite von Speedtest.net beschrieben: https://www.speedtest.net/apps/cli

Der Speedtest-Client ermittelt für die Messung automatisch einen Server, der sich möglichst in der Nähe befindet. Welche verwendet wird, kann man den zurückgelieferten Daten entnehmen.

MQTT-Client

Als MQTT-Client verwende ich den Mosquitto-Client. Dieser lässt sich auf Proxmox einfach mit apt install mosquito-client installieren.

Messung durchführen und Daten an den MQTT-Broker senden

Für die Ausführung der Messung reicht es aus, Speedtest auf der Kommandozeile auszuführen:

$ speedtest -f json

Durch den Parameter -f json wird das Ergebnis der Messung im JSON-Format ausgegeben. Die Messung dauert übrigens ein paar Sekunden. Zum Testen kann speedtest auch ohne Parameter ausgegeben werden, dann kann man die Messung in der Console verfolgen.

Die so erhaltenen Daten können dann direkt an den MQTT-Broker geschickt werden, z.B.

$ speedtest -f json | mosquitto_pub \
       -h 192.168.2.16 \
       -u <User ID> -P <Kennwort> \
       -t homeassistant/speedtest -s

mosquitto_sub ist der Befehl, mit dem Daten den Broker geschickt werden. Er benötigt folgende Parameter:

  • -h ist die IP-Adresse des MQTT-Brokers; wenn der Broker nicht den Port 1833 verwendet, muss zusätzlich noch mit dem Parameter -p der Port angegeben werden.
  • -u und -P sind die User ID und das Kennwort, die im Broker definiert sind.
  • -t enthält das "MQTT-Topic". Der Wert kann im Prinzip frei gewählt werden, muss jedoch exakt so in der MQTT-Konfiguration in Home Assistant verwendet werden.
  • -s mit diesem Parameter wird mosquitto_pub mitgeteilt, dass die zu versendenden Daten ("Payload") über stdin übergeben werden.

Um die Messung in regelmäßigen Abständen auszuführen, kann man auf Linux cron verwenden. Dazu habe ich den Speedtest-Aufruf in ein Shell-Script (/usr/local/bin/runspeedtest) geschrieben und dieses dann per crontab -e in die cron-Tabelle aufgenommen:

0 0-23/2 * * * /usr/local/bin/runspeedtest >/dev/null

Durch die Angabe 0-23/2 wird die Messung alle zwei Stunden ausgeführt. Eine recht gute Unterstützung bei der Erstellung von crontab-Einträgen gibt es hier: https://crontab.guru/.

Konfiguration in Home Assistant

Als letztes müssen noch passende Sensoren in Home Assistant definiert werden. Das geht in diesem Fall nur über die configuration.yaml.

Für die MQTT-Sensoren habe ich eine separate Konfigurationsdatei (config_mqtt.yaml) erstellt und diese in der configuration.yamlwie folgt referenziert:

mqtt: !include config_mqtt.yaml

In der config_mqtt.yaml habe ich zwei Sensoren definiert: je einen für die Download- und Upload-Geschwindigkeit:

sensor:
  - name: "Download Speed"
    state_topic: "homeassistant/speedtest"
    unique_id: dslspeed_down
    value_template: "{{ (value_json.download.bandwidth / 131072) | round(2) }}"
    unit_of_measurement: "Mbit/s"
    device_class: "data_rate"
    state_class: "measurement"
    icon: "mdi:speedometer"
    device:
      name: "DSL Speedtest"
      identifiers:
        - "Telekom"
  - name: "Upload Speed"
    state_topic: "homeassistant/speedtest"
    unique_id: dslspeed_up
    value_template: "{{ (value_json.upload.bandwidth / 131072) | round(2) }}"
    unit_of_measurement: "Mbit/s"
    device_class: "data_rate"
    state_class: "measurement"
    icon: "mdi:speedometer"
    device:
      name: "DSL Speedtest"
      identifiers:
        - "Telekom

Ich werde jetzt nicht jeden einzelnen Eintrag erklären, da man die Informationen auch in der Home Assistant Dokumentation findet kann. Wichtig sind allerdings diese Einträge:

  • state_topic: dieser Wert enthält den Namen des MQTT-Topics und muss mit dem Wert übereinstimmen, der beim Aufruf von mosquitto_pubim Parameter -t übergeben wurde.
  • value_template: Speedtest liefert einen JSON-Zeichenkette zurück. Mit dem Ausdruck value_json.download.bandwidth wird innerhalb der JSON-Struktur zum Wert für die Download-Bandbreite navigiert und der Wert zurückgeliefert.
    Speedtest liefert den Wert als Bytes/s zurück. Der Sensor soll aber Mbit/s zurückliefern, daher muss der Wert durch 131072 (= 1024 * 1024 / 8) dividiert werden.
  • unique_id: damit Sensoren als Entitäten in der Home Assistant-Oberfläche angezeigt werden, müssen sie jeweils eine eindeutige ID haben.
  • Die device-Angaben sind zwar nicht zwingend nötig, aber durch diese Angaben wird für die MQTT-Integration ein Gerät "DSL Speedtest" erzeugt, das dann die beiden Sensoren enthält.
    Das macht die Verwaltung der verschiedenen MQTT-Sensoren etwas einfacher.

Speedtest.net liefert in der JSON-Zeichenkette noch weitere Daten zurück. Bei Bedarf können weitere Sensoren hinzugefügt werden, die diese Daten enthalten. Es muss dann jeweils nur ein passendes value_template definiert werden.