MQTT2 mit signal-mqtt Docker: Wer hat ein Beispiel zum senden in eine Gruppe?

Begonnen von ch.eick, 31 Januar 2026, 17:41:11

Vorheriges Thema - Nächstes Thema

ch.eick

Hallo zusammen,
solch einen Effekt hatte ich bisher noch nie.
Was ich nicht verstehe ist, dass das userReadings bei nur einer empfangenen Nachricht mehrfach durchlaufen wird.
Bei anderen MQTT2 Devices konnte ich sowas nicht feststellen.
Bei meinem ersten Test, bei dem nur ich alleine in der Gruppe war lief noch alles wie gewünscht. Als der zweite Benutzer nun in die Gruppe kam und ich dann im userReadings nach der Uuid unterscheiden musste, da trat dann diese Mehrfach Reaktion auf.

EDIT: Ich denke ein Problem wird sein, dass die readings, die ich verarbeite nicht alle zur gleichen Zeit geschrieben werden und auch vom zweiten MQTT Topic erneut geschrieben werden.
  Um die readings aus einer Nachricht z.B. in in_date_* schreiben zu können müsste ich innerhalb eines redingList Eintrages alle readings analysieren und schreiben.

  Wenn dieses Topic kommt, stehen im json alle zusammengehörigen Informationen drin. Wie müsste ich das denn als Perl schreiben, damit alle readings genau aus diesem json gelesen werden.
  Die parms_envelope Pfade sind bei dataMessage und syncMessage gleich und somit nicht eindeutig.

  $DEVICETOPIC:signal/in:.* { {in_message_data=>json2nameValue($EVENT)->{params_envelope_dataMessage_message} } }


readingList
$DEVICETOPIC:signal/in:.* { {in_message_sent=>json2nameValue($EVENT)->{params_envelope_syncMessage_sentMessage_message} } }
$DEVICETOPIC:signal/in:.* { {in_message_data=>json2nameValue($EVENT)->{params_envelope_dataMessage_message} } }
$DEVICETOPIC:signal/in:.* { {in_groupName=>json2nameValue($EVENT)->{params_envelope_syncMessage_sentMessage_groupInfo_groupName} } }
$DEVICETOPIC:signal/in:.* { {in_source=>json2nameValue($EVENT)->{params_envelope_source} } }
$DEVICETOPIC:signal/in:.* { {in_sourceNumber=>json2nameValue($EVENT)->{params_envelope_sourceNumber} } }
$DEVICETOPIC:signal/in:.* { {in_sourceUuid=>json2nameValue($EVENT)->{params_envelope_sourceUuid} } }
$DEVICETOPIC:signal/in:.* { {in_sourceName=>json2nameValue($EVENT)->{params_envelope_sourceName} } }
$DEVICETOPIC:signal/in:.* { {in_account=>json2nameValue($EVENT)->{params_account} } }

Der MQTT2_FHEM_Server empfängt auch nur eine Nachricht mit dem gewünschten Inhalt.
Warum jedes mal vom user2 noch eine delivery Nachricht hinterher kommt verstehe ich ebenfalls noch nicht.
18:11:46.102 signal_receiver signal/in {"jsonrpc":"2.0","method":"receive","params":{"envelope":{"source < persönliche Daten user1> "}}
18:11:46.134 signal_receiver signal/in/method/receive/source_number/%2B49xxxxxx
18:11:46.899 signal_receiver signal/in {"jsonrpc":"2.0","method":"receive","params":{"envelope":{"source < persönliche Daten user2 delivery Information> "}}
18:11:46.930 signal_receiver signal/in/method/receive/delivered/true

Event log
2026-01-31 18:00:56.368 MQTT2_DEVICE signal_receiver in_source: +49
2026-01-31 18:00:56.368 MQTT2_DEVICE signal_receiver in_message_sent: 3
2026-01-31 18:00:56.368 MQTT2_DEVICE signal_receiver in_sourceUuid: 925814d3-cxxx8bdd
2026-01-31 18:00:56.368 MQTT2_DEVICE signal_receiver in_sourceNumber: +49
2026-01-31 18:00:56.368 MQTT2_DEVICE signal_receiver in_sourceName: user1

2026-01-31 18:00:57.225 MQTT2_DEVICE signal_receiver in_source: 984fad9d-3yyy239
2026-01-31 18:00:57.225 MQTT2_DEVICE signal_receiver in_sourceUuid: 984fad9d-3yyy239
2026-01-31 18:00:57.225 MQTT2_DEVICE signal_receiver in_sourceName: user2

FHEM Log
2026.01.31 18:00:56.349 3: signal_receiver      ur_02 : in_sourceUuid  : 984fad9d-3yyy239
2026.01.31 18:00:56.349 3: signal_receiver      ur_02 : in_message_sent: 3
2026.01.31 18:00:56.352 3: signal_receiver      ur_02 : in_sourceUuid  : 984fad9d-3yyy239
2026.01.31 18:00:56.352 3: signal_receiver      ur_02 : in_message_sent: 3
2026.01.31 18:00:56.355 3: signal_receiver      ur_02 : in_sourceUuid  : 925814d3-cxxx8bd
2026.01.31 18:00:56.355 3: signal_receiver      ur_02 : in_message_sent: 3
2026.01.31 18:00:56.356 3: signal_receiver      ur_02 : in_command      : null
2026.01.31 18:00:56.359 3: signal_receiver      ur_02 : in_sourceUuid  : 925814d3-cxxx8bd
2026.01.31 18:00:56.359 3: signal_receiver      ur_02 : in_message_sent: 3
2026.01.31 18:00:56.359 3: signal_receiver      ur_02 : in_command      : null
2026.01.31 18:00:56.362 3: signal_receiver      ur_02 : in_sourceUuid  : 925814d3-cxxx8bd
2026.01.31 18:00:56.362 3: signal_receiver      ur_02 : in_message_sent: 3
2026.01.31 18:00:56.362 3: signal_receiver      ur_02 : in_command      : null
2026.01.31 18:00:56.365 3: signal_receiver      ur_02 : in_sourceUuid  : 925814d3-cxxx8bd
2026.01.31 18:00:56.365 3: signal_receiver      ur_02 : in_message_sent: 3
2026.01.31 18:00:56.365 3: signal_receiver      ur_02 : in_command      : null

Attribute
event-on-change-reading in_message.*
event-on-update-reading in_analyse,in_source.*

userreading
in_analyse_mapping_sent:in_message_sent.* {
  my $in_source = ReadingsVal("$NAME","in_sourceUuid","null");
  Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_sourceUuid  : $in_source");
  my $in_analyse = lc(ReadingsVal("$NAME","in_message_sent","null"));
  Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_message_sent: $in_analyse ");
  if (   $in_source eq "925814d3-c417-4848-bfbf-aaf306b978bd" ) {
    my $in_command = "null";
    if ( $in_analyse ne "null") {
      my %h=eval "(".(AttrVal("$NAME","in_commands","n/a")).")";
      $in_command = $h{$in_analyse} if defined $h{$in_analyse};
#      fhem("$in_command");
     Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_command     : $in_command");
     return $in_command;
    }
  }
  return "null";
}

VG  Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

rudolfkoenig

Das oben gezeigt readingList ist ineffizient, unter anderem weil das JSON parsen mehrfach durchgelaufen wird.
Ich empfehle stattdessen sowas:
$DEVICETOPIC:signal/in:.* {
    my $r = json2nameValue($EVENT);
    return { in_message_sent => $r->{params_envelope_syncMessage_sentMessage_message},
            in_message_data => $r->{params_envelope_dataMessage_message},
            in_groupName    => $r->{params_envelope_syncMessage_sentMessage_groupInfo_groupName},
            ...
          } }
Alternativ setzt man das jsonMap Attribut, was genau fuer dieses Problem implementiert wurde.

Um das Problem mit userReading zu untersuchen haette ich gerne eine komplette Nachricht.
Die Werte gerne anonymisiert, aber mit allen Schluesseln.

ch.eick

#2
Okay, das Trennen war schon mal eine gute Idee.
Mit diesen Definitionen ist nun auch im Log wieder Ruhe und es wird nur das richtige json genommen.

Payload
18:20:13.202 signal_receiver signal/in  
{"jsonrpc":"2.0","method":"receive","params":{"envelope":{"source":"+49","sourceNumber":"+49","sourceUuid":"925814xxx8bd","sourceName":"user1","sourceDevice":1,"timestamp":1769880013437,"serverReceivedTimestamp":1769880013113,"serverDeliveredTimestamp":1769880013115,"syncMessage":{"sentMessage":{"destination":null,"destinationNumber":null,"destinationUuid":null,"timestamp":1769880013437,"message":"2","expiresInSeconds":3600,"viewOnce":false,"groupInfo":{"groupId":"ik32NK0yeJc=","groupName":"FHEM cli","revision":5,"type":"DELIVER"}}}},"account":"+49"}}


18:20:15.202 signal_receiver signal/in
{"jsonrpc":"2.0","method":"receive","params":{"envelope":{"source":"984fadyyyyy35e76239","sourceNumber":null,"sourceUuid":"984fad9yyy5e76239","sourceName":"user2","sourceDevice":1,"timestamp":1769873304823,"serverReceivedTimestamp":1769873305096,"serverDeliveredTimestamp":1769873305097,"dataMessage":{"timestamp":1769873304823,"message":"Test","expiresInSeconds":30,"viewOnce":false,"groupInfo":{"groupId":"ik32NK0y9+ereJc=","groupName":"FHEM cli","revision":4,"type":"DELIVER"}}},"account":"+49"}}

redingList
  Das wird leider nur einzeilig angenommen, gibt es da noch einen Trick?
  Wichtig ist besonders das "my $ret = $j->{params_envelope_syncMessage_sentMessage_message}; return if(!$ret);", da ansonsten die Payload auch für das andere json verwendet wird.
$DEVICETOPIC:signal/in:.* {my $j = json2nameValue($EVENT);my $ret = $j->{params_envelope_syncMessage_sentMessage_message}; return if(!$ret) ;return {in_sync_message_sent => $j->{params_envelope_syncMessage_sentMessage_message},in_sync_source => $j->{params_envelope_source},in_sync_sourceUuid => $j->{params_envelope_sourceUuid},in_sync_sourceNumber => $j->{params_envelope_sourceNumber},in_sync_sourceName => $j->{params_envelope_sourceName}};}

userReadings
in_sync_analyse_mapping_sent:in_sync_message_sent.* {
  my $in_source = ReadingsVal("$NAME","in_sync_sourceUuid","null");
  Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_sync_sourceUuid   : $in_source");
  my $in_analyse = lc(ReadingsVal("$NAME","in_sync_message_sent","null"));
  Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_sync_message_sent : $in_analyse ");
  if (   $in_source eq "925814dxxxxxxxxxf306b978bd" ) {
    my $in_command = "null";
    if ( $in_analyse ne "null") {
      my %h=eval "(".(AttrVal("$NAME","in_commands","n/a")).")";
      $in_command = $h{$in_analyse} if defined $h{$in_analyse};
      if ($in_command ne "null") {
#        fhem("$in_command");
          Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_sync_command      : $in_command");
      } else {
          Log3($name,3,sprintf("%-20s ur_02 : ", $name)."in_sync_command      : Not found");
      }
      return $in_command;
    }
  }
  return "null";
}
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

rudolfkoenig

ZitatOkay, das Trennen war schon mal eine gute Idee.
Ich wuesste gerne, worauf diese Bemerkung sich bezieht.

ZitatDas wird leider nur einzeilig angenommen, gibt es da noch einen Trick?
Sogar mehrere: als Funktion in 99_myUtils.pm auslagern, oder, noch besser: jsonMap verwenden.

Beim Absetzen der ersten Nachricht wird userReading einmal aufgerufen:
2026.02.01 11:59:09.803 3: m2d                  ur_02 : in_sync_sourceUuid  : 925814xxx8bd
2026.02.01 11:59:09.803 3: m2d                  ur_02 : in_sync_message_sent : 2
beim Aufruf der zweiten Nachricht nicht. Letzteres ist dem ReadingList zu verdanken.

Ich habe die o.g. event-on-* Attribute weggelassen: die passen nicht zum zweiten Beitrag (und filtern damit alles weg), und ich verstehe auch nicht, wozu sie gut sein sollen.

ch.eick

Zitat von: rudolfkoenig am 01 Februar 2026, 12:05:14
ZitatOkay, das Trennen war schon mal eine gute Idee.
Ich wuesste gerne, worauf diese Bemerkung sich bezieht.
Oh ja, das ist nicht klar geworden. Ich meine das Trennen von syncMessage und dataMessage auf unterschiedliche readings.
Vorher wurde durch beide MQTT Topics aus dem json gleiche Daten gelesen und in die selben readings geschrieben. Nun trenne ich in is_sync_.* und in_data_.* .

Zitat
ZitatDas wird leider nur einzeilig angenommen, gibt es da noch einen Trick?
Sogar mehrere: als Funktion in 99_myUtils.pm auslagern, oder, noch besser: jsonMap verwenden.
Okay, das leuchtet ein

ZitatBeim Absetzen der ersten Nachricht wird userReading einmal aufgerufen:
2026.02.01 11:59:09.803 3: m2d                  ur_02 : in_sync_sourceUuid  : 925814xxx8bd
2026.02.01 11:59:09.803 3: m2d                  ur_02 : in_sync_message_sent : 2
beim Aufruf der zweiten Nachricht nicht. Letzteres ist dem ReadingList zu verdanken.
Ja, dadurch das im readingList jetzt entschieden wird, ob es ein in_sync_.* oder ein in_data_.* ist, wird das geziehlt in separate readings abgelegt und es kommt nicht zu einer doppelten Beschreibung.

ZitatIch habe die o.g. event-on-* Attribute weggelassen: die passen nicht zum zweiten Beitrag (und filtern damit alles weg), und ich verstehe auch nicht, wozu sie gut sein sollen.
Sorry, das stimmt, ich hatte schon zuviel Stunden am Rechner gesessen und somit die Altlasten übersehen.
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

ch.eick

Hallo zusammen,
jetzt versuche ich etwas über signal-mqtt zu versenden und bekomme die Payload nicht hin.
Wer hätte da ein Beispiel für mich.

Im Docker Container Log sehe ich leider meine Nachricht nicht und dann kommt natürlich auch nichts in der Gruppe an.
Das Empfangen kann ich bereis sehen.

EDIT: Das habe ich in der Zwischenzeit schon rausgefunden.
   Ich habe im Forum jedoch noch Beispiele Gefunden, die mit { qq()} aufgerufen werden, was ist dabei denn der Vorteil?
sendHelp:noArg signal/out {"jsonrpc":"2.0","method": "send","params": {"groupId":"xxxxxx/9+ereJc=","sourceName": "SmartHome","message": "Test" } }
sendHelp2 signal/out {"jsonrpc":"2.0","method": "send","params": {"groupId":"xxxxxx/9+ereJc=","sourceName": "SmartHome","message": "$EVENT" } }

VG  Christian
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick