[gelöst] MQTT2_CLIENT bzw. Client-Modul dazu verhindert longpoll?

Begonnen von Beta-User, 20 Februar 2021, 17:23:38

Vorheriges Thema - Nächstes Thema

drhirn

Beim Erstellen des Logs für Rudi ist mir aufgefallen, dass MQTT2_CLIENT eiskalt die ganze MQTT-Kommunikation mithört. Und da kommt ganz schön was zusammen (Audio).
Hier ein Ausschnitt: rhasspyMQTT2: dispatch autocreate=no\000rhasspyMQTT2\000hermes/audioServer/wohnzimmer/audioFrame\000RIFF$\010\000\000WAVEfmt \020\000\000\000\001\0

Ich kann mich dunkel erinnern, dass ich vor Urzeiten (bei Snips noch) zuerst FHEM Mqtt-Server spielen habe lassen. Aber dann auf einen externen Mosquitto gewechselt bin, weil FHEM mit der Verarbeitung der ganzen Anfragen Probleme hatte. Und ich glaube, da hatte ich auch das Phänomen mit nicht aktualisierenden Readings.

Kann das sein? Und wenn ja, kann ich irgendwie verhindern, dass MQTT_CLIENT alles mithört?

Im Anhang das (riesige) Log

drhirn

#16
@Rudi:

Rhasspy ist ein Sprachassistent, der aus verschiedensten Python-Modulen zusammengesetzt ist. Sämtliche dieser Teile kommunizieren via MQTT miteinander (via Hermes Protokoll).

Das 10_RHASSPY Modul für FHEM macht nichts anderes, als sich in diese MQTT-Kommunikation einzuhängen und Intents auszuwerten, sofern sie nach einem gewissen Schema (z.B. de.fhem:SetOnOff) benannt sind.

Dazu muss zum einen natürlich das Modul installiert sein, zum anderen müssen auch die zu schaltenden Devices mit bestimmten Attributen versehen werden. Das sind:

  • rhasspyName - Der Name, unter dem das Device angesprochen werden soll
  • rhasspyRoom - Der physische Raum, in dem sich das Device befindet
  • rhasspyMapping - Die Befehle, mit den das Gerät gesteuert werden kann
  • room - Um vom Modul angesprochen werden zu könne, müssen die Devices im FHEM-room Rhasspy sein

Ein ganz einfaches Dummy-Device könnte z.B. so aussehen:

defmod lampe dummy
attr lampe rhasspyMapping SetOnOff:cmdOn=on,cmdOff=off\
GetOnOff:currentVal=state,valueOff=off
attr lampe rhasspyName lampe,radio
attr lampe rhasspyRoom wohnzimmer,schlafzimmer
attr lampe room Rhasspy
attr lampe setList toggle on off


Die Logik zur Spracherkennung läuft ausschließlich in der "Rhasspy-Base" ab. Dort werden auch Slots (Devices, Räume, Farben, etc.) und Sentences/Intents (z.B. "schalte das licht ein") definiert.
Ein gültiger Intent zum Steuern obiger Lampe wäre z.B.

[de.fhem:SetOnOff]
\[schalte] lampe{Device} (an|aus){Value}

("schalte" ist optional, deswegen in eckigen Klammern; {Device} und {Value} sind "Slot-Namen", die 10_RHASSPY unter anderem auswertet; "an" und "aus" können beide verwendet werden)

Spricht man jetzt den Satz "lampe an", verarbeitet die Rhasspy-Base diesen und schickt eine MQTT-Nachricht an hermes/intent/de.fhem:SetOnOff. Die könnte z.B. so aussehen:
{"input": "lampe an", "intent": {"intentName": "de.fhem:SetOnOff", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "lampe"}, "slotName": "Device", "rawValue": "lampe", "confidence": 1.0, "range": {"start": 0, "end": 5, "rawStart": 0, "rawEnd": 5}}, {"entity": "OnOffValue", "value": {"kind": "Unknown", "value": "an"}, "slotName": "Value", "rawValue": "an", "confidence": 1.0, "range": {"start": 6, "end": 8, "rawStart": 6, "rawEnd": 9}}], "sessionId": "wohnzimmer-snowboy-05371e8d-da8a-45ec-a7cd-859c1285c68e", "customData": null, "asrTokens": [[{"value": "radio", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 5, "time": null}, {"value": "an", "confidence": 1.0, "rangeStart": 6, "rangeEnd": 8, "time": null}]], "asrConfidence": null, "rawInput": "lampe an", "wakewordId": "snowboy", "lang": null}

10_RHASSPY weißt durch den "intentName", dass es zuständig ist. Es wertet den Inhalt aus ("Device", "Value", "siteId" oder "room" wenn vorhanden) und bastelt daraus ein FHEM-Kommando. Welches dann auch ausgeführt wird. Anschließend wird eine Antwort an hermes/dialogueManager/endSession gesendet, damit Rhasspy weiß, dass die Session abgeschlossen ist.


Um zu testen brauchst du also eine Rhasspy-Instanz. Da würde sich Docker anbieten.

docker-compose.yml:

version: '3'

services:
    rhasspy:
        image: "rhasspy/rhasspy"
        container_name: rhasspy
        restart: unless-stopped
        volumes:
            - ".config/rhasspy/profiles:/profiles"
            - "/etc/localtime:/etc/localtime:ro"
            - "/etc/asound.conf:/etc/asound.conf"
        ports:
            - "12101:12101"
            - "12183:12183"
        command: --user-profiles /profiles --profile de
        devices:
          - "/dev/snd:/dev/snd"
        ipc: host


12101 ist der Port des Webinterfaces
12183 ist der Port des "internen" MQTT-Servers

Das jetzt genau zu erklären, sprengt ein bisschen den Rahmen. Hier ist ein praktischer Getting-Started-Guide: https://rhasspy.readthedocs.io/en/latest/tutorials/#getting-started-guide


Zu 10_RHASSPY.pm:
Damit das Modul sich zu Rhasspy verbinden kann, braucht es in Version 0.2.0 ein MQTT2_DEVICE mit geänderter clientOrder:

defmod <Devicename> MQTT2_CLIENT <MQTT url:port der Rhasspy-Base>
attr <Devicename> clientOrder RHASSPY MQTT_GENERIC_BRIDGE MQTT2_DEVICE


Dieses MQTT2_CLIENT Device muss dann als IODev von 10_RHASSPY.pm verwendet werden.
defmod <Devicename> RHASSPY <IODev> <Standardraum>
"<Standardraum>" dient nur dazu, 10_RHASSPY zu sagen, welchen Raum es verwenden soll, wenn ich Sprachkommando keiner angegeben wird.

Im 10_RHASSPY-Device muss dann noch die URL zum Rhasspy-Base HTTP-API angegeben werden, damit die Slots aktualisiert werden können:
attr <10_RHASSPY-Devicename> rhasspyMaster http://<URL der Rhasspy-Base>:12101

Anschließend ein Test-Device mit den oben genannten Attributen versehen und in den Raum "Rhasspy" legen.

Dann "set updateSlots" und "set trainRhasspy" im 10_RHASSPY ausführen.


Anschließend kannst du - sollte ich nichts vergessen haben - mit "set textCommand ..." Befehle ausführen. Z.B.:
set <10_RHASSPY-Devicename> textCommand lampe an


Ist das irgendwie hilfreich? Wenn Fragen offen sind, gerne! Ansonsten hab ich heute morgen die CmdRef korrigiert, die funktioniert jetzt. Und es gibt das README auf GitHub.


Beta-User

Zitat von: drhirn am 21 Februar 2021, 11:14:36
Beim Erstellen des Logs für Rudi ist mir aufgefallen, dass MQTT2_CLIENT eiskalt die ganze MQTT-Kommunikation mithört. Und da kommt ganz schön was zusammen (Audio).
[...]
Kann das sein? Und wenn ja, kann ich irgendwie verhindern, dass MQTT_CLIENT alles mithört?
OK, dann hätte ein Blick in die Doku genügt...

@drhirn: Setz' die Subscriptions bei MQTT2_CLIENT mal auf "setByTheProgram" und aktiviere diese beiden Zeilen wieder.

@Rudi, sorry für die Frage, war mir bisher nicht bewußt, dass es da diesen "kleinen aber feinen" Unterschied gibt, da muss ich mir auf für das attrTemplate-Thema @MGB noch was überlegen...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

drhirn

Doku hätte mir nichts genützt, weil ich's eh nicht verstanden hätte ;).

Leider war das dann wohl nicht der Grund. Keine Änderung im Verhalten.

Hier das aktuelle (jetzt natürlich wesentlich kleinere Log):


2021.02.22 08:52:22.906 5: rhasspyMQTT2: dispatch autocreate=no\000rhasspyMQTT2\000hermes/dialogueManager/sessionStarted\000{"sessionId": "wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67", "siteId": "wohnzimmer", "customData": "snowboy", "lang": null}
2021.02.22 08:52:22.906 4: RHASSPY_Parse called, short Topic is hermes/dialogueManager/
2021.02.22 08:52:22.907 4: grep found hermes/dialogueManager/
2021.02.22 08:52:22.907 5: RHASSPY: [Rhasspy] Parse (MQTT2_CLIENT : 'rhasspyMQTT2'): Msg: hermes/dialogueManager/sessionStarted => {"sessionId": "wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67", "siteId": "wohnzimmer", "customData": "snowboy", "lang": null}
2021.02.22 08:52:22.907 5: Parsed value: wohnzimmer for key: siteId
2021.02.22 08:52:22.908 5: Parsed value: wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67 for key: sessionId
2021.02.22 08:52:26.615 5: rhasspyMQTT2: dispatch autocreate=no\000rhasspyMQTT2\000hermes/intent/de.fhem_SetOnOff\000{"input": "deckenlampe an", "intent": {"intentName": "de.fhem:SetOnOff", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "deckenlampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 0, "end": 11, "rawStart": 0, "rawEnd": 11}}, {"entity": "OnOffValue", "value": {"kind": "Unknown", "value": "an"}, "slotName": "Value", "rawValue": "ein", "confidence": 1.0, "range": {"start": 12, "end": 14, "rawStart": 12, "rawEnd": 15}}], "sessionId": "wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67", "customData": null, "asrTokens": [[{"value": "deckenlampe", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 11, "time": null}, {"value": "an", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 14, "time": null}]], "asrConfidence": null, "rawInput": "deckenlampe ein", "wakewordId": "snowboy", "lang": null}
2021.02.22 08:52:26.616 4: RHASSPY_Parse called, short Topic is hermes/intent/
2021.02.22 08:52:26.616 4: grep found hermes/intent/
2021.02.22 08:52:26.616 5: RHASSPY: [Rhasspy] Parse (MQTT2_CLIENT : 'rhasspyMQTT2'): Msg: hermes/intent/de.fhem_SetOnOff => {"input": "deckenlampe an", "intent": {"intentName": "de.fhem:SetOnOff", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "deckenlampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 0, "end": 11, "rawStart": 0, "rawEnd": 11}}, {"entity": "OnOffValue", "value": {"kind": "Unknown", "value": "an"}, "slotName": "Value", "rawValue": "ein", "confidence": 1.0, "range": {"start": 12, "end": 14, "rawStart": 12, "rawEnd": 15}}], "sessionId": "wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67", "customData": null, "asrTokens": [[{"value": "deckenlampe", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 11, "time": null}, {"value": "an", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 14, "time": null}]], "asrConfidence": null, "rawInput": "deckenlampe ein", "wakewordId": "snowboy", "lang": null}
2021.02.22 08:52:26.616 5: Parsed value: deckenlampe ein for key: rawInput
2021.02.22 08:52:26.616 5: Parsed value: an for key: Value
2021.02.22 08:52:26.617 5: Parsed value: wohnzimmer for key: siteId
2021.02.22 08:52:26.617 5: Parsed value: deckenlampe an for key: input
2021.02.22 08:52:26.617 5: Parsed value: wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67 for key: sessionId
2021.02.22 08:52:26.617 5: Parsed value: 1 for key: probability
2021.02.22 08:52:26.617 5: Parsed value: SetOnOff for key: intent
2021.02.22 08:52:26.618 5: Parsed value: deckenlampe for key: Device
2021.02.22 08:52:26.618 5: handleIntentSetOnOff called
2021.02.22 08:52:26.618 5: Device selected: lampe1
2021.02.22 08:52:26.618 5: rhasspyMapping selected: cmdOn=on,cmdOff=off
2021.02.22 08:52:26.618 5: Cmd: >set lampe1 on<
2021.02.22 08:52:26.619 4: dummy set lampe1 on
2021.02.22 08:52:26.619 5: Running command [on] on device [lampe1]
2021.02.22 08:52:27.456 5: rhasspyMQTT2: dispatch autocreate=no\000rhasspyMQTT2\000hermes/dialogueManager/sessionEnded\000{"termination": {"reason": "nominal"}, "sessionId": "wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67", "siteId": "wohnzimmer", "customData": "snowboy"}
2021.02.22 08:52:27.456 4: RHASSPY_Parse called, short Topic is hermes/dialogueManager/
2021.02.22 08:52:27.457 4: grep found hermes/dialogueManager/
2021.02.22 08:52:27.457 5: RHASSPY: [Rhasspy] Parse (MQTT2_CLIENT : 'rhasspyMQTT2'): Msg: hermes/dialogueManager/sessionEnded => {"termination": {"reason": "nominal"}, "sessionId": "wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67", "siteId": "wohnzimmer", "customData": "snowboy"}
2021.02.22 08:52:27.457 5: Parsed value: wohnzimmer for key: siteId
2021.02.22 08:52:27.457 5: Parsed value: wohnzimmer-snowboy-509a272f-b819-4af4-b214-c107e7c14a67 for key: sessionId

Beta-User

Hmm, das sieht schon mal besser aus, (und ist auch auffschlussreich hinsichtlich der Funktionsweise usw.).
Allerdings kann ich nach der Bereinigung der Flut im Moment erst recht keinen Grund mehr erkennen, warum longpoll aus dem Tritt kommen sollte....
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

JensS

Nachdem ich gestern Abend die 0.2.0 getestet habe, wurde mein Logfile (./log/Rhasspy_Intent.log Rhasspy:lastIntentPayload.*) nicht weiter gefüllt.
Es scheint, als wurde kein Event ausgelöst.
Gruß Jens
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.

rudolfkoenig

Wenn ich mit "mosquitto_pub -i id -t topic -m msg" an MQTT2_CLIENT mit "attr global verbose 5" was sende, dann schaut das so aus:
Zitat2021.02.22 22:28:36 5: m2c: dispatch autocreate=simple\000m2c\000topic\000msg
2021.02.22 22:28:36 4: MQTT2_DEVICE_Parse: MQTT2_m2c topic => topic
2021.02.22 22:28:36 5: Starting notify loop for MQTT2_m2c, 1 event(s), first is topic: msg
2021.02.22 22:28:36 5: End notify loop for MQTT2_m2c

In eurem Log sehe ich kein "Starting notify loop", d.h. RHASSPY_Parse hat nicht den Namen des betroffenen Geraetes zurueckgeliefert.

Beta-User

Argh, also mein Fehler, sorry...

Danke für's Schubsen, dann sollte es vollends gelingen, das auch an der Stelle gradezuziehen ::) .

@drhirn:
update folgt irgendwann dann noch, aber kannst du bis dahin bitte auch schauen, ob das mit den subscriptions immer zuverlässig klappt. Da gab es auch irgendein Problem, das aber über einen etwas längeren timer bei der Initialisierung gelöst sein sollte...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Beta-User

Kurze Rückmeldung:
Funktioniert jetzt wohl alles, wie es soll (bzw. der weitere Weg ist klarer), siehe https://forum.fhem.de/index.php/topic,118926.msg1135195.html#msg1135195

So langsam habe ich auch eine nähere Vorstellung, warum der Matching-Mechanismus @MySensors und MQTT-alt aus Sicht der Wissenden nicht so prickelnd ist... (hab's irgendwo weit unten auf der Liste, das ggf. für MySensors umzubauen).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files