OpenWRT - Status Wifi-Teilnehmer via MQTT an FHEM senden

Begonnen von rob, 13 August 2020, 16:39:12

Vorheriges Thema - Nächstes Thema

rob

Hallo.

Im Titel genannte Umsetzung möchte ich gern teilen. Komme von einer Frage aus dem Anfängerbereich her https://forum.fhem.de/index.php/topic,113454.msg1077873.html#msg1077873. Wollte das nicht direkt dort belassen, damit Einsteiger nicht verleitet werden ausgerechnet damit zu starten.

Darum gehts:
In FHEM soll erkannt werden, ob ein Wifi-Teilnehmer connected ist oder disconnected. Damit kann man dann Anwesenheiten und/oder Notifys bedienen. Während es für die Fritzbox viele schöne Lösungen gibt, schauts für OpenWRT mager aus - nutzen wahrscheinl. nicht so viele.

Vorweg:
Fhem sollte stabil laufen, aktuell sein und eine fixe IP haben (z.B. 192.168.1.10)
OpenWRT ab v17.01 mit ausreichend Platz für die u.s. Pakete
für die Namen zu den MAC-Adressen, habe ich jedem bekannten Teilnehmer statische IP und Namen im Router gegeben*

FHEM
MQTT2-Server definieren

define myMQTT_Server MQTT2_SERVER 1883 global
attr myMQTT_Server autocreate simple


OpenWRT
Pakete installieren, Script anlegen und Dämonen starten

  • login via LuCI --> System --> Paketverwaltung --> Update lists...
  • unter Filter: hostapd-utils eingeben --> Install...
  • erneut unter Filter: mosquitto-client bzw. mosquitto-client-nossl eingeben --> Install...
oder per ssh:

opkg update
opkg install hostapd-utils
opkg install mosquitto-client

unter v19.07. gibt es u.a. mosquitto-client-nossl - wer aber ssl nutzen will, müsste das entspr. Paket nehmen, hab ich nicht getestet

per ssh ein Script anlegen, welches den MQTT-Teil künftig macht; z.B. /root/send_MQTT.sh:

  • vi send_MQTT.sh --> dann mit i weiter u. Text einfügen
  • ESC und :w --> File wird geschrieben und :q wieder raus aus vi

#!/bin/sh

if [ "$2" = "AP-STA-POLL-OK" ]
  then exit 0
fi

myIfName=$1                                                                                                         
myEvent=$2                                                                                                           
myMacAdress=$(echo $3 | tr a-z A-Z)                                                                                                     
myMQTT_device=OpenWRT_$myIfName
#your fhem ip here
myMQTT_host=192.168.1.10
myMQTT_message=$myEvent
myvar1=$(uci show dhcp | grep -oE "host\[\d+\].mac='"$myMacAdress"'"|grep -oE "\[(\d+)\]")
myHostName=$(uci get dhcp.@host$myvar1.name)

if [ -z "$myHostName" ]
  then myMQTT_topic="openWRT/unknownhost:$myMacAdress"
  else myMQTT_topic="openWRT/$myHostName:$myMacAdress"
fi

#send it all off through MQTT-client
mosquitto_pub -h $myMQTT_host -t $myMQTT_topic -m $myMQTT_message -i $myMQTT_device

Dann ausführbar machenchmod +x send_MQTT.sh

Jetzt wollen wir die Dämonen starten, müssen aber erst die Interfaces rausfinden, wo sie dran horchen sollen:
hostapd_cli i ergibt z.B.

Selected interface 'guests'
Available interfaces:
guests
wlan0
wlan1


Je Interface benötigen wir einen Dämonen -> durch die Aufrufparameter im Script wird je Interface ein MQTT-Device angelegt und künftig aktualisiert

hostapd_cli -i wlan0 -a /root/send_MQTT.sh -B
hostapd_cli -i wlan1 -a /root/send_MQTT.sh -B
hostapd_cli -i guests -a /root/send_MQTT.sh -B


Jetzt machen wir die Dämonenstarts noch dauerhaft, um nicht nach jedem (zugegeben seltenen) Routerstart dran denken zu müssen:

  • via LuCI -> System -> Systemstart -> lokales Startskript
  • die nötigen Kommandos reinhacken und speichern

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
hostapd_cli -i wlan0 -a /root/send_MQTT.sh -B
hostapd_cli -i wlan1 -a /root/send_MQTT.sh -B
hostapd_cli -i guests -a /root/send_MQTT.sh -B
exit 0

Am besten einen Reboot ausführen und beobachten was in FHEM passiert.

Schlussworte:
Wer mehrere Router als AP mit OpenWRT im Einsatz hat, wiederholt den ganzen OpenWRT-Teil auf jedem AP.
Sollen die FHEM-Devices die AP klar unterscheiden, müssen entweder die Interfaces je Router unique benannt werden oder es muss im Script entspr. angepasst werden (z.B. in "myMQTT_device=OpenWRT_$myIfName" den Prefix OpenWRT_ unique machen; das Script wäre ja auf jedem Router eigenständig).
Ansonsten wird nicht nach AP unterschieden, sodass es Wurscht ist worüber ein Teilnehmer sich verbindet - Vorteil: Notify ist etw. einfacher zu stricken.

Das MQTT-Script könnte wahrscheinlich an einem besseren Ort liegen, wo es auch ein System-Upgrade d. OpenWRT überlebt. Ich war noch zu faul darüber nachzudenken  :P

*Für die Namen zu den MAC-Adressen, habe ich jedem bekannten Teilnehmer statische IP und Namen im Router gegeben, weil ich das eh für andere Zwecke brauche.
Fremde/ volatile Teilnehmer z.B. im Gäste-WLAN erscheinen deshalb bei mir so
unknownhost_00_1A_2B_3C_4D_5E   AP-STA-DISCONNECTED   2020-08-13 16:06:20
Wer das nicht will oder auch die volatilen Namen haben mag, müsste sich in die OpenWRT-Möglichkeiten tiefer eingraben und das ins Script übernehmen. Otto hat in seinem Blog ja schon prima Beispiele (http://heinz-otto.blogspot.com/2019/03/precence-und-openwrt-der-3-versuch.html), über welchen ich inspiriert wurde den MQTT-Weg anzugehen.

Disclaimer:
Viele Wege führen nach Rom. Das Script und die MQTT-Geschichten in Fhem kann man natürlich viel weiter ausfeilen/ besser machen. Für meine Zwecke ist es so OK, für wen anderes womöglich ein Nogo. Anregungen können wir ja gerne hier sammeln (z.B. von Fhem aus Teilnehmer aktiv rauswerfen (hostapd_cli disassociate) oder gar kein MQTT nehmen, sondern direkt in Dummys die Readings schreiben, den state mit 0/1 belegen anstatt AP-STA-CONNECTED/ AP-STA-DISCONNECTED usw.).

So und nun viel Spaß beim Frickeln :)

Viele Grüße
rob

yersinia

Coole Anleitung, Danke! :)

Ich hab noch eine Frage bezgl. der Persistenz: meiner Erfahrung nach, müssen die Pakete nach jedem Upgrade nachinstalliert werden. Ob die Scripte bestehen bleiben, kommt auf den Speicherort und die Art des Sysupgrades an. Korrekt?
Dies würde bedeuten, dass man sich die Pakete notieren muss - oder diesen Thread als Lesezeichen. Es sei denn, man baut selbst - aber werden die wenigsten tun.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

rob

Hallo yersinia.

Gerne. Ja, ist auch mein Kenntnisstand. Nach Sysupgrade fast alles von vorn. Nach einem Reset definitiv alles von vorn  :o
Man kann zwar Backups machen, was aber keine Pakete einschließt und ich hab noch nicht durchschaut, welche Configs dabei includiert sind.

Viele Grüße
rob

Wernieman

Nur zur Klärung:

im Grunde Arbeitest Du Ereignisorientiert und pusht die Daten.

Wenn der hostapd_cli eine Änderung registriert startet er Dein Script, was die Änderung zu FHEM pusht? Bei Dir per MQTT. es würden aber auch andere Protokolle gehen (z.B. telnet oder http).

Könnte man den Aufruf des Scriptes nicht auch direkt in der Config des hostapd hinterlegen? Habe allerdings noch nie mit dem Deamon und openwrt gearbeitet, bisher nur unter Debianbassierten Systemen (incl. Ubuntu) und Gentoo ...
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

yersinia

#4
Zitat von: rob am 13 August 2020, 19:59:19Man kann zwar Backups machen, was aber keine Pakete einschließt und ich hab noch nicht durchschaut, welche Configs dabei includiert sind.
MWn wird /etc/config/* gesichert.
OpenWRT LuCi GUI -> System -> Backup / Flash Firmware -> tab Configuration -> Button Open list...
Oder unter /etc/sysupgrade.conf (siehe auch Backup & Restore).

Hier kannst du auch einpflegen, welche files durch ein Upgrade erhalten bleiben sollen.

Für umfangreiche Paket(nach)installation sowie Konfiguration in OpenWRT empfehle ich das selber bauen ([1], [2]) - geht relativ schnell und man hat alles, was man benötigt im Flash direkt. Man kann sogar anderes rausschmeissen - wie zB IPv6 Support. Ich baue zB für einen MR3020 selbst, wegen des begrenzten Flash Speichers.

Zitat von: Wernieman am 14 August 2020, 08:12:16Könnte man den Aufruf des Scriptes nicht auch direkt in der Config des hostapd hinterlegen? Habe allerdings noch nie mit dem Deamon und openwrt gearbeitet, bisher nur unter Debianbassierten Systemen (incl. Ubuntu) und Gentoo ...
Ich denke nicht. OpenWRT nutzt aber das init system, sollte also nicht weit weg von Gentoo und Debian (non-systemd ;)) sein - ansonsten liegt mMn BusyBox zu Grunde.
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

Volker80

Dankeschön für diese super Anleitung. die Umsetzung hat auf Anhieb geklappt.

rob

Hallo Wernieman.
Zitat von: Wernieman am 14 August 2020, 08:12:16
im Grunde Arbeitest Du Ereignisorientiert und pusht die Daten.
Wenn der hostapd_cli eine Änderung registriert startet er Dein Script, was die Änderung zu FHEM pusht? Bei Dir per MQTT. es würden aber auch andere Protokolle gehen (z.B. telnet oder http).
Ja, genauso isses. Beim pushen könnte alles Mögliche verwendet werden. Man müsste es halt entspr. scripten je nach gusto.

Zitat von: Wernieman am 14 August 2020, 08:12:16
Könnte man den Aufruf des Scriptes nicht auch direkt in der Config des hostapd hinterlegen?
Ich hab nur Dokus gefunden wo es mehrstufig sein muss. Ich würde yersinia zustimmen - eher schwierig das direkter zu triggern.
Vielleicht könnte man da was selber bauen (mit Knowhow + Zeit), das würde imho dann auf einen Selbstbau-hostapd rauslaufen. Theoretisch könnte man auch die Sourcen ändern und was selber comilieren. Ist jetzt wirklich theoretisch, denn ich kann das sicher nicht  ;D

Viele Grüße
rob

rob

@yersinia: Danke für die Infos. Ich glaub das muss ich auch angehen. Wie groß ungefähr ist denn der Aufwand bei neuen Releases alles nachzuziehen?
Ich frag so doof, weil ich früher mal ewig viel Lebenszeit fürs Aktualisieren von Windows-XP unattended Setup-DVDs verplempert hab. Jetzt hab ich SamrtHome ... lol  ;D

@Volker80: das freut mich sehr, dann waren meine Ausführungen einigermaßen schlüssig - kam schon vor, dass ich nach längerer Zeit meine eigenen Dokus nicht mehr verstanden hab  ::)

VG
rob

Wernieman

habe jetzt mal Zeit für die Doku gefunden und Ihr habt Recht, es ist unabhängig von der hostapd.conf

Man müsste eventuell sich ein Start-Script dafür schreiben ...
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

yersinia

Zitat von: rob am 14 August 2020, 21:24:29Wie groß ungefähr ist denn der Aufwand bei neuen Releases alles nachzuziehen?
Am Anfang relativ hoch, da man sich -unter Linux- erstmal alle notwendigen Pakete zum compilieren selbst installieren muss (auch durch Trial&Error während des compilierens). Man muss sich auch den make-Befehl zusammenbauen und testen. Der Rest ist straight-forward und gut beschrieben. Du kannst auch eigene config Dateien mitgeben.
Also ist Console/Terminal Erfahrung gut, auch der Umgang mit vi und scp. Natürlich kann es passieren, dass man sich den Router soft-bricked - da hilft es 1.) einen Plan B zu haben (zB Reserve-/Zweit-Router wenn es der Hauptrouter ist) und 2.) zu wissen wie der Failsafe mode funktioniert - und was man dann tun muss, um ein sysupgrade einspielen zu können. (Hat mir auch schon oft den Arsch gerettet ::))

Wenn man das dann allerdings einmal (dokumentiert) hat, ist es danach ein Leichtes, dass für jedes Release neu zu machen. Einfach das Imagebuilder-File für die Architektur runterladen, compilieren, per sysupgrade aufspielen, fertig.

Man kann sich aber auch den opkg-Befehl notieren und es dann nach jedem Upgrade nachinstallieren, ist ja eigtl auch kein Akt. Insbesondere wenn einige config files und eigene Skripte sowieso mit gesichert werden.

Backup, Backup, Backup! muss ich ja nicht zusätzlich erwähnen, oder? ;)
viele Grüße, yersinia
----
FHEM 6.3 (SVN) on RPi 4B with RasPi OS Bullseye (perl 5.32.1) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

valknut

Zitat von: rob am 13 August 2020, 16:39:12
Hallo.

Im Titel genannte Umsetzung möchte ich gern teilen. Komme von einer Frage aus dem Anfängerbereich her https://forum.fhem.de/index.php/topic,113454.msg1077873.html#msg1077873. Wollte das nicht direkt dort belassen, damit Einsteiger nicht verleitet werden ausgerechnet damit zu starten.

Darum gehts:
In FHEM soll erkannt werden, ob ein Wifi-Teilnehmer connected ist oder disconnected. Damit kann man dann Anwesenheiten und/oder Notifys bedienen. Während es für die Fritzbox viele schöne Lösungen gibt, schauts für OpenWRT mager aus - nutzen wahrscheinl. nicht so viele.

Vorweg:
Fhem sollte stabil laufen, aktuell sein und eine fixe IP haben (z.B. 192.168.1.10)
OpenWRT ab v17.01 mit ausreichend Platz für die u.s. Pakete
für die Namen zu den MAC-Adressen, habe ich jedem bekannten Teilnehmer statische IP und Namen im Router gegeben*

FHEM
MQTT2-Server definieren

define myMQTT_Server MQTT2_SERVER 1883 global
attr myMQTT_Server autocreate simple


OpenWRT
Pakete installieren, Script anlegen und Dämonen starten

  • login via LuCI --> System --> Paketverwaltung --> Update lists...
  • unter Filter: hostapd-utils eingeben --> Install...
  • erneut unter Filter: mosquitto-client bzw. mosquitto-client-nossl eingeben --> Install...
oder per ssh:

opkg update
opkg install hostapd-utils
opkg install mosquitto-client

unter v19.07. gibt es u.a. mosquitto-client-nossl - wer aber ssl nutzen will, müsste das entspr. Paket nehmen, hab ich nicht getestet

per ssh ein Script anlegen, welches den MQTT-Teil künftig macht; z.B. /root/send_MQTT.sh:

  • vi send_MQTT.sh --> dann mit i weiter u. Text einfügen
  • ESC und :w --> File wird geschrieben und :q wieder raus aus vi

#!/bin/sh

if [ "$2" = "AP-STA-POLL-OK" ]
  then exit 0
fi

myIfName=$1                                                                                                         
myEvent=$2                                                                                                           
myMacAdress=$(echo $3 | tr a-z A-Z)                                                                                                     
myMQTT_device=OpenWRT_$myIfName
#your fhem ip here
myMQTT_host=192.168.1.10
myMQTT_message=$myEvent
myvar1=$(uci show dhcp | grep -oE "host\[\d+\].mac='"$myMacAdress"'"|grep -oE "\[(\d+)\]")
myHostName=$(uci get dhcp.@host$myvar1.name)

if [ -z "$myHostName" ]
  then myMQTT_topic="openWRT/unknownhost:$myMacAdress"
  else myMQTT_topic="openWRT/$myHostName:$myMacAdress"
fi

#send it all off through MQTT-client
mosquitto_pub -h $myMQTT_host -t $myMQTT_topic -m $myMQTT_message -i $myMQTT_device

Dann ausführbar machenchmod +x send_MQTT.sh

Jetzt wollen wir die Dämonen starten, müssen aber erst die Interfaces rausfinden, wo sie dran horchen sollen:
hostapd_cli i ergibt z.B.

Selected interface 'guests'
Available interfaces:
guests
wlan0
wlan1


Je Interface benötigen wir einen Dämonen -> durch die Aufrufparameter im Script wird je Interface ein MQTT-Device angelegt und künftig aktualisiert

hostapd_cli -i wlan0 -a /root/send_MQTT.sh -B
hostapd_cli -i wlan1 -a /root/send_MQTT.sh -B
hostapd_cli -i guests -a /root/send_MQTT.sh -B


Jetzt machen wir die Dämonenstarts noch dauerhaft, um nicht nach jedem (zugegeben seltenen) Routerstart dran denken zu müssen:

  • via LuCI -> System -> Systemstart -> lokales Startskript
  • die nötigen Kommandos reinhacken und speichern

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
hostapd_cli -i wlan0 -a /root/send_MQTT.sh -B
hostapd_cli -i wlan1 -a /root/send_MQTT.sh -B
hostapd_cli -i guests -a /root/send_MQTT.sh -B
exit 0

Am besten einen Reboot ausführen und beobachten was in FHEM passiert.

Schlussworte:
Wer mehrere Router als AP mit OpenWRT im Einsatz hat, wiederholt den ganzen OpenWRT-Teil auf jedem AP.
Sollen die FHEM-Devices die AP klar unterscheiden, müssen entweder die Interfaces je Router unique benannt werden oder es muss im Script entspr. angepasst werden (z.B. in "myMQTT_device=OpenWRT_$myIfName" den Prefix OpenWRT_ unique machen; das Script wäre ja auf jedem Router eigenständig).
Ansonsten wird nicht nach AP unterschieden, sodass es Wurscht ist worüber ein Teilnehmer sich verbindet - Vorteil: Notify ist etw. einfacher zu stricken.

Das MQTT-Script könnte wahrscheinlich an einem besseren Ort liegen, wo es auch ein System-Upgrade d. OpenWRT überlebt. Ich war noch zu faul darüber nachzudenken  :P

*Für die Namen zu den MAC-Adressen, habe ich jedem bekannten Teilnehmer statische IP und Namen im Router gegeben, weil ich das eh für andere Zwecke brauche.
Fremde/ volatile Teilnehmer z.B. im Gäste-WLAN erscheinen deshalb bei mir so
unknownhost_00_1A_2B_3C_4D_5E   AP-STA-DISCONNECTED   2020-08-13 16:06:20
Wer das nicht will oder auch die volatilen Namen haben mag, müsste sich in die OpenWRT-Möglichkeiten tiefer eingraben und das ins Script übernehmen. Otto hat in seinem Blog ja schon prima Beispiele (http://heinz-otto.blogspot.com/2019/03/precence-und-openwrt-der-3-versuch.html), über welchen ich inspiriert wurde den MQTT-Weg anzugehen.

Disclaimer:
Viele Wege führen nach Rom. Das Script und die MQTT-Geschichten in Fhem kann man natürlich viel weiter ausfeilen/ besser machen. Für meine Zwecke ist es so OK, für wen anderes womöglich ein Nogo. Anregungen können wir ja gerne hier sammeln (z.B. von Fhem aus Teilnehmer aktiv rauswerfen (hostapd_cli disassociate) oder gar kein MQTT nehmen, sondern direkt in Dummys die Readings schreiben, den state mit 0/1 belegen anstatt AP-STA-CONNECTED/ AP-STA-DISCONNECTED usw.).

So und nun viel Spaß beim Frickeln :)

Viele Grüße
rob

Hallo Zusammen,

vielen Dank für das Tutorial, funktionierte bei mir auch auf Anhieb.

Ich habe dazu allerdings eine Frage. Ich verwende bei mir zusätzlich zum Router einen Access-Point, welcher via VLAN-Trunk an meinem Router hängt. Demzufolge funktioniert das Skript bei mir am Access Point nicht, weil in diesem das DHCP deaktiviert ist, damit mein Router die Hosts verwalten kann.

Ich habe einies gesucht, probiert, aber komme nicht zum Ziel: Kann man das Skript so abändern, dass die Netzwerke( in Openwrt "Interfaces") überwacht werden. Also wenn ein sich ein Host anmeldet, ganz gleich ob über wlan, lan,... ein Trigger auslöst und das dann nach dem gleichen Schema via MQTT gesendet wird?

Vielen Dank vorab.

PS: Ich habe das bisherige Skript auch in einem Cronjob mit angehangen. Ich steuere meine WLAN Zugangspunkte nach Zeit. Und jedes mal, wenn ein WLAN abgeschaltet wird, löscht es auch die laufenden Skripte. Deshalb starte ich 30 Sekunden danach die Skripte erneut

rob

Hallo.

Danke fürs Feedback.

Zitat von: valknut am 23 Februar 2021, 21:08:12
Ich habe dazu allerdings eine Frage. Ich verwende bei mir zusätzlich zum Router einen Access-Point, welcher via VLAN-Trunk an meinem Router hängt. Demzufolge funktioniert das Skript bei mir am Access Point nicht, weil in diesem das DHCP deaktiviert ist, damit mein Router die Hosts verwalten kann.
Mit VLAN-Segmentierung kenne ich mich nicht so aus, habs selber auch nicht im Einsatz. Einen zweiten Router nutze ich aber ebenfalls als Access-Point und auf diesem ist kein DHCP aktiv.
Der Hauptaufruf im Script via "uci show dhcp" bringt bei mir trotzdem alle Clients, obwohl kein DHCP aktiviert ist.
Die Einschränkung auf Wifi erfolgt im Script indirekt via MAC durch "grep ... $myMacAdress ...", welche vom daemon übergeben wird. Und das auch nur dann, wenn ein daemon auf den nötigen Interfaces sitzt.

Ich hätte auch über "/tmp/dhcp.leases" gehen können. Hat aber den Haken, dass dort wirklich nur leases drin stehen. Weil ich fast allen Clients im LAN/WLAN statische IP gebe, würden mir die statischen fehlen.

Was ergibt "uci show dhcp" wenn Du das im Cli vom AP einhackst? Da sollten alle gesuchten Clients drin stehen, egal ob LAN oder Wifi. Wenn nicht, gibt es ggf. einen Unterschied wg. VLAN(?).
Was ergibt "hostapd_cli i" am AP? Da sollten alle Interfaces auftauchen, die der AP hat. Eigentlich auch VLAN-Krams(?).

Manchmal unterscheiden sich die Aufrufe je nach Wifi-Hardware (iw vs. wlc usw.). Vielleicht wäre bei Deinem AP ein anderer Aufruf nötig. Mal schauen.

Viele Grüße
rob

valknut

#12
Hallo und vielen Dank für die Rückmeldung. Also erstmal zur Hardwarre. Mein Router ist ein Turris Omnia (aktuelles Modell - openwrt 19.07) und der AP ein Gl-inet AR750 (openwrt 18.06). Auf beiden Geräten läuft dein Skript.

mit "uci show dhcp" sehe ich am Router sowie am AP nur die gespeicherten Leases, nicht aber die aktuell verbundenen.
z.B.
dhcp.@host[20]=host
dhcp.@host[20].mac='XX:XX:XX:XX:XX:XX'
dhcp.@host[20].name='Diensttelefon'
dhcp.@host[20].dns='1'
dhcp.@host[20].ip='10.2.40.130'

Lege ich das Gerät nicht an, taucht es bei der Abrfrage, auch wenn es verbunden ist, nicht auf.

In der Gui ist bei beiden Geräten der Host zu sehen, wenn er verbunden ist. Verbinde ich den Host mit dem Router, sehe ich das auch im Fhem. Host am AP - keine Reaktion im Fhem (autocreate mqtt Broker auf "simple").
mit "hostapd_cli i) werden bei mir ausschließlich die wifi1... etc angezeigt.

Ich denke, dass das VLAN an der Stelle keine Rolle spielt. Oder vielleicht hat mein Gl-inet AR750 ein Problem mit dem Skript.
Der einzige Unterschied ist wirklich das abgeschaltete DHCP. Ansonsten sind die Interfaces exakt gleich eingerichtet

Ich glaube in meinem Fall würde es mit den dhcp.leases klappen, wie müsste das skript dafür aussehen?

Ich habe mal etwas rumgespielt und folgendes Script genutzt:
#!/bin/sh

# configure dnsmasq with --dhcp-script= this script
# based on this article: https://jpmens.net/2013/10/21/tracking-dhcp-leases-with-dnsmasq/
op="${1:-op}"
mac=$(echo $2 | tr a-z A-Z)
ip="${3:-ip}"
#hostname="${4}"
myMQTT_device=DHCP
#tstamp="`date '+%Y-%m-%d %H:%M:%S'`"

topic="dhcp/${mac}"

myvar1=$(uci show dhcp | grep -oE "host\[\d+\].mac='"${mac}"'"|grep -oE "\[(\d+)\]")
myHostName=$(uci get dhcp.@host$myvar1.name)

if [ "$op" == "arp-del" ]
  then payload="DISCONNECTED"
  else payload="CONNECTED"
fi

if [ -z "$myHostName" ]
  then myMQTT_topic="dhcp/unknownhost:${mac}"
  else myMQTT_topic="dhcp/$myHostName:${mac}"
fi

mosquitto_pub -h 10.2.89.2 -t "${myMQTT_topic}" -m "${payload}" -i $myMQTT_device


Das CONNECT klappt soweit, aber der DISCONNECT nicht am AP. Vielleicht kannst du mal inhaltlich nochmal drüber schauen. Habe das lediglich adaptiert aus der Skript-Quelle und deinem.

Vielen vielen Dank

rob

So ganz verstehe ich nicht, warum es bei dem AP nicht klappen will. Das Script hat ja wie angedeutet nur zwei Aufgaben: zur übergebenen MAC den Hostnamen finden und alles per MQTT wegsenden.
Woher nun der Hostname kommt, wäre im Prinzip Wurscht.
Deshalb könnten die Leases auch herhalten. Am AP gibt es die aber leider nicht, weil der ja kein DHCP macht. Vielleicht ginge das mit DHCP-Relay irgendwie - keine Ahnung, weil ich mit statischen IP arbeite  :-[

Mir ist noch eingefallen: die Zuordnung MAC - IP - Name vom WebIF wird gespeichert unter: /etc/config/dhcp. Diese Dateien halte ich auf meinen AP's mit dem Main-Router Snychron (händisch, so oft ändert sich ja nix). Solange ich einen Client dort noch nicht erfasst habe, erscheint er auch im WebIF ohne Namen (andere nehmen dafür /etc/ethers).
Vielleicht ist es das, was auch Dein AP benötigt. Nur arbeitest Du ja mit DHCP. Irgendwie muss der AP mitgeteilt bekommen, wie die Hosts heißen. Ein einfacher AP bekommt das nicht mit. Also doch DHCP-Relay?
Zumindest testweise könntest Du mal eine Kombi aus MAX+IP+Namen im WebIF vom AP eintragen und diesen Client mit dem AP verbinden - der Name sollte gefunden werden. Das wäre aber Schritt zwei, denn
Zitat von: valknut am 27 Februar 2021, 22:08:35
Lege ich das Gerät nicht an, taucht es bei der Abrfrage, auch wenn es verbunden ist, nicht auf.
Zumindest als UNKNOWN sollte die Verbindung angezeigt werden.

Also wäre Schritt eins mal zu schauen, ob der hostapd auf dem AP überhaupt tut. Kopiere bitte mal die Datei "send_MQTT.sh" nach "send_MQTT.sh.old" und schmeiß aus der send_MQTT.sh alles raus und füge diese Zeilen ein:

#!/bin/sh
echo "`date` - gefunden - name ${1} Event ${2} MAC $3" >> /tmp/testhostapd.log

Danach mit einem Client am AP anmelden/abmelden. Es sollte die Datei /tmp/testhostapd.log entstehen und solches beinhalten:

Mon Mar  1 11:34:31 CET 2021 - gefunden - name wlan0 Event AP-STA-DISCONNECTED MAC 00:11:22:33:44:55
Mon Mar  1 11:34:57 CET 2021 - gefunden - name wlan0 Event AP-STA-CONNECTED MAC 00:11:22:33:44:55
Mon Mar  1 11:40:50 CET 2021 - gefunden - name wlan0 Event AP-STA-DISCONNECTED MAC 00:11:22:33:44:55
Mon Mar  1 11:41:05 CET 2021 - gefunden - name wlan0 Event AP-STA-CONNECTED MAC 00:11:22:33:44:55


Wenn das zuverlässig klappt, wäre Schritt zwei dran s.o. (Datei wieder löschen und old zurück umbenennen).

Ansonsten habe ich für Schritt 2 diese Diskussion gefunden: https://forum.openwrt.org/t/associated-stations-list-in-ap-how-to-show-host-names/63475. Dort geht es auch um die Namensverteilung im Netz. Anscheinend gibt es bei dem Thema noch mehr Leute mit Fragezeichen wie mich.
Im WebIF erscheinen vom Haupt-Router ja z.B. die Gäste auch mit dem Hostnamen. Dahinter muss irgendeine Abfrage stecken. Ich habe bisher nicht finden können, welche konkret. Kurios, wo doch alles OPEN ist. Steht bestimmt irgendwo, ich war bisher nur zu doof es zu finden.

Wenn ich das von Dir verlinkte Vorgehen unter https://jpmens.net/2013/10/21/tracking-dhcp-leases-with-dnsmasq/ richtig verstehe, dann macht das dortige Script etwas ähnliches wie dieses hier. Nur "hängt" es nicht am hostapd, sondern am dnsmasq-daemon. Dann wäre das Script nur auf dem Main-Router nötig, denn nur der macht DHCP. Der AP bräuchte dann kein Script mehr.
Auch eine schöne Variante. In Deiner Adaption wäre beides vermischt. Ich fürchte das klappt nur eingeschränkt, weil die Aufruf-Parameter vom hostapd kommen und anders sind, als vom dnsmasq. Ich würde Dir empfehlen entweder auf die dnsmasq-Variante zu setzen oder die hostapd. Oder noch ganz was eigenes austüfteln und hier posten :)

Viele Grüße
rob

PS: Wenn der Hauptrouter keinen DHCP-Server betreibt, sondern ein ganz anderer Rechner im Netz, dürfte die Namensfindung auch auf dem Hauptrouter ins Leere laufen. Ggf. interessant für alle, die Pi-Hole mit der DHCP-Option laufen haben.
PPS: Denkansatz: im Prinzip könnte auch Fhem selbst für die Übersetzung von MAC nach Name sorgen. Ein DHCP-Server müsste die Leases halt automatisch übermitteln.Dann ließen sich die hier beschriebenen Ansätze noch flexibler verwenden.


rob

Zitat von: valknut am 27 Februar 2021, 22:08:35
Das CONNECT klappt soweit, aber der DISCONNECT nicht am AP. Vielleicht kannst du mal inhaltlich nochmal drüber schauen. Habe das lediglich adaptiert aus der Skript-Quelle und deinem.
Ich habe grad mal diese Script-Variante aus dem Link getestet. Der Vorteil ist, dass alles in den Parametern steht, was man so braucht: IP, Name , MAC und Zustand vom Lease und es zentral dort laufen kann, wo dnsmasq sich um DHCP kümmert.
Nachteil ist, dass ein Lease zunächst gültig bleibt, auch wenn der Client abgemeldet ist. Für Anwesenheitserkennung vielleicht ungünstig - hängt auch von der konfigurierten Leasetime ab.

Zu Deiner Adaption
In der Variable $1 stehen bei mir nur die Werte add, old oder del als reine Aufrufparameter. Im Script übergibst Du diese Werte modifiziert an $op -->op="${1:-op}" und fragst später nach, ob "op==arp-del", was wahrscheinlich nie zutrifft und deshalb kommt kein "DISCONNECTED".
Vorschlag:

$op=$1
...

if [ "$op" == "del" ]
  then payload="DISCONNECTED"
  else payload="CONNECTED"
fi

Den Teil mit den Namensermittlung aus meinem Script kannst rauswerfen, unnötig da

myHostName=$4

Bereits den Namen aus dem Parameter beziehen kann.

Wrapped up:

#!/bin/sh

# configure dnsmasq with --dhcp-script= this script
# based on this article: https://jpmens.net/2013/10/21/tracking-dhcp-leases-with-dnsmasq/
op=$1
mac=$(echo $2 | tr a-z A-Z)
ip="${3:-ip}"
#hostname="${4}"
myMQTT_device=DHCP
#tstamp="`date '+%Y-%m-%d %H:%M:%S'`"

topic="dhcp/${mac}"

#myvar1=$(uci show dhcp | grep -oE "host\[\d+\].mac='"${mac}"'"|grep -oE "\[(\d+)\]")
myHostName=$4

if [ "$op" == "del" ]
  then payload="DISCONNECTED"
  else payload="CONNECTED"
fi

if [ -z "$myHostName" ]
  then myMQTT_topic="dhcp/unknownhost:${mac}"
  else myMQTT_topic="dhcp/$myHostName:${mac}"
fi

mosquitto_pub -h 10.2.89.2 -t "${myMQTT_topic}" -m "${payload}" -i $myMQTT_device


Hab das aber nicht getestet und es verbleibt noch der Nachteil, das der Status "del" stark verzögert eintreten kann.

Viele Grüße
rob