Von MQTT2_SERVER verschickte Nachrichten mit type "reserved"

Begonnen von krikan, 21 Oktober 2019, 21:19:21

Vorheriges Thema - Nächstes Thema

rudolfkoenig

ZitatDann warten wir mal ab...


Wenn man Folgendes:
sub
valetudo2svg($$$)
{
  my ($reading, $d, $filename) = @_;
  my %ret;

  if($d !~ m/height":(\d+),"width":(\d+).*?floor":\[(.*\])\]/) {
    $ret{$reading} = "ERROR: Unknown format";
    return \%ret;
  }
  my ($w,$h,$nums) = ($1, $2, $3);

  my $svg=<<"EOD";
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="$w" height="$h" viewBox="0 0 $w $h">
<g fill="#000000" stroke="none">
  <rect x="0" y="0" width="$w" height="$h" stroke="black" stroke-width="1" fill="none"/>
EOD

  $nums =~ s/\[(\d+),(\d+)\]/
    $svg .= "<rect x=\"$1\" y=\"$2\" width=\"1\" height=\"1\"\/>\n";
    ""
  /xge;
  $svg .= "</g></svg>";

  if(!open FD,">$filename") {
    $ret{$reading} = "ERROR: $filename: $!";
    return \%ret;
  }
  print FD $svg;
  close(FD);
  $ret{$reading} = "Wrote $filename";
  return \%ret;
}
in 99_myUtils.pm aufnimmt, und readingList der MQTT device mit
valetudo/rockrobo/map_data:.* {valetudo2svg("map_data",$EVENT,"www/images/valetudo_map.svg")}ergaenzt, dann kann man mitdefine valetudo_map weblink htmlCode <img src="fhem/images/valetudo_map.svg">das Bitmap anzeigen.

Zu meinem Verstaendnis: wann werden welche Bitmaps gesendet?

Beta-User

...wenn jemand ein funktionierendes Device hat und hier ein RAW einstellt, bastel ich gerne ein attrTemplate draus und packe den Code für's Wiederfinden ins Wiki (tendenziell zu den Praxisbeispielen, samt link im template...)
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

krikan

Rudi, das "Dann warten wir mal ab..." war nicht als Aufforderung an Dich gedacht, aber ich nehme den Code dankend an.  :)

Zitat von: rudolfkoenig am 23 Oktober 2019, 15:09:32
Zu meinem Verstaendnis: wann werden welche Bitmaps gesendet?
Bisherige Einschätzung:
Einmalig kommt  "ruhende" Grundrißbitmap mit Angabe der No-Go-Areas, Sauger/Ladestationsposition,...
Nach Start des Saugvorgangs wird jede Sekunde(!) die Grundrißbitmap wieder übertragen mit der geänderten Saugerposition (und Fahrweg?).
Habe mal einen Screenshot aus dem Valetudo-Frontend nach Start des Saugvorgangs als Beispiel angehängt; No-Go-Areas sind rot, Rest ist hoffentlich selbsterklärend. Am Ende des Saugvorgangs hat man in Valetudo eine Bitmap mit dem kompletten Fahrweg.

Zitat von: Beta-User am 23 Oktober 2019, 15:42:41
...wenn jemand ein funktionierendes Device hat und hier ein RAW einstellt, bastel ich gerne ein attrTemplate draus und packe den Code für's Wiederfinden ins Wiki (tendenziell zu den Praxisbeispielen, samt link im template...)
Liefere etwas, wenn ich mehr Klarheit habe. Das dauert noch. Kämpfe noch mit vielen Dingen.

Blöd ist unter anderem, dass nach Neustarts von MQTT auf dem Sauger ein neues MQTT2-DEVICE für den Sauger in FHEM per autocreate angelegt wird. Habe jetzt neben dem derzeit aktuellen MQTT2_mqttjs_5618b3f3, 2 alte und tote Devices (MQTT2_mqttjs_b3bf0259, MQTT2_mqttjs_fd62c953). Wie ich das in Valetudo anpassen kann, ist mir unklar. Oder gibt es dazu einen Weg über FHEM?

Gruß, Christian

rudolfkoenig

ZitatHabe mal einen Screenshot aus dem Valetudo-Frontend nach Start des Saugvorgangs als Beispiel angehängt; No-Go-Areas sind rot, Rest ist hoffentlich selbsterklärend. Am Ende des Saugvorgangs hat man in Valetudo eine Bitmap mit dem kompletten Fahrweg.
Ich habe in der Funktion nur den Grundriss implementiert, da ich die Koordinaten der anderen Werte nicht verstehe.

ZitatOder gibt es dazu einen Weg über FHEM?
Ja, in MQTT2_DEVICE readingsList kein clientId: spezifizieren, also nur topic:message als regexp.
Und entweder autocreate in MQTT2_SERVER auf no setzen, oder nach und nach alle topics in die richtige MQTT2_DEVICE Instanz migrieren.
Besser waere es valetudo beizubringen, einen festen Clientid zu verwenden.

ZitatNach Start des Saugvorgangs wird jede Sekunde(!) die Grundrißbitmap wieder übertragen mit der geänderten Saugerposition (und Fahrweg?).
Das duerfte ein rpi1 ueberfordern.

Beta-User

...etwas zu spät...

Das Ding scheint eine random-CID zu verwenden, das machen scheinbar einige Projekte auf pharo (?) -Basis so, kann man vermutlich irgendwo beim Compilieren der Firmware verhindern.
Kannst ja mal versuchen, die CID-Präfixe aus der readingList eines Eintrags zu entfernen und die anderen zu löschen.
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

rudolfkoenig

ZitatDas Ding scheint eine random-CID zu verwenden, das machen scheinbar einige Projekte auf pharo (?) -Basis so, kann man vermutlich irgendwo beim Compilieren der Firmware verhindern.
Ich habe jetzt dem MQTT2_SERVER ein clientId Attribut spendiert (analog zu MQTT2_CLIENT), was aber die autocreate Faehigkeiten auf die des MQTT2_CLIENTs reduziert.

Beta-User

...ist vermutlich einfacher, dann steht es in der commandref. Schade nur, dass die Leute voraussichtlich schnell vergessen haben werden, dass man das nach Anlegen der "Problemfälle" besser wieder ausschalten 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

rudolfkoenig

Die Problemfaelle muss man "frisieren" (d.h. readingList ohne clientid anlegen), sonst gibt es nach dem Ausschalten des Attributes wieder Chaos.

krikan

Zitat von: rudolfkoenig am 23 Oktober 2019, 20:05:18
Ich habe in der Funktion nur den Grundriss implementiert, da ich die Koordinaten der anderen Werte nicht verstehe.
Verständlich. Das Grundrissthema/Grafik werde ich selbst nicht weiterverfolgen, da ich so etwas in FHEM eigentlich nicht brauche. Evtl. findet sich jemand, der es weiter optimiert.
Störend ist mMn die enorme Sendefrequenz der "großen" MQTT-Nachrichten.

ZitatJa, in MQTT2_DEVICE readingsList kein clientId: spezifizieren, also nur topic:message als regexp.
Und entweder autocreate in MQTT2_SERVER auf no setzen, oder nach und nach alle topics in die richtige MQTT2_DEVICE Instanz migrieren.
Besser waere es valetudo beizubringen, einen festen Clientid zu verwenden.
Danke für den Hinweis zur Anpassung in FHEM.
Lösung in valetudo habe ich bisher nicht gefunden. Vielleicht kennt sich jemand anderes besser aus und kann aus den x .js-Dateien die passende Stelle herauslesen.

Beta-User

Gibt es auf dem Robbi eine Datei "/mnt/data/valetudo/config.json"?

Eigentlich hätte ich angenommen, dass das, was dort als identifier genannt wird, auch verwendet wird bzw. der default "roborock".

In dem Zusammenhang habe ich aber was interessantes gefunden: https://github.com/eclipse/paho.mqtt.python/issues/209#issuecomment-334481970. Da heißt es:
Zitat

       
  • paho will still try an empty client_id by default with MQTT 3.1.1.
  • but if the connect fail with rejected identifier (and client_id is empty), an random one is generated.
@Rudi: eventuell liegt das mit den "random" CID's auch daran, dass MQTT2_SERVER unbedingt eine ClientID haben will? (Wir hatten das Thema schon mit dem Octoprint, deswegen kam ich auf paho).
Eventuell wäre es ein (eventuell ebenfalls nicht unproblematischer) workaround, bei leerer ClientID-Angabe die IP-Adresse zu verwenden, von der die Anfrage kommt? (Ich habe das nicht im Code geprüft usw., weiß also nicht, ob das ein zielführender Vorschlag ist...!).
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

krikan

Zitat von: Beta-User am 24 Oktober 2019, 12:12:31
Gibt es auf dem Robbi eine Datei "/mnt/data/valetudo/config.json"?

Eigentlich hätte ich angenommen, dass das, was dort als identifier genannt wird, auch verwendet wird bzw. der default "roborock".
Ja, die gibt es, darin taucht die ClientId aber nicht auf und darum versuche ich bisher ergebnislos aus den x .js-Dateien zu ermitteln, woher die Client-Id kommt. Der MQTT-Abschnitt sieht übrigens so aus:
  "mqtt": {
    "enabled": true,
    "identifier": "rockrobo",
    "topicPrefix": "valetudo",
    "autoconfPrefix": "fhem",
    "broker_url": "mqtt://raspberrypi",
    "provideMapData": true,
    "caPath": ""
  },

Beta-User

Hmmm, ich kenn' mich ja mit Java auch nicht aus...

Das Random-Ding kenne ich noch von Octoprint (Diskussion hier), und auch von zigbee2mqtt. Beides scheint paho-basiert zu sein, und beides mal war das Schüsselwort "client_id". Vermutlich steht irgendwo im code von paho die Lösung und wir suchen an der falschen Stelle?

Vielleicht magst du einen Versuch mit einem zusätzlichen Element dieses Namens in der Liste in dem .json-file wagen?
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

krikan

#27
Zitat von: Beta-User am 24 Oktober 2019, 12:55:03
Vielleicht magst du einen Versuch mit einem zusätzlichen Element dieses Namens in der Liste in dem .json-file wagen?
Hat leider keine Auswirkung/Erfolg.

Nach meiner mehr von Raten denn von Wissen getragenen Code/Repo-Analyse von Valetudo (bei besserer Kenntnis bitte berichtigen), komme ich zum gleichen Ergebnis:
Valetudo nutzt für mqtt: https://www.npmjs.com/package/mqtt/v/2.18.8

MQTT-Verbindung wird durch Valetudo in der function MqttClient.prototype.connect (https://github.com/Hypfer/Valetudo/blob/0.4.0/lib/MqttClient.js#L144) und dort speziell mit mqtt.connect (https://github.com/Hypfer/Valetudo/blob/0.4.0/lib/MqttClient.js#L150) aufgebaut.

Die per mqtt.connect übergebenen "options" werden in https://github.com/Hypfer/Valetudo/blob/0.4.0/lib/MqttClient.js#L150 ff. festgelegt. Die Konstante "options" wird in mit einem "leeren" Objekt initialiisiert "const options = {};" und anschließend nur noch die Eigenschaft "options.ca" vor dem Aufruf von mqtt.connect festgelegt. Alle anderen möglichen options von mqtt.connect (https://www.npmjs.com/package/mqtt/v/2.18.8#connect) werden also nicht übergeben und mit default-Werten beim Verbindungsaufbau angenommen. Festlegungen von clientId durch Valetudo, die als options bei mqtt.connect übergeben werden können, sind nach meiner Interpretation nur durch Code-Änderungen möglich. (nochmals: Bitte korrigiert mich gegebenenfalls.)

Als Standard vergibt mqtt eine zufallsbasierte clientId nach dem Schema
'mqttjs_' + Math.random().toString(16).substr(2, 8)
Das habe ich hier auch beobachtet. Diese clientId ändert sich demnach spätestens beim Client-Neustart immer wieder.

Allgemeiner zum MQTT-Protokoll:
Zitateventuell liegt das mit den "random" CID's auch daran, dass MQTT2_SERVER unbedingt eine ClientID haben will?
Nach http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html#_Toc385349767 gilt doch der Grundsatz, dass die clientId existieren muss. Eine fehlende clientId "kann" der Server akzeptieren; muss er aber nicht. Da die clientId letztlich doch zur Identifizierung des einen, speziellen Gerätes verwendet wird, verstehe ich schon nicht, warum überhaupt "ohne clientId" erlaubt ist: Wie unterscheidet man verschiedene Geräte? Die Vergabe einer zufallsbasierten clientId ohne Speicherung, die einen Client-Neustart überlebt, ist für mich genauso unverständlich; letztlich kann man dann auch keine vergeben. Wie soll denn dann die Identifizierung mehrer (Valetudo-)Clients erfolgen? Nur durch Anpassung von bspw. "identifier": "rockrobo", "topicPrefix": "valetudo"? Was soll die clientId dann?

Das mqtt.js-Package wird doch häufig verwendet. Tritt das hier beobachetet Problem(?) auch bei anderen darauf basierenden Clients auf. Und über den "Tellerrand geschaut": Wie lösen andere MQTT-Server das Problem mit den clientIds.

Ach so, "gute" Quellen als Link zu meinen ? nehme ich gerne an. Bisher habe ich noch nicht herausgefunden, wo zusätzlich Erläuterungen zu MQTT halbwegs verlässlich zu finden sind.

edit: Verstümmelte Url-Links ausgebaut. Autokorrektur  ???

rudolfkoenig

Die clientId kriegt nur der MQTT-Server, sie wird nicht an den anderen Clients weitergegeben.
Soweit ich weiss, ist "unclean Session" die einzige beabsichtigte Verwendug der clientId: wenn der Server ein unclean Session akzeptiert, dann gelten die Subscriptions vom letzten Session.
MQTT2_SERVER akzeptiert nur clean Sessions.

Ich kann die Idee mit der IP bei leerer clientId implementieren, bin aber unsicher, ob das nicht mehr Probleme verursacht, brauche also eine weitere Stimme :)

Otto123

Ich gebe mal mein "gelerntes" der letzten Tage wieder:
mosquitto verwendet, wenn keine CID angegeben wird, den Namen + die Prozess ID (Defaults to mosquitto_sub_ appended with the process id.)
cloudmqtt lässt bei der Anmeldung jede CID nur einmal zu.
Die Tools die ich probiert habe (mqttbox, MyMQTT, Chrome Plugins) verfahren so wie mqttbox schreibt: It should be unique per client for given broker. The broker uses it for identifying the client and the current state of the client. It is auto generated by default.

Also die CID ist scheinbar wirklich wurscht, außer bei autocreate vom MQTT2_SERVER/CLIENT

Jeder Client (egal mit welcher CID) kann bei Standardeinstellung des Servers in einen (den gleichen) Topic publishen.
Also man muss auf den Topic aufpassen beim publishen. Namen die in den Topic einfließen müssen Unikat sein! Insofern ist mir die Standardnamensgebung des Topic bei Tasmota völlig unklar, alle anderen Namen sind Unikat nur der Topic nicht  :o

Ist jetzt sicher für die Anwesenden nichts neues, ich wollte nur Christian bei seinen Erkenntnissen bestätigen :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz