Hallo,
ich möchte mir gere ein DOIF erstellen, bei dem meine NEST-Geräte die Lautstärke resetten, sobald der mediaplayer auf IDLE spring.
Da ich mehrere NEST-Geräte habe möchte ich es natürlich Generisch erstellen.
Ich bekomme es auch hin, den Devicenamen des auszulösenden Events auszulesen.
Aber ich schaffe es nicht, diesen Devicenamen in einen Perl-Aufruf für mein Reset-Script in der 99_myUtilities.pm einzubauen.
Entweder meckert er mir fehlende Anführungenzeichen an, oder es sind zu viele oder er erkennt die Variable nicht als Variable sondern als Text.
Der Aufruf der Funktion lautet sinngemäß "{ResetVolume("Schlafzimmerlautsprecher")}", im DOIF wird das Schlafzimmerlautsprecher dann durch die Variable getauscht, also {ResetVolume($DEVICE)}.
Aber so fehlen in der Funktion die Anführungszeichen. Wie lautet die korekte Schreibweise, damit er mir den Devicenamen in Anführungszeichen in die Funktion schreibt?
Hier das List des DOIF's:
Internals:
CFGFN
DEF (["lautsprecher:^mediaPlayerState:.IDLE$"])
{ResetVolume("/"$DEVICE"")}
DOIFDEV ^global$|lautsprecher
FUUID 6176545f-f33f-6c14-a1b2-77cd67e2e818ed31
MODEL FHEM
NAME Reset_Volume
NR 123272
NTFY_ORDER 50-Schlafzimmerlautsprecher_DOIF_1
STATE cmd_1
TYPE DOIF
VERSION 24905 2021-09-01 18:35:54
READINGS:
2021-10-25 09:15:19 Device Schlafzimmerlautsprecher
2021-10-25 09:15:19 cmd 1
2021-10-25 09:15:19 cmd_event Schlafzimmerlautsprecher
2021-10-25 09:15:19 cmd_nr 1
2021-10-25 09:15:19 error {ResetVolume("/"Schlafzimmerlautsprecher"")}: syntax error at (eval 907428) line 1, near ""/"Schlafzimmerlautsprecher"
2021-10-25 09:15:07 mode enabled
2021-10-25 09:15:19 state cmd_1
Regex:
accu:
collect:
cond:
:
0:
"lautsprecher:^mediaPlayerState:.IDLE$" lautsprecher:^mediaPlayerState:.IDLE$
attr:
cmdState:
wait:
waitdel:
condition:
0 ::EventDoIf('lautsprecher',$hash,'^mediaPlayerState:.IDLE$',0)
do:
0:
0 {ResetVolume("/"$DEVICE"")}
1:
helper:
DEVFILTER ^global$|lautsprecher
NOTIFYDEV global|.*lautsprecher.*
event mediaPlayerState: IDLE
globalinit 1
last_timer 0
sleeptimer -1
timerdev Schlafzimmerlautsprecher
timerevent mediaPlayerState: IDLE
triggerDev Schlafzimmerlautsprecher
DOIF_eventa:
cmd_nr: 1
cmd: 1
cmd_event: Schlafzimmerlautsprecher
error: {ResetVolume("/"Schlafzimmerlautsprecher"")}: syntax error at (eval 907428) line 1, near ""/"Schlafzimmerlautsprecher"
cmd_1
DOIF_eventas:
cmd_nr: 1
cmd: 1
cmd_event: Schlafzimmerlautsprecher
error: {ResetVolume("/"Schlafzimmerlautsprecher"")}: syntax error at (eval 907428) line 1, near ""/"Schlafzimmerlautsprecher"
state: cmd_1
timerevents:
mediaPlayerState: IDLE
mediaCurrentPosition:
mediaCurrentPosPercent:
online
timereventsState:
mediaPlayerState: IDLE
mediaCurrentPosition:
mediaCurrentPosPercent:
state: online
triggerEvents:
mediaPlayerState: IDLE
mediaCurrentPosition:
mediaCurrentPosPercent:
online
triggerEventsState:
mediaPlayerState: IDLE
mediaCurrentPosition:
mediaCurrentPosPercent:
state: online
internals:
readings:
trigger:
uiState:
uiTable:
Attributes:
do always
room Test
P.S.
Um Fragen vorzubeugen warum ein DOIF statt eines Notifys - Ganz einfach deshalb, weil ich im DOIF mit "samewait" über eine Zeit prüfen kann, dass keine weitere Ansage hinterherkommt.
Moin,
dein Versuch zu "escapen" liefert einen syntaxfehler, weil er einfach falsch geschrieben ist. Escapen geht mit \ (=Backslash).
Wenn also der Funktionsaufruf in Anführungszeichen stehen muss und Du willst aber auch welche übergeben müsste es so aussehen:
{ResetVolume("\"$DEVICE\"")}
Zumindest würde ich das so versuchen, da ich da auch eher rumprobiere als es "genau" zu wissen ;)
Interessant wäre noch die Funktion, ob die Übernahme dort richtig stattfinden kann.
Und nun mal generell: du nutzt viel DOIF, und die sind z.T. sehr komplex mit Timern und/oder Zuständen. Das geht zwar (bis zu einem gewissen grad) mit fhem-DOIF, aber versuch doch mal Perl-DOIF. Du musst nur wirklich unterscheiden und nicht mischen! im Perl-DOIF hast Du die meisten Attribute nicht (wait, do) die bisher wichtig waren, sondern Du mußt Timer z.B. selbst definieren und den state setzen (wenn daran Bedarf besteht), aber Du hast auch die volle Kontrolle. Um bei Deinem Beispiel zu bleiben brauchst Du auch keine Funktion in der 99_myUtils, sondern schreibst das einfach im DOIF mit rein. Du kannst auch Funktionen im Perl-DOIF definieren, die von anderen DOIFs aus nutzbar sind, das ist hier aber wohl nicht der Fall.
Ich würde den Versuch mal wagen. Bedeutet halt nochmal die commandref zu Perl-DOIF studieren und dann am besten mal einen Versuch starten.
Ich würde mal so sagen: Je komplexer die Aufgabenstellung desto einfacher ist es mit Perl-DOIF im Vergleich zu fhem-DOIF.
Und ja: es ist Perl, aber in der 99_myUtils ist doch auch Perl drin, oder?
Viel Erfolg!
Sany
Also leider funktioniert deine Lösung offenbar nicht.
Ich kann nachvollziehen, dass das DOIF auslöst und wenn ich statt der Variable den Klartext einfüge wird es auch ausgeführt. Es hängt definitiv an der Schreibweise der Variablen. Der Inhat ist auch korrekt, wird zuindest in einer der Fehlermeldung richtig ausgelesen.
Was deinen Hinweis angeht, so sind ja genau diese Attribute der Grund warum ich DOIF bevorzuge. Wenn ich diese im Perl-Modus nicht mehr habe, warum sollte ich mir die Arbeit dann künstlich erschweren?
Und eine solche Funktion in einem DOIF, dazu ist doch gerade die 99_myUtils für da oder habe ich die letzten 2 Jahre nur MMist gelernt?
Ich weiß, dass man im Perl-Modus etwas mehr Möglichkeiten hat, aber ehrlich gesagt, habe ich bisher noch keine dieser Mehrsachen vermisst. Im Umkehrschluss würde ich aber do, wait, waitsame etc. extrem vermissen.
Also bei einem notify wenn ich den Devicenamen übergeben will, mache ich das einfach so:
define nTest notify Triggerdev:Regex {Subname($NAME)}
(bei notify ist das auslösende Device eben $NAME)
Also einfach ohne nix was...
...deine Aufgabe (wenn das wirklich "alles" ist), ginge ganz einfach auch mit einem notify... 8)
EDIT: in der sub dann my ($Device) = @_; (jaja, böse Prototypen ;) oder halt mit shift [sollte ja auch gehen])
Gruß, Joachim
Ich weiß, hatte ich auch bisher in einem Notify gelöst.
Aber da hat es den Reset immer wieder mal zu früh rausgehauen - frag mich nicht warum.
Mit dem DOIF kann ich einfach per wai eine zusätzliche Wartezeit implementieren in der der IDLE-Wert sich nicht verändern darf.
Die korekte Schreibweise ist
({ResetVolume("$DEVICE")})
Habs mit weiterem Ausprobieren schließlich gefunden.