Vorbereitung des Routers
Für das cgi Script braucht man die Komponente bash auf dem Router, das ist schnell installiert.System / Software im Feld "Download and install package:" einfach bash eintippen und Ok drücken.
Im Pfad /www/cgi-bin/ muss man jetzt eine Datei wifi-client mit folgendem Inhalt anlegen (z.B. mit WinsSCP).
Ich habe gegenüber dem Original Artikel noch die Umwandlung von Gross in Kleinbuchstaben eingebaut.
Die Zeile im Code unterhalb dem Hinweis # Pfade anpassen je nach AP-Config!! muss man unbedingt anpassen!
Je nach dem welche Wlan Hardware verbaut ist:
- radio0 -> phy0
- radio1 -> phy1
- wlan1 -> netdev:wlan1
- wlan1-2 -> netdev:wlan1-2
#!/bin/bash # Decodes an URL-string # an URL encoding has "+" instead of spaces # and no special characters but "%HEX" function urlDec() { local value=${*//+/%20} # replace +-spaces by %20 (hex) for part in ${value//%/ \\x}; do # split at % prepend \x for printf printf "%b%s" "${part:0:4}" "${part:4}" # output decoded char done } # For all given query strings # parse them an set shell variables function setQueryVars() { local vars=${*//\*/%2A} # escape * as %2A for var in ${vars//&/ }; do # split at & local value=$(urlDec "${var#*=}") # decode value after = value=${value//\\/\\\\} # change \ to \\ for later value=${value,,} # upper in lower case eval "CGI_${var%=*}=\"${value//\"/\\\"}\"" # evaluate assignment done } # Execute the evaluation # set all variables for both, POST and GET data # $QUERY_STRING ist part of the environment and contain the part after ? setQueryVars $QUERY_STRING $(</dev/stdin) # Set formatting the Response to plain Text echo Content-type: text/plain echo # for the Query ?dev=xxxxxx&test=yyyyyy # Query dev= -> $CGI_dev contain value after dev= # Query test= -> $CGI_test contain value after test= # Test the string contain only numbers,lower letters and : case $CGI_dev in *[!0-9a-f:]*|"") echo "NOK MAC"; exit 0;; esac # Pfade anpassen je nach AP-Config!! if [ -d "/sys/kernel/debug/ieee80211/phy1/netdev:wlan1/stations/$CGI_dev" ] || [ -d "/sys/kernel/debug/ieee80211/phy1/netdev:wlan1-1/stations/$CGI_dev" ] || [ -d "/sys/kernel/debug/ieee80211/phy1/netdev:wlan1-2/stations/$CGI_dev" ] || [ -d "/sys/kernel/debug/ieee80211/phy0/netdev:wlan0/stations/$CGI_dev" ]; then echo "connected" else echo "no device" fiDiese Datei braucht jetzt nur noch das Ausführen (x) Recht für Alle, kann man auch gleich mit WinSCP machen.
Ohne Weiteres kann man sofort die Funktion testen:
http://wrt1900/cgi-bin/wifi-client?dev=11:22:33:aa:bb:ccBei bekannter MAC Adresse erscheint ein connected als Quittung, ansonsten eine entsprechende Ausgabe.
Funktion in 99_myUtils.pm
Um diese Abfrage in einem PRESENCE Device zu verwenden, braucht man noch eine kleine Perlfunktion.sub wlan_det($) { use LWP::UserAgent; my ($client)= @_; my $ua = new LWP::UserAgent; my $response = $ua->get('http://wrt1900/cgi-bin/wifi-client?dev='.$client); unless ($response->is_success) { return 99; } my $content = $response->decoded_content(); if ($content =~ m/connected/) { return 1; } else { return 0; } }Ich musste gegenüber dem Originalbeitrag noch die Zeile mit "use LWP:.." ergänzen. Es ist eigentlich besser diese einmalig am Anfang der 99_myUtils.pm nach der Zeile
"# Enter you functions below _this_ line."
und vor allen eigenen Subs zu platzieren.
Die Definition in FHEM ist wie gewohnt:
defmod iPhone PRESENCE function {wlan_det("11:22:33:aa:bb:cc")}
Nacharbeit
Das war jetzt quick&dirty - man kann noch- die Übergabe oder Definition der Router IP besser machen.
- die Definition der abzufragenden Pfade im Router verbessern.
- Prüfen was genau passiert wenn der Router nicht erreichbar ist (FHEM blockiert?)
- Die Abfrage funktioniert so nur für Wifi, LAN Clients ermitteln?
Hallo, danke für die Zusammenstellung.
AntwortenLöschenFrage: Ist tatsächlich 'defmode' gemeint ?
Das Programm
AntwortenLöschenhttp://wrt1900/cgi-bin/wifi-client?dev=11:22:33:aa:bb:cc
ausgeführt in der Browserzeiler funktioniert super.
Wird das Programm auf dem Router aber über die Perl-Funktion in der 99_myUtils aufgerufen liefert die Funktion wlan_det() immer 99.
Möglich Ursache für Ergebnis 99, ist das ein self signed Zertifikaten verwendet.
AntwortenLöschenEinfach
my $ua = new LWP::UserAgent;
durch ersetzten
my $ua = LWP::UserAgent->new(
ssl_opts => {
SSL_verify_mode => SSL_VERIFY_NONE(), # ausschalten
verify_hostname => 0, # und auch auslassen!
}
);