Es musste also eine Alternative für die Anwesenheitserkennung her. Bei der Recherche nach fertigen Lösungen wurde ich nicht so richtig fündig (ioBroker nutze ich nicht, Python-Programmierung war nicht im Lösungsraum, ...). Also habe ich selbst angefangen, etwas mit HomeMatic-/CUxD-Bordmitteln zu basteln. Hilfreich waren dabei u. a. folgende Links:
- https://ubntwiki.com/products/software/ ... roller/api
- https://bartsimons.me/playing-around-wi ... ontroller/
Herausgekommen ist eine relativ simple, aber ihren Zweck erfüllende Lösung, die ich hier kurz vorstellen möchte.
Grundidee:
Meine Lösung basiert (wie z. B. auch die von Jens Maus) darauf, regelmäßig die im (W)LAN eingebuchten Geräte über ihre MAC-Adresse abzufragen und darüber zu ermitteln, wer zu Hause (bzw. im heimischen WLAN) ist und wer nicht. Dazu wird die API-Schnittstelle des UniFi-Controllers angezapft. Die prinzipbedingten Einschränkungen dieser Methode (Verlassen des WLANs wird erst mit einigen Minuten Verzögerung erkannt) bleiben natürlich bestehen - für mich ist die Genauigkeit völlig akzeptabel.
Voraussetzungen:
- CCU3 mit installiertem CUxD Daemon (inkl. eines in der CCU3 konfigurierten System.Exec-Devices sowie eines System.Timer-Devices, welches alle 60 Sekunden auslöst)
- UniFi-Controller (für die hier vorgestellte Lösung habe ich im Controller einen zusätzlichen Account mit minimalen Admin-Rechten angelegt)
Zuerst habe ich einige Parameter, die sich ggf. später ändern können, über Systemvariablen in der CCU3 konfigurierbar gemacht. Folgende Systemvariablen habe ich angelegt:
Für den Anwesenheitsstatus einzelner Familienmitglieder (Name1...Name3 können natürlich individuell angepasst werden):
- Anwesenheit.Name1 --> Logikwert (wahr = anwesend, falsch = abwesend)
- Anwesenheit.Name2 --> Logikwert (wahr = anwesend, falsch = abwesend)
- Anwesenheit.Name3 --> Logikwert (wahr = anwesend, falsch = abwesend)
- Smartphone_Name1.mac_address --> Zeichenkette (Format "aa:bb:cc:dd:ff")
- Smartphone_Name2.mac_address --> Zeichenkette (Format "aa:bb:cc:dd:ff")
- Smartphone_Name3.mac_address --> Zeichenkette (Format "aa:bb:cc:dd:ff")
- UniFi-Controller.ip_address_port --> Zeichenkette (Format "xxx.xxx.xxx.xxx:xxxx")
Im dort verwendeten Script müsst Ihr die Variablen "usr" [= "your_username";] und "pwd" [= "your_passwort";] mit Euren individuellen Werten für den UniFi-Controller belegen. Falls Ihr zuvor in den Systemvariablen Name1...Name3 verändert habt, müsst Ihr außerdem die Variable "phone_list" [= "Name1:Name2:Name3";] ebenfalls entsprechend anpassen.
Code: Alles auswählen
!--- Version: v0.1 --- Smartphones checken ---------------------------------------------
! Zyklisch (z. B. 1x pro Minute) über den UniFi-Controller ermitteln, ob definierte Smartphones
! im WLAN eingebucht sind und jeweiligen Status in entsprechenden Systemvariablen speichern
! --------------------------------------------------------------------------------------
! Bekannte/zu prüfende Smartphones:
string phone_list = "Name1:Name2:Name3";
! --------------------------------------------------------------------------------------
! IP-Adresse/Port des UniFi-Controllers aus Systemvariablen auslesen:
string sysvar = "UniFi-Controller.ip_address_port";
string unifi_ip_port = dom.GetObject(sysvar).State().ToString();
! --------------------------------------------------------------------------------------
! UniFi-Controller-Username/-Password sollen NICHT in einer Systemvariable gespeichert werden, um Kompromittierung zu erschweren, daher hier fest definiert:
string usr = "your_username";
string pwd = "your_passwort";
! --------------------------------------------------------------------------------------
! An UniFi-Controller anmelden und XML-Liste der verbundenen Geräte abfragen:
string url_login = "https://" # unifi_ip_port # "/api/login";
string cmd_login = " --data-binary '{\"username\":\"" # usr # "\",\"password\":\"" # pwd # "\",\"strict\":true}' --compressed --insecure -c cookies.txt";
string url_dev_list = "https://" # unifi_ip_port # "/api/s/default/stat/sta";
string cmd_dev_list = " --compressed --insecure -b cookies.txt -c cookies.txt";
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("/usr/local/addons/cuxd/curl -X POST '"#url_login#"'" #cmd_login#" --next '"#url_dev_list#"'" #cmd_dev_list#"");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
string xml_result = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
! vorher gesetztes Cookie wieder löschen:
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("rm /usr/local/addons/cuxd/cookies.txt");
! --------------------------------------------------------------------------------------
! XML-Ergebnis (UniFi-Controller-Abfrage) auswerten:
string phone;
string mac_adr;
boolean status;
boolean letzter_status;
! für jedes Element der Smartphone-Liste:
foreach (phone, phone_list.Split(":"))
{
! MAC-Adresse ermitteln:
mac_adr = dom.GetObject("Smartphone_" # phone # ".mac_address").State().ToString();
! Letzten Anwesenheitsstatus ermitteln:
letzter_status = dom.GetObject("Anwesenheit." # phone).State();
! MAC-Adresse in xml_result suchen:
status = xml_result.Contains(mac_adr);
if (status != letzter_status)
{ dom.GetObject("Anwesenheit." # phone).State(status); }
}
!---------------------------------------------------------------------------------------
Jetzt sollten alle 60 Sekunden (entsprechend den Einstellungen des verwendeten CUxD-System.Timer-Devices) über den UniFi-Controller die im (W)LAN aktiven Smartphones abgefragt und die entsprechenden Systemvariablen (Anwesenheit.Name1...3) gesetzt werden.
Viel Spaß beim Nachbauen!
L.N.