MQTT - Externe Geräte (Smartphone) einbinden

Hallo @spenceur

Kannst du mir bei der Konfiguration der Anwendung helfen?
Wenn ich auf „Verbindung prüfen“ klicke, erhalte ich immer den Fehler „Verbindung fehlgeschlagen“.
Welchen Port hast du konfiguriert? Mit TLS oder ohne?

Danke für deine Hilfe :slight_smile:

Hallo

Kein TLS

Danke für deine Antwort :slight_smile:

Ich verstehe nicht, aber es ist unmöglich, sich mit « Testverbindung » zu verbinden. Jedes Mal bekomme ich einen « Timeout »-Fehler.

Trotzdem habe ich sogar die Firewall in meinem Raspberry Pi überprüft, Port 1883 ist offen, das Passwort Gladys ist korrekt, ich habe keine Idee mehr zum Debuggen..

Ich frage mich, ob es nicht eine Einschränkung auf dem MQTT-Server gibt, die standardmäßig auf localhost beschränkt ist.

[EDIT]

$ sudo cat /var/lib/gladysassistant/mosquitto/mosquitto.conf

allow_anonymous false
connection_messages true
password_file /mosquitto/config/mosquitto.passwd
listener 1883

Die Ports sind sowohl für eingehenden als auch für ausgehenden Verkehr in iptables geöffnet, also sehe ich nicht, was nicht funktioniert.

Auf Ebene der Mosquitto-Logs gibt es nur die Verbindungen von Gladys:

0: mosquitto version 2.0.12 starting
0: Config loaded from /mosquitto/config/mosquitto.conf.
0: Opening ipv4 listen socket on port 1884.
0: Opening ipv6 listen socket on port 1884.
0: mosquitto version 2.0.12 running
0: New connection from 127.0.0.1:32768 on port 1884.
0: New client connected from 127.0.0.1:32768 as mqttjs_cb088900 (p2, c1, k60, u'z2m').
0: New connection from 127.0.0.1:32770 on port 1884.
0: New client connected from 127.0.0.1:32770 as gladys-main-instance-473225 (p2, c1, k60, u'gladys').

[EDIT 2]

Über meinen VPN Wireguard, der auf dem Raspberry Pi läuft, kann ich die Anwendung mit MQTT verbinden. Es handelt sich also definitiv um ein Problem mit dem eingehenden Datenverkehr.
Danke für deine Bestätigung der App-Konfiguration :slight_smile:

Wie hast du das in dem „Zeitplan“-Bereich der Anwendung konfiguriert?

Ich habe das in der Android-App eingestellt, es wird erfolgreich gesendet, aber Gladys scheint die Daten nicht zu verstehen (ich sehe nichts in Gladys oder in den Logs):

  • Presence Topic: oneplus7tpro/presence
  • Battery Topic: oneplus7tpro/battery

[EDIT]

Tatsächlich wird es in Gladys angezeigt, nämlich:

gladys/master/device/mqtt:oneplus7tpro/feature/mqtt:oneplus7tpro:presence/state

Genau :slight_smile:
Falls du mehr Infos brauchst, zögere nicht

Ich habe gerade einige Szenen erstellt, um meine Anwesenheit zu verwalten, aber es funktioniert nicht wie gewünscht.

  1. Bei einer Statusänderung meines Telefons zeigt es an: „Benutzer gesehen zu Hause“.

  2. Alle 16 Minuten löst es „Präsenz in den letzten 15 Minuten überprüfen“ aus und markiert mich als abwesend, falls zutreffend.

Mein Telefon sendet alle 15 Minuten ein WLAN-Signal, um anzuzeigen, dass ich da bin. Wenn ich mein WLAN deaktiviere, wird das Signal nicht mehr empfangen und Gladys markiert mich als abwesend. Perfekt!

ABER WENN ich das WLAN wieder aktiviere, wird das Signal zwar von Gladys empfangen, ist aber identisch mit den vorherigen und löst die Szene 1 nicht aus, die mich nie als anwesend markiert.

Dabei kann der Block „Präsenz überprüfen“ mich als abwesend markieren, aber nicht als anwesend, wenn er mich erkennt (es steht sogar explizit, dass Gladys nichts tut, wenn sie mich erkennt).

Wie kann ich dieses Problem lösen? Für mich ist das ein Problem, das es eigentlich nicht geben sollte. Entweder fehlt ein Auslöser oder der Block „Präsenz überprüfen“ muss verbessert werden.
Oder ich habe etwas übersehen :sweat_smile:

Hast du die Anwendung 1 wirklich beim Verbinden mit dem Netzwerk gesetzt?
Hier ist mein Gerät:


Nur zur Information, ich sende auch den Batteriezustand, das kann ja nie schaden :slight_smile:

Und auf der Anwendungsseite



Ich habe zwei, weil ich mehrere Netzwerke zu Hause habe :slight_smile:

Dann prüfe ich auf Szenarien den Zustand meines OnePlus (Anwesenheit und Abwesenheit) und fertig

Der Unterschied zwischen unseren beiden Situationen liegt im Typ der Nachricht.

Alles ist auf meiner Seite identisch, außer dass ich keine Abwesenheitsnachrichten sende.
Ich möchte lieber, dass Gladys das Signal als „keepalive“ erkennt.

  • Wenn das Signal weniger als 16 Minuten alt ist, bin ich da
  • Andernfalls bin ich abwesend

Ich habe das Problem gefunden: Es ist der Auslöser „Präsenz erkennen“, der auf eine Signaländerung wartet. Im Gegensatz zum Auslöser auf einem einfachen Gerät, der alle Ereignisse berücksichtigen kann.
Und in meinem Fall wird nur alle 15 Minuten ein Präsenzsignal gesendet und kein Abwesenheitssignal. Daher werden die neuen Signale nicht berücksichtigt.
Ist das beabsichtigt @pierre-gilles ?

Mein einziger Trick ist es, den Batteriewert meines Telefons zu verwenden, um einen Sensorwert zu erhalten, der die Verwendung des Standardauslösers für alle Sensoren ermöglicht.

Genau so ist es vorgesehen :slight_smile: Die Bluetooth-Integration funktioniert auf die gleiche Weise, sie erwartet, dass ein « 1 » empfangen wird, jedes Mal, wenn ein Bluetooth-Gerät erkannt wird. Allerdings erwartet sie nicht, dass ein Bluetooth-Gerät « 0 » sendet, wenn es nicht erkannt wird. Genau das Fehlen des Sendens von « 1 » erzeugt eine Abwesenheit auf Gladys-Seite.

Ebenso, wenn du zurückkommst, normalerweise ist es nicht nötig, über eine 0 zu gehen, damit die 1 kompatibilisiert wird.

Siehe Bluetooth-Tutorial:

Kannst du das genauer erklären? :slight_smile:

Kannst du uns Screenshots deiner Szenen zeigen, damit wir sehen können, wo es hakt?

Hier sind die beiden Szenen, die ich zur Verwaltung meiner Anwesenheit verwende.

1 - Anwesenheit

2 - Abwesenheit


Untersuchungen

In Szene Nr. 1, wenn ich mich nur auf „Gerätestatusänderung“ verlasse, markiert Gladys mich nie als anwesend, obwohl die Anzeige des Geräts „Anwesenheit“ im Dashboard korrekt ist (z. B. nach einigen Sekunden).
Wenn ich das Gerät „Batterie“ hinzufüge, das mit meinem Telefon verbunden ist und gleichzeitig mit meiner Anwesenheit gesendet wird, kann ich die Option „Nur ausführen, wenn der Schwellenwert überschritten wird“ deaktivieren, wodurch ich bei jeder empfangenen Nachricht als anwesend markiert werden kann.

[EDIT]

Letzte Frage: Warum kann der Block „Präsenz prüfen“ mich nicht als Anwesend oder Abwesend markieren, wenn er ein Signal im angegebenen Zeitraum erkennt?
Aktuell kann er mich nur als abwesend markieren, aber ich hätte gerne die Möglichkeit, diese Funktion auch zu nutzen, um als anwesend markiert zu werden.

Super seltsam! Die Auslöser « Anwesenheitserkennung » haben die Option « Nur ausführen, wenn die Schwelle überschritten wird » ausgeblendet und standardmäßig auf « falsch » gesetzt. Du kannst das übrigens in den API-Aufrufen überprüfen, die Route GET /api/scene/:scene_selector sollte dir etwas wie das Folgende anzeigen:

Ich habe gerade einen Test bei mir zu Hause durchgeführt und konnte dein Problem nicht reproduzieren: Die Szene wird bei mir jedes Mal korrekt ausgeführt…

Weil wir den Benutzer so schnell wie möglich als anwesend markieren wollen, wenn du nach Hause kommst, und nicht unbedingt alle X Minuten, wenn du deine Szene alle X Minuten programmiert hast.

Wenn du deine Szene alle 10 Minuten programmiert hast, bedeutet das, dass dein Benutzer erst nach potenziell 10 Minuten als zu Hause markiert wird.

Wenn du eine Szene hast, die sofort ausgelöst wird, sobald das Gerät erkannt wird, ist es zumindest quasi sofort und wenn du eine Szene « Wenn ich nach Hause komme » hast, die das Licht einschaltet und alles, willst du, dass es direkt passiert.

Ich verstehe, in diesem Fall fehlt eine Option in diesem Block „mich als abwesend markieren, wenn in diesem Zeitraum kein Signal erkannt wurde“.

Denn das wollte ich machen, ohne es zu schaffen, weil es meiner Meinung nach standardmäßig nicht möglich ist.

Genau das ist es, ich glaube nicht, dass wir diese Option wollen, das ist nicht so toll für die Benutzererfahrung!

Aber ich würde wirklich gerne verstehen, warum die Erkennung bei dir nicht funktioniert, bei mir funktioniert es perfekt! ^^

Kannst du das JSON deiner Szene über die API anzeigen lassen, wie in meinem vorherigen Post gezeigt? :slight_smile:

{
    "id": "b1a0b488-02eb-4b3d-b5d9-d8fb3b016328",
    "name": "Anwesenheit: Louis ist da",
    "icon": "home",
    "active": true,
    "selector": "presence-louis-est-la",
    "actions": [
        [
            {
                "type": "user.set-seen-at-home",
                "user": "louis",
                "house": "ermont"
            }
        ],
        []
    ],
    "triggers": [
        {
            "type": "device.new-state",
            "device_feature": "mqtt-oneplus7tpro-presence",
            "value": 1,
            "operator": "=",
            "threshold_only": false
        },
        {
            "type": "device.new-state",
            "device_feature": "mqtt-oneplus7tpro-battery",
            "value": 0,
            "operator": ">="
        }
    ],
    "last_executed": null,
    "created_at": "2021-03-29T16:02:53.000Z",
    "updated_at": "2021-10-14T20:51:33.668Z"
}

« threshold_only »: false

Das sieht für mich gut aus!

Hast du spezifische Logs auf der Gladys-Seite, die erklären könnten, warum es nicht funktioniert? Bist du dir zu 1000% sicher, dass ein ganzzahliger Wert 1 jedes Mal über die MQTT-Integration gesendet wird, wenn du es versuchst?

Denn ich kann es wirklich nicht reproduzieren. Bei mir wird die Szene jedes Mal ausgeführt, wenn ich 1 mehrmals hintereinander sende.

Ich glaube, das Problem kommt von meiner Präsenz-Publisher-Anwendung, die „online“ statt „1“ sendet.

Ich habe gerade die Änderung in der Anwendung (die nicht gut dokumentiert ist) vorgenommen, das sollte das Problem beheben!

Aber für die Präsenz-Erkennungskomponente stelle ich die Frage anders:
Wie kann ich erkennen, dass ich anwesend bin, basierend auf einem sichtbaren Signal, wenn ich im WLAN bin, und dann auf das Fehlen eines Signals?

Das dachte ich mir schon.

Was meinst du? Was möchtest du tun?

Ich möchte, dass Gladys mich zu Hause erkennt, wenn mein Telefon im WLAN ist und ein MQTT-Signal sendet.
Und wenn das Signal nicht innerhalb von 15 Minuten empfangen wird, bin ich abwesend. Und genau dabei komme ich nicht weiter.

Na, machst du das nicht schon mit der Aktion „Präsenz prüfen“? Ich dachte, dieser Teil funktioniert gut

Entschuldigung, ich glaube, ich habe mich verheddert!

Zusammenfassung und Kontext:

  • Gladys ist bei mir zu Hause auf einem Raspberry Pi installiert und ist weder im Internet exponiert noch darauf zugreifbar.
  • Ich habe noch kein Gladys Plus-Abo, daher kein Zugriff auf Gladys direkt über das Internet.
  • Bedarf: Ich möchte als „anwesend“ definiert werden, wenn mein Telefon nur über WLAN verbunden ist.

Vorgehensweise:

  • Ich verwende presence publisher für Android, das es ermöglicht, sobald ich zu Hause über WLAN verbunden bin, MQTT-Nachrichten an Gladys zu senden.
  • In Gladys, unter « MQTT », erstelle ich ein neues Gerät vom Typ « Anwesenheit » mit den Werten « 1 » und « 0 » (keine andere Wahl als Zahlen).
  • Anwesenheitserkennung: In einer Szene ermöglicht der Block « Gerätezustandsänderung » für das MQTT-Gerät, das mit dem sendet, was meine Anwendung sendet, mich als anwesend zu markieren.
  • Abwesenheitserkennung: In einer anderen Szene markiere ich mich als abwesend, wenn das Signal älter als 15 Minuten ist. Dafür ermöglicht mir der Block « Prüfen der Anwesenheit » in den letzten 15 Minuten, mich als abwesend zu markieren, wenn das Signal nicht mehr empfangen wird.

Achtung: Standardmäßig sendet die Anwendung « online » und nicht « 1 » an Gladys. Sobald ich den Parameter in der Android-Anwendung geändert habe, funktionieren die Szenen wie erwartet (zuvor dachte ich, es wäre 1 und 0).

Tipp: Ich wollte, dass die Anwendung Nachrichten sendet, ohne ihr den Zugriff auf den GPS zu gewähren und meinen GPS immer eingeschaltet zu lassen (notwendig, um ihr zu ermöglichen, den WLAN-SSID zu kennen).
Ich verwende, was die Anwendung « Abwesenheitsnachrichten » nennt, um Gladys zu benachrichtigen, dass ich zu Hause im WLAN bin (logisch :sweat_smile:). Da Gladys mich als anwesend markiert, wenn sie Nachrichten hat, und als abwesend, wenn sie keine hat, funktioniert es so, wie ich es möchte!

Dafür:

  1. GPS-Berechtigung (Standort) verweigern
  2. Unter « Bedingungen » « Send without wifi » aktivieren
  3. Im Abschnitt « None of the above matches » « Send absence message » aktivieren und den Wert « Absence message » auf « 1 » ändern.