Sonos steuern

Begonnen von Will, 05 Januar 2013, 15:51:12

Vorheriges Thema - Nächstes Thema

JoeALLb

#690
Ich komme mit meiner Kalender-Einbindung nicht wirklich weiter.
Mir ist schon klar, dass meine Frage hier nicht das Sonos-Modul selbst betrifft,
vielleicht hat aber dennoch einen Tip für mich. GGf. wäre das als Beispiel fürs Wiki auch nett.

Mit einer dieser Zeile (nur anderen URL) habe ich einen Google-Kalender in fhem eingebunden. Funktioniert soweit ganz gut!
define Kalender_W Calendar ical url https://www.google.com/calendar/ical/no9r7jrf5cnactm2v8s%40group.calendar.google.com/private-cd4e2da76beb60/basic.ics 600

Ein simples Starten von Sonos darüber funktioniert bereits!

Für eine Wecker-Einbindung versuche ich jedoch, den Wecker von Sonos selbst zu programmieren, dabei habe ich jedoch code-verständnis-probleme.


Mit diesem define habe ich schwierigkeiten...
Kalender_W:modeUpcoming.*googlecom {
my $reading="%EVTPART0"; my $uid= "%EVTPART1"; my $erinnerungsname= fhem("get Kalender_W full $uid");
my ($sdate,$stime,$edate,$etime) = $erinnerungsname =~ /.*?(\d\d.\d\d.\d\d\d\d)\s(\d\d:\d\d:\d\d)-(\d\d.\d\d.\d\d\d\d)\s(\d\d:\d\d:\d\d).*\z/;
fhem("set Sonos_Schlafzimmer Speak 40 de $sdate , $stime , $edate , $etime"); 

set Sonos_Schlafzimmer Alarm Create 100 { Enabled => 1, Volume => 35, StartTime => '$stime', Duration => '00:15:00', Repeat => 0, Shuffle => 0, ProgramURI => 'x-rincon-buzzer:0', ProgramMetaData => ' ', Recurrence_Once => 0, Recurrence_Monday => 1, Recurrence_Tuesday => 1, Recurrence_Wednesday => 1, Recurrence_Thursday => 1, Recurrence_Friday => 1, Recurrence_Saturday => 0, Recurrence_Sunday => 0, IncludeLinkedZones => 0 };
}
fhem("set Sonos_Schlafzimmer Speak 40 de Weckzeit in Sonos auf $stime geändert."); 

define SonosAddGroup at +*00:10:00 set Sonos Groups [Sonos_Schlafzimmer,Sonos_Bad];


Die ersten drei Zeilen scheinen zu funktionieren, aber mit der Zeitübergabe in der dritten Zeile hapert es.
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

Reinerlein

Hi JoeALLb,

das, was mir so direkt auffällt, ist, dass das Set mit dem Alarm-Create und dem Gruppendefinieren nicht in einem fhem() steht.
Du befindest dich doch auf "Perl-Ebene", oder übersehe ich da was?

Desweiteren kannst du als ID für das Create einfach 0 angeben. Dann fragst du dich später nicht, was die 100 da sollte :-) Der Parameter muss nur da sein, damit ich das Alarmhandling in einer Methode abhandeln kann, wird aber für das Create ignoriert...

Ausserdem dürftest du ein Problem bekommen, wenn du den Kalendereintrag anpasst, dann erzeugst du doch immer einen neuen Alarm, oder? Ich würde einmal einen Alarm (korrespondierend zum Kalendereventnamen vielleicht) erzeugen, und mittels der dann bekannten ID diesen bei den Kalender-Events immer nur anpassen. Dann gibt es nix doppeltes.

Desweitern sehe ich gerade, dass du anschließend zwei Player gruppierst. Das hat aber auf den Alarm keine Auswirkung, da du den Parameter "IncludeLinkedZones" auf 0 gesetzt hast. Das sollte dann auf 1 gesetzt werden, dann werden gruppierte Zonen mit in den Alarm mit einbezogen...

Soweit das, was mir spontan auffällt, vielleicht hilft dir das aber ja schon weiter :-)

Grüße
Reiner

JoeALLb

Hallo Reiner, danke für die Antwort.
Anbei meine Kommentare:


Zitat von: Reinerlein am 24 Januar 2014, 15:08:30
das, was mir so direkt auffällt, ist, dass das Set mit dem Alarm-Create und dem Gruppendefinieren nicht in einem fhem() steht.
Du befindest dich doch auf "Perl-Ebene", oder übersehe ich da was?

mit fhem davor hat er die Variable der Zeit nie ausgewertet und übergeben, deshalb habe ich mit ein paar anderen schreibweisen experimentiert.
Gibt es eigentlich für ein Notify soetwas wie "Gib "Erfolg" auf der Telnet-Console aus?"

Zitat von: Reinerlein am 24 Januar 2014, 15:08:30
Desweiteren kannst du als ID für das Create einfach 0 angeben. Dann fragst du dich später nicht, was die 100 da sollte :-) Der Parameter muss nur da sein, damit ich das Alarmhandling in einer Methode abhandeln kann, wird aber für das Create ignoriert...
Ausserdem dürftest du ein Problem bekommen, wenn du den Kalendereintrag anpasst, dann erzeugst du doch immer einen neuen Alarm, oder? Ich würde einmal einen Alarm (korrespondierend zum Kalendereventnamen vielleicht) erzeugen, und mittels der dann bekannten ID diesen bei den Kalender-Events immer nur anpassen. Dann gibt es nix doppeltes.
Das hatte ich mit 100 eigentlich schon gemacht, weshalb ich immer die 100 dafür verwenden wollte. Allerdings habe ich den ursprünglichen Alarm in Sonos selbst angelegt und
wollte eben genau diesen hier abändern.



Zitat von: Reinerlein am 24 Januar 2014, 15:08:30
Desweitern sehe ich gerade, dass du anschließend zwei Player gruppierst. Das hat aber auf den Alarm keine Auswirkung, da du den Parameter "IncludeLinkedZones" auf 0 gesetzt hast. Das sollte dann auf 1 gesetzt werden, dann werden gruppierte Zonen mit in den Alarm mit einbezogen...

Meine Gedanken dazu waren folgende: In der Früh, wenn der Wecker egeht, weiß ich nicht, in welcher Zone sich das Schlafzimmer befindet.
Aus diesem Grund schalte ich den Sonos dort ohne gruppen ein.
Da ich nach ca. 10 minuten ins Bad gehe, möchte ich nach 10 Minuten den Player in Bad mit in die Gruppe aufnehmen.
Da dann das Schlafzimmer schon Musik "spielt", sollte die selbe Musik einfach auch im Bad gespielt werden.

Das sollte doch so funktionieren?!?

liebe Grüße
Joe
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

Reinerlein

Hi Joe,

hier mal ein Codeschnipsel für die Variablen-Geschichte (nicht vollständig :-):

{
  .
  fhem("set Sonos_Schlafzimmer Alarm Update 100 { Enabled => 1, StartTime => '$stime' }");
  .
}
Wenn du einen Perl-String mit doppelten Anführungszeichen beginnst, kannst du zum einen einfache Anführungsstriche innerhalb des Strings direkt verwenden, und zum anderen einfache Variablennamen angeben, die dann auch aufgelöst werden.
Wenn du mit einfachen anfängst, kannst du doppelte im String haben, aber es werden keine Variablen aufgelöst.

Bei einem Update brauchst du in dem Hash auch nur die Parameter angeben, die sich ändern sollen. Alles andere wird beibehalten...

Zu der ID: Diese wird beim Erzeugen eines Alarms durch das Sonos-System vergeben, und kann nicht vorgeschlagen werden. Deswegen wird der Parameter durch das Modul (für Create) ignoriert. Die Rückgabe in LastActionResult enthält dann die neue ID.

Erfolg/Misserfolg: Du kannst einfach eine Log-Ausgabe durchführen:

Log3 Sonos_Wohnzimmer, 3, "Alles OK";
.
.
Log3 Sonos_Wohnzimmer, 1, "Hier ist ein Fehler aufgetreten";

Also erst den Devicenamen (ist für den Devicespezifischen Loglevel wichtig), dann der Loglevel dieser Nachricht (u.U. wird die Nachricht je nach gesetztem Deviceloglevel unterdrückt), und dann die Nachricht selbst. Üblicherweise ist die Nummer kleiner, je mehr die Meldung einen Fehler beschreibt :-)
Dann kannst du deine Testausgabe auch in den Log schreiben lassen, und musst es dir nicht erzählen lassen :-)

Leider kann ich dir das bzgl. der Gruppierung nach dem Weckerstart nicht sagen. Ich benutze den nicht :-)

Grüße
Reiner

djhans

Hallo zusammen,
ich lebe auch noch und lese auch sporadisch hier mit, allerdings erlaubt es meine Zeit derzeit nicht, weitere Sonos-Tests zu machen. Mein fhem liegt quasi auf Eis...

Ich habe aber mal eine Frage an die Sonos Experten. Ich weiß, das gehört nicht gerade hier hin, brennt mir aber unter den Nägeln und ggf. kennt jemand einen workaround dazu.

Ich muss mein komplettes Sonos System platt machen. Somit verliere ich die gespeicherten Playlisten. Hat jemand eine Idee, wie ich diese sichern und später wieder zurückspielen kann? Hat man Zugriff auf die Listen über das fhem-Modul?

Wäre klasse, wenn es eine Lösung gäbe,
Danke und Gruß,
djhans

Reinerlein

Hi djhans,

es gibt mit dem Modul die Möglichkeit die aktuelle Abspielliste als .m3u Datei zu sichern (und natürlich auch wieder zu laden).
Momentan funktionieren auch Napster und Spotify-Titel als besondere Formate in der Playlist.
Du solltest das aber am Besten mal testen, ich glaube nicht, dass es viel benutzt wird, somit kann ich auch nicht sagen, ob da noch was im argen liegt.

Wenn du andere Titel als Standard, Napster oder Spotify benötigst, dann schreib das hier, dann schaue ich mal, was da geht.

Ach so, die Befehle lauten SavePlaylist und LoadPlaylist. Formate und Hinweise siehe Wiki...

Grüße
Reiner

djhans

Hi Reiner,
ich bin schon wieder zu doof.
Habe die Playliste in den Bad-Sonos geladen und will jetzt mit:

set Sonos_Bad SavePlaylist file:c:/Test/Test.m3u
abspeichern.

Wo speichert er denn hin, wenn ich das im Browser angebe? Das muss doch lokal auf dem Pi sein und nicht auf meinem PC, oder? Ich hätte erwartet, dass er mit
set Sonos_Bad SavePlaylist file:Test.m3u
das ganze im fhem Verzeichnis auf dem Pi ablegt....
djhans.

Reinerlein

Hi djhans,

das Prinzip ist korrekt. Die Angabe mit "c:" funktioniert allerdings nur, wenn du Fhem unter Windows laufen hast.
Es zählt immer die Sichtweise vom Fhem-SubProzess aus (also im Normalfall im FHEM-Vz., also dort wo die Module alle liegen)...
Am Besten ein bekanntes Verzeichnis angeben, z.B. "/mnt/SonosSpeak/test.m3u", falls du das Vz. hast...

Grüße
Reiner

djhans

Hallo,
yep das funzt! Die Playlisten lassen sich speichern und anschließend wieder in ein anderes Sonossystem laden.
Und so habe ich es gemacht:
1. Player im Controller auswählen, z.B. "Schlafzimmer"
2. Playliste unter "Sonos Playlisten" auswählen und in den Abspielbereich des gewählten Players laden
3. unter fhem: set Sonos_Schlafzimmer SavePlaylist file:Test.m3u
4. Playliste wird als m3u im fhem-Pfad gespeichert

anschließend...
set Sonos_Schlafzimmer LoadPlaylist file:Test.m3u.
dann im SonosController selber: Playliste speichern unter <beliebigen Namen vergeben>

Tolle Sache! auf diese Art und Weise kriegt man jede Playliste ins SonosSystem. eine andere Möglichkeit kenne ich nicht!

Gruß,
Christian.

djhans

Hallo,
ich möchte das Alarm Thema noch mal aufgreifen. Das Dingen über Google Kalender anzusteuern geht, finde ich aber unglücklich. Besser ist es wohl, den Wecker im Sonos entsprechend zu modifizieren.

Ich verstehe nicht ganz, wie ich den Radiosender einstelle. Das scheint recht kompliziert zu sein, da man ProgrammURI und ProgramMetaData ermitteln muss. Habe einen Timer im Sonos angelegt und den Sender eingestellt, aber die Daten sind irgendwie merkwürdig. Gibt es eine Möglichkeit, diese Daten sauber auszulesen? Mit "get Alarm ID" kriegt man nur den Hashwert und nicht den eigentlichen Parameter. Oder wie macht man das am Besten mit dem Sender, zumal man den auch mal modifizieren möchte...

...und noch eine Frage. Im Sonos Player kann man nur bestimmte Zeiten auswählen, kann man auch beliebige Duration times setzten?
wie macht ihr das?

Danke und Gruß,
djhans

Reinerlein

Hallo djhans,

Zu den Metadaten und der URI: Diese Informationen kannst du auch einfach über die Weboberfläche kopieren. Dort stehen sie ja im Klartext. Die Metadaten sind übrigens eine XML-Struktur, die auch komplett notwendig sind.
Der Befehl "get Alarm [ID]" gibt den entsprechenden Alarm-Eintrag des Readings als Perl-Hash zurück, sodass man ihn direkt in eigenem Code verwenden kann. Sonst braucht man das nicht unbedingt... Das kann man ja auch selber machen...

Zu den Zeitangaben: Allgemein kann man beliebige Zeiten angeben, solange man das Format beachtet. Das gilt z.B. auch für den Sleeptimer, den man am Controller nur in 15 Minuten-Schritten setzen kann, aber natürlich kann man mit Fhem auch andere Dauern setzen.

Grüße
Reiner

djhans

#701
Hallo Reiner,
Besten Dank. Das mit dem Hash habe ich noch nicht begriffen! Aber Du meinst, ich soll die Daten für den Radiosender aus dem Webinterface von fhem nehmen, richtig? Kann man das noch weitere separieren? Das steht da zwar im Klartext, aber wenn man mehrere Timer hat, dann muss man schon genau suchen.

Ich meine, kann man die URI iund die Metadaten m Klartext im Fhem abfragen? Dann könnte man dies einfach in eine Variable kopieren und so seine anderen Timer setzten....
Nachtrag:
hier fällt mir auf, dass das Initialisieren der Sonos_Geräte sehr lange dauert. Das heisst, die Grundkonfiguration darf erst nach ein paar Minuten drübergebügelt werden. Derzeit binde ich beim Start einfach mit include den Code ein. Das muss man wohl anders machen....


Und noch eine Frage:
Ih spiele gerade mit den Soundeinstellungen und setzte beim Start von fhem alles auf Defaultwerte. Den SUB kann ma nicht direkt ansprechen, oder? Da gibt es bei den Raumeinstellungen im Controller ein Untermenü "Sub" in dem man folgendes einstellen kann:


  • Pegeleinstellung
  • Plazierungseinstellung
    • Lautsprechergröße
    • 1.Kompakt
    • 2.
    • 3.
    • 4.Regal/Decke
    • 5.
    • 6. Boden
    • 7.

    Die restlichen Werte sind nicht belegt.
    Gruß,
    Christian.

Reinerlein

Hi djhans,

zu dem Alarm: Ja, ich meinte über die Oberfläche. Wenn du es per Code auslesen möchtest, steht in der Beschreibung des get-Alarm-Befehls im Wiki ja ein Hinweis, wofür der Befehl nur eine Kurzform ist.
Wenn du dir das um den Feldnamen erweiterst, kannst du in deinem Perl-Code folgendes schreiben:

{
.
my $metaData = eval(ReadingsVal('Sonos_Wohnzimmer', 'AlarmList', '{}'))->{1}{ProgramMetaData};
my $programURI = eval(ReadingsVal('Sonos_Wohnzimmer', 'AlarmList', '{}'))->{1}{ProgramURI};
.
}
Das eval() macht aus dem Reading (ein String) mit der textuellen Darstellung eines Hashs wieder einen 'echten' Perl-Hash, auf dem man mit den Perl-üblichen Mitteln arbeiten kann.
Die 1 ist hier die ID des Alarms, welche du im Notfall über das Reading AlarmListIDs auslesen kannst. Dort stehen alle Alarm-IDs dieses Raumes als Komma-separierte Liste drin. Und natürlich musst du deinen Raumnamen u.U. anpassen...

Zu der Initialisierungszeit: Das ist richtig. Deshalb startet ja auch der Überprüfungstimer z.B. erst nach 120 Sekunden, da ich dann davon ausgehen kann, das die gesamte Erkennerei im allgemeinen durch sein dürfte. Aber im Prinzip kannst du natürlich schon Notifies bauen, die während dieser Erkennungsphase getriggert werden. Solange du innerhalb des Notify nicht auf andere (u.U. noch nicht fertige Player) zugreifst (also im eigenen Player-Kontext bleibst), sollte das alles gehen. Ich verwende das z.B. bei einem Player, um dort einen Radiosender mit einer bestimmten Lautstärke festzulegen (als Reaktion auf die Änderung des 'Presence'-Readings).

Zu dem Sub: Allgemein versuche ich die Grundeinstellungsmöglichkeiten des Sonos-Systems aus dem Modul rauszuhalten... Hier würde ich persönlich sagen, dass das zur Einrichtung des Sub gehört, und im laufenden Betrieb wohl eher nicht angepasst wird.
Es gibt hier ja auch absichtlich keine Möglichkeit, z.B. die einzelnen Player umzubenennen, oder das Icon anzupassen...
Hinzukommt, dass ich keinen Sub habe, und das somit auch nicht probieren/sehen kann :-)

Grüße
Reiner

djhans

Hallo,
Besten Dank Reiner, probiere das mal aus.....

Noch einmal zum SUB. Sind die von mir genannten Dinge nicht gleichzusetzen mit  "Gruppe bilden" oder "weiße LED" ausschalten? zumindest die Pegelanpassung beim SUB ist m.E. Teil der Soundeinstellungen, da diese die Dominanz des SUBs im Raum bestimmt. Bass und Treble zusammen mit der Pegeleinstellung macht m.E. Sinn.

Ein denkbares Szenario wäre beispielsweise auch so etwas:
Im Wohnzimmer gibt es einen Connect AMP mit Standlautsprechern für die normale Mucke. Der TV hat eine Playbar und zwei Play 1. Zusammen mit dem SUB hat man nun 5.1 für den Film. Wenn die normale Mucke läuft, ist 5.1 nicht so dolle. 2.1 macht da mehr Sinn. Man könnte nun mit einem einfachen klick die Playbar, die Play1 und den ConnectAmp inkl. SUB, zu einer Gruppe umkonfigurieren. (also ConnectAmp+SUB, 2x Play1 Stereopaar, und Playbar einzeln) Dazu müssten dann die Konfiguration des SUBs geändert werden. (Regal/Bodenlautsprecher, etc..)

Das geht derzeit mit dem Sonos Controller nicht so wirklich gut, da man die 5.1 Konstellation erst komplett auflösen muss. Wenn man das über das fhem Modul steuern könnte, wäre das ne prima Sache... wie gesagt, ist halt nur so eine Idee!

Wenn ich in Sachen SUB unterstützen kann, mache ich das gerne...ne Playbar habe ich genau aus diesem Grund noch nicht.
Gruß,
djhans.

Reinerlein

Hi djhans,

ok, ich gebe dir mit den Pegeleinstellungen recht. Das könnte noch gut ins Konzept passen, aber das Umgestalten der Landschaft eher nicht. Momentan gehen ja auch nur Gruppenbildungen, aber z.B. keine Stereopaare o.ä.

Ich kann mir dazu ja mal Gedanken machen. Dann haben wir bald einen kompletten Controller in Fhem umgesetzt :-)
Es dürfte halt zu einiger Verwirrung führen, wenn der Name eines Fhem-Devices nicht mehr direkt mit seiner Funktion oder Örtlichkeit zusammenhängt. Das Modul selbst hat damit kein Problem, da es nur auf die UDNs reagiert bzw. steuert. Aber der Anwender...

Das dürfte dann vermutlich auch echt kompliziert für den Anwender des Moduls werden, da dann ja einiges umgestellt werden könnte:
- Name der Zone (was passiert, wenn es den Namen schon gibt -> Fehler, aber nicht mehr so richtig automatisiert)
- Icons der Zone anpassen
- Paare bilden (manuell muss man bei einem Player die Mute/Play/Pause-Taste drücken, damit Links festgelegt wird. Ob das auch automatisiert notwendig ist, muss man testen)
- Sub anbinden/trennen (da weiss ich nicht, was für manuelle Schritte notwendig sind)
- PlayBar mit anderen Playern paaren (auch hier habe ich keine praktische Erfahrung)

Grüße
Reiner