. Netzwerk – Smarthome

bookmark_borderSpeedtest mit OpenHAB – neu

Nach mehreren Versionen der Implementierung eines dauerhaften Speedtests bin ich im OpenHAB Forum wieder auf einen sehr guten Artikel gestoßen. Seit ich den Speedtest anhand dieses Artikels eingerichtet habe läuft nun alles super.
Man muss dazu nur ein paar Vorbereitungen treffen:

sudo apt-get install gnupg1 apt-transport-https dirmngr
export INSTALL_KEY=379CE192D401AB61
# Ubuntu versions supported: xenial, bionic
# Debian versions supported: jessie, stretch, buster
export DEB_DISTRO=$(lsb_release -sc)
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys $INSTALL_KEY
echo "deb https://ookla.bintray.com/debian ${DEB_DISTRO} main" | sudo tee  /etc/apt/sources.list.d/speedtest.list
sudo apt-get update
# Other non-official binaries will conflict with Speedtest CLI
# Example how to remove using apt-get
# sudo apt-get remove speedtest-cli
sudo apt-get install speedtest

Anschließend kann man sich mit

speedtest -L

eine Liste der Server anzeigen lassen die in der Nähe sind. Um sich einen festen Server auszusuchen. Diesen merken wir uns. Geht natürlich auch ohne aber ich mache es lieber so. Nun noch die Items anlegen. Die sehen bei mir so aus

String      SpeedtestSummary        "FRITZ!Box [%s]"             <network>       
Number      SpeedtestResultPing     "Ping [%.3f ms]"             <"speedtest_ping">                
Number      SpeedtestResultDown     "Downlink [%.2f Mbit/s]"     <"speedtest_download">  
Number      SpeedtestResultUp       "Uplink [%.2f Mbit/s]"       <"speedtest_upload"> 
String      SpeedtestRunning        "Speedtest running ... [%s]" <"speedtest_run">           
String      SpeedtestTestServer     "Testserver [%s]"            <"speedtest_summary">             
Switch      SpeedtestRerun          "Start manuell"              <"speedtest_reload">      
DateTime    SpeedtestResultDate     "letzter Test [%1$td.%1$tm.%1$tY, %1$tR Uhr]"   <"speedtest_date">
String      SpeedtestResultError    "Error Message [%s]"         <"speedtest_error">   

Danach kommt dann das anlegen der eigentlichen Regel, die bei mir so aussieht. In Zeile 12 „–accept-license –accept-gdpr“ muss man nicht unbedingt jedesmal mitgeben. Klappt bei mir aber Problemlos wenn ich das einfach dauerhaft mitgebe und dann kann ich es bei Updates etc auch nicht vergessen.

rule "Speedtest"
when
 
    Time cron "0 0 * * * ?" or
    Item SpeedtestRerun changed from OFF to ON or
    Item SpeedtestRerun received command ON

then
    SpeedtestRunning.postUpdate("Messung läuft...")

 system
	val speedtestExecute = "speedtest --accept-license --accept-gdpr -s 33264 -f json"	//Hochschule Trier
    var speedtestCliOutput = executeCommandLine(speedtestExecute, 120*1000)

    SpeedtestRunning.postUpdate("Datenauswertung...")

    // starts off with a fairly simple error check, should be enough to catch all problems I can think of
    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 server = transform("JSONPATH", "$.server.name", speedtestCliOutput) + ', ' + transform("JSONPATH", "$.server.location", speedtestCliOutput)
		SpeedtestTestServer.postUpdate(server)

        SpeedtestSummary.postUpdate(String::format("ᐁ%.1f  ᐃ%.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("(unbekannt)")
        SpeedtestRunning.postUpdate("Fehler")

        logError(ruleId, "--> speedtest failed. Output:\n" + speedtestCliOutput + "\n\n")
    }

    SpeedtestRerun.postUpdate(OFF)
end

bookmark_borderSpeedtest in OpenHAB

Es gibt einen neuen Artikel zum Thema Speedtest mit OpenHAB – neu

Heute habe ich mich auf die Suche gemachte wie ich einen automatischen Speedtest in mein OpenHAB integrieren kann. Auf der Suche bin ich hier über den Beitrag in der OpenHAB Community gestoßen.
Es funktionierte auch alles so weit, nur der gemessene Upload war sehr langsam. Nach weiterem Suchen bin ich darauf gestoßen dass es möglicherweise an der Art wie ich speedtest-cli installiert habe. Nämlich über apt-get. Nun habe ich das python Script wie hier beschrieben geladen und ausführbar gemacht.

wget https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py
chmod +x speedtest.py

Danach das Script einmal testen

speedtest.py 

Nun muss man sich einen Server aus der Liste aussuchen weil die Auswertung im folgenden auf Grund unterschiedlicher Server-Namen nicht funktioniert

speedtest.py --list | grep "Germany"

Aus der Liste sucht man sich einen Server aus. Ich nehme einaml 4997

speedtest.py --server 4997
Retrieving speedtest.net configuration...
Testing from Vodafone Kabel Deutschland (XXX.XXX.XXX.XXX)...
Retrieving speedtest.net server list...
Retrieving information for the selected server...
Hosted by inexio (Saarlouis) [XX.XX km]: 51.842 ms
Testing download speed................................................................................
Download: 154.99 Mbit/s
Testing upload speed................................................................................................
Upload: 37.84 Mbit/s

Abhängig vom Server-Namen muss man dann den Split für den Ping machen und auch die richtigen Zeilen wählen (Siehe hier Code-Zeile 25,26 und 27). Bei mir ist es der 6. Teil der Textzeile 4 für den Ping sowie die Zeilen 6 bzw. 8 für Download bzw. Upload (Man beginnt beim Zählen jeweils mit 0). Ansonsten muss man nur noch in Zeile 23 das „Ping“ durch „Retrieving“ ersetzen.

rule "Speedtest"
when
    //Time cron "0 0 5,13 * * ?" or
    Time cron "0 0 * * * ?" or
    Item SpeedtestRerun received command ON
then
    logInfo("Speedtest", "--> speedtest executed...")
    SpeedtestRunning.postUpdate("Messung läuft...")

    // 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.py --server 4997", 120*1000) //Inexio
    //var String speedtestCliOutput = executeCommandLine("/usr/local/bin/speedtest.py --server 1746", 120*1000)	//Vodafone

    // for debugging:
    //var String speedtestCliOutput = "Ping: 43.32 ms\nDownload: 21.64 Mbit/s\nUpload: 4.27 Mbit/s"
    //logInfo("Speedtest", "--> speedtest output:\n" + speedtestCliOutput + "\n\n")

    SpeedtestRunning.postUpdate("Datenauswertung...")

    // starts off with a fairly simple error check, should be enough to catch all problems I can think of
    if (speedtestCliOutput.startsWith("Retrieving") && speedtestCliOutput.endsWith("Mbit/s")) {
        var String[] results = speedtestCliOutput.split("\\r?\\n")
        var float ping = new java.lang.Float(results.get(4).split(" ").get(6)) //Inexio
        // var float ping = new java.lang.Float(results.get(4).split(" ").get(7)) //Vodafone
        var float down = new java.lang.Float(results.get(6).split(" ").get(1))
        var float up   = new java.lang.Float(results.get(8).split(" ").get(1))
        SpeedtestResultPing.postUpdate(ping)
        SpeedtestResultDown.postUpdate(down)
        SpeedtestResultUp.postUpdate(up)
        SpeedtestSummary.postUpdate(String::format("ᐁ%.1f  ᐃ%.1fMbit/s | %.0f ms", down, up, ping))
        SpeedtestRunning.postUpdate("-")
        logInfo("Speedtest", "--> speedtest finished.")
    } else {
        SpeedtestResultPing.postUpdate(0)
        SpeedtestResultDown.postUpdate(0)
        SpeedtestResultUp.postUpdate(0)
        SpeedtestSummary.postUpdate("(unbekannt)")
        SpeedtestRunning.postUpdate("Fehler bei der Ausführung")
        logError("Speedtest", "--> speedtest failed. Output:\n" + speedtestCliOutput + "\n\n")
    }
    SpeedtestRerun.postUpdate(OFF)
end

bookmark_bordernginx / FRITZ!Box / IPv6

Ich wollte mir nun noch nginx als reverse proxy installieren um den Port 80 auf dem RaspPi direkt zu OpenHAB durchzuleiten. Gesagt getan und mit der IP-Adresse (IPv4) ging das auch sehr flott gemäß der Anleitung hier. Mein Eintrag in der nginx config sieht dann so aus:

server {
    listen                                    80;
    server_name                               IPV4_openhab;

    location / {
        proxy_pass                            http://localhost:8080/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
    }
}

Nur leider ging es dann nicht wenn ich den Hostnamen eingebe. Nach etwas Recherche und einem kurzen Test mit tracert konnte ich sehen, dass die FRITZ!Box den Hostname auf die IPv6-Adresse auflöst. Somit ist ein zusätzlicher Eintrag in der nginx config notwendig der wie folgt aussehen muss. Danach klappt es auch mit IPv6 und dem Hostnamen.

server {
    listen                                    [::]:80;
    server_name                               hostname_openhab;

    location / {
        proxy_pass                            http://localhost:8080/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
    }
}

Edit: Zunächst hat die obige Konfiguration funktioniert. Aber es scheint wohl nicht alles abgefackelt zu sein weshalb meine Konfig nun so aussieht. Damit habe ich hoffentlich alle möglichen Fälle abgedeckt. Zudem leite bei der Eingabe des Host Namen immer direkt auf die Basic UI

server {
    listen                                    80;
    listen                                    [::]:80;
    server_name                               IPV4_openhab;
    location / {
        proxy_pass                            http://localhost:8080/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
        }
    }

server {
    listen                                    80;
    listen                                    [::]:80;
    server_name                               hostname_openhab;

    location = / {
        return 301 /basicui/app;
        }

    location / {
        proxy_pass                            http://localhost:8080/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
        }
    }

bookmark_borderUbiquiti WiFiman

Seit kurzem gibt es eine neue App von Ubiquiti: WiFiman die ich mir für iOS mal etwas angeschaut habe. Die App ist sehr schlank und bietet genau das was man braucht, wenn aus irgend einem Grund das „Internet nicht geht“.

Auf der Statusseite sieht man die eigene IP, den Status der Internetverbindung mit der öffentlichen IP sowie verschieden Server Pings. Die Server zu welchen der Ping erfolgt können auch geändert werden. Dann gibt es auch noch einen graphisch schick gestalteten Speed Test. Hier gibt es nix zu sagen. Sieht gut aus, funktioniert und die letzten Ergebnisse werden gespeichert.

Als letztes gibt es noch den Discovery Tab. Hier sieht mal alle Geräte im Netz und welche Services wie z.b. Bonjour oder UPNP diese bieten und ggf. auch die zugehörigen Ports. Darüber hinaus kann der Ping und die Package Loss Rate auch sehr nützlich sein um Verbindungsprobleme zu erkennen.

Aus meiner Sicht ein nettes kleines Tool. Leider werden die IPv6 Adressen nicht angezeigt, aber geht auch so.

bookmark_borderUniFi Controller als Docker auf der Synology

Nachdem ich etwas über ein Jahr standhaft behauptet habe, dass man den Controller eigentlich nicht auf einem Server installieren braucht und es völlig ausreicht, wenn er lokal läuft, habe ich nun doch meine Meinung geändert. Ich wollte einfach mal das Arbeiten mit Docker Containern auf der Synology ausprobieren und da es den UniFi Controller schon als fertiges Paket gibt habe ich mich dafür entschieden. Dazu habe ich den Container von Jacob Alberty.

Ich habe beim Anlegen des Containers den Netzwerk Bridge Modus belassen aber anschließend alle Ports 1:1 gemappt da die Ports bei mir noch frei waren.

Danach muss man die Geräte noch auf den neuen Controller umziehen. Dazu habe ich die Geräte aus meinem lokalen Controller entfernt. Anschließend ein Backup erstellt um meine Netzwerkeinstellungen während des ersten Starts des neuen Controllers dort zu importieren.
Nach dem Entfernen der Geräte auf dem lokalen Controller muss man mit den UnFi-Discover Tool noch die Inform Adresse ändern, da die Geräte sich sonst nicht von selbst beim neuen Controller melden. Also „http://ip-of-controller:8080/inform“. Jetzt sind alle Vorbereitungen getroffen. Als nächstes beim neuen Controller anmelden „http://ip-of-controller:8080“, das Backup importieren und die Geräte hinzufügen. Fertig.
Das einzige was bei mir verloren ging waren die fest eingestellten WLAN Kanäle und die fixen IP’s, das ist aber schnell wieder erledigt.

 

bookmark_borderGetrenntes Gastnetzwerk mit FRITZ!Box, Netgear und UniFi

Heute möchte ich mich dem Thema widmen wie man sein Gastnetz sauber vom eigenen Netz trennt. Mein Setup besteht aus einer FRITZ!Box 6430 Cable einem Netgear JGS516PE Switch sowie einem UniFi AP AC PRO und einem UniFi AC Mesh AP. Natürlich lässt sich das Ganze auch mit einem etwas anderen Setup aufbauen. Der Router muss nur das Gastnetz auf einem seiner Netzwerk Ports unterstützen und alle anderen Komponenten müsste mit VLAN nach dem Standard IEEE 802.1Q zurechtkommen.

Einstellungen FRITZ!Box

Das WLAN der FRITZ!Box sollte deaktiviert werden, da dies durch die UniFi Access Points bereitgestellt wird und diese im Gegensatz zur FRITZ!Box ein ordentliches Handover ermöglichen. Jeder der schon mal mit mehreren voneinander unabhängigen APs gearbeitet hat kennt bestimmt die Eigenart dieses Setups. Jeder AP versucht das WLAN Gerät so lange wie möglich zu versorgen und erst, wenn gar kein Empfang mehr möglich ist wird die Verbindung gekappt, sodass ein anderer AP übernehmen kann. Bei professionelleren Lösungen wie z.B. den APs von UniFi wird sichergestellt, dass der jeweils beste AP die Verbindung übernimmt, aber dies nur am Rande.

Wichtig für unser Setup ist, dass man unter Heimnetz -> Netzwerkübersicht -> Netzwerkeinstellungen den Gastzugang für LAN 4 aktivieren. Falls gewollt kann hier auch noch die Zustimmung zu den Nutzungsbedingungen erzwungen werden, was ich jedoch nicht benötige. Das wärs dann auch schon. Diese Funktion sollte in allen aktuellen FRITZ!Boxen vorhanden sein. Bei mir ist aktuell die FRITZ!OS: 06.83 installiert.

Einstellungen Switch

Die Einstellungen sind bei meinem JGS516PE über die Weboberfläche unter VLAN -> 802.1Q -> Advanced erreichbar. Wie ihr seht habe ich 2 VLAN IDs eingerichtet. ID 01 ist mein Heimnetz und 10 steht für mein Gastnetz.

Mein Heimnetz ist Standardmäßig auf allen Ports im Modus untagged mit Ausnahme von Port 14, da dieser mit dem LAN Port 4 meiner FRITZ!Box verbunden ist auf der das Gastnetz anliegt. Untagged bedeutet, dass alle Netzwerkpakete ohne Tag, also ohne Marker, dem vom Switch dem VLAN 1 zugeordnet werden. Umgekehrt bedeutet es auch, dass ausgehende Pakete aus VLAN 1 nicht mit einem Tag versehen werden. Dies ist wichtig, da nicht jedes Gerät mit getaggten Paketen umgehen kann. Ein normaler PC sollte beispielsweise keine getaggten Pakete erhalten.

Das VLAN 10 ist untagged auf Port 14, an dem das Gastntz der FRITZ!Box angeschlossen ist und tagged als 2. Netz auf den Ports 3 und 5. Die hier angeschlossenen Kabel transportieren nun beide Netze. Hier sind dann auch meine APs angeschlossen die mit Hilfe des Tags die Pakete dem passenden WLAN zuordnen können.

Nun fehlt nur noch eine Einstellung und zwar die PVID. Hierüber wird gesteuert welchem VLAN das Switch eingehende Netzwerkpakete ohne Tag zuordnet. Hier muss in meinem Fall also überall die 1 stehen mit Ausnahme von Port 14 für das Gastnetz.

Möchtet ihr zusätzlich noch ein Kabelgebundenes Gastnetz etablieren muss der Port der dafür vorgesehen ist auch die PVID 10 bekommen und der Port muss auch im Bereich Membership dem VLAN 10 (untagged) zugeordnet werden und bei 01 gelöscht werden. Solltet Ihr mehrere Switches im Haus verteilt haben können beide Netz auch hier über ein Kabel transportiert werden. Die Einstellungen sind dann analog zu Port 3 bzw. 5 in meinem Beispiel auf beiden Switches vorzunehmen.

Einstellungen Access Points

Die Einstellungen erfolgen bei mir über den UniFi Controller in der Version 5.4.16 unter Einstellungen -> Drahtlose-Netzwerke.

Mein Heimnetz ist dabei keinem VLAN zugeordnet, es ist also untagged. Setzt man hier den Haken für VLAN und gibt ID 01 mit funktioniert das Setup nicht mehr!

Für das Gastnetz ist die VLAN Zuordnung mit der ID 10 aktiv. Auf die weiteren Einstellmöglichkeiten möchte ich hier nicht näher eingehen und somit ist die Trennung der Netzwerke abgeschlossen.

Nun sollte man das ganze einmal testen. Am einfachsten sieht man ob es geklappt hat indem man sich einfach mit jedem WLAN einmal verbindet und schaut welche IP-Adresse man bekommt. Bei der Fritz box sind die Standard IPs für das Heimnetz im Bereich 192.168.178.xxx und für das Gastnetz 192.168.179.xxx.

Stolperfallen bei der Einrichtung

  • Wenn man nicht aufpasst, sperrt man sich währen der Einrichtung selbst aus. Rutscht der PC an dem man arbeitet versehentlich ins Gastnetz kann man sein Switch natürlich nicht mehr erreichen. Das ist zwar gewollt aber im Rahmen der Einrichtung unpraktisch.
  • Das VLAN 01 sollte nicht gelöscht werden.
  • Auf den Ports die mehrere Netzwerke transportieren sollte immer genau ein Netz untagged sein. Hat man hier auch das Netz 01 als tagged eingestellt klappt es nicht, auch wenn die Einstellung für das WLAN entsprechend vorgenommen wurde.