Sonos steuern

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

Vorheriges Thema - Nächstes Thema

Spartacus

Hallo,
habe noch mal eine Frage zum Sonos Speak.
Habe targetSpeakFileHashCache auf 0 gesetzt und Timestamp auch.

Ich lasse über Speak bestimmte Ereignisse mit Uhrzeit ansagen. Ich hatte erwartet, das die Datei im SonoSpeak-Dir überschrieben wird, wenn es sich um das gleiche Abspielgerät handelt, aber es wird für jede Ansage eine neue Datei angelegt. Ist das so gewollt, oder habe ich ein Einstellungs-Problem?

Christian
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

Reinerlein

Hi Christian,

Das sollte auch so sein...
Vergiss nicht bei Attributänderungen den Sonos-SubProzess durch temporäres Setzen des Attributes "disable" am Sonos-Device neu zu starten (Alternativ Fhem neu starten)...

Wenn du möchtest, dass Dateien wiederverwendet werden (da wird dann gar keine Google-Anfrage mehr gemacht, wenn es den Text schonmal gibt), dann musst du das Attribut mit dem HashCache auf "1" setzen, und den Timestamp auf "0".
In deiner jetzigen Variante kann er ja nicht erkennen, ob die Datei, die er im Filesystem vorfindet, denselben Text ansagen würde, und muss dementsprechend immer neu bei Google anfragen und herunterladen...
Es sollte aber bei dir trotzdem für jeden Player nur eine Datei anlegen, die dann jedesmal überschrieben wird...

Grüße
Reiner

Spartacus

Hallo Reiner,
ja, das war es! Der Neustart hat gefehlt. Jetzt wird die Datei brav überschrieben...
Wiederkehrende gleiche Ansagen, werde ich wohl mit playURI abspielen lassen, alles andere muss ja sowieso immer neu gewandelt werden.

Christian
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

Masterfunk

Zitat von: Reinerlein am 08 Februar 2015, 23:24:38
Hi Detlef,

also aus irgendeinem Grund bekommt er da ein ungültiges Device zugespielt, welches überhaupt nicht UPnP-konforme Daten liefert...

Kannst in der Datei Common.pm (also da, wo der Fehler auftritt) mal vor die Zeile 219 etwas einfügen?
Die neue Zeile 219 und die Zeile 220 (ehemals 219) sehen dann wie folgt aus:

next if (ref $services ne "ARRAY");
for my $serviceElement (@$services) {

Damit wird dieser Fehler nicht mehr erzeugt werden... die Frage ist dann, ob es besser läuft :)
Wenn das in die richtige Richtung geht, würde ich dass dann auch so einchecken... Ich habe ja schon ein paar Fehler in der Lib korrigiert...

Danke schon mal.

Grüße
Reiner

Hallo Reiner,

hast Du das schon eingecheckt? Bzw. kommt das noch. Ansonsten muss ich das in meine Installationsdoku aufnehmen, damit ich für den Fall einer Neuinstallation auch daran denke das anzupassen.

Gruß Detlef

Reinerlein

Hi Detlef,

es wird auf jeden Fall im nächsten Sonos-Update enthalten sein. Ich bin nur diese Woche berufsmäßig unterwegs in Deutschland, und kann gerade nicht so richtig einchecken...

Da sind ja noch ein paar andere Dinge fertig, die auch noch auf die Veröffentlichung warten :) ich denke zum Wochenende hin wird das passieren..

Grüße
Reiner

Masterfunk

Prima, wollte auch keinen Druck machen.
Find das eh extrem bemerkenswert was Du und auch andere in der "Freizeit" noch für die "Community" lseisten.
Hut ab!

Gruß Detlef

Spartacus

Hallo,
ich habe ein paar Threads zuvor diese Funktion gefunden:
sub WeckerSonos() {     
   my $StartTime=eval(ReadingsVal('OG.kz.SON.ZP_S1', 'AlarmList', '{}'))->{1}{StartTime};
   Log(3, "Alarm Start Time|" . $StartTime . "|Ende");
}

und ich würde damit gerne die Startzeit des Weckers auslesen. Aber leider funktioniert das nicht?
Ich bekomme nichts angezeigt.
Ich rufe {WeckerSonos} auf!

Im Prinzip will ich damit eigentlich abfragen, ob der Wecker eingeschaltet ist und habe es etwas modifiziert.
sub WeckerEnabled() {     
   my $AlarmState=eval(ReadingsVal('OG.kz.SON.ZP_S1', 'AlarmList', '{}'))->{1}{Enabled};
   return $AlarmState ;

Aber auch hier kommt nix zurück!
Jemand eine Idee?
Christian
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

Reinerlein

Hi Christian,

ist denn überhaupt ein Alarm mit der ID 1 vorhanden?
Direkt sehen kannst du das im Reading "AlarmListIDs", dort werden alle IDs als Liste nochmal aufgeführt...

Ansonsten sieht der Code eigentlich gut aus...

Grüße
Reiner

Spartacus

Hi reiner,
danke für den Hinweis! Natürlich sollte man auch die richtige Alarm-ID verwenden...

Jaja, ich habe halt immer Tomaten auf den Augen...

Gruß,
Christian
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

Spartacus

Hallo,
habe mal eine Frage zu meinem Ansagemodul! Ist zwar nichts Sonos-spezifisches, aber ich wundere mich, warum die letzte Ansage abgespielt wird, obwohl "cnt.NRW.start.FErienClone.dum" auf "-deaktiv-" steht! Wird "-deaktiv" als "0" ausgewertet?
*06:50:00
{
my $days = Value("cnt.NRW.start.FerienClone.dum");;
if ((!$we) && $days <= 10 && $days >= 2)
{
  fhem ("set OG.kz.SON.ZP_S1 Speak 20 de noch $days Tage bis zu den Ferien.");;
  fhem ("set DG.kz.SON.ZP_S1 Speak 20 de noch $days Tage bis zu den Ferien.")
}
if ((!$we) && $days == 1) 
{
  fhem ("set OG.kz.SON.ZP_S1 Speak 20 de nur noch ein Tag bis zu den Ferien.");;
  fhem ("set DG.kz.SON.ZP_S1 Speak 20 de nur noch ein Tag bis zu den Ferien.")
}
if ((!$we) && $days == 0) 
{
  fhem ("set OG.kz.SON.ZP_S1 Speak 20 de endlich Ferien.");;
  fhem ("set DG.kz.SON.ZP_S1 Speak 20 de endlich Ferien.")
}
}

Christian
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

Reinerlein

Hi Christian,

das ist wahr. Das liegt daran, dass Perl bei Zahlenvergleichen versucht aus dem String eine Zahl zu machen. Dabei geht er so vor, dass er das erste Zeichen im String sucht, welches zu einer gültigen Zahl passt, und von da an solange weitersucht, bis er ein Zeichen findet, welches nicht mehr zu einer Zahl passt.
Das bedeutet, dass bei dir ein '-' übrig bleibt. Und das wiederrum ist für Perl bereits eine gültige Zahl...

Hiermit prüfbar:

if ('-deaktiv-' == 0) { print "Null" } else { print "Nicht Null" }
Das Ding gibt das Wort "Null" aus...

Du musst dir einen anderen Marker für inaktiv suchen, nicht so was Zahlenähnliches :)
Dann allerdings kommt eine Fehlermeldung, dass du versuchst einen Zahlenvergleich mit einer Nichtzahl zu machen...

Des Weiteren würde ich aus Optimierungsgründen solche eine If-Kette immer versuchen als If-Elsif-Kette aufzubauen. Bei dir könnten durch einen dummen Zufall mehrere Einträge matchen. Das passiert einem bei Verwendung von elsif nicht. Da passt höchstens der falsche (dann aber nur einer), und man muss ein bißchen auf die Reihenfolge achten (dafür werden die einzelnen Statements einfacher, da sie ja hierarchisch aufgebaut sind) erhält dafür aber auch eine schnellere Ausführung...
Außerdem kann man gerade bei deiner Sonos-Namensgebung Fhem-Features prima nutzen...
Ist aber natürlich prinzipiell auch wurscht :)


*06:50:00
{
my $days = Value("cnt.NRW.start.FerienClone.dum");;
if ($days eq '-deaktiv-') { return }
if ((!$we) && $days == 0) {
  fhem ("set (O|D)G.kz.SON.ZP_S1 Speak 20 de endlich Ferien.");;
} elsif ((!$we) && $days == 1) {
  fhem ("set (O|D)G.kz.SON.ZP_S1 Speak 20 de nur noch ein Tag bis zu den Ferien.");;
} elsif ((!$we) && $days <= 10) {
  fhem ("set (O|D)G.kz.SON.ZP_S1 Speak 20 de noch $days Tage bis zu den Ferien.");;
}
}
Daran siehst du dann auch, dass Punkte in Fhem-Devicenamen eigentlich keine soo gute Idee sind, da man korrekterweise deinen Devicenamen beim Ansprechen dann z.B. so schreiben muss:

fhem ("set OG\.kz\.SON\.ZP_S1 Speak 20 de noch $days Tage bis zu den Ferien.");;
sonst passt der Code auch auf ein Device mit dem Namen "DGxkzySONzZP_S1". Hier vielleicht noch eindeutig, bei vielen hundert Devices in Fhem sicherlich eine mögliche Fehlerquelle...

Ich verwende deshalb ja immer die Unterstriche zur Trennung. Sind eindeutig in regulären Ausdrücken und ordnen auch eine Struktur...

Grüße
Reinerlein

Spartacus

Hi Reinerlein,
danke für Deine sehr ausführliche Erklärung, ich werde den modifizierten Code einmal ausprobieren! Danke auch für Deine Optimierungen und die Tipps!

Das Namensschema habe ich mir irgendwo abgeguckt und fand es eigentlich sehr brauchbar! Über den "." hatte ich nicht weiter nachgedacht, aber Du hast natürlich recht!

Alles jetzt zu ändern, ist mir zu aufwändig! Ich muss jetzt damit leben... :-)
Christian
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

Spartacus

Hallo,
der modifizierte Code funktioniert prima und die Ferien können kommen....

Jetzt kommt das nächste Thema...
Ich hatte diesen Code gefunden um damit den Alarmzustand auszulesen.
sub AlarmEnabled($$) {     
my ($player, $alarmID) = @_;
   my $AlarmState=eval(ReadingsVal('$player', 'AlarmList', '{}'))->{$alarmID}{Enabled};
return $AlarmState;
}

Das funzt auch ganz gut, nur kann man auch darauf triggern? Wahrscheinlich sollte ich mir ein UserReading anlegen, oder wie wertet man das am Besten aus?

Hintergrund:
mit diesem DOIF steuere ich die Weckerfunktion des Sonos.
([state.NRW.FerienClone.dum] or [hl.01.Feiertag.cdm:today] ne "none")
((set OG.kz.SON.ZP_S1 Alarm Update 674 {Volume => 2, Enabled => 0}))
DOELSE
((set OG.kz.SON.ZP_S1 Alarm Update 674 {Volume => 2, Enabled => 1}))

Attribut:  cmdState   auto_aus|auto_ein

Wenn jetzt der Wecker über den Controller gesteuert wird, bekommt das DOIF das nicht mit und zeigt den falschen Statzs an. Also muss ich darauf irgendwie triggern!

Jemand eine Idee?
Christian
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

Reinerlein

Hi Christian,

das einfachste wird ein userReading sein, wo der Enabled-Wert deines gesuchten Alarms direkt enthalten ist, und diesen dann als Zusatzbedingung mit in das DOIF.

Hier das userReading im Sonosplayer-Device:

Alarm674Enabled:AlarmList { eval(ReadingsVal('OG.kz.SON.ZP_S1', 'AlarmList', '{}'))->{674}{Enabled} }


In deinem DOIF muss das doch nur noch als Zusatzbedingung dazu, oder?

(([state.NRW.FerienClone.dum] or [hl.01.Feiertag.cdm:today] ne "none") and [OG.kz.SON.ZP_S1:Alarm674Enabled] eq "1")
((set OG.kz.SON.ZP_S1 Alarm Update 674 {Volume => 2, Enabled => 0}))
DOELSE
((set OG.kz.SON.ZP_S1 Alarm Update 674 {Volume => 2, Enabled => 1}))
Jetzt hat DOIF auch einen Trigger auf die Alarm-Änderung am Controller...
Ob es das macht, was du möchtest, solltest du nochmal komtrollieren :)

Grüße
Reiner

justme1968

ich habe immer noch ein problem beim initialisieren eines players per appeared notify.

die currentTrackURI ist in notify noch gesetzt und verhindert das ich zwischen eingestecktem player und neu gestartetem fhem unterscheiden kann.

das ging schon mal nach dem du es repariert hattest, inzwischen aber nicht mehr.

hast du eine idee?

wenn nicht lösche ich das reding im disappeared fall einfach selber.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968