Hallo zusammen
Folgendes DOIF schaltet bei Werbung auf einen anderen Sender und nach fixen 2min (angenommene Werbungsende) wieder zurück.
Gerne hätte ich nun, dass auf dem anderen Sender gewartet wird, bis aktuelles Lied zu Ende geht und erst dann wieder zurückgeschaltet wird (nicht mitten im Lied).
Schaffs aber leider nicht. Zu erwähnen wäre auch, dass ich drei Player habe, die unabhängig voneinander triggern sollen, daher auch beginnt mit ["^SB_Player_: Advert:"] in der Bedingung.
Internals:
DEF (["^SB_Player_: Advert:"] or ["^SB_Player_: Publicidad"])
(set $DEVICE favorites [$DEVICE:PREVFAVORITES])
(set $DEVICE favorites [$DEVICE:PREVFAVORITES])
DOELSE
MODEL FHEM
NAME doif_SB_Player_Advert_Pause
NR 163
NTFY_ORDER 50-doif_SB_Player_Advert_Pause
STATE cmd_2
TYPE DOIF
READINGS:
2018-12-17 22:33:08 Device SB_Player_HIFI
2018-12-17 22:37:07 cmd 2
2018-12-17 22:37:07 cmd_event doif_SB_Player_Advert_Pause
2018-12-17 22:37:07 cmd_nr 2
2018-12-17 22:31:11 mode enabled
2018-12-17 22:37:07 state cmd_2
2018-12-17 22:37:07 wait_timer no timer
Regex:
cond:
:
0:
"^SB_Player_: Advert:" ^SB_Player_: Advert:
"^SB_Player_: Publicidad" ^SB_Player_: Publicidad
attr:
cmdState:
repeatsame:
wait:
0:
2
120
waitdel:
condition:
0 ::EventDoIf('^SB_Player_',$hash,' Advert:',0) or ::EventDoIf('^SB_Player_',$hash,' Publicidad',0)
devices:
do:
0:
0 set $DEVICE favorites [$DEVICE:PREVFAVORITES]
1 set $DEVICE favorites [$DEVICE:PREVFAVORITES]
1:
0
helper:
event currentTitle: Advert:
globalinit 1
last_timer 0
sleepdevice set_cmd_1
sleepsubtimer 1
sleeptimer -1
timerdev
timerevent currentTitle: Advert:
triggerDev
DOIF_eventas:
cmd_nr: 2
cmd: 2
cmd_event: doif_SB_Player_Advert_Pause
state: cmd_2
timerevents:
currentTitle: Advert:
timereventsState:
currentTitle: Advert:
triggerEvents:
currentTitle: Advert:
triggerEventsState:
currentTitle: Advert:
internals:
itimer:
readings:
trigger:
uiState:
uiTable:
Attributes:
checkReadingEvent 0
do always
room SB_PLAYER
wait 2,120
Wenn die Liedlänge in einem Reading verfügbar gemacht wird, dann könnte wait indirekt gesetzt werden.
attr <name> wait 2,[SB_Player:<Liedlänge>]
Es gibt ein Reading "Duration", das wird aber von den meisten Radiosendern nicht gefüllt.
Meine Ideen drehen sich momentan um eine Triggerung, wenn sich das Reading "currentArtist" ändert auf dem anderen Sender, dann ist ja auch das Lied fertig, aber ich befürchte damit verliere ich dann das auslösende $DEVICE von den drei existierenden.
Dann speichere $DEVICE in einem Reading des DOIF und modifiziere den set-Befehl entsprechend, etwa so
set [$SELF:<letztes Device>] favorites {(ReadingsVal("[$SELF:<letztes Device>]","PREVFAVORITES","<default>"))}
Danke, so hab ich hingebracht. Do always ebenfalls rausgenommen:
Internals:
DEF (["^SB_Player_: Advert:"] or ["^SB_Player_: Publicidad"] )
## Auslösendes Device ins Reading abspeichern:
(setreading $SELF LetztesDevice $DEVICE)
## Wechsel zum anderen Sender:
(set [$SELF:LetztesDevice] favorites {(ReadingsVal("[$SELF:LetztesDevice]","PREVFAVORITES","xx"))} )
## Letztes Lied anderer Sender speichern:
(setreading $SELF LetztesLied {(ReadingsVal("[$SELF:LetztesDevice]","currentArtist","xx"))})
## Letztes Device in Var packen für das folgende DOELSEIF:
({my $LetztesDevice = $DEVICE;
})
DOELSEIF ([$LetztesDevice:currentArtist] ne [$SELF:LetztesLied] )
(set [$SELF:LetztesDevice] favorites {(ReadingsVal("[$SELF:LetztesDevice]","PREVFAVORITES","xx"))})
Attributes:
checkReadingEvent 0
room SB_PLAYER
wait 0,0,5:0
Bringe es noch nich ganz hin mit dem DOELSEIF und der Variable:
{my $LetztesDevice = SB_Player_xx; }: Bareword "SB_Player_xx" not allowed while "strict subs" in use at (eval 59157) line 1
Soweit ich weiss wird $DEVICE durch den Devicenamen ersetzt, es ist keine Variable, daher in Anführungszeichen setzen "$DEVICE", wenn es in Perl verwendet wird.
Es sollte auch die Variable $device existieren, die kann ohne Anführungszeichen verwendet werden.
my $LetztesDevice existiert nur in dem Perl-Block in dem es definiert ist und nicht in einem anderen Zweig (DOELSEIF/DOELSE), deshalb musst Du in Readings zwischenspeichern.
Zitat von: Ellert am 18 Dezember 2018, 19:28:35
my $LetztesDevice existiert nur in dem Perl-Block in dem es definiert ist und nicht in einem anderen Zweig (DOELSEIF/DOELSE), deshalb musst Du in Readings zwischenspeichern.
Oder DOIF-Perl verwenden, dort gibt es Instanzvariablen - die behalten ihren Wert auch bis zum nächsten Durchlauf ;)
Im Moment kämpfe ich am meisten mit der DOELSEIF-Bedingung im 2. Zweig (1. Zweig schaltet erstmal korrekt auf anderen Sender):
Soetwas müsste ich haben:
DOELSEIF ( [ [$SELF:LetztesDevice]:currentArtist ] ne [$SELF:LetztesLied] )
Dabei wollte ich als Umgehung weil das obige Fehler gab (Reading in einem Reading) nun [$SELF:LetztesDevice] in eine Variable packen:
## Letztes Device in Var packen für das folgende DOELSEIF:
({my $LetztesDevice = "$DEVICE";
})
DOELSEIF ([$LetztesDevice:currentArtist] ne [$SELF:LetztesLied] )
Mit dem Hinweis, dass die Variable nicht bestehen bleibt oder es Instanzvars gibt (?), war mir einiges klar und ich versuchte wieder statt Variablen zu benutzen es mit Readings zu versuchen. Versuchsweise mit dem direkten Namen ansprechen:
DOELSEIF ( [ SB_Player_xx:currentArtist ] ne [$SELF:LetztesLied] )
Dabei triggert er wie wild hin und her zw. cmd_1 und cmd_2, sodass ich keine Kontrolle mehr habe was da so passiert.
[ [$SELF:LetztesDevice]:currentArtist ] indirekte Geräteangaben sind nicht erlaubt, Alternativen https://forum.fhem.de/index.php/topic,94170.0.html
ZitatDabei triggert er wie wild hin und her zw. cmd_1 und cmd_2, sodass ich keine Kontrolle mehr habe was da so passiert.
Du musst überlegen, welche Auslöserangaben in der Bedingung triggern sollen und welche nicht, das vermindert die Wahrscheinlichkeit von ungewollten Triggern, https://commandref.fhem.de/commandref_DE.html#DOIF_Zeitintervalle_Readings_und_Status_ohne_Trigger
Und es besteht die Möglichkeit, die Zweige gegeneinander zu verriegeln, wie in diesem Beispiel https://wiki.fhem.de/wiki/DOIF/Mehrfachnutzung_eines_Tasters
Das funktioniert auch für den Unterstatus cmd_1_1 cmd_1_2 usw.
Nach langer Zeit hab ich es nun doch endlich geschafft:
DEF (["^SB_Player_: Advert:"] or ["^SB_Player_: Publicidad"] or ["^SB_Player_: Promo pagina web"] )
#############################################
## Wechselt vom UrsprungsSender zum UebergangsSender:
#############################################
(set $DEVICE favorites [$DEVICE:PREVFAVORITES])
(setreading $SELF AusloeserDevice $DEVICE, setreading $SELF UebergangsSender [$DEVICE:favorites])
#############################################
## Zwischenstufe mit Zeitverzögerung:
#############################################
DOELSEIF (["^SB_Player_:currentArtist"] and "$DEVICE" eq [$SELF:AusloeserDevice] and [$SELF:cmd_nr] == 1)
()
#############################################
## Wechselt zurück zum UrsprungsSender nach Liedwechsel, ausser Sender wurde manuell gewechselt:
#############################################
DOELSEIF (["^SB_Player_:currentArtist"] and [$DEVICE:favorites] eq [$SELF:UebergangsSender] and "$DEVICE" eq [$SELF:AusloeserDevice] and [$SELF:cmd_nr] == 2)
(set $DEVICE favorites [$DEVICE:PREVFAVORITES])
Attributes:
do resetwait
room SqueezeBox
startup set $SELF checkall
wait 2,0,0:120:0