Sonos2mqtt - vielleicht hat jemand Lust mitzumachen

Begonnen von Otto123, 31 Mai 2020, 18:30:55

Vorheriges Thema - Nächstes Thema

Stefan_Hvr

Für mich perfekt.
Komme nur leider nicht dazu das Variabel Problem zu lösen.
Viele Grüße aus Hannover
EnOcean, Zigbee, Shelly MQTT, Homebridge, Fritzbox, Harmonyhub, Alexa, Worx MQTT, Sonos MQTT, Tahoma, Telegram, Vorwerk,IRoomba MQTT, Buderus Km200,
seit 08/2019 Hausautomation mit FHEM

Otto123

#916
Ich habe jetzt mal folgenden Code eingebaut.
Eine Abfrage für die Listen:
sub sonos2mqtt_searchList
{
use JSON;use HTML::Entities;use Encode qw(encode decode);
my $regex = shift //return'';
my $list  = shift //return'';
my $enc = 'UTF8';
my $uri = '';my $UpnpClass = '';my $ItemId = '';my $CdUdn = '';
my $dev = (devspec2array('model=sonos2mqtt_bridge'))[0];
my $decoded = decode_json(ReadingsVal($dev,$list,''));
my @array=@{$decoded->{'Result'}};
   $regex=~s/[\/()]/./g;
   for (@array) {
      if (encode($enc, decode_entities($_->{'Title'}))=~/$regex/i)
         {
          $uri = $_->{'TrackUri'};
          $ItemId = $_->{'ItemId'} || '';
          $UpnpClass= $_->{'UpnpClass'} || '';
          $CdUdn= $_->{'CdUdn'} || '';
         }
   }
   return ($uri,$ItemId,$UpnpClass,$CdUdn);
}

Eine Ergänzung zum play Befehl:
if($cmd eq 'play') {
   if (@arr == 1) { $payload = qq({ "command": "$cmd" }) }
   else {
     if ($arr[1] eq 'Radio') {$search = (split(' ', $EVENT,3))[2] ;$fav = "Radios"}
     elsif ($arr[1] eq 'Favorite') {$search = (split(' ', $EVENT,3))[2] ;$fav = "Favorites"}
     elsif ($arr[1] eq 'Playlist') {$search = (split(' ', $EVENT,3))[2] ;$fav = "Playlists"}
     my ($uri,$ItemId,$UpnpClass,$CdUdn)=sonos2mqtt_searchList($search,$fav);
     if ($arr[1] eq 'Playlist') {
       $payload = qq({"command": "adv-command","input": { "cmd": "AVTransportService.RemoveAllTracksFromQueue" }});
       fhem("set $NAME x_raw_payload $payload");
       fhem("set $NAME input Queue");
       $payload = qq({"UpnpClass": "$UpnpClass","ItemId": "$ItemId","CdUdn": "$CdUdn"});
       $payload = qq({ "InstanceID": 0,"DesiredFirstTrackNumberEnqueued": 0,"EnqueueAsNext": true,"EnqueuedURI":"$uri","EnqueuedURIMetaData": $payload});
       $payload = qq({ "command": "adv-command","input": {"cmd": "AVTransportService.AddURIToQueue","val": $payload}});
   }
   else { $payload = qq({ "command": "setavtransporturi",  "input": "$uri"}) }

return qq($topic $payload);
}

Damit geht jetzt sowas:
set alias=Arbeitszimmer play Radio CruiseOne
set alias=Arbeitszimmer play Playlist Testliste
set alias=Arbeitszimmer play Favorite Deutschlandfunk

Irgendwie wollte ich nicht immer wieder die setList modifizieren und länger machen, deswegen habe ich mal play erweitert. Das geht universeller, da braucht man bloß die 99_sonos2mqttUtils zu erweitern und nicht immer auch das Template.
Die Befehle starten nicht sondern bereiten vor. Ein set ... play würde dann wirklich starten. Weiß ich noch nicht ob das so besser ist. Aber manchmal will man etwas vorbereiten und erst später starten, weil ja das System auch immer Reaktionszeiten hat.
Wer das ausprobieren will muss jetztmal so vorgehen, ich will vorm nächsten einchecken noch ein bisschen drüber nachdenken.
{qx(wget -qO ./FHEM/99_sonos2mqttUtils.pm https://raw.githubusercontent.com/heinz-otto/scripts/master/fhem/99_sonos2mqttUtils.pm);;fhem('reload 99_sonos2mqttUtils.pm')}
{sonos2mqtt_mod_list('SonosBridge','getList','Reply:Favorites,Radios,Playlists Reply'.q( {sonos2mqtt($NAME,$EVENT)}))}

Dann muss man noch einmalig oder bei einer Änderung innerhalb Sonos die Listen holen:
get SonosBridge Reply Playlists;sleep SonosBridge:Reply.*;setreading SonosBridge Playlists [SonosBridge:Reply]
get SonosBridge Reply Favorites;sleep SonosBridge:Reply.*;setreading SonosBridge Favorites [SonosBridge:Reply]
get SonosBridge Reply Radios;sleep SonosBridge:Reply.*;setreading SonosBridge Radios [SonosBridge:Reply]

Das gefällt mir auch besser als immer wieder die getList anpassen :) aber vielleicht bewährt es sich nicht?
Ich muss jetzt sicher mal lernen wie man in Perl richtig Arrays zurückgibt und nicht soviel rumschubst  :-[

Gruß Otto
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

kjmEjfu

Ich komme nicht mehr hinterher  ;D ;D

Aber echt cool, dass du so viel Zeit und Energie investiert!
Migriere derzeit zu Home Assistant

87insane

Hey zusammen, bin aktuell dabei einen kleinen player in smartvisu zu basteln auf mqtt Basis.

Ich kämpfe zb noch ein wenig mit zb dem Album cover aber das ist ein html/sv Thema.

Was ich aber auch suche ist ein currentTrackPosition reading. Das habe ich bisher leider nicht. Einzig die duration Time gibt es. Kennt jemand einen schönen weg daraus nun eine Art Countdown oder so zu machen? Soweit ich das in der Sonos2MQTT Doku gesehen habe, wird es auch nicht mit gesendet. Da es aber ganz nett ist zu sehen wie lange so ein Titel noch geht....

Anbei mal die bisherige grob Fassung.


Gruß,
87insane

Spartacus

Hallo zusammen,
ich bin heute zufällig über diesen Thread gestolpert und benötige etwas Hilfe beim Verstehen der ganzen Thematik:
Ich habe aktuell keine MQTT Erfahrung, glaube aber, hier die richtige Lösung für mich gefunden zu haben. Ich nehme mal an MQTT-Befehle lassen sich ohne Probleme über Subnetz-Grenzen hinweg routen und ich wäre damit dann auch in der Lage meine Player im anderen Subnetz zu steuern. Aber vielleicht kann mich kurz jemand abholen:

Situation:
  • Fhem läuft bei mir auf einer VM im VLAN50
  • Ich verwende auf dieser VM u.a. ConBee2 mit div. Zigbee Devices und auch IKEA Sonos-Controller
  • Sonos Player laufen im VLAN10
  • eine Player Steuerung funktioniert leider nur, wenn SONOS-Module/Controller und Player im gleichen Subnetz sind (hier habe ich bislang nur das fhem eigene SONOS Modul getestet, ich denke aber das sonos2mqtt  die Player ähnlich discovered)
  • meine "Fhem-SonosController" sollen aber auf dem fhem im VLAN 50 laufen.
die Idee:
  • Ich installieren ein fhem mit sonos2mqtt im Player Subnetz (der läuft bereits und die Player werden auch in fhem gefunden und angelegt)
  • ich steuere nun über MQTT-Befehle in meinem fhem im VLAN 50 die Player im VLAN10

Frage:
  • was muss ich jetzt auf meinem fhem im VLAN50 einrichten, damit ich die Player, die auf dem sonos2mqtt-fhem gefunden wurden ansteuern kann (z.B. Lautstärke)
  • wie kann ich in meinem VLAN50-Fhem auf Player Events aus dem sonos2mqtt -fhem reagieren kann. Brauche ich zwingend noch fhem2fhem, oder geht das auch über MQTT?

Vielen Dank
Spartacus
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

87insane

Hey ich drehe das ganze mal logisch um.

Sonos2mqtt ist eigentlich ein Dienst. Wohin er das ganze sendet/senden DARF, reglementierst du mit deiner VLAN Struktur ja selber. Grundsätzlich hast du hier auch nicht erklärt auf welchem Layer du was blockierst usw.

Kurz um: du brauchst keinen ganzen neuen fhem server um die Daten des Dienstes zu empfangen. Du brauchst eigentlich nur ein Gerät auf dem der Dienst läuft. Zudem brauchst du am sich einen mqtt Server. Ich empfehle den fhem eigenen.
Damit du mit mqtt laufen lernst, empfehle ich dir mal irgendein Gerät einfach gegen einen server sprechen zu lassen. Die topic Struktur muss du einmal verstehen, dann ist es super einfach. Glaube aber das dieser thread tatsächlich nicht für Deine Anfrage gedacht ist. Ggf einen eigenen dafür auf machen? Oder ggf sich SuFu nutzen. Es gibt hier diverse Anleitungen. Im shelly Forum gibt es auch eine von mir im Bezug auf shellys. Aber ich denke die erklärt auch generell sehr gut die Basics.

Mal in grob: Client Gerät -> Dienst (zb sonos2mqtt, zigbee2mqtt usw) -> MQTT Server -> Fhem Bridge -> Endgerät in fhem. So laufen die Daten durch die Gegend. Auch anders rum natürlich. Hinzu kommen ggf Update Funktionen, die gegen Internet Server sprechen. Oder aber selber einen server in das entsprechende Netz stellen.

Gruß,
Kai

Otto123

#921
Hallo Spartacus,

ich denke auch, dass die Sonosplayer nur in einem Subnetz laufen können und sonos2mqtt (ich rede von dem nodejs Dienst) im gleichen Subnetz laufen muss.

Wo Dein FHEM mit seinem MQTT2_SERVER steht ist völlig Wurst. MQTT Protokoll ist nicht an ein Subnetz gebunden.

Die Idee:
ZitatIch installieren ein fhem mit sonos2mqtt im Player Subnetz
braucht es dafür nicht! Du brauchst nur sonos2mqtt. In FHEM selbst ist es nur der MQTT2_SERVER und ein paar generische MQTT2_Devices.

VLAN10 Sonosplayer und sono2mqtt
VLAN50 FHEM mit MQTT2_Server

Am einfachsten nimmst Du den docker Container von Stephan, falls docker für Dich ein Thema ist

Ich habe das im Wiki mal noch etwas ergänzt https://wiki.fhem.de/wiki/MQTT2-Module_-_Praxisbeispiele#Sonos2Mqtt

Gruß Otto
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

Otto123

Hallo Kai,
Zitat von: 87insane am 13 März 2021, 10:25:11
Da es aber ganz nett ist zu sehen wie lange so ein Titel noch geht....
Du könntest meine volume fading Routine dahingehen entwickeln:
for (1..$d) {fhem("sleep $_;setreading $NAME timeleft {([$NAME:timeleft]+$s)}")}
$d ist die Laufzeit in 10er sec und $s wäre einfach 10.
timeleft setzt Du bei jedem Titelwechsel neu.
kannst auch sekunden nehmen, ich weiß nicht ob FHEM bei einer bestimmten Anzahl unnamed sleeps einfach "platzt" :)

Gruß Otto
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

Spartacus

Hallo zusammen,
ganz lieben Dank für die schnellen Antworten. Ich denke, ich habe jetzt verstanden, was zu tun ist. Ich werde dann mal basteln.
Mit Docker wird das wahrscheinlich nichts, da ich es bislang nicht geschafft habe dem Container ein separates Subnetz mitzugeben. Mein Host ist ne qnap auf dem Docker und Virtualisation Station läuft. Der Station kann ich einfach sie Subnetzte den verschiedenen VMs zuordnen. Bei Docker kriege ich das irgendwie nicht hin.

Ich setzte jetzt ne Debian VM mit sonos2mqtt auf und dann spiele ich mal damit rum.....

Besten Dank,
Spartacus
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

87insane

Zitat von: Otto123 am 14 März 2021, 17:15:36
Hallo Kai,Du könntest meine volume fading Routine dahingehen entwickeln:
for (1..$d) {fhem("sleep $_;setreading $NAME timeleft {([$NAME:timeleft]+$s)}")}
$d ist die Laufzeit in 10er sec und $s wäre einfach 10.
timeleft setzt Du bei jedem Titelwechsel neu.
kannst auch sekunden nehmen, ich weiß nicht ob FHEM bei einer bestimmten Anzahl unnamed sleeps einfach "platzt" :)

Gruß Otto

Die .sleep missbrauche ich schon sehr oft seit du die mal ins Spiel gebracht hast. Gerade bei Sonos und egal ob mqtt oder über das Modul, die sind schrecklich zu steuern.

Was ich hier suche ist eine in fhem existierende Funktion. Ne Art userreading. Das setzen (immer bei Track Wechsel zb) wäre an sich einfach. Gibt es in fhem bisher keine Funktion -> Zeit in Format hh:mm:es oder so mit dem Ergebnis bzw der Wahl alle 5s zb die Zeit ab zu ziehen? Das Sonos Modul berechnet die Zeiten so wie ich das lese auch sehr komplex. Der kollege hat echt Zeit investiert!

Mich wundert das das nicht eh von Sonos2mqtt mit kommt. Die einspeisende App, wie zb spotify liefert das ja mit.

Otto123

#925
@Spartacus: "da ich es bislang nicht geschafft habe dem Container ein separates Subnetz mitzugeben." "Bei Docker kriege ich das irgendwie nicht hin."
              vergiss diese Gedanken! Da bist Du mMn völlig auf dem falschen Dampfer!
Kurz gesagt: Entweder der container ist in seiner Welt, seinem Netz -> so solltest Du den sonos2mqtt Container betreiben. Du mappst bloß Port "6329:6329" nach draußen. Siehe meine Notiz
oder Du stellst den container in "network_mode: host" und damit steht er einfach im Hostnetz.
Docker ist mMn keine vlan/netzwerktest/router Umgebung!

@87insane Dann habe ich Dich falsch verstanden, ich dachte Du willst in Abständen die interpolierte verbleibende Zeit ausgeben. Ob das jetzt sekunden oder mm:ss habe ich nicht bedacht. Das ist doch nur ein Format? https://wiki.fhem.de/wiki/Zeitangaben,_rechnen_mit
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

Spartacus

Moin,
sorry, aber 1x muss ich doch noch nerven!

Sonos2mqtt läuft als Dienst auf einem Debian-Server in einer eigenen VM im VLAN10 (172.16.10.135)
Auf dem fhem-Server läuft der MQTT-Server in VLAN50 (172.16.50.40)

define mqtt2s MQTT2_SERVER 1883 global
attr mqtt2s room MQTT_IO
attr mqtt2s  autocreate simple


Die Bridge sollte dann auch so aussehen:
define SonosBridge MQTT2_DEVICE
attr SonosBridge IODev mqtt2s
attr SonosBridge room MQTT2_DEVICE
set SonosBridge attrTemplate sonos2mqtt_bridge_comfort


Was ich jetzt aber nicht verstehe ist, wie weiß der sonos2mqtt-Dienst nun welchen MQTT-Server er nehmen soll? Wo gebe ich ihm die IP und den Port mit?

@87insane
es gibt aktuell keine FW-Rules zwischen VKAN10 und VLAN50. Also normales Layer 3 Routing

Danke,
Spartacus






Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Otto123

#927
Hallo Spartacus,

ich mach es mal spannend - ich will ja mein Doku verbessern. Du nervst überhaupt nicht :)
Du findest die Antwort auf Deine Frage hier nicht?
https://wiki.fhem.de/wiki/MQTT2-Module_-_Praxisbeispiele#Sonos2Mqtt

Du hast mit pm2 gestartet?

Gruß Otto
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

87insane

Hey nochmal... Die Schnittstelle bietet leider die Track Time nicht. Aber ich glaube das man das so ca zaubern kann mit Track Wechsel und dann eben duration Time - Intervall oder aktueller Zeit ..... Kann mir nur nicht vorstellen das fhem das nicht schon selber kann.

Wir wollten ja eh nur Anreiz geben und einen neuen Player bauen. Du hast es bis zur Spitze getrieben :) bzw alle die hier geholfen haben. Eigentlich fehlt mir ein wenig die Option von zeitsprüngen innerhalb von Tracks. Deswegen und wegen der visu suche ich nach einem weg. Mit duration und act_position hätte man ja schon so gut wie die Möglichkeit. Ggf fehlt mir nur die zündende Idee. Du hast das also auch keines wegs falsch verstanden. Meine Worte sind nur nicht so treffend, wie die deinen.

An spartacus, teste mal ein wenig. Du wirst es nach dem ersten Licht an/aus verstehen. Guck dir echt mal die Beispiele an und behalte die grobe Auflistung im Hinterkopf. An sich ist mqtt mittlerweile mein Liebling. Ich erlaube mir frecherweise auch mqtt Geräte zu definieren aber als dummy. Denn in denen kann ich mir die setlist komplett manipulieren. Sicher mag das wieder jemand hier nicht aber ich nutze keine dummy geröte mehr. Lieber einen fake mqtt ... Das gleiche nur mehr Möglichkeiten.

Spartacus

Moin,
ok. Ich glaube ich komme der Sache etwas näher.... (aber stimmt das mit den vier Bindestrichen "--  --mqtt" ?)
Mein sonos2mqtt ist der 172.16.10.135

define n_pm2_sonos notify global:INITIALIZED "pm2 -s start sonos2mqtt -- --mqtt mqtt://myuser:the_secret_password@172.16.10.135:1800"
sleep global:ATTR.SonosBridge.stateFormat.connected;trigger n_pm2_sonos start


Welche Daten gebe ich für "myuser" und "the_secret_password" an? Ist das der Std-Login für die Debian-Maschine selber?

So starte ich jetzt zwar den sonos2mqtt-Service auf dem remote Rechner, aber irgendwie muss der Dienst ja auch den mqtt-Broker finden.

Für das Docker Image ändert man offenbar die enviroment.
environment:
SONOS2MQTT_MQTT=mqtt://192.168.56.121:1883 # mqtt2_server FHEM, erweiterter Syntax siehe oben

ABER:
wo findet man diese Einstellung, außerhalb einer Docker-Umgebung. Ich habe ja nur nen simples Debian mit dem Dienst.....

Spartacus.
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R