Erklärung zu json2nameValue / MQTT readingList Json - bestimmte Elemente filtern

Begonnen von 87insane, 07 Juli 2020, 20:09:47

Vorheriges Thema - Nächstes Thema

87insane

Hallo zusammen,

ich benötige eine Erklärung zu json2nameValue.
{ json2nameValue($EVENT,'',$JSONMAP) } = Ein Wert wie HASH(0x6401360)
Leider findet man im Netz nicht wirklich was oder ich suche falsch... Habe auch separat nochmal hier im Forum gesucht aber leider kein Wiki oder erklärten Beitrag dazu gefunden.

Wenn man in einer ReadingList mit json2nameValue so wie oben gezeigt auflöst, werden darauß einzelne Readings mit den entsprechenden Werten.
Nun würde ich gerne aus einem so auflösbarem Json String aber gerne nur z.B. eine Sache heraus suchen. Dazu würde ich an sich gerne verstehen wie das hier genau funktioniert.
Bei vielen MQTT Geräten bin ich immer wieder am überlegen ob und wie ich es am besten nutze.

Ich würde mich über ein paar Worte dazu freuen....

Danke und Gruß,
87insane

Beta-User

Rudi hatte dazu mal das geschrieben:
Zitat von: rudolfkoenig am 01 Juni 2020, 10:47:26
json2nameValue liefert eine Referenz auf ein Hash zurueck
Rund um diesen Beitrag gibt es mMn. auch ein paar brauchbare Ideen, was man zur Vor- und Nachbereitung der in dem referenzierten Hash enthaltenen Daten machen kann.

Vielleicht erläuterst du deinen Usecase etwas näher, dann wird es ggf. etwas weniger abstrakt?

Wenn es "nur" darum geht, den JSON auf das Vorhandensein eines bestimmten Elements zu prüfen und dann nur diesen Auszug bzw. den zugehörigen Wert (ggf. unter anderem Readingnamen) zurückzugeben: auch dafür gibt es ein paar Beispiele in der mqtt2.template, wie man das direkter mit regex lösen kann.

Und: "Wunschliste" dürfte der falsche Forenbereich sein ;)
ZitatAnregungen, Ideen, Vorschläge für FHEM Erweiterungen.

Verschiebe das ganze nach (?) MQTT (json2nameValue() ist zwar nicht auf MQTT beschränkt, aber dort bisher am häufigsten verwendet afaik, und ins Wiki braucht das mMn. auch nicht, ist zu speziell).
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

87insane

#2
...verschoben...

Es geht mir um eine generelle Erklärung da ich dieses Stück Code und was dahinter steckt als sehr mächtig erachte. Dafür möchte ich es aber auch verstehen. (Große macht und Verantwortung usw :-P)

Ja es geht am Ende darum (auch wenn das dann wieder eine andere Funktion ist), aus einem JSON String gezielt Elemente heraus zu holen. Oft braucht man gerade bei MQTT nicht den ganzen Zweig zu abonnieren. ABER bitte nicht falsch verstehen. Auch wenn es eine andere Funktion sein sollte, möchte ich json2nameValue verstehen!

Was ich probiere ist aktuell:
Testweise (da es da ggf auch gebraucht wird) aus dem SONOS2MQTT gezielt Master und Slave-Erkennung zu bauen.
Dafür teste ich einfach damit ich es verstehe zb. aus dem folgendem was rauß zu ziehen. Ich weiß durch eine bekannte Suchmaschine, das es auch möglich sein muss ein Extrakt zu ziehen von einzelnen Elementen. Da jason2nameValue den ganzen kram wohl entpackt muss ich es ja nutzen können. FHEM macht aus dem HASH ja auch einzel Werte.
Ich dachte an sowas wie, alles in eine VAR zu packen und dann rauß reg exen... Also die gleiche Richtung wie du und auch die Templates. Um das ganze zu testen (gestern zu viele Stunden!), habe ich mir die ganze Zeit die aktuelle SVN offen gehalten mit den Template Daten. Leider war das ganze nicht von Erfolg gekrönt.

Am Ende würde ich in der ReadingList so auch gegen die CID des Gerätes vergleichen usw.... Aber ich will absichtlich zu tief ins Detail gehen, da es mir um die grundsätzliche Funktionalität geht.
Im devGuide hatte ich auch alles durch geklickt aber es ist einfach nix gutes zu finden. Spätestens hier (https://wiki.fhem.de/wiki/Kategorie:Development) hätte ich Text dazu erwartet, der mehr als ein "diese Funktion existiert" ist (hab ich mir ausgedacht den Satz.. geht um die wenigen Infos.

Anbei noch der JSON Array String (denke den wolltest du auch mal haben ;) - Ist aus dem "sonos/RINCON_([0-9A-Z]+):.*" Pfad):
{"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer","coordinatorUuid":"RINCON_7828CAF427B201400",
"currentTrack":{"Album":"Hey Pablo EP","Artist":"Anti Up",
"AlbumArtUri":"http://192.168.20.70:1400/getaa?s=1&u=x-sonos-spotify:spotify:track:4gnH8nfdJfN115QAzzUc3E%3fsid%3d9%26flags%3d8224%26sn%3d3",
"Title":"Hey Pablo","UpnpClass":"object.item.audioItem.musicTrack","Duration":"0:04:09","ItemId":"-1","ParentId":"-1",
"TrackUri":"x-sonos-spotify:spotify:track:4gnH8nfdJfN115QAzzUc3E?sid=9&flags=8224&sn=3","ProtocolInfo":"sonos.com-spotify:*:audio/x-spotify:*"},
"enqueuedMetadata":{"Artist":"Spotify","AlbumArtUri":"https://i.scdn.co/image/ab67706f00000002470dd505fcf08e4693db9b24","Title":"Dance Party",
"UpnpClass":"object.container.playlistContainer#playlistItem","ItemId":"0006002cspotify%3aplaylist%3a37i9dQZF1DXaXB8fQg7xif",
"ParentId":"spotify%3aview%3aginger-genre-affinity%5b0%5d"},"nextTrack":{"Album":"Arbeit nervt","Artist":"Deichkind",
"AlbumArtUri":"http://192.168.20.70:1400/getaa?s=1&u=x-sonos-spotify:spotify:track:1PzWE6FRyQzyUIQ60DSceN%3fsid%3d9%26flags%3d8224%26sn%3d3",
"Title":"Arbeit nervt","UpnpClass":"object.item.audioItem.musicTrack","Duration":"0:03:18","ItemId":"-1","ParentId":"-1",
"TrackUri":"x-sonos-spotify:spotify:track:1PzWE6FRyQzyUIQ60DSceN?sid=9&flags=8224&sn=3","ProtocolInfo":"sonos.com-spotify:*:audio/x-spotify:*"},
"transportState":"PAUSED_PLAYBACK","playmode":"NORMAL","ts":1594128615493,"volume":{"Master":0,"LF":100,"RF":100},
"mute":{"Master":false,"LF":false,"RF":false}}


sonos/RINCON_7828CAF4289001400:..uuid...RINCON_([0-9A-Z]+) so geht es ja leider nicht^^ Das wäre zu einfach.

Beta-User

Also:

Zu json2NameValue() hatte ich die mMn. aufschlussreichste Diskussion bereits verlinkt, die mir bekannt ist. Zurück kommt also ein Hash (genauer: eine Referenz darauf!), etwas verkürzt gesagt also eine unsortierte "Liste" von "Namen-Wert"-Paaren.
Dass dabei durch json2NameValue() nicht einfach nur der JSON aufgebrochen wird (das können auch andere, allgemeine Perl-Funktionen aus diversen libs), sondern auch eine "doppelte Umbenennung" bzw. Filterung stattfindet (1. Umbenennung mit "Präfix", zweite+Filterung via jsonMap), sollte auch soweit klar sein.



Um dein Problem zu lösen, brauchst du mMn json2nameValue() nicht:
Mal unterstellt, es ist der konkrete "RINCON" Topic-Branch, über den der JSON reinkommt? Dann brauchst du auch den Rückgriff auf die CID nicht, machst eine Regex mit zwei Suchelementen auf den Inhalt von "uuid" bzw. "coordinatorUuid", vergleichst beide miteinander und gibst dann "irgendwas" zurück.
Was, kannst du selbst bestimmen, ich wäre für was "einfaches" zu haben, also z.B. einen Hash, der entweder {"isMaster"=>"true"} oder {"isMaster"=>"false"} lautet. Falls gar kein match gefunden wird, gib "undef" zurück.
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

87insane

Zu 1) Naja den Link hatte ich beim suchen auch gesehen. Aber dafür reicht mein Verständnis nicht...




Zu 2) Ne. Das geht leider so einfach nicht. Dachte ich zuerst auch und dann wäre es etwas einfacher. Aber wenn ein Player nun den Pfad aller Player abonniert, bekommt er immer auch alle Infos. Die eigene uuid ändert sich in dem Moment ja auch. Also müsste man explizit Dinge rauß filtern. Weil der String kommt so komplett rein. Ich hätte nun die uuid gegen die CID gestellt. Dann habe ich bei aktueller CID Vergabe, immer den eigentlichen Playernamen ohne große Zauberei. Denn uuid = CID.
Wenn man nun gezielt Dinge aus einem Zweig ableiten würde, hätte man zwar mehr readingList-Einträge aber es wäre dafür sauberer am Ende im devStateIcon und es würden x Prüfungen weg fallen. Dazu hätte man eine saubere Struktur....
Klar kann man eine solche Ausgabe machen wie auch loadState.... Ich wollt aber erstmal tiefer rein bevor ich etwas irgendwie aufbaue... Deswegen hier die Frage :)

Beta-User

Na ja, 1) ist eben nicht so einfach, es setzt ein "etwas vertiefteres" Verständnis von Perl data types voraus (weiß nicht, ob dir das hier weiterhilft: https://perldoc.perl.org/perldata.html).... Bin da selber immer sehr stark gefordert...

Wenn "alle" "RINCON" abboniert werden, dann macht es wohl Sinn, vorab dann noch eine Prüfung einzubauen, ob "man" überhaupt betroffen ist, also entweder $1 oder $2; dann aber eventuell als "tristate": Master ($1 eq CID, $2 ne CID), Slave ($1 ne CID, $2 eq CID) oder "Single" ($1 eq CID eq $2)?
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

87insane

#6
1) Schaue ich mir an. DANKE - Es hilft wenn einer die korrekten Worte kennt.




2)
sonos/RINCON_([0-9A-Z]+):.* { $TOPIC =~ m,(RINCON_[0-9A-Z]+),; InternalVal("$NAME","CID","") eq "$1" ? {"TEST"=>"$1"} : {"TEST" => "0"} }

Das hier ist mein Test bisher... Alle RINCONS drin und Vergleich gegen CID. Aber da muss noch ein wenig mehr rein.. Geht aber schonmal.
Woher kommt bei dir die $2? Im Topic steht ja z.B. "sonos/RINCON_7828CAF4289001400"

Beta-User

Zitat von: 87insane am 08 Juli 2020, 13:42:33
sonos/RINCON_([0-9A-Z]+):.* { $TOPIC =~ m,(RINCON_[0-9A-Z]+),; InternalVal("$NAME","CID","") eq "$1" ? {"TEST"=>"$1"} : {"TEST" => "0"} }

Das hier ist mein Test bisher... Alle RINCONS drin und Vergleich gegen CID. Aber da muss noch ein wenig mehr rein.. Geht aber schonmal.
Woher kommt bei dir die 2? Im Topic steht ja z.B. "sonos/RINCON_7828CAF4289001400"
Verstehe ich nicht. Du kannst zwar auch erst "$TOPIC" nochmal scannen, aber im JSON-payload ist es ja auch nochmal drin, und die mußt du sowieso auch regex-parsen (sonst würde es reichen, nur den "eigenen" Topic doppelt zu abbonieren, oder?), von daher kann man sich das mMn. direkt sparen. (Aber das Prinzip scheint jetzt klarer zu sein?)
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

87insane

Es ist klarer.. Auf jeden Fall...

Ich würde gerne direkt aus der Payload lesen. Hatte mir dann aber erstmal mit der Bridge Regex geholfen, da ich es nicht hinbekam. Wenn du natürlich jetzt sagst, du bekommst aus dem Zweig dies und jenes rauß indem du.... - Wäre ich glücklich :)

Was Punkt 1) angeht, werde ich mir da noch einiges durchlesen müssen. Danke für den Link! (Hab gehofft von Arrays weg bleiben zu können...Ich hasse sie seit dem ersten Berufsschuljahr vor tausend Jahren^^)

Beta-User

regexr.com sagt mit deinem JSON und dieser regex
uuid.:.([^"]+).*coordinatorUuid.:.([^"]+)$1 RINCON_7828CAF427B201400
$2 RINCON_7828CAF427B201400...
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

87insane

#10
Dann würde ich das doch ein wenig anders machen... Die CID ist immer gleich aber der Logik nach, läuft das leider nicht....

Das hier ist deine Idee:
Master: ($1 eq CID, $2 ne CID)
Slave: ($1 ne CID, $2 eq CID)
Single: ($1 eq CID eq $2)

Damit geht aber kein Master/Slave/Single. Du hast mich aber auf einen guten Weg geworfen...

Master: uuid eq coordinatorid eq CID, groupName ne name
Slave: uuid eq CID ne coordinatorid, groupName ne name
Single: uuid eq coordinatorid eq CID, groupName eq name

In meinen Augen kann dann die Prüfung auf Name und Gruppe in der Theorie entfallen. Denn die ersten beiden ergeben das gleich und der letzte könnte ein else sein.
ABER wenn man mehrere Gruppen hat, sollte trotzdem sauber zugeordnet werden. Die coordinatorid sagt zwar wer Boss ist und auch jedem Slave wem er angehört. Aber ggf. macht es Sinn genau zu wissen, welche Player in eine Gruppe gehören. Man bekommt aber wie schon mal beschrieben immer nur Gruppennamen wie "Master + 2" oder wie es auch im Reading steht: "Wohnzimmer + 2". Die +2 wissen wieder nur die Slaves selber und die wiederum bekommen keine Reading Updates mehr auf Ihrem Zweig, wenn Sie einem Master angehören.
Das bedeutet - Alle Slaves bekommen noch schnell die Info wem sie angehören: groupName: Master +2, Single bleiben wie sie sind und Master bekommen nun nur noch Updates der Readings und müssen diese weitervererben. Deswegen der Versuch das direkt in der ReadingList sicher und sauber zu integrieren.

Ist das nun wieder eher im mqqt2sonos zu besprechen?
PS: Mich nervt es das wir alle hier nirgendwo ein Gespräch komplett führen können. Wir brauchen sowas wie MS Teams...

Bin aber noch hart am grübeln.... Du bist leider blind ... Ich Frage mich ab und an was du an Hardware besitzt. Hätte auch gern überall Kabel aber die Sonos laufen mit oder ohne Kabel genauso .... Dazu liefern sie super Klang. Ich selber würde mir keine Baustein Anlage mehr ins Wohnzimmer stellen.

Beta-User

...vermutlich macht es mehr Sinn, das mit denen auszufeilen, die die Geräte haben - ob es im Haupt-sonos2mqtt-Thread untergeht oder sehr speziell ist, ist eine andere Frage...

Wie dem auch sei:
Der Hauptfall düfte sein, dass eine Box solo unterwegs ist, also sollte diese Prüfung ($3 eq $4 ?) auch möglichst weit nach vorne, dabei muß aber doch abgesichert sein, dass es wirklich was mit der betreffenden Box zu tun hat, oder? Diese Prüfung (vermutlich: uuid eq CID?) müßte also bleiben (wobei ich annehmen würde, dass das dann auch immer über den zur CID passenden Zweig kommt? Was das ganze dahingehend vereinfachen könnte, dass man nur mir Variablen $1 bis $4 aus der regex arbeiten kann?)
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

87insane

In diese Richtung denke ich auch ... nur die Umsetzung ist bei mir etwas Zeit spieliger als bei dir....die Übung...
Ich versuche mal weiter... Danke Dir!

EDIT: (Muss mir das echt abgewöhnen!) - Du hast aber im ganzen Recht! Genau das würde ich weiter ausbauen. Bestehen auf 1-4. Die CID hatte ich zur Verbildlichung aufgenommen. Du hast das aber mal echt gut erklärt jetzt gerade. Das verstehe ich sogar und sagt genau was ich sagen wollte.. Du hast es verbessert mit der Info der 3,4 - die in der Tat (ohne das du es wissen konntest, da keine HW) aber meist der Fall sein sollten. Denn gepairt = auch nur ein Gerät habe ich von @Otto123 gelernt. (Wobei ich mir sicher bin im Sommer ein Stero Pair in der Garage hatte ähnliche Merkmale im original Modul...Will aber so ungern zum testen Pairen wegen dem Modul... Dann ist wieder alles durcheinander...).
Muss mich nochmal in Ruhe hinsetzen und mir das ansehen. Ich male mir sowas meist auf.. Hört sich doof an aber das klappt dann. Wie machst du das immer. Ab und an sind bei Dir die Lösungen in 2min hier drin!

87insane

Siehst du das hier ähnlich wie ich oder würdest du es noch anders machen?

sonos/RINCON_([0-9A-Z]+):.* { $EVENT =~ m,.*name.:.([^"]+)...groupName.:.([^"]+)...coordinatorUuid.:.([^"]+),; my $CID = InternalVal($NAME,"CID",""); $1 eq $2 ? {"TEST"=>"SINGLE"} : $CID ne $3 ? {"TEST"=>"SLAVE"} : {"TEST"=>"MASTER"} }

Klappt auf jeden Fall so. Hab es so kurz wie möglich nach diesen Regeln gebaut:
Master: uuid eq coordinatorid eq CID, groupName ne name (else)
Slave: uuid eq CID ne coordinatorid, groupName ne name
Single: uuid eq coordinatorid eq CID, groupName eq name

So brauchen wir die uuid aktuell nichtmal und es reicht $1-$3 + CID. Würde, wenn es passt so weiter brauen, was meinst du?  Ginge auch mit 1-4 wenn man die uuid als Vergleich nimmt. ABER es gibt bei 1-4 ganz kurz beim verlassen einer Gruppe einen falschen Schwenk. Denk gibt es im Vergleich zur immer festen CID nicht. Deswegen würde ich lieber die CID nehmen.

Beta-User

Zitat von: Beta-User am 08 Juli 2020, 16:36:22
(wobei ich annehmen würde, dass das dann auch immer über den zur CID passenden Zweig kommt? Was das ganze dahingehend vereinfachen könnte, dass man nur mir Variablen $1 bis $4 aus der regex arbeiten kann?)
Das ist vielleicht etwas kryptisch gewesen, daher nochmal die Langform des Gedankens:
Ist es nicht so, dass die CID sowieso _nur_ dann matcht, wenn der JSON über zu der CID gehörende Topic-Tree kommt? Dann kann man das weiter vereinfachen bzw. unnötige Prüfungen vermeiden...
Würde also testweise mal mit folgendem ins Rennen gehen:
sonos/RINCON_7828CAF427B201400:.* { $EVENT =~ m,uuid.:.([^"]+)...name.:.([^"]+)...groupName.:.([^"]+)...coordinatorUuid.:.([^"]+),; $2 eq $3 ? {"grouping"=>"SINGLE"} : $1 eq $4 ? {"grouping"=>"MASTER"} : {"grouping"=>"$4"} }
So hat man gleich die Info, unter wessen Kontrolle das Teil steht ;) .

Eventuell wäre es auch (mind.) in dem $2 eq $3-Fall sinnvoll, die (eigene) uuid in "grouping" (oder ein 2. Reading) zu schreiben; hängt halt auch davon ab, was man dann mit der Info weiter anstellen will... (z.B. "set Lautstärkeänderung" auf den Master umleiten usw.?)
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

87insane

Wegen der CID / $4 Prüfung hatte ich in meinem Beitrag noch was an gehangen.
ZitatGinge auch mit 1-4 wenn man die uuid als Vergleich nimmt. ABER es gibt bei 1-4 ganz kurz beim verlassen einer Gruppe einen falschen Schwenk. Denk gibt es im Vergleich zur immer festen CID nicht. Deswegen würde ich lieber die CID nehmen.
Die CID ist stabiler... Hab mir das ganze über den EVENT Monitor angesehen und es ist zwar immer nur sehr kurz beim verlassen einer Gruppe aber das muss nicht sein. Bei CID ist das direkt korrekt.

Der schwere Part und da habe ich keine Idee... Nun müsste wenn = SLAVE, dieser die Daten des Masters übernehmen und in seine eigenen schreiben. Aber es werden nicht alle benötigt. Nur sowas wie state, title, track... Infos eben.
Das mit der Lautstärke ist ein wenig Tricky. Es gibt für jeden Lautsprecher innerhalb einer Gruppe eine einzel Lautstärke. Aber es gibt innerhalb einer Gruppe noch einen Master Regler. Dieser regelt die Lautstärke relativ zu allen Lautsprechern. Also Box 1 auf 25% und Box 2 auf 50% = Der Master würde auf 50% stehen. Wenn ich nun auf 60% schiebe (am Master Regler), werden auch alle Slaves um 10% angehoben. (Hoffe man versteht wie ich das meine).
Ich wollte hingehend der Readings aufräumen und den Player dem entsprechend mit aufräumen und anpassen. Das hier ist der Weg zur sauberen Gruppen Fähigkeit. Ist aber auch super MQTT/Regex Training.

Bin aber schon am weiter regexen...

Beta-User

Hmm, dann ist das mit der CID auch ok.

Was aber weiter ein Punkt bleibt: Wenn möglich, dann nur auf den eigenen Topic hören?

Was die Readings angeht: beim devStateIcon kann man ja abfragen, von welchem Device bestimmte (einzelne) Werte effektiv gelesen werden sollen; das könnte man (aus dem "TEST") auch via devspec2array abfragen bzw. bestimmen (und am besten in ein separates Reading packen). Ist halt einigermaßen kompliziert...
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

87insane

Von der Tendenz her würde ich eher in so eine (NICHT fertig) Richtung gehen:
sonos/RINCON_([0-9A-Z]+):.* { $EVENT =~ m,.*name.:.([^"]+)...groupName.:.([^"]+)...coordinatorUuid.:.([^"]+).*currentTrack.:..(Album.:.([^"]+)...Artist.:.([^"]+)...AlbumArtUri.:.([^"]+)...Title.:.([^"]+)...UpnpClass.:.([^"]+)...Duration.:.([^"]+))?(Artist.:.([^"]+).*Title.:.([^"]+))?,; my $CID = InternalVal($NAME,"CID",""); $1 eq $2 ? {"TEST"=>"SINGLE - $13 $6 $8"} : $CID ne $3 ? {"TEST"=>"SLAVE","TEST2"=>"$13 $5 $7"} : {"TEST"=>"MASTER"} }

So konnte ich Track Daten usw abfangen vom Master auch in den Slaves. Müsste ich nur noch A) original Reading überschreiben oder B) neue dafür anlegen lassen...

Das meinstest du mit:
ZitatWas aber weiter ein Punkt bleibt: Wenn möglich, dann nur auf den eigenen Topic hören?
nehme ich mal an. Ist die Frage wie man in Gruppen sonst an die Daten kommt...? Ich könnte mir das nun komplett zusammen Regexen und mal vorstellen wie ich das so meine.... Ist leider ein sehr spezieller Fall mit den JSONs....

Bei Radio sehen die so aus:
{"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","mute":{"Master":false,"LF":false,"RF":false},"ts":1594288723969,"currentTrack":{"Artist":"SURF MESA","AlbumArtUri":"http://192.168.20.70:1400/getaa?s=1&u=x-sonosapi-stream:s167727%3fsid%3d254%26flags%3d8224%26sn%3d0","Title":"ILY (I LOVE YOU BABY) (TOPIC REMIX)","UpnpClass":"object.item.audioItem.musicTrack","ItemId":"-1","ParentId":"-1","TrackUri":"x-sonosapi-stream:s167727?sid=254&flags=8224&sn=0","ProtocolInfo":"sonos.com-http:*:audio/mpeg:*"},"enqueuedMetadata":{"Title":"I Love 2 Dance","UpnpClass":"object.item.audioItem.audioBroadcast","ItemId":"-1","ParentId":"-1"},"transportState":"PLAYING","playmode":"NORMAL"}


Bei z.B. Album basierter Wiedergabe (Spotify) so:
{"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","mute":{"Master":false,"LF":false,"RF":false},"ts":1594287882462,"currentTrack":{"Album":"No!","Artist":"CID","AlbumArtUri":"http://192.168.20.70:1400/getaa?s=1&u=x-sonos-spotify:spotify:track:0VPTpC1ZLQRoz1n06mksVZ%3fsid%3d9%26flags%3d8224%26sn%3d3","Title":"No!","UpnpClass":"object.item.audioItem.musicTrack","Duration":"0:03:11","ItemId":"-1","ParentId":"-1","TrackUri":"x-sonos-spotify:spotify:track:0VPTpC1ZLQRoz1n06mksVZ?sid=9&flags=8224&sn=3","ProtocolInfo":"sonos.com-spotify:*:audio/x-spotify:*"},"enqueuedMetadata":{"Artist":"Spotify","AlbumArtUri":"https://i.scdn.co/image/ab67706f00000002470dd505fcf08e4693db9b24","Title":"Dance Party","UpnpClass":"object.container.playlistContainer#playlistItem","ItemId":"0006002cspotify%3aplaylist%3a37i9dQZF1DXaXB8fQg7xif","ParentId":"spotify%3aview%3aginger-genre-affinity%5b0%5d"},"nextTrack":{"Album":"Turn Me On (feat. Vula)","Artist":"Riton","AlbumArtUri":"http://192.168.20.70:1400/getaa?s=1&u=x-sonos-spotify:spotify:track:0qaWEvPkts34WF68r8Dzx9%3fsid%3d9%26flags%3d8224%26sn%3d3","Title":"Turn Me On (feat. Vula)","UpnpClass":"object.item.audioItem.musicTrack","Duration":"0:03:28","ItemId":"-1","ParentId":"-1","TrackUri":"x-sonos-spotify:spotify:track:0qaWEvPkts34WF68r8Dzx9?sid=9&flags=8224&sn=3","ProtocolInfo":"sonos.com-spotify:*:audio/x-spotify:*"},"transportState":"PAUSED_PLAYBACK","playmode":"NORMAL"}


Das muss man schon genau gucken. Bin aktuell bei $13...

Beta-User

Hmmm, alsooooo:

- Wenn du tatsächlich alle Topic-branches abbonieren mußt, um auf die "passenden" Daten zu kommen, _vermute_ ich, dass da irgendwo noch eine Lücke ist mit Infos, die ggf. von einem dritten Gerät kommen; die Bedingung $1 eq $2 müßte dann auch zutreffen, aber der JSON gar nichts mit dem aktuellen Gerät zu tun haben => dieser Fall wäre noch zu verwerfen.

- Im Moment _glaube ich_, dass es zielführend wäre, dann nur noch den generalisierten Topic zu abonnieren und ggf. (teilweise) mit unterschiedlichen (dynamischen) Präfixen zu arbeiten. Dann können wir via jsonMap (nur) den Teil rauszufiltern, der uns wirklich interessiert - und brauchen dabei dann uU. effektiv gar nicht mehr nach der Quelle zu unterscheiden (oder brauchen wir z.B. die Angabe des MASTER für irgendwas, z.B. Kommandos? Hatte verstanden: eigentlich eher nicht?). Pseudo-Code (ohne Korrektur von obigem):
sonos/RINCON_([0-9A-Z]+):.* { $EVENT =~ m,name.:.([^"]+)...groupName.:.([^"]+)...coordinatorUuid.:.([^"]+),; my $CID = InternalVal($NAME,"CID",""); $1 eq $2 ? json2nameValue($EVENT,'SINGLE_',$JSONMAP) : $CID ne $3 ? json2nameValue($EVENT,'SLAVE_',$JSONMAP) : json2nameValue($EVENT,'MASTER_',$JSONMAP) }

Dann sollte es möglich sein, jeweils den Teil via jsonMap rauszupicken (und auf das passende Effektiv-Reading zu mappen), der gebraucht wird...?

(Was mir als Bausteinchen fehlt, ist ein Gefühl dafür, welche Daten ggf. wie noch ankommen, wenn so ein Teil unter der Kontrolle eines anderen steht; kommen dann noch (flasche) Infos zum angeblich laufenden Track usw?)
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

87insane

1) Gegen CID zusätzlich prüfen?

2) Kommandos in einer Gruppe: play/pause (geht an jedem Player), track weiter/track zurück (geht nur am Master), lauter/leiser (geht an jedem player aber auch am Master (spezielle Erklärung dazu war oben). Ist leider spezieller.

3) Das Bausteinchen: Wenn ein Player einem Master untergeordnet ist, bekommt er auf seinem Zeig KEINE Infos mehr. Also bleibt in diesem Player alles wie es war. Dann steht im Reading für Track einfach iwas altes drin, was vorher mal drin war. Genau das ist ja das Problem, warum ein Slave in diesem Moment die Daten vom Master bekommen sollte. Aber in meinen Augen eben gefiltert. Nicht alles ist überhaupt notwendig. Ich würde die Readings hier wirklich so halten, wie sie auch gebraucht werden. Der JSON String enthält auch ein wenig, was man nicht bruacht....
Deswegen würde ich das A) So von der Bridge entscheiden lassen oder B) in jedem Player so als Reading hinterlegen.
Findest du es wirklich sinnig über json2nameValue zu gehen? Dann hat man wieder x Readings und einige aktuell und andere nicht. Ich würde mit der Variante immer die gleichen nutzen und überschreiben...Aber ggf. übersehe ich den Vorteil deiner Variante...  ???

Beta-User

Ad 1: Vermutlich. Wobei das ohne den konkreten MQTT-Verkehr zu kennen eben eher eine Schätzung ist... Btw.: ich _glaube_ es wäre zielführend, statt auf die CID das Attribut devicetopic zu "nutzen" (ist eigentlich eher ein Mißbrauch...) und das entsprechend zu füllen. Das ist ggf. etwas transparenter (aber leider auch nicht deutlich einfacher)?
Ad 2: Klingt einerseits kompliziert. Aber wenn ich das andererseits mal etwas genereller ansehe:
a) wir kennen/können kennen die uuid des Masters und wir wissen auch, wann wir ggf. die Steuerungselemente für Gruppenbedienung benötigen würden?
b) wir wissen auch, über welchen Topic wir die an den Master gerichteten Befehle absetzen müssten (ganz ohne den Namen ermitteln zu müssen ;) ). Allerdings ist der nicht statisch, sondern wäre eben je nach aktuellem Master (mit Perl) zusammenzubasteln. Ergo fehlen eigentlich nur ein paar weitere setList-Einträge...?

Ad 3: Dass der "normale Zweig" dann "stumm" ist, ist erst mal gut (wobei ich glaube, dass es einfacher wäre, alles über das regex-Topic zu empfangen).
Zum Rest: Meine Idee mit json2nameValue() und den Präfixen war ja nicht unbedingt, mehr Readings zu erzeugen, sondern ggf. via jsonMap genau den Teil rauszufischen, der uns interessiert und dann damit die "normalen" Readings zu überschreiben (und den Rest eben mit :0 zu verwerfen). Das mag sogar etwas mehr Auswerteaufwand bzw. Programmschritte im Hintergrund erfordern, ist aber mMn. am Ende für den User deutlich transparenter (da "Standardfunktion") als ein Perl-regex-Bandwurm, und v.a.: er ist nicht ganz so statisch, man kann leichter was dran ändern und ist nicht direkt aufgeschmissen, wenn sich an der Struktur des JSON je mal was ändern sollte...
(Evtl. sollte man den Präfix noch als Parameter schreiben, den man vorneweg ermittelt?)

Falls es an mehreren Stellen viel und in der "one-liner-notation" unübersichtliches Perl werden wird: evtl. sollte man da eine eigene myUtils mit ausliefern?
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

87insane

2
a) Ja
b) Finde es nicht schlimm wenn die Steuerung so ist wie sie ist. Dennoch macht ein "weiter" Knopf auch in jedem Raum Sinn. Kann man drüber nachdenken.

3
Muss ich mir ansehen... Bei Perl weiß ich besser was ich mache als bei JasonMap usw. Lesen..lesen...Habe aber eine Vermutung wie du das meinen könntest.
Ich hatte doch mal den Verkehr des Zweiges rein geworfen? Einmal als Radio und einmal mit z.B. Spotify. Ich weiß nicht welche Möglichkeiten es noch gibt aber laut definition sollte es nur diese beiden Formen geben auf dem Zweig.
Die Präfix lasse ich mal als unbeantwortet.. Sehe (noch?) keinen Sinn drin. Das kann sich aber noch ändern ;)

Hab aber leider keine Idee wie ich die zweite Prüfung darein bekomme ...
$2 eq $3
? {"grouping"=>"SINGLE"}
: $CID ne $4
? {"grouping"=>"SLAVE"}
: {"grouping"=>"MASTER"} }

Normal würde ich jetzt prüfen ob $2 eq $3 & $CID eq $1 ist. Aber geht ja mit ternary nicht... soweit ich weiß. Hat da wer eine Idee? :)

Beta-User

ad 2: Da unterhalten wir uns über Optionen, ist m.E. einfach "nice to have" und weil wir's halt können :P ...

ad 3: Was die Prüfung angeht, müßte eigentlich als erste Prüfung das hier funktionieren:
$2 eq $3 && $CID eq $1
Aber: irgendwie meint mein Bauchgefühl, dass das nicht hinreichend ist, um "den dritten Mann" außen vor zu lassen? *

Das mit jsonMap und dem Ignorieren bestimmter Werte wird evtl. klarer, wenn du dir z.B. mal das tasmota_3socketUSB_split (oder einen anderen aktuellen mehrkanalignen Tasmota) ansiehst? Wenn du das mal nachgespielt hast, wirst du es easy finden ;) .

Betr. die payloads usw.: es ist für mich sehr schwierig, immer die jeweils passende Info rauszufischen, selbst wenn sie irgendwo steht. Und selbst wenn hier der payload in verschiedenen Varianten stehen sollte, kann ich immer noch nicht ohne weiteres wissen, über welchen Topic das kam und in welchem Kontext (master/slave/single). Hier war es master, aber über welchen Topic? Vermutlich den eigenen...? Und wie sieht das zugehörige Slave-Gerät message-mäßig aus? (ad *: das ist vermutlich auch hier unser eigentliches Thema, nicht der Master... Ich würde also TOPIC+PAYLOAD von Messages benötigen, die an einen Slave und ein nicht beteiligtes drittes Gerät gehen.) Ich gehe davon aus, dass irgendwas kommen müßte, wenn man am Slave die Lautstärke ändert?

Zwischenzeitlich ist das aber vermutlich nicht mehr so dringlich, denn zum einen sind die Bausteinchen jetzt mAn. alle bekannt, ich denke auch, die richtige Richtung empfohlen zu haben mit dem jsonMap, der Rest ist sowieso zusammenbauen und (v.a.) testen...
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

87insane

2) ok.. Damit kann ich leben :)

https://github.com/svrooij/sonos2mqtt/issues/110#issuecomment-652288934

Nur Master und Single haben Payloads. Slaves bekommen nur noch Antwort auf zugelassene Aktionen, wie z.B. volume. Ansonsten bekommen die Slaves nichts mehr ab dem Moment wo sie einem Master / einer Gruppe angehören.

Hmmm.. cool, geht also doch so einfach "&&"... Teste mal ob es Seitenwind gibt...

Teste das alles mal und gebe Feedback.

Beta-User

Was den Link angeht: Danke, das ist dahingehend aufschlussreich, dass wir das wohl bis dahin richtig verstanden haben.
Zitat von: 87insane am 09 Juli 2020, 15:53:03
Nur Master und Single haben Payloads. Slaves bekommen nur noch Antwort auf zugelassene Aktionen, wie z.B. volume. Ansonsten bekommen die Slaves nichts mehr ab dem Moment wo sie einem Master / einer Gruppe angehören.
Was hier noch fehlt: Welche Infos kommen dann? Wenn es an der Stelle wieder "ich schicke alles" (aber mit teils veralteten Werten) ist, dann haben wir eine Aufgabe, wenn es nur "Differenzmeldung" ist, ist es easy, denn die können wir einfach "durchwinken" (im Sinne von normal verarbeiten)...
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

87insane

ZitatWas hier noch fehlt: Welche Infos kommen dann? Wenn es an der Stelle wieder "ich schicke alles" (aber mit teils veralteten Werten) ist, dann haben wir eine Aufgabe, wenn es nur "Differenzmeldung" ist, ist es easy, denn die können wir einfach "durchwinken" (im Sinne von normal verarbeiten)...
Keine Infos mehr... Die Slaves bekommen erst wieder in Ihrem Zeig eine Info wenn Sie die Gruppe verlassen. Solange ist das Gerät wie tot. Nur wenn Befehle angetriggert werden (die am Slave gehen), dann kommen auch genau diese Infos zurück. z.B. Volume.

Ich kämpfe gerade noch damit, zu zu ordnen wenn Single, dann nimm auch nur deine Daten und nicht die, des anderen Single, wenn er auf einmal was macht...

Beta-User

Zitat von: 87insane am 09 Juli 2020, 17:24:05
Keine Infos mehr... Die Slaves bekommen erst wieder in Ihrem Zeig eine Info wenn Sie die Gruppe verlassen. Solange ist das Gerät wie tot. Nur wenn Befehle angetriggert werden (die am Slave gehen), dann kommen auch genau diese Infos zurück. z.B. Volume.
Das klingt gut!

ZitatIch kämpfe gerade noch damit, zu zu ordnen wenn Single, dann nimm auch nur deine Daten und nicht die, des anderen Single, wenn er auf einmal was macht...
Ungetestete Idee: Wenn es (nur) den anderen betrifft, kommt die eigene "RINCON" in der payload auch nicht vor? Dann sollte sich das mit einer "Vorabregex" checken lassen?
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

87insane

ZitatDas klingt gut!
Bisher ärgert es mich nur!

ZitatUngetestete Idee: Wenn es (nur) den anderen betrifft, kommt die eigene "RINCON" in der payload auch nicht vor? Dann sollte sich das mit einer "Vorabregex" checken lassen?
Schwierig ist es für mich das so hin zu bekommen das:
Wenn Single dann eigene Readings, wenn Slave dann die Readings des Masters und wenn Master, die eigenen Readings. Ich hatte bisher auch nur eine Master/Slave "Erkennung". Single hast du neu hinzugefügt und die Idee ist gut. Die Umsetzung fällt mir aber schwer.
Wie meinst du das mit der Regex in dem Fall? Meinst du IN json2nameValue??

Beta-User

Also, meine bisherige Interpretation:

- Wenn Slave, kommen nur noch eingeschränkte Infos an den "eigenen" Topic. Die könn(t)en wir direkt mit json2nameValue($EVENT,'',$JSONMAP) verarbeiten (vorsichtshalber mit $JSONMAP, brauchen wir vermutlich nicht).

- Wenn Master, kommen die Readings über denselben Topic, oder? Dann sollten wir die ebenfalls direkt mit json2nameValue($EVENT,'',$JSONMAP) verarbeiten können.

- Wenn Slave, kommen die Readings über einen anderen Topic, aber die Payload enthält irgendwo "unseren" Rincon? Wissen wir dann, wo, also in welchem JSON-Element? Mein Vorschlag war, einfach den ganzen JSON via regex zu parsen, und dann entweder "nichts" zu machen, oder eben bei einem match den Rest (=vorhandenen Code) anzuhängen. ABER: wenn das vorherige paßt, dann aber nur noch für den betreffenden "logischen Ast", der Rest ist ja schon erledigt, und dann nur hier effektiv mit dem/den passende/n Präfix(en) zu arbeiten.

(Im Prinzip stelle ich dieselbe Frage (was wann über welchen Topic an payload kommt) mal wieder in einem neuen Gewand...)
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

87insane

Wenn Slave: An den eigenen Topic kommen nur noch Infos wenn aus dem eigenen Topic auch etwas wie z.B. Lautstärke....(schrieb ich ja auch schon).

Wenn Master: Hier kommen dann weiterhin über seinen Topic die Infos.

Wenn Slave: Kommen die Readings garnicht mehr...siehe oben. Sie sollten dann aber vom Master kommen, damit man in dem Player auch den wirklichen Status hat. Man erkennt in der Payload nur wer der Master einer Gruppe ist. Man erkennt nicht wer genau die Mitglieder sind. "groupName Wohnzimmer + 2". Die Mitglieder selber erkennen nur wem sie angehören, da der Gruppenname auch immer den MASTER am Anfang des Namens hat und das eben die coordinator ID bei Gruppen beitritt bekannt gegeben wird. Es gibt also keine Auflistung der Slave RINCONs in der Payload. Die Slaves kennen sich untereinander demnach gar nicht. Nur der Master kennt beide Partner.

Ich bekomme es nicht hin, das mit dem rL Eintrag, nicht die Single sich immer was falsches schnappen.
Alle Player sind Single. Ich starte im WZ die Musik, mit der aktuellen Regel werden dann alle Single zu Slave außer dem, der wirklich spielt. Also übernehmen alle die Infos des spielenden. Ist natürlich quark denn in echt spielt ja nur WZ und nicht auch noch Küche usw. ...Der Kopf qualmt

Beta-User

Hmm, klingt für mich, als jagten wir ein Phantom: Wenn es keine Möglichkeit gibt anhand Topic/Payload zu erkennen, welcher Slave zu welchem Master gehört, versuchen wir es mit untauglichen Mitteln...

Ergo ginge es am ehesten indirekt, aber da bin ich dann raus. Mit indirekt meine ich: Wir bemerken, dass es überhaupt einen Master gibt und versuchen dann z.B. anhand einer Lautstärkeänderungsanweisung an jeden potentiellen Slave rauszuknobeln, wer es denn nun ist oder irgend so was in der Art...
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

87insane

Nein Nein....

Man kann anhand der payload schon erkennen wer welchem Master angehört. Glaube wir missverstehen uns.
In der payload steht ein Gruppen Name. Dieser sagt wer Master ist. Denn da steht zb "Wohnzimmer + bla"  ... In dem Fall ist Wohnzimmer der Master. Gleichzeitig sehen wir die Koordinator ID. Also zwei Indikatoren. Diese bekommt der slave noch übermittelt und dann ist Ende. Ggf macht für dich nicht dir payload sondern mal ein Event Ausschnitt Sinn. Versuche das noch dieses we... Bin aber noch ne Weile am arbeiten.

Wenn du den Event Monitor siehst, wird dir klar was ich meine. Das ist an sich kein Weltuntergang. Glaube auch das du das zwischendurch verstanden hattest aber ich dich ggf durch meine Tests verwirrt hab.

Ach ja.. Wenn nochmal jemand fragt wie man einfach und schnell einen JSON bereit stellen kann. In meinen Augen, den Zweig den man will, einfach in readingname=>$EVENT schieben. Finde das ist eine super Lösung bevor man sein log mit Verbose füllt. So kann man dazu auch wunderbar heraus filtern wenn man mag. Was sagst du dazu? Finde das ist eine einfache aber super debug Lösung.

rudolfkoenig

Kann bitte jemand die eigentliche Aufgabe und das Problem dabei kurz zusammenfassen?
Am besten mit einem konkreten Beispiel :)

Ich habe den Eindruck, es geht darum, dass mehrere MQTT2_DEVICE Instanzen aus der gleichen Nachricht jeweils  unterschiedliche Teile in Reading/Event konvertieren sollten, aber es gibt noch Probleme bei der Festlegung wer was haben soll.

87insane

Nur Handy, deswegen keinen Quellcode zur Hand.

Einfach gesagt bekommen Sonos Lautsprecher über mqtt im Gruppen Verbund als slave keine readings mehr über ihren Zweig.
Sobald ein Lautsprecher einer gruppe angehört gibt es einen Master. Nur noch der Master erhält readings und die slaves sind quasi tot. AUßER wenn man zb Volume am slave ändert, dann bekommt der slave auch Volume als Antwort.

Deine Vermutung ist also gut. Am schönsten wäre es das der slave oder die slaves (je nach Anzahl der Lautsprecher daheim) den Zweig des masters mit nutzen um aktuellen Track Titel, Status usw zu sehen. Sollte eine Box Master sein, sollte sie ihre eigenen Daten verwerten, gleiches gilt wenn eine box solo ist. Diese drei Zustände gibt es.

Hat das so geholfen oder brauchst du mehr futter? Wenn ja, was genau?

rudolfkoenig

Ideal waere fuer jeden der drei Zustaende ein Beispiel-Input (topic+message) und eine Liste der gewuenschten Readings.

Beta-User

Ergänzend: Bitte noch topic+Message von der "speziellen" Situation, dass sich eines der Geräte nach "Slave" verabschiedet!

Wenn da die "Master-uuid" drinsteht, geht es doch und wir brauchen dann ein zweites Abonnement auf "alles, außer dem eigenen uuid-Zweig". In der müßte dann m.E. geprüft werden, ob uuid eq ReadingsVal($NAME,"maasterUuid","none"), und dann json2nameValue() mit Präfix verwendet werden. Dazu ein Mapping (jsonMap), das alles, was wir aus diesem Zweig nicht brauchen verwirft und die gewünschten Readings dann auf die "normalen" Namen ohne Präfix mappt.
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

Zitat von: 87insane am 24 Juli 2020, 15:24:38
Hey zusammen,

leider ist die Zeit bisher nicht besser geworden aber anbei mal die Payloads aus dem Zweig "sonos/RINCON_123HEX:.*"...
Diese sollte ich schon ewig mal hier hochladen... :-\ Hoffe das ist soweit noch okay..
Glaube, das ist in diesem Thread besser aufgehoben...

Zitatpayload wenn Single und play
{"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer","coordinatorUuid":"RINCON_7828CAF427B201400","currentTrack":{"Artist":"1LIVE mit Larissa Rieß und Philipp Isterewicz","AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgxNzk3JnM9Nzg2NmYyOWMjYmFiMDQ4M2U2MjRiNDcwNWQ2ZGQ5ZWI1NGU5YjYzZGY","UpnpClass":"object.item","ItemId":"-1","ParentId":"-1","TrackUri":"x-rincon-mp3radio://https://wdr-edge-2020-fra-lg-cdn.cast.addradio.de/wdr/1live/live/mp3/128/stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgxNzk3JnM9Nzg2NmYyOWMjYmFiMDQ4M2U2MjRiNDcwNWQ2ZGQ5ZWI1NGU5YjYzZGY","ProtocolInfo":"x-rincon-mp3radio:*:*:*"},"enqueuedMetadata":{"AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"1LIVE","UpnpClass":"object.item.audioItem.audioBroadcast","ItemId":"-1","ParentId":"-1"},"transportState":"PLAYING","playmode":"NORMAL","ts":1595595401660,"volume":{"Master":11,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false}}

Payload wenn joinGroup Wohnzimmer
Master: {"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","volume":{"Master":11,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false},"ts":1595596556496,"currentTrack":{"AlbumArtUri":"http://192.168.20.70:1400/getaa?u=x-rincon-mp3radio:%2f%2fhttps:%2f%2fwdr-1live-live.icecastssl.wdr.de%2fwdr%2f1live%2flive%2fmp3%2f128%2fstream.mp3%3far-distributor%3df0e2&v=1","Title":"1LIVE","UpnpClass":"object.item","ItemId":"-1","ParentId":"-1","TrackUri":"x-rincon-mp3radio://https://wdr-1live-live.icecastssl.wdr.de/wdr/1live/live/mp3/128/stream.mp3?ar-distributor=f0e2","ProtocolInfo":"x-rincon-mp3radio:*:*:*"},"enqueuedMetadata":{"AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"1LIVE","UpnpClass":"object.item.audioItem.audioBroadcast","ItemId":"-1","ParentId":"-1"},"transportState":"STOPPED","playmode":"NORMAL"}
Slave: {"uuid":"RINCON_7828CAF4289001400","name":"Küche","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","transportState":"PLAYING","playmode":"NORMAL","ts":1595596556496,"volume":{"Master":14,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false}}
Ich gehe jetzt mal davon aus, dass die "Slave"-Message auch unter dem HEX "RINCON_7828CAF4289001400"-Zweig kommt?
(Es wäre wirklich einfacher, wenn ich nicht raten müßte, UNTER WELCHEM GENAUEN Topic welche Message kommt, aber ich wiederhole mich da vermutlich...)

Zum Testen mal folgendes:
defmod MQTT2_RINCON_7828CAF4289001400 MQTT2_DEVICE RINCON_7828CAF4289001400
attr MQTT2_RINCON_7828CAF4289001400 readingList sonos/RINCON_7828CAF4289001400:.* { json2nameValue($EVENT,'',$JSONMAP) }\
  sonos/RINCON_(?!7828CAF4289001400)[A-Z0-9]+:.* { my $master = ReadingsVal($NAME,"coordinatorUuid",""); $EVENT =~ m,coordinatorUuid.:.$master, ? json2nameValue($EVENT,'M_',$JSONMAP) : undef }

(Mangels Topic-Message-Paaren kann ich leider nicht selbst testen..., aber was hier passieren sollte, müßte ggf. mit jsonMap weiterbearbeitbar sein, evtl. können wir in der zweiten rL-Zeile auch einen Filter als 4. Argument in json2nameValue() setzen).
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

87insane

Testen geht gerade leider nicht aber...

Ich habe bei beiden Players den RINCON Pfad genommen. Der Slave hat natürlich einen anderen RINCON Namen.
Bei mir ist hier der Master: RINCON_7828CAF427B201400 und der Slave: RINCON_7828CAF4289001400

Ich denke ich habe deutlich gesagt aus welchem Topic es kommt: sonos/RINCON_123HEX - Der natürlich von beiden beteiligten Playern, hier auch gepostet wurde.

Ggf. schafft das gerade jemand anderes zu testen. Bei mir würde es dauern. Würde es aber natürlich machen, wenn kein anderer gerade kann...

Beta-User

Ok, jetzt habe ich das selber zusammengefrickelt; da war noch ein kleiner Typo drin, der ist auch im anderen Beitrag korrigiert.

Hier mal ein RAW von dem, was man da bekommt, wenn man erst die Abmeldung unter den Master macht
sonos/RINCON_7828CAF4289001400 {"uuid":"RINCON_7828CAF4289001400","name":"Küche","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","transportState":"PLAYING","playmode":"NORMAL","ts":1595596556496,"volume":{"Master":14,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false}}
und dann sowas hinterherschickt:
sonos/RINCON_7828CAF427B201400 {"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","volume":{"Master":11,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false},"ts":1595596701688,"currentTrack":{"Artist":"1LIVE mit Larissa Rieß und Philipp Isterewicz","AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE","UpnpClass":"object.item","ItemId":"-1","ParentId":"-1","TrackUri":"x-rincon-mp3radio://https://wdr-edge-2020-fra-lg-cdn.cast.addradio.de/wdr/1live/live/mp3/128/stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE","ProtocolInfo":"x-rincon-mp3radio:*:*:*"},"enqueuedMetadata":{"AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"1LIVE","UpnpClass":"object.item.audioItem.audioBroadcast","ItemId":"-1","ParentId":"-1"},"transportState":"PLAYING","playmode":"NORMAL"}

defmod MQTT2_RINCON_7828CAF4289001400 MQTT2_DEVICE RINCON_7828CAF4289001400
attr MQTT2_RINCON_7828CAF4289001400 IODev MQTT2_FHEM_Server
attr MQTT2_RINCON_7828CAF4289001400 readingList sonos/RINCON_7828CAF4289001400:.* { json2nameValue($EVENT,'',$JSONMAP) }\
sonos/RINCON_(?!7828CAF4289001400)[A-Z0-9]+:.* { my $master = ReadingsVal($NAME,"coordinatorUuid","7828CAF4289001400");; $EVENT =~ m,coordinatorUuid.:.$master, ? json2nameValue($EVENT,'M_',$JSONMAP) : undef }

setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_coordinatorUuid RINCON_7828CAF427B201400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_AlbumArtUri https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_Artist 1LIVE mit Larissa Rieß und Philipp Isterewicz
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_ItemId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_ParentId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_ProtocolInfo x-rincon-mp3radio:*:*:*
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_Title stream.mp3?ar-distributor=f0e2&;_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_TrackUri x-rincon-mp3radio://https://wdr-edge-2020-fra-lg-cdn.cast.addradio.de/wdr/1live/live/mp3/128/stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_UpnpClass object.item
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_AlbumArtUri https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_ItemId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_ParentId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_Title 1LIVE
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_UpnpClass object.item.audioItem.audioBroadcast
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_groupName Wohnzimmer + 1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_mute_LF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_mute_Master false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_mute_RF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_name Wohnzimmer
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_playmode NORMAL
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_transportState PLAYING
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_ts 1595596701688
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_uuid RINCON_7828CAF427B201400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_volume_LF 100
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_volume_Master 11
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_volume_RF 100
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 coordinatorUuid RINCON_7828CAF427B201400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 groupName Wohnzimmer + 1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 mute_LF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 mute_Master false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 mute_RF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 name Küche
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 playmode NORMAL
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 transportState PLAYING
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 ts 1595596556496
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 uuid RINCON_7828CAF4289001400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 volume_LF 100
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 volume_Master 14
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 volume_RF 100


Ergo sollte sich da jetzt mit filter und jsonMap was basteln lassen.

@Rudi, das hier hatte ich bzgl. filter erfolglos (@fhem.pl 22408) versucht:
attr MQTT2_RINCON_7828CAF4289001400 readingList sonos/RINCON_7828CAF4289001400:.* { json2nameValue($EVENT,'',$JSONMAP) }\
sonos/RINCON_(?!7828CAF4289001400)[A-Z0-9]+:.* { my $master = ReadingsVal($NAME,"coordinatorUuid","7828CAF4289001400");; $EVENT =~ m,coordinatorUuid.:.$master, ? json2nameValue($EVENT,'M_',$JSONMAP,'.*currentTrack.*') : undef }

(mit und ohne .* vorne/hinten)
Paßt das eigentlich so und fhem.pl ist nicht aktuell genug, oder übersehe ich mal wieder was?
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

Leider arbeitet map und filter nicht richtig bei geschachtelten JSON, d.h. in diesem Fall wurde gegen Artist und nicht gegen M_currentTrack_Artist geprueft.

Ich habe das jetzt umgestellt: es wird gegen M_currentTrack_Artist geprueft, sowohl fuer map, wie auch fuer filter.
Das bedeutet leider, dass alte Installationen, die map mit so einem Struktur verwenden, angepasst werden muessen.

Beta-User

Betrifft das evtl. Ebus? Dann bitte deutliche Info an User allg. u. Reinhardt im speziellen.
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

OppiM

Hi,

Ich habe seit ich heute FHEM aktualisiert habe das Problem, dass sich die Readings meines Landroid nicht mehr aktualisiert. Eingebunden ist er nach dieser Anleitung https://forum.fhem.de/index.php/topic,111959.0.html.

Dieser JSON wird empfangen:
{"cfg":{"id":1,"lg":"it","tm":"18:10:34","dt":"26/07/2020","sc":{"m":1,"p":0,"d":[["14:00",0,0],["14:00",240,0],["14:00",0,0],["14:00",240,1],["14:00",0,0],["14:00",240,0],["14:00",240,1]]},"cmd":0,"mz":[0,0,0,0],"mzv":[0,0,0,0,0,0,0,0,0,0],"rd":120,"sn":"xxxxxxxxxxxxxxxxxx"},"dat":{"mac":"xxxxxxxxxxxx","fw":3.52,"bt":{"t":32.7,"v":20.06,"p":100,"nr":2323,"c":0,"m":1},"dmp":[-1.7,1.5,351.5],"st":{"b":34737,"d":618349,"wt":36673},"ls":1,"le":0,"lz":2,"rsi":-61,"lk":1}}

Alle Werte, für die kein JSONMap-Eintrag existiert, werden aktualisiert. Doch wenn ein JSONMap-Eintrag vorhanden ist (z.B. dat_rsi:wifiQuality), wird das wifiQuality-Reading nicht aktualisiert bzw. angelegt, wenn nicht vorhanden.

Zitat von: rudolfkoenig am 24 Juli 2020, 18:10:17
Ich habe das jetzt umgestellt: es wird gegen M_currentTrack_Artist geprueft, sowohl fuer map, wie auch fuer filter.
Das bedeutet leider, dass alte Installationen, die map mit so einem Struktur verwenden, angepasst werden muessen.

Könnte es an dieser Umstellung liegen und wie müssten die maps dann angepasst werden?

[EDIT]
Auch andere Devices, die JSONMap benutzen, zeigen jetzt die gleichen Symptome (z.B. Tasmota). Alles, was über JSONMap läuft, wird nicht aktualisiert.
Wifi_RSSI    74    2020-07-26 18:41:25
Wifi_Signal  -63   2020-07-26 18:41:25
current      0.078 2020-07-26 16:52:11
power        2.10  2020-07-26 16:52:11
state        on    2020-07-26 18:41:21
voltage      239   2020-07-26 16:52:11


Wifi_RSSI, Wifi_Signal und state sind normale Werte, current, power und voltage kommen (normalerweise) über JSONMAP mit dem mapping
POWER1:0 POWER2:0 POWER3:0 POWER4:0 Dimmer:0 Channel_0:0 Channel_1:0 Channel_2:0 Channel_3:0 Channel_4:0 HSBColor:0 Color:0 ENERGY_Current:current ENERGY_Power:power ENERGY_Voltage:voltage

Gruß,
Michael

rudolfkoenig

Danke fuer den Hinweis, dieser Umbau hat leider die Mapping-Funktion ausser Dienst gesetzt.
Ich habe es gefixt und eingecheckt.

OppiM

Ich hab die Änderung per Hand in der fhem.pl eingetragen, danach wurden die JSONMap-Readings wieder aktualisiert.

Danke für den schnellen Fix!

Gruß,
Michael

87insane

Hallo zusammen,

kann ich hier noch was testen?

@Beta-User: Wohin geht deine Tendenz... Du hast das alles im Überblick :)

Beta-User

Nachdem Rudi das mit dem filter repariert hat, solltest du eigentlich hier anknüpfen können:
Zitat von: Beta-User am 24 Juli 2020, 17:15:57
Ok, jetzt habe ich das selber zusammengefrickelt; da war noch ein kleiner Typo drin, der ist auch im anderen Beitrag korrigiert.

Hier mal ein RAW von dem, was man da bekommt, wenn man erst die Abmeldung unter den Master macht
sonos/RINCON_7828CAF4289001400 {"uuid":"RINCON_7828CAF4289001400","name":"Küche","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","transportState":"PLAYING","playmode":"NORMAL","ts":1595596556496,"volume":{"Master":14,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false}}
und dann sowas hinterherschickt:
sonos/RINCON_7828CAF427B201400 {"uuid":"RINCON_7828CAF427B201400","name":"Wohnzimmer","groupName":"Wohnzimmer + 1","coordinatorUuid":"RINCON_7828CAF427B201400","volume":{"Master":11,"LF":100,"RF":100},"mute":{"Master":false,"LF":false,"RF":false},"ts":1595596701688,"currentTrack":{"Artist":"1LIVE mit Larissa Rieß und Philipp Isterewicz","AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE","UpnpClass":"object.item","ItemId":"-1","ParentId":"-1","TrackUri":"x-rincon-mp3radio://https://wdr-edge-2020-fra-lg-cdn.cast.addradio.de/wdr/1live/live/mp3/128/stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE","ProtocolInfo":"x-rincon-mp3radio:*:*:*"},"enqueuedMetadata":{"AlbumArtUri":"https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard","Title":"1LIVE","UpnpClass":"object.item.audioItem.audioBroadcast","ItemId":"-1","ParentId":"-1"},"transportState":"PLAYING","playmode":"NORMAL"}

defmod MQTT2_RINCON_7828CAF4289001400 MQTT2_DEVICE RINCON_7828CAF4289001400
attr MQTT2_RINCON_7828CAF4289001400 IODev MQTT2_FHEM_Server
attr MQTT2_RINCON_7828CAF4289001400 readingList sonos/RINCON_7828CAF4289001400:.* { json2nameValue($EVENT,'',$JSONMAP) }\
sonos/RINCON_(?!7828CAF4289001400)[A-Z0-9]+:.* { my $master = ReadingsVal($NAME,"coordinatorUuid","7828CAF4289001400");; $EVENT =~ m,coordinatorUuid.:.$master, ? json2nameValue($EVENT,'M_',$JSONMAP) : undef }

setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_coordinatorUuid RINCON_7828CAF427B201400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_AlbumArtUri https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_Artist 1LIVE mit Larissa Rieß und Philipp Isterewicz
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_ItemId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_ParentId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_ProtocolInfo x-rincon-mp3radio:*:*:*
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_Title stream.mp3?ar-distributor=f0e2&;_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_TrackUri x-rincon-mp3radio://https://wdr-edge-2020-fra-lg-cdn.cast.addradio.de/wdr/1live/live/mp3/128/stream.mp3?ar-distributor=f0e2&_art=dj0yJmlwPTkzLjIzNy4xNzMuMTQ1JmlkPWljc2N4bC1lazY3N3ZkbmImdD0xNTk1NjgzMDE0JnM9Nzg2NmYyOWMjZTVjM2I2ZWY4ZTExOTBmNDM3OTRlNjI1NGE1YzM1OTE
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_currentTrack_UpnpClass object.item
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_AlbumArtUri https://img.ardmediathek.de/standard/00/42/92/13/72/-295433861/1x1/576?mandant=ard
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_ItemId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_ParentId -1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_Title 1LIVE
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_enqueuedMetadata_UpnpClass object.item.audioItem.audioBroadcast
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_groupName Wohnzimmer + 1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_mute_LF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_mute_Master false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_mute_RF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_name Wohnzimmer
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_playmode NORMAL
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_transportState PLAYING
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_ts 1595596701688
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_uuid RINCON_7828CAF427B201400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_volume_LF 100
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_volume_Master 11
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:50:36 M_volume_RF 100
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 coordinatorUuid RINCON_7828CAF427B201400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 groupName Wohnzimmer + 1
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 mute_LF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 mute_Master false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 mute_RF false
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 name Küche
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 playmode NORMAL
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 transportState PLAYING
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 ts 1595596556496
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 uuid RINCON_7828CAF4289001400
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 volume_LF 100
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 volume_Master 14
setstate MQTT2_RINCON_7828CAF4289001400 2020-07-24 16:49:19 volume_RF 100


Ergo sollte sich da jetzt mit filter und jsonMap was basteln lassen.

Bessere Erkenntnisse habe ich nicht, und den Überblick über die diversen Varianten des devStateIcon habe ich schon lange nicht mehr...
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

TomLee

Hab auch mal eine Frage zu json2nameValue.

Gegeben ist folgender JSON:

{"Result":[{"AlbumArtUri":"http://cdn-radiotime-logos.tunein.com/s296020q.png","Title":"011.FM-NonStop60s","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/26","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s296020?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"http://dtu8ldmaopof3.cloudfront.net/i/https:%2F%2Fderpimagecache.s3.amazonaws.com%2Fimage%2F475_288x162_2020-01-22-10-30-00-920.png_180.jpg","Title":"1A Deutsche Hits","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/41","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:rpde_svc_475?sid=232&flags=32&sn=4","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"http://dtu8ldmaopof3.cloudfront.net/i/https:%2F%2Fderpimagecache.s3.amazonaws.com%2Fimage%2F1944_288x162_2019-02-12-13-40-09-357.png_640.jpg","Title":"COSMO Chillout","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/30","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:rpde_svc_1944?sid=232&flags=32&sn=4","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"http://cdn-profiles.tunein.com/s20295/images/logoq.png","Title":"DASDING 92.5 (Euro-Hits)","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/34","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s76488?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"http://cdn-profiles.tunein.com/s84548/images/logoq.jpg","Title":"die neue welle 101.8 (Rock)","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/39","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s84548?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"AlbumArtUri":"http://cdn-radiotime-logos.tunein.com/s65628q.png","Title":"FM نجوم 100.6 (Arabisch)","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/29","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s65628?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"},{"Title":"Hitradio Ö3 99.9 (Österreichisch)","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/37","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s8007?sid=254&flags=8224&sn=0","ProtocolInfo":"x-rincon-mp3radio:*:*:*"},{"Title":"Hörbücher","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/32","ParentId":"FV:2","TrackUri":"x-rincon-playlist:RINCON_000E58F7F67C01400#S://192.168.188.26/OwnMusic/Hörbücher","ProtocolInfo":"x-rincon-playlist:*:*:*"},{"AlbumArtUri":"http://cdn-radiotime-logos.tunein.com/s97066q.png","Title":"PsyRadioChillout","UpnpClass":"object.itemobject.item.sonos-favorite","ItemId":"FV:2/15","ParentId":"FV:2","TrackUri":"x-sonosapi-stream:s97066?sid=254&flags=8224&sn=0","ProtocolInfo":"x-sonosapi-stream:*:*:*"}],"NumberReturned":9,"TotalMatches":9,"UpdateID":3}


Wenn json2nameValue eine Referenz auf einen Hash zurückgibt, dann verstehe ich es bisher so das mit dem JSON oben eine Referenz auf einen Hash von Hashes zurückgegeben wird.

Mir gibt

{ use Data::Dumper qw(Dumper);;my $h = json2nameValue(ReadingsVal("SonosBridge","Favorites","unknown"),'','lustig','Title|TrackUri');;Dumper $h}

$VAR1 = {};

zurück.


Hätte erwartet das mit j2nv so was in der Art zurückgeben wird :

$VAR1 = {
    Result_1 => {
        Title => 'NonStop60s',
        TrackUri => 'x-sonosapi-stream:s296020?sid=254&flags=8224&sn=0',
    },
    Result_2  => {
        Title => '1A Deutsche Hits',
        TrackUri => 'x-sonosapi-stream:rpde_svc_475?sid=232&flags=32&sn=4',
    },
    ...
};


Lieg ich damit so falsch ?

Kann bitte irgendwer in verständlichen Worten zeigen oder erklären wie das Ergebnis, welches j2nv liefert, wirklich aussieht ?

Gruß

Thomas

Otto123

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

Beta-User

Zitat von: Otto123 am 07 August 2020, 13:21:11
... und was man anstatt 'lustig' wirklich hinschreiben sollte.  ;D
Sorry, habe das hier zu spät gesehen. Meine (ggf. verbesserungsfähige) Antwort ist hier zu finden:
Zitat von: Beta-User am 07 August 2020, 13:24:57
2 ist der "prefix". Der kann (meistens) leer bleiben. Da was reinzuschreiben macht nur dann Sinn, wenn man z.B. JSON aus unterschiedlichen Quellen/Topics hat, die aber intern dieselben Strukturen aufweisen und daher dieselben Namen ergeben würden (Rudi hat das "wegen" Ebus entwickelt und dabei dann gleich auch das 3. Argument eingeführt, weil die "eigentlichen" Readingnamen dann ziemlich unleserlich und unhandlich wurden). Das 3. Argument ist eigentlich (?) ein Hash, in der Regel macht es keinen Sinn, da was anderes reinzuschreiben als das "simple" $JSONMAP, das intern dann vor dem Ausführen der Funktion mit dem Hash aus dem Internal ersetzt wird, der wiederum aus dem Attribut jsonMap gebildet wird (in der attr-Funktion von MQTT2_DEVICE). Das 3. Argument/$JSONMAP dient also dazu, leserliche (oder besser passende oder standardkonforme) Readingnamen zu erzeugen, indem die "technischen Readingnamen" durch beliebige ersetzt werden können...
[...]
Jein; Rudi hat dazu mal ausgeführt, dass j2nv "eine Referenz auf einen Hash" zurückliefert. Das macht einen Unterschied beim Zugriff auf die Daten, Details rund um diesen Beitrag: https://forum.fhem.de/index.php/topic,111429.msg1059608.html#msg1059608[...]Eventuell ist die "grep"-Variante dann auch ein Weg, die Schleife einzusparen (die dann aber wegen Filter eh' nicht mehr viele Datenfelder durchgehen muß, oder? Man könnte aber direkt nach einem match auch das return einbauen, oder?). Muß aber zugeben, dass ich mir das Problem jetzt nicht im Detail angesehen habe und das ganze insgesamt auch recht abstrakt ist. Kann also auch ein gut gemeinter Hinweis in die falsche Richtung sein...
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

ZitatLieg ich damit so falsch ?
Ich meine ja: json2nameValue liefert eine Referenz auf ein "flaches" Hash zurueck, was aus "Name"=>"Wert" Paaren besteht.
Es dient nicht dazu, JSON in Perl Datenstrukturen zu verwandeln, sondern um JSON Daten nach FHEM Readings bzw. Events zu konvertieren.

Parameter 1 ist das Input, Parameter 2 wird als Prefix angestellt (um zwei JSONs mit gleichen Inhalt unterscheiden zu koennen), Parameter 3 ist eine Referenz auf ein Hash, um die Namen aendern zu koennen, und Parameter 4 ist ein Regexp, um nur bestimmte Namen zu akzeptieren. Filtern geht zwar auch mit Parameter 3, kann aber umstaendlich sein. Nur der erste Parameter ist verpflichtend.