Hallo liebe KollegInnen!
Ich versuche die AlarmList meiner Sonos-Player auszulesen und scheitere dabei offensichtlich an meinen Perl-Kenntnissen.
Mein Letzter Versuch (in einem Notify) sieht so aus:
my %%al = ReadingsVal("Sonos_Wohnzimmer","AlarmList","");
Log 1, $al{'29'}{'Volume'};
Leider bekomme ich da nur:
2015.02.18 08:26:37 1: PERL WARNING: Odd number of elements in hash assignment at (eval 5550) line 11.
2015.02.18 08:26:37 3: eval: { [...]}
2015.02.18 08:26:37 1:
Die AlarmList sieht z.B. so aus:
{'29' => {'Recurrence_Thursday' => 0,'IncludeLinkedZones' => '1','Volume' => '12','Shuffle' => 1,'Recurrence_Wednesday' => 0,'ProgramURI' => 'x-sonosapi-stream:s217275?sid=254&flags=32&sn=0','Repeat' => 0,'Recurrence_Once' => 0,'StartTime' => '08:30:00','Duration' => '02:00:00','Recurrence_Sunday' => 0,'Enabled' => '1','Recurrence_Friday' => 0,'Recurrence_Saturday' => 0,'Recurrence_Tuesday' => 0,'RoomUUID' => 'RINCON_000E583671AC01400','ProgramMetaData' => '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="R:0/0/19" parentID="R:0/0" restricted="true"><dc:title>Bravo! Opera</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON65031_</desc></item></DIDL-Lite>','Recurrence_Monday' => 0},'17' => {'Recurrence_Thursday' => 0,'IncludeLinkedZones' => '1','Volume' => '12','Shuffle' => 1,'Recurrence_Wednesday' => 0,'ProgramURI' => 'x-sonosapi-stream:s44255?sid=254&flags=32','Repeat' => 0,'Recurrence_Once' => 0,'StartTime' => '06:29:00','Duration' => '01:00:00','Recurrence_Sunday' => 0,'Enabled' => '1','Recurrence_Friday' => 0,'Recurrence_Saturday' => 0,'Recurrence_Tuesday' => 0,'RoomUUID' => 'RINCON_000E583671AC01400','ProgramMetaData' => '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="R:0/0/0" parentID="R:0/0" restricted="true"><dc:title>Ö2 Radio Wien</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON65031_</desc></item></DIDL-Lite>','Recurrence_Monday' => 0}}
Bin für jede Hilfe dankbar!
Viele Grüße
Markus
Hi Markus,
du liest mit ReadingsVal erstmal nur den String "AlarmList" aus. Wenn du das als Hash verwenden möchtest, musst du das erst noch mit "eval()" umwandeln (und zur Sicherheit einen leeren Hash als Standard einsetzen):
my %%al = eval(ReadingsVal("Sonos_Wohnzimmer","AlarmList","{}"));
Log 1, $al->{29}{Volume};
Grüße
Reinerlein
Hallo reinerlein
Danke für die rasche Reaktion.
Habe es nun so angepasst, jetzt kommt die Meldung:
Global symbol "$al" requires explicit package name at (eval 6323) line 11.
LG
Markus
Hi Markus,
mach mal den Pfeil hinter "$al" weg.
Also doch deine Schreibweise:
Log 1, $al{29}{Volume};
Grüße
Reiner
Hallo Reiner,
ich bin noch recht neu in der fhem-Materie und kann dir sagen, dass dein SONOS Modul der Hauptgrund für den Einstieg gewesen ist. Vielen Dank dafür!
Nun zum Thema:
ähnlich wie von Thom in diesem Thread (http://forum.fhem.de/index.php/topic,10033.285.html) beschrieben möchte ich die nächste "Weckzeit" eines Play1 auslesen um andere events zu starten (z.B. Weckzeit +15min: Steckdose in der Küche an...).
Leider komme ich weder mit deinem dort beschriebenen noch mit dem hier beschriebenen Weg weiter :( Verwende ich den hier beschriebenen code, bekomme ich eine ähnlich Fehlermeldung:
Global symbol "%al" requires explicit package name at ./FHEM/99_myUtils.pm line 56.
Meine Perl-Skills reichen leider noch nicht mal aus, um zu verstehen wie ich aus dem Hash die Uhrzeit auslesen kann. Ich nehme an dafür ist:
Log 1, $al{29}{Volume};
gedacht?
Ich würde mich sehr freuen, wenn du das vielleicht kurz erklären könntest.
Hallo Vanagon,
sorry für die späte Rückmeldung, bin gerade anderweitig etwas eingespannt.
Dieses AlarmList-Reading enthält die textuelle Repräsentation eines Hash of Hashes.
Diesen Text kann man mittels des Perl-Befehls "eval()" wieder in eine "echte" Datenstruktur umwandeln.
Im Ergebnis ist auf der ersten Ebene die ID des Alarms zu verwenden, den du abfragen möchtest. In der zweiten Ebene des Hash sind dann die einzelnen Informationen als Schlüssel-Wert-Paare vorhanden.
Wie hier im Thread geschrieben, musst du also folgendes schreiben, wenn du die Alarme eines Raumes als Hash of Hashes haben möchtest:
my %alarme = eval(ReadingsVal("Sonos_Wohnzimmer","AlarmList","{}"));
Wenn du das direkt in einem Notify verwendest, musst du das Prozentzeichen u.U. maskieren (also verdoppeln). Dazu mehr bei den Notify-Beschreibungen...
Nun hast du in der Variablen "%alarme" also alle Alarme dieses Raumes (in diesem Fall des Wohnzimmers). Einen bestimmten Alarm erhältst mit der Angabe eine ID:
my %alarm = %alarme{1};
Wenn es die ID 1 für einen Alarm bei dir gibt :)
In dem Hash "%alarm" (Einzahl, ohne e am Ende) sind jetzt alle Informationen des gesuchten Alarms enthalten.
Damit kannst du jetzt die einzelnen Informationen rausholen:
my $volume = $alarm{Volume};
my $startTime = $alarm{StartTime};
Aber es hilft ein wenig, sich mit Perl-Hashes auseinanderzusetzen. Sonst bleibt das ein bömisches Dorf :)
Da ich das alles frei ohne Test schreibe kann durchaus der ein oder andere Tippfehler enthalten sein...
Grüße
Reiner
Späte Rückmeldung? Ich bitte dich, das war ja wohl super fix!
Danke schon mal für die Erläuterung. Ich habe die Struktur jetzt glaube ich verstanden, es hapert wohl noch an der Umsetzung. Meine Testabfrage sieht momentan so aus:
sub
Alarm_Sonos_Bad
{
my %alarme = eval(ReadingsVal("Sonos_Bad","AlarmList","{}"));
my %alarm = %alarme{4};
my $startTime = $alarm{StartTime};
{fhem ("set state_dummy_long $startTime")};
}
Beim abspeichern bekomme ich die Fehlermeldung: syntax error at ./FHEM/99_myUtils.pm line 56, near "%alarme{" Global symbol "%alarm" requires explicit package name at ./FHEM/99_myUtils.pm line 57. syntax error at ./FHEM/99_myUtils.pm line 59, near "}"
Dann werde ich mich wohl mal etwas tiefer in das Thema Perl-Hash bzw. generell Perl einlesen ;)
Gruß
Sebastian
Hi Sebastian,
ich habe das mal bei mir nachgestellt.
So geht es bei mir mit dem Alarmzugriff:
sub
Alarm_Sonos_Bad
{
my $startTime = eval(ReadingsVal("Sonos_Bad","AlarmList","{}"))->{4}->{StartTime}};
fhem ("set state_dummy_long $startTime")
}
Grüße
Reiner
Wow! Vielen Dank für die super schnelle Antwort! Funktioniert perfekt.
Und nochmal: ein riesen Lob für das tolle Modul!
Guten Abend,
Erste Sahne das SONOS Modul. Vielen Dank!
Alles versucht, aber ich schaffe es nicht das Bsp hier an den Start zu bekommen.
Ziel ist es die Readings Favourites, Playlists und Radios in mySQL zu schreiben.
Jemand Zeit und Lust mich zu unterstützen ? VIELEN Dank
Hallo Lausi,
ich bin mir nicht ganz sicher, was genau du erreichen möchtest.
Möchtest du den textuellen Inhalt der entsprechenden Readings in eine Tabelle in einer MySQL-Datenbank übertragen?
Hast du denn schon eine entsprechende DB-Verbindung? Gibt es die Tabelle bereits? Auf was genau zielt deine Frage?
Da können wir dir sicherlich helfen, allerdings musst du etwas genauer verraten, was du bereits hast, und noch brauchst :)
Grüße
Reinerlein
Hallo Reinerlein,
danke für deine Antwort.
Wollte als Test mal das Bsp von hier (Alarmzeit auslesen) probieren. Leider ohne Erfolg :-(
Mein Problem ist das Reading auszulesen ( mit eval) und danach die Inhalte zB Radiosender in Variablen zu schreiben.
Der Rest Variable in Tabelle mySql schreiben und lesen ist kein Problem.
Gruß
Lausi
Hi Lausi,
ok, das sollte gehen :)
also, kurz adaptiert heißt das:
sub mySonosWohnzimmer() {
my $result = '';
my $favourites = eval(ReadingsVal("Sonos_Wohnzimmer","Favourites","{}"));
foreach my $key (keys $favourites) {
$result .= "Key \"$key\":\n~ Cover: ".$favourites->{$key}->{Cover}."\n~ Title: ".$favourites->{$key}->{Title}."\n\n";
}
return $result;
}
Der Code ermittelt per eval den Favoriten-Hash, und gibt diesen pro Schlüssel aus. Für die anderen Readings musst du dir das entsprechend anpassen...
Ach ja, dabei hilft es Perl-Hashs zu kennen :)
Grüße
Reinerlein
Hi Reinerlein,
vielen Dank das waren die entscheidenden Zeilen.
Perfekt, jetzt habe ich alles in Tabelle stehen :-)
Gruß
Lausi
Hallo in die Runde. Auch wenn der Thread schon ein paar Tage alt ist, so habe ich dennoch eine Frage zu dem Thema "Auslesen der Alarmliste".
Ich bin davon ausgegangen, dass die Readings AlarmRunning und AlarmRunningID befüllt werden, wenn Sonos einen Alarm gestartet hat. Bei mir bleiben sie leider leer.
Es geht mir darum, die jeweilige Laufzeit (Duration) des jeweiligen Alarms auszulesen und einem Mißstand abzuhelfen, nämlich dem, dass trotz eingestellter Laufzeit Sonos nicht abschaltet, sondern munter weiter spielt. Ich meine mich zu erinnern, dass dies mal seitens Sonos automatisch ging - aktuell jedenfalls gehen die Sonos-Boxen nach einem Alarm + Duration nicht mehr automatisch aus.
Hallo Yil,
diese beiden Readings werden zusammen mit den Titelinformationen aktualisiert. Bei mir klappt das auch, werden denn die anderen Informationen aktualisiert?
Grüße,
Reinerlein
Hi Reinerlein,
Bei einem neuen Alarm hat's funktioniert. Und ich bin dann auch drauf gekommen, wieso es bisher nicht ging:
ich habe nämlich gruppierte Boxen, und die AlarmRunningID wird nur in den Master (IsMaster = 1) geschrieben, nicht aber in den SlavePlayer. Dort aber war der Alarm in Sonos angelegt. Die Gruppierung mache ich ebenfalls über FHEM, aber in der für meine Logik falschen Reihenfolge. Wenn ich das korrigiere, passt es wieder.
Trotzdem sehe ich darin ein kleines Verbesserungspotenzial für das Modul: für mich macht es mehr Sinn, die AlarmRunningID dort zu setzen, wo auch der Hash-String AlarmList ausgelesen wird, unabhängig davon, wer in der Gruppe Master ist und wer nicht. Denn in Sonos wird der Alarm ja auch bei der Box aufgeführt, die ich einstelle und nicht bei der gruppierten Box.
VG Yil