Hallo,
ich schlage Ihnen ein Tutorial zur Überwachung der Anwesenheit eines mit dem WLAN verbundenen Telefons und zum Senden des Status an Gladys über MQTT vor.
Ich schlage zwei Versionen vor:
- Mit nmap (funktioniert mit allen Boxen)
- Mit der Freebox-API mit oder ohne nmap in einem zweiten Schritt.
Alles auf einem Raspberry.
TUTORIAL Nr. 3: Anwesenheit eines Benutzers über das WLAN seines Telefons anzeigen.
Gladys-Seite:
- Erstellung des MQTT-Geräts:
Name: Telefon verbunden mit WIFI
Externe ID: mqtt:Raum:PhoneConnected (mqtt:Raum:Element)
Raum: Raum
- Hinzufügen einer Ganzzahlzähler-Funktionalität:
Name: Verbindungsstatus
Externe ID der Funktionalität: mqtt:PhoneConnected:StateConnection (mqtt:Element:Funktion)
Minimalwert: 0 (Telefon nicht verbunden)
Maximalwert: 1 (Telefon verbunden)
Verlauf der Zustände speichern: Ja
Ist dies ein Sensor: Ja
MQTT-Topic zum Veröffentlichen: Sie können sich das Topic, das später verwendet wird, zur Seite legen.
- Hinzufügen des Geräts zum Dashboard:
Hier gibt es nichts Besonderes, Sie müssen wie gewohnt vorgehen.
Das war’s mit Gladys ![]()
BASH-Seite:
- Gemeinsame Datei: /opt/mosquitto/MQTTConfig.sh
Ich werde die gemeinsame Datei verwenden, die ich in meinen anderen Tutorials vorgeschlagen habe: [TUTO] Partage d'informations entre BASH et Gladys
Sie ermöglicht es, die Anwesenheit von Befehlen zu testen, einen Austausch der Verbindungsvariablen zu Gladys zu haben und Farbe in die Nachrichten zu bringen.
- BASH-Skript: /opt/mosquitto/PhoneConnected.sh
Wir werden es mit einem der beiden folgenden Codes füllen, einen mit nmap, den anderen mit der Freebox-API.
nmap erfordert Root-Rechte.
Die Idee ist es, einen Befehl auszuführen und die IP und die MAC-Adresse des Telefons zu suchen.
Man muss also beide kennen und seine Box so konfigurieren, dass die IP des Telefons fest ist.
Es ist möglich, nicht an der MAC-Adresse zu arbeiten, dafür muss man nur die IP-Adresse der Variable PhoneMAC zuweisen.
Nur das, was sich zwischen ### Variablen zur Anpassung befindet, muss angepasst werden.
- Code, der nur nmap verwendet:
Benötigt die Befehle curl, mosquitto_pub und nmap.
#/bin/bash
############################################################
## Senden der Anwesenheit des Telefons im WLAN an Gladys ##
############################################################
### Variablen zur Anpassung
# Anzahl der Sekunden zwischen den Temperaturabfragen
# Ein kleiner Wert ist keine sehr gute Idee...
TimeOut=30
# Adresse des Gerätetopics
# Verfügbar in Gladys > Integration > MQTT > Geräte > Raspberry-Temperatur > Temperatur > MQTT-Topic zum Veröffentlichen
Topic="gladys/master/device/mqtt:Raum:PhoneConnected/feature/mqtt:PhoneConnected:StateConnection/state"
# IP des Telefons
PhoneIP="192.168.0.100"
# MAC-Adresse des Telefons
PhoneMAC="AA:BB:CC:DD:EE:FF"
# Standardmäßig ist das Telefon nicht verbunden
OldState=0
### Variablen zur Anpassung
# Laden der gemeinsamen Datei
source /opt/mosquitto/MQTTConfig.sh
# Überprüfung der Anwesenheit der Befehle, die bei Abwesenheit das Skript beenden
# Benötigt den Befehl curl des Pakets curl
# Benötigt den Befehl mosquitto_pub des Pakets mosquitto-clients
# Benötigt den Befehl nmap des Pakets nmap
! CommandCheck "curl:curl" "mosquitto_pub:mosquitto-clients" "nmap:nmap" && exit 1
# Blockiert das Skript, wenn TimeOut kleiner als 1 ist
if (( ${TimeOut:-0} < 1 ))
then
echo -e "[${ROUGE}Fehler${RAZ}] TimeOut ist unangemessen." 1>&2
exit 1
fi
# Unendliche Schleife
while true
do
# Suche nach der IP des Telefons mit nmap und dann nach seiner MAC-Adresse im Ergebnis
# Wenn wir es finden, ist es ein falscher Negativfall
sudo nmap -sP -n "${PhoneIP}" | grep -q "${PhoneMAC}" && State=1 || State=0
# Wenn sich der Zustand ändert
if [[ ${State} != ${OldState} ]]
then
# Aktualisierung der Vergleichsvariablen
OldState=${State}
# Anzeige der Information
echo -e "[${FUCHSIA}$(date +'%x %X')${RAZ}] Der Verbindungsstatus des Telefons hat sich geändert, Verbindungsstatus: ${BLEUFONCE}${State}${RAZ}."
# Senden der Information an Gladys mit mosquitto_pub
# -u User: Benutzername für die Verbindung zum MQTT-Broker, stammt aus der Datei MQTTConfig.sh
# -P Pass: Passwort für die Verbindung zum MQTT-Broker, stammt aus der Datei MQTTConfig.sh
# -t Topic: Adresse des Gerätetopics, das in Gladys erstellt wurde, definiert zu Beginn des Skripts
# -m Temperatur: Verwendung der Temperatur
mosquitto_pub -u "${User}" -P "${Pass}" -t "${Topic}" -m "${State}"
# Abrufen des Rückgabewerts des Befehls mosquitto_pub
MosquittoReturns=${?}
# Anzeige des MQTT-Fehlercodes, wenn Rückgabewert > 0
(( ${MosquittoReturns} )) && echo -e "[${ROUGE}Fehler${RAZ}] Der Befehl mosquitto_sub hat den Code ${MosquittoReturns} zurückgegeben." 1>&2
fi
# Pause des Skripts für die angeforderte Zeit
sleep "${TimeOut}"
done
In diesem Beispiel sucht der Befehl nmap die IP meines Telefons (192.168.0.100) und seine MAC-Adresse (AA:BB:CC:DD:EE:FF) alle 30 Sekunden.
Wenn sich der Zustand ändert, wird er an Gladys gesendet.
- Version mit der Freebox:
Um mit der Freebox-API zu kommunizieren, ist es notwendig, eine App auf der Freebox zu deklarieren.
Schnelles Tutorial dazu:
Ausführung des Befehls curl:
curl -X POST -i "http://mafreebox.freebox.fr/api/v10/login/authorize/" --data '{
"app_id": "fr.freebox.gladys",
"app_name": "Präsenz Telefon",
"app_version": "0.1",
"device_name": "pi"
}'
Wir erstellen eine App mit dem Namen Präsenz Telefon und der ID fr.freebox.gladys.
Man muss die Aktion auf dem Bildschirm der Freebox bestätigen (zumindest bei meiner Freebox Revolution).
Das gibt etwas wie:
{"success":true,"result":{"app_token":"xxxxxxx","track_id":1}}
Es ist wichtig, den app_token zu behalten! Er muss in den Skriptparametern angegeben werden.
Die App muss bestätigt werden, wir überprüfen mit den curl- und jq-Befehlen:
track_id=1 # Nummer, die in der Rückgabe des vorherigen Befehls angegeben ist
curl "http://mafreebox.freebox.fr/api/v10/login/authorize/${track_id}" 2>/dev/null | jq -r '.result.status'
Das muss granted zurückgeben.
Falls nicht, müssen Sie etwas warten, bevor Sie den Befehl erneut ausführen.
Das Skript erfordert die Befehle curl, mosquitto_pub, jq und nmap.
#/bin/bash
############################################################
## Senden der Telefonpräsenz im WLAN an Gladys ##
############################################################
### Zu personalisierende Variablen
# Anzahl der Sekunden zwischen den Temperaturabfragen
# Ein kleiner Wert ist keine sehr gute Idee...
TimeOut=30
# Adresse des Gerätetopics
# Verfügbar in Gladys > Integration > MQTT > Geräte > Raspberry-Temperatur > Temperatur > MQTT-Topic zum Veröffentlichen
Topic="gladys/master/device/mqtt:Salle:PhoneConnected/feature/mqtt:PhoneConnected:StateConnection/state"
# FreeBox-App-ID
AppId="fr.freebox.gladys"
# FreeBox-App-Token
FreeBoxAppToken="xxxxxxx"
# FreeBox-API, ich verwende v10
FreeBoxAPi="http://mafreebox.freebox.fr/api/v10"
# Telefon-IP
PhoneIP="192.168.0.100"
# Telefon-MAC-Adresse
PhoneMAC="AA:BB:CC:DD:EE:FF"
# Standardmäßig ist das Telefon nicht verbunden
OldState=0
### Zu personalisierende Variablen
# Laden der gemeinsamen Datei
source /opt/mosquitto/MQTTConfig.sh
# Überprüfung der Anwesenheit der Befehle, die bei Abwesenheit den Skriptstopp verursachen
# Benötigt den Befehl curl des Pakets curl
# Benötigt den Befehl mosquitto_pub des Pakets mosquitto-clients
# Benötigt den Befehl jq des Pakets jq
# Benötigt den Befehl nmap des Pakets nmap
! CommandCheck "curl:curl" "mosquitto_pub:mosquitto-clients" "jq:jq" "nmap:nmap" && exit 1
# Blockiert das Skript, wenn TimeOut kleiner als 1 ist
if (( ${TimeOut:-0} < 1 ))
then
echo -e "[${ROUGE}Fehler${RAZ}] TimeOut ist unangemessen." 1>&2
exit 1
fi
# Funktion zur Verbindung mit der FreeBox
function FreeBoxConnection()
{
# Abrufen der Challenge
Challenge="$(curl "${FreeBoxAPi}/login/" 2>/dev/null | jq -r '.result.challenge')"
# Hash der Challenge mit dem App-Token
Password="$(printf "${Challenge}" | openssl sha1 -hmac "${FreeBoxAppToken}")"
Password="${Password##* }"
# Anforderung eines Sitzungstokens
SessionTokenRequest=$(curl -s -X POST "${FreeBoxAPi}/login/session/" --data "{
\"app_id\": \"${AppId}\",
\"password\": \"${Password}\"
}")
# Abrufen des Sitzungstokens
SessionToken=$(jq -r '.result.session_token' <<< "${SessionTokenRequest}")
# Wenn kein Sitzungstoken vorhanden ist, wird das Problem gemeldet
if [[ "${SessionToken}" == "null" ]]
then
echo -e "[${ROUGE}Fehler${RAZ}] Es ist nicht möglich, das Sitzungstoken abzurufen!."
return 1
fi
# Wenn alles in Ordnung ist
return 0
}
# Endlosschleife
while true
do
# Abrufen der Verbindungen
FreeBoxInfos=$(curl --header "X-Fbx-App-Auth: ${SessionToken}" "${FreeBoxAPi}/wifi/ap/1/stations/" 2>/dev/null)
# Wenn die Verbindung nicht mehr aktiv ist
if [[ $(jq '.success' <<< "${FreeBoxInfos}") == "false" ]]
then
# Endlosschleife, die versucht, eine Verbindung herzustellen
while ! FreeBoxConnection
do
sleep "${TimeOut}"
done
# Sobald die Schleife verlassen wird, startet die übergeordnete Schleife neu
continue
fi
# Suche nach dem Telefon in der FreeBox-Verbindungsrückgabe mit seiner MAC-ID
# Achtung, der Status ist invertiert für mehr Klarheit in Gladys
# 1 = verbunden, 0 = getrennt
grep -q "${PhoneMAC}" <<< "${FreeBoxInfos}" && State=1 || State=0
# 2. Überprüfung im Falle einer Nichtverbindung mit nmap
# Seltenes Szenario, in dem alles in Ordnung zu sein scheint, aber die Rückgabe das Telefon nicht anzeigt
if (( ! ${State} ))
then
# Suche nach der Telefon-IP mit nmap und dann nach der MAC-Adresse im Ergebnis
# Wenn wir es finden, ist es ein falsch-negatives Ergebnis
sudo nmap -sP -n "${PhoneIP}" | grep -q "${PhoneMAC}" && State=1
fi
# Wenn sich der Status geändert hat
if [[ ${State} != ${OldState} ]]
then
# Aktualisierung der Vergleichsvariablen
OldState=${State}
# Anzeige der Information
echo -e "[${FUCHSIA}$(date +'%x %X')${RAZ}] Der Verbindungsstatus des Telefons hat sich geändert, Verbindungsstatus: ${BLEUFONCE}${State}${RAZ}."
# Senden der Information an Gladys mit mosquitto_pub
# -u User: Benutzername für die Verbindung zum MQTT-Broker, stammt aus der Datei MQTTConfig.sh
# -P Pass: Passwort für die Verbindung zum MQTT-Broker, stammt aus der Datei MQTTConfig.sh
# -t Topic: Adresse des Gerätetopics, das in Gladys erstellt wurde, definiert zu Beginn des Skripts
# -m Temperatur: Verwendung der Temperatur
mosquitto_pub -u "${User}" -P "${Pass}" -t "${Topic}" -m "${State}"
# Abrufen des Rückgabewerts des Befehls mosquitto_pub
MosquittoReturns=${?}
# Anzeige des mosquitto-Fehlercodes, wenn der Rückgabewert > 0 ist
(( ${MosquittoReturns} )) && echo -e "[${ROUGE}Fehler${RAZ}] Der Befehl mosquitto_sub hat den Code ${MosquittoReturns} zurückgegeben." 1>&2
fi
# Pause des Skripts für die angeforderte Zeit
sleep "${TimeOut}"
done
Das Beispiel wird die Freebox alle 30 Sekunden nach den aktuellen Verbindungen fragen.
Wenn das Sitzungstoken nicht mehr gültig ist, wird ein neues angefordert.
Wenn das Telefon nicht vorhanden ist, füge ich einen Scan mit nmap hinzu, da die Freebox manchmal die Anwesenheit des Telefons nicht zurückgibt, obwohl sie es gut sieht.
Wenn man nmap zusätzlich zur Freebox nicht verwenden möchte:
Man muss ändern:
! CommandCheck "curl:curl" "mosquitto_pub:mosquitto-clients" "jq:jq" "nmap:nmap" && exit 1
zu
! CommandCheck "curl:curl" "mosquitto_pub:mosquitto-clients" "jq:jq" && exit 1
et man muss löschen:
# 2. Überprüfung im Falle einer Nichtverbindung mit nmap
# Seltenes Szenario, in dem alles in Ordnung zu sein scheint, aber die Rückgabe das Telefon nicht anzeigt
if (( ! ${State} ))
then
# Suche nach der Telefon-IP mit nmap und dann nach der MAC-Adresse im Ergebnis
# Wenn wir es finden, ist es ein falsch-negatives Ergebnis
sudo nmap -sP -n "${PhoneIP}" | grep -q "${PhoneMAC}" && State=1
fi
- Ausführung des Skripts:
Es reicht ein einfaches:
bash /opt/mosquitto/PhoneConnected.sh
Das zeigt zum Beispiel an:
[24/03/2023 16:18:21] Der Verbindungsstatus des Telefons hat sich geändert, Verbindungsstatus: 1.
[24/03/2023 16:18:52] Der Verbindungsstatus des Telefons hat sich geändert, Verbindungsstatus: 0.
[24/03/2023 16:19:23] Der Verbindungsstatus des Telefons hat sich geändert, Verbindungsstatus: 1.
…
Und der Wert wird in Gladys aktualisiert.
Im Fehlerfall sollten Fehlermeldungen angezeigt werden.
Wenn alles funktioniert, bleibt nur noch die Ausführung des Skripts beim Starten des Raspberry (crontab oder anderes).
Zögern Sie nicht, Feedback zu geben, wenn Sie Fragen oder Verbesserungsvorschläge haben.
Weitere Tutorials:
TUTORIAL Nr. 1: Anzeigen der Raspberry-Temperatur in Gladys.
TUTORIAL Nr. 2: Ausführen eines BASH-Befehls über eine Gladys-Aktion.
TUTORIAL Nr. 4: Verwaltung eines Robotersaugers unter Valetudo in Gladys.