FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: czcbe am 17 Dezember 2018, 23:07:41

Titel: [Gelöst] DOIF und SB_Player bei Werbung umschalten
Beitrag von: czcbe am 17 Dezember 2018, 23:07:41
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
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: Ellert am 18 Dezember 2018, 00:10:37
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>]
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: czcbe am 18 Dezember 2018, 08:44:31
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.
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: Ellert am 18 Dezember 2018, 11:28:21
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>"))}
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: czcbe am 18 Dezember 2018, 19:03:30
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
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: Ellert am 18 Dezember 2018, 19:28:35
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.
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: Damian am 19 Dezember 2018, 07:56:52
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 ;)
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: czcbe am 19 Dezember 2018, 10:04:23
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.
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: Ellert am 19 Dezember 2018, 10:55:28
[ [$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.
Titel: Antw:DOIF und SB_Player bei Werbung umschalten
Beitrag von: czcbe am 29 März 2019, 20:38:30
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