Habe „auf die Schnelle“ eine kleine Lösung gebastelt. Ist zwar ein Script, aber ein Anfang. Kann man ja in ein Modul übernehmen. Ist alles quick & dirty programmiert. Tipps zur Optimierung des Codes nehme ich gern entgegen. Werde diesen Ansatz dies bei Gelegenheit in meine Präsenzmelde-Script übernehmen, um die zyklischen Abfragen mit Logins an den Controller zu minimieren. Außerdem kommt die Meldung beim Ausbuchen eines Endgerätes wesentlich schneller als beim Abfragen (hier dauert es bei mir bis zu 10 min bis jemand als abwesend gilt).
Was macht das Script?
Eingehende Syslog-Meldungen vom Unifi-Controller werden via UDP-Socket in eine Registervariable umgeleitet. Diese ist mit dem Script verbunden, welches derzeit drei Meldungen herausfiltert: jeweils die Mac-Adresse bei Ein- und Ausbuchen eines Endgerätes in das / aus dem WLAN sowie die IP-Adresse, die das Endgerät beim Einbuchen bekommt.
Was ist zu tun?
[ul]
[li]Syslog-Server (Remote-Protokollierung) im Unifi-Controller einrichten (Einstellungen -> Zone) mit IP vom IPS und dem Port, auf den IPS lauscht[/li][li]UDP-Socket anlegen (wenn nichts verändert wurde, sind die beiden Ports jeweils 514, Sende-Host ist die IP vom Unifi-Controller und Empfangs-Host die IPS-IP)[/li][li]Script anlegen und Inhalt reinkopieren[/li][li]drei Variablen als String anlegen und im Script mit den „SetValue“-Befehlen verknüpfen[/li][li]Registervariable im Baum anlegen und auf das soeben angelegte Script verweisen (ID zusätzlich im Script hinterlegen)[/li][/ul]
Das Script:
<?
$regvar = 30988;
$newdata = $_IPS['VALUE'];
// Daten in Puffer speichern
$buffer = RegVar_GetBuffer($regvar);
$buffer .= $newdata;
RegVar_SetBuffer($regvar, $buffer);
// in UTF8 wandeln
$utf8data = utf8_decode($newdata);
// Fall 1: Endgerät hat WLAN verlassen
if (strpos($utf8data, "EVENT_STA_LEAVE") !== false)
{
preg_match_all("/\b[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\b/su", $utf8data, $macs);
$mac = $macs[0][0];
SetValue(30906, $mac);
echo "WLAN verlassen durch ".$mac."
";
}
// Fall 2: Endgerät hat sich ins WLAN eingebucht
if (strpos($utf8data, "EVENT_STA_JOIN") !== false)
{
preg_match_all("/\b[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\b/su", $utf8data, $macs);
$mac = $macs[0][0];
SetValue(10111, $mac);
echo "WLAN betreten von ".$mac."
";
}
// Fall 3: IP-Adresse des Endgerätes nach Einbuchen auslesen
if (strpos($utf8data, "EVENT_STA_IP") !== false)
{
preg_match_all("/\b[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\b/su", $utf8data, $macs);
$mac = $macs[0][0];
preg_match_all("/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/", $utf8data, $ips);
$ip = $ips[0][1];
SetValue(21933, $ip);
}
?>
Nun sollten ein Haufen Meldungen in die Registervariable laufen (kann man sich mittels Debug anzeigen lassen). Jede Meldung wird auf ein paar Schlüsselwörter geprüft und das Ergebnis entsprechend in eine der drei Variablen geschrieben. Man wird sicherlich noch mehr damit machen können, ist nur halt mühsam, sich die passenden Zeilen herauszusuchen, die das gesuchte Ereignis widerspiegeln.
Trotzdem: MQTT würde mir auch besser gefallen.