Hallo zusammen,
ich versuche mich seit einigen Tagen an einer Verbesserung meiner Perl-Kenntnisse und gleichzeitig meinen Doifs.
Problemstellung:
Das Modul UWZ gibt Wetterwarnungen aus, die je nach Anzahl "dynamisch" (von 0 bis x) sind und mit WarnCount (=Gesamtanzahl) versehen ist. Ich hatte bis jetzt ein wenig elegantes Doif, welches einfach abgefragt hat, ob WarnCount > 0 und dann im Doelseif jeden Befehl einzeln (eine Telegram-Push Nachricht) einzeln versendet hat.
Die Readings der Warntexte sind aufgebaut Warn_X_Longtext.
Ich habe nun (mein erstes) DOIF im Perl versucht und scheitere, trotz einigen Stunden Forum und CommandRef an zwei Punkten:
1. Readingsnum erwartet lt. DOIF Fehlermeldung einen "Timestamp"??? - hab auch Readingsval versucht, aber gleiche Fehlermeldung.
2. Wie kann ich das Reading Warn_X_Longtext in der Schleife richtig zusammensetzen? der Reine Perlcode funktioniert, aber das mit den Readings will mir nicht in den Kopf.
Hier mal der Beispielcode:
{{if (uwz.neusiedl:WarnCount) ne "0")}
{my $max=[{ReadingsNum("uwz.neusiedl","WarnCount",0)}];
for (my $i = 0; $i <= $max-1; $i++)
{
## first message with graphic
if $i=1; fhem_set (MaLaBot sendImage @#Smart-MaLa-Home /tmp/neusiedl.png)
## all others only reading
myreading$="Warn_$i_LongText";
{fhem_set (MaLaBot sendImage @#Smart-MaLa-Home set MaLaBot message @#Smart-MaLa-Home WETTERWARNUNG FÜR NEUSIEDL am SEE: [uwz.neusiedl:$myreading])}
}}}
Gibt es eine for/foreach Variante eigentlich im "FHEM" Modus auch - gefunden hätte ich darüber nichts...
Danke für eure Hilfe...
lg Shamal
{{if ([uwz.neusiedl:WarnCount, 0] ne "0")} #somit hast Du ein Trigger...
{my $max= ReadingsNum("uwz.neusiedl","WarnCount",0); #entweder
{my $max=[uwz.neusiedl:WarnCount:d, 0]; #oder. Somit sollte er nicht mehr ein Timestamp verlangen
if ($i == 1) { fhem_set (MaLaBot sendImage @#Smart-MaLa-Home /tmp/neusiedl.png) } #syntaxisch besser...
$myreading ="Warn_$i_LongText"; #syntaxisch besser...
{fhem_set ("MaLaBot sendImage @#Smart-MaLa-Home set MaLaBot message @#Smart-MaLa-Home WETTERWARNUNG FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl",$myreading, "")}
Wegen for/foreach: es gibt die Aggregationsfunktionen:
https://fhem.de/commandref_DE.html#DOIF_aggregation. Z.B. in Perl Modus:
Zitat von: CommandRefdefine di_Fenster DOIF {if (["^Window:open"]) {foreach (AggrDoIf('@','^windows','state','"open"')) {Log3 "di_Fenster",3,"Das Fenster $_ ist noch offen"}}}
define di_Temperature DOIF {if (["^room:temperature"]) {foreach (AggrDoIf('@','^room','temperature','$_ < 15')) {Log3 "di_Temperatur",3,"im Zimmer $_ ist zu kalt"}}
Und es gibt noch andere Möglichkeiten, dein DOIF zu realisieren... aber dann sind wir noch in einem Monat da ;)
Hallo Amenomade,
zuerst ein herzliches Danke für deine Hilfe. Hab das DOIF mal umgebaut, und "warte" auf die nächste Wetterwarnung. Das alte ist sicherheitshalber noch aktiv.
Das mit Aggregationsfunktion habe ich durchgelesen, aber ehrlich - es hat mich mehr verwirrt, als erhellt. In den Beispielen ist (soweit ich das entziffern konnte) eigentlich nur von einer Aggregation der Devices die Rede, dass ich mit dieser Funktion ein Reading auswerten und danach eine "For" im FHEM-Modus machen kann, hat sich mir nicht erschlossen.
Soweit ich das aus der Doku verstanden hatte, kann ich zwar einen Wert auslesen bzw. "berechnen", diesen aber nur in den State des DOIF schreiben. Den höchsten Wert berechnen muss ich ja nicht, weil der in WarnCount steht.
Um dann eine Schleife zu machen, muss ich ja doch ins Perl, oder?
PS:Ehrlich - das Beispiel mit den offenen Fenstern hab ich nicht im geringsten kapiert:
define di_Fenster DOIF {if (["^Window:open"]) {foreach (AggrDoIf('@','^windows','state','"open"')) {Log3 "di_Fenster",3,"Das Fenster $_ ist noch offen"}}} - wo ist da der Zähler? - den ich ja noch um 1 erniedrigen muss, weil die Readings mit 0 beginnen..
lg - und einen Monat mag ich dich nicht beschäftigen :)
Shamal
In einem foreach Loop enthält $_ nach und nach jedes Element.
Sicherer und lesbarer wäre:
define di_Fenster DOIF {if (["^Window:open"]) {foreach $element (AggrDoIf('@','^windows','state','"open"')) {Log3 "di_Fenster",3,"Das Fenster $element ist noch offen"}}}
Aber bleib erstmal bei deiner Schleife bis zu Ende (bis es funktioniert). Danach wirst Du evtl. spielen können ;)
Hallo Amenomade,
genau das mache ich mal - jetzt warte ich mal auf die nächste Warnung - zur Sicherheit ist das "alte" noch aktiv. Wenn das neue auch klappt, dann spiele ich mal mit den Funktionen.
Danke für deine Hilfe!
lg Shamal
Hallo nocheinmal,
ich kämpfe jetzt schon seit dem letzten Mal mit dem DOIF. Jetzt hätten wir gerade wieder Warnungen. Trotz allem Lesen steig ich noch nicht dahinter, wann welche Klammer im Perl-Modus sein muss.
Mein letzter Versuch war jetzt so, allerdings macht das DOIF genau gar nichts. Ich kann nur enablen, disablen - bekomme aber auch keinerlei Info, was nicht passt. Könnt ihr mir mal einen letzten Schubs geben :)
{ if ([uwz.neusiedl:WarnCount, 0] ne "0")}
{my $max=([uwz.neusiedl:WarnCount:d,0]);
for (my $i = 0; $i <= $max-1; $i++);
$myreading="Warn_$i_LongText";
if ($i == 1);
{ fhem_set (MaLaBot sendImage @#Smart-MaLa-Home /tmp/neusiedl.png)};
{fhem_set("MaLaBot message @#Smart-MaLa-Home PERL-WETTERWARNUNG FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl",$myreading, ""))
};
}
Danke,
Shamal
Ich nutze ja kein/kaum DOIF ABER:
Zitat
{ if ([uwz.neusiedl:WarnCount, 0] ne "0")}
KANN ja nur NICHTS machen... ;)
Also:
geschweifte Klammer auf -> Perl (nehme an auch bei DOIF-Perl)
dann if "irgendwas" -> dann kommt was passieren soll "wenn"...
ABER: dann machst du geschweifte Klammer zu -> fertig!
Also EGAL was auch beim "if" rauskommt: du "sagst" es SOLL NICHTS passiern (und genau das tut es ja auch laut deiner Aussage ;) )...
Also mindestens mal die geschweifte "Klammer zu" gleich nach dem "if" weg!
Ob der Rest so stimmt siehst du dann...
EDIT: und evtl. Zahlen nicht als "String-Vergleich"... (kann auch mal "unerwartete" Ergebnisse liefern ;) ) Also X < Y / X > Y / X == Y / X != Y vs. TextX lt TextY / TextX gt TextY / TextX eq TextY / TextX ne TextY
Gruß, Joachim
Hallo MadMax-FHEM,
hab ich mal so gemacht - funkt allerdings immer noch nicht. Hab jetzt auch schon mit ";;" herumprobiert, zugebenermaßen schon recht verzweifelt und vermutlich deshalb auch "wahllos"... :)
Danke mal vorab,
Shamal
Zitat von: MadMax-FHEM am 08 Juni 2020, 10:12:52
Ich nutze ja kein/kaum DOIF ABER:
KANN ja nur NICHTS machen... ;)
Genauso für die for Schleife und das 2. if, die sofort mit einem Semikolon geschlossen werden...
Ich vermute übrigens, dass es in der Log schon schreit, und zwar mit sinnvollen Fehlermeldungen...
Wenn man DOIFs auf Perl schreiben möchtet, sollte man vielleicht ein bisschen Perl Syntax lernen
Hallo Amenomade,
a) Das Eventlog zeigt (trotz Verbose 5) nichts aus "enabled" und "disabled", sonst hätte ich mir weiterhelfen können.
2020-06-08 12:29:14 DOIF di.msg.uwztest mode: enabled
2020-06-08 12:29:14 Global global MODIFIED di.msg.uwztest
2020-06-08 12:29:20 DOIF di.msg.uwztest mode: enabled
b) im Log selbst steht überhaupt nichts dazu. Nicht eine Silbe vom uwz oder vom DOIF selbst.
c) ja, Perl Syntax ist gut, die Kombination mit FHEM ist vielleicht für Anfänger ein wenig gewöhnungsbedürftig. Und ganz ehrlich: Der Rat hilft mir leider nicht weiter. Nach sicher 20 Stunden div. CommandRefs, 140 Seitige Threads, etc. lesen ist irgendwann das mühsam aufgebaute Verständnis wieder vorbei. Und auch irgendwann sieht man den Wald vor lauter Bäumen nicht.
lg Shamal
Ja verständlich...
...hilft aber (auf Dauer) nix ;)
Da "musst" du durch... ;)
Wie geschrieben: ich nutze kein DOIF und damit auch kein DOIF-Perl ;)
Was in einer Sub in myUtils (nur um zu "demonstrieren" wo das so geht ;) gut, bis auf "set-Magic-Zeugs" vermutlich aber auch das nutze ich nicht ;) ) gehen sollte:
{ # Perl "Anfang" (vermute ich)
if ([uwz.neusiedl:WarnCount, 0] ne "0")
{
my $max=([uwz.neusiedl:WarnCount:d,0]);
for (my $i = 0; $i <= $max-1; $i++)
{
$my reading="Warn_$i_LongText"; # Leerzeichen zwischen my und reading eingefügt ;)
if ($i == 1)
{
fhem_set ("MaLaBot sendImage @#Smart-MaLa-Home /tmp/neusiedl.png"); # fhem_set korrigiert ;) ABER: ich nutze ja kein DOIF, daher kenne ich auch fhem_set nicht ;) Nur fhem(" ") in Perl-Sub, ok dann giltet die "Ausrede" nicht ;)
} # damit wird aber NUR dieser fhem-Befehl bei ==1 ausgeführt! Wenn auch der 2te NUR bei ==1 ausgeführt werden soll, dann eben den 2ten Aufruf "eine Ebene höher", also auch "innerhalb der Klammer" (kannst ja nur du wissen ;) )
fhem_set("MaLaBot message \@#Smart-MaLa-Home PERL-WETTERWARNUNG FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl",$reading, "")); # hier muss dann nat. statt $myreading "nur" $reading hin... ;)
} # ende: for / d.h. alles von "for" bis "hier" wird in der Schleife bearbeitet
} # ende: "erstes" if. D.h. das vom 1. if bis hier wird nur ausgeführt, wenn uwz.neusiedl:WarnCount != 0 ist... Und nat. das DOIF überhaupt getriggert wird ;)
} # Perl "Ende" (vermute ich)
Und wie du siehst habe ich auch (deutlich) "umstrukturiert", so sieht man (besser) was "zusammenhǵehört" etc.
EDIT: <= $max-1 macht dasselbe wie < $max ;)
EDIT: ob das hier tatsächlich geht weiß ich nicht $myreading="Warn_$i_LongText"; ich würde (sicherheitshalber) so schreiben: $myreading="Warn_" . $i . "_LongText";
EDIT: du siehst auch, dass einige Strichpunkte entfernt wurden (ich hoffe, ich habe alle "erwischt", die "zu viel sind")... Ein Strichpunkt "beendet" einen Perl-Befehl/-Zeile. Ein Strichpunkt OHNE irgendwas ist wie ein "Null-Befehl"... Daher macht ein if(irgendwas); quasi NIE "etwas" (also zumindest nicht abhängig von "irgendwas" ;) ), weil ja nach der Bedingung gleich der "Leerbefehl" kommt, welcher schon abhängig von der Bedingung ausgeführt wird... Aber: halt "nichts macht" ;)
Gruß, Joachim
Hallo Joachim,
dein Post hat schon mal ein wenig Licht in die Sache gebracht, und sollte meiner Meinung nach auch funktionieren. WarnCount ist derzeit 2, und somit sollte das DOIF ja funktionieren. Ich war bis jetzt der Meinung, dass ein syntaktisch richtiges DOIF auch die checkall, sowie die CMD Zweige zur Verfügung stellt, damit ich hier weiter testen kann.
Auch in deinem Beispiel gibt es nur "enable" und "disable" und das war's dann auch. Log leer, Eventmonitor leer... leider gar nix, wo ich mich anhalten oder vortasten könnte.
EDIT: Die Strichpunkte waren schon echte "Verzweiflungstaten", weil ich zahlreichen Bespielen und Posts immer wieder andere Varianten gefunden habe, wie es "jetzt" funktioniert... da gibts auch die ";;" Varianten...
Danke auf jeden Fall,
lg Shamal
Also... ehrlich?
Hab ein DOIF namens testDOIF mit genau deiner Definition erstellt
{ if ([uwz.neusiedl:WarnCount, 0] ne "0")}
{my $max=([uwz.neusiedl:WarnCount:d,0]);
for (my $i = 0; $i <= $max-1; $i++);
$myreading="Warn_$i_LongText";
if ($i == 1);
{ fhem_set (MaLaBot sendImage @#Smart-MaLa-Home /tmp/neusiedl.png)};
{fhem_set("MaLaBot message @#Smart-MaLa-Home PERL-WETTERWARNUNG FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl",$myreading, ""))
};
}
Dann folgendes:
define uwz.neusiedl dummy
setreading uwz.neusiedl WarnCount 1
Und sofort kommt im DOIF:
READINGS:
2020-06-08 13:11:53 Device uwz.neusiedl
2020-06-08 13:11:53 block_01 condition c01: syntax error, line 1, at EOF
2020-06-08 13:11:53 block_02 condition c02: syntax error at (eval 159) line 2, at EOF
Global symbol "$myreading" requires explicit package name (did you forget to declare "my $myreading"?) at (eval 159) line 3.
Global symbol "$myreading" requires explicit package name (did you forget to declare "my $myreading"?) at (eval 159) line 6.
Mist, stimmt, da ist dann doch was "durchgerutscht"...
...aber so ist das, wenn man "fremden" Code versucht "gerade zu biegen" ;)
Hab diesen Fehler auch grad "korrigiert"...
...mal sehen was ich noch so "übersehen" hab... ;)
Gruß (und sorry), Joachim
Hallo Joachim & Amenomade,
nochmal Danke vorab - ich habe jetzt das Doif von Amenomade mal rauskopiert und auf ein komplett neues gelegt. VErbose wieder auf 5 und Ergebnis wie vorher... - ist auch spannend...
2020-06-08 13:19:42 DOIF di.msg.perltest mode: enabled
2020-06-08 13:20:33 DOIF di.msg.perltest mode: enabled
2020-06-08 13:20:34 Global global MODIFIED di.msg.perltest
Das mit dem myreading hatte ich schon wieder ausgebessert, das kam aus einem copy-paste fehler mit testvariablen in der perl-umgebung.
Das Doif tut trotzdem nix...
lg Shamal
Und schon wenn man auf einer richtigen Perl-Syntax achtet, kriegt man zumindest keine "syntax" Fehlermeldung mehr.
{ if ([uwz.neusiedl:WarnCount, 0] ne "0") {
my $max=[uwz.neusiedl:WarnCount:d,0];
for (my $i = 0; $i <= $max-1; $i++){
my $myreading="Warn_".$i."_LongText";
if ($i == 1)
{ fhem_set ("MaLaBot 'sendImage @#Smart-MaLa-Home /tmp/neusiedl.png'")}
fhem_set("MaLaBot message ".'@#Smart-MaLa-Home PERL-WETTERWARNUNG FÜR NEUSIEDL am SEE: '.ReadingsVal("uwz.neusiedl",$myreading, ""));
}
}
}
Ob das noch was tut, was erwartet ist, ist noch eine andere Geschichte, aber zumindest würde man mit richtigem Code anfangen.
Was zeigst du da!?
EventMonitor!?
Da kommen nat. nur Events...
...Fehler stehen wenn dann im fhem Log (auch nur DA wirkt verbose)...
Hast du auch das setreading ausgeführt!?
Weil: OHNE dass das DOIF getriggert wird, tut es auch NICHTS!
(soviel ist sogar mir klar, obwohl ich KEIN DOIF nutze ;) )
Gruß, Joachim
Hallo Joachim,
im Log ist auch nichts anderes..
2020.06.08 13:10:33 4: parse status message for li.wz.panel
2020.06.08 13:10:37 3: UWZ uwz.neusiedl: UWZ.1811 Done fetching data
2020.06.08 13:11:33 4: parse status message for li.wz.panel
2020.06.08 13:12:07 1: PERL WARNING: Argument "ok" isn't numeric in numeric gt (>) at (eval 4296436) line 1.
2020.06.08 13:12:33 4: parse status message for li.wz.panel
2020.06.08 13:13:33 4: parse status message for li.wz.panel
2020.06.08 13:14:01 3: UWZ uwz.wien: UWZ.1811 Done fetching data
2020.06.08 13:14:33 4: parse status message for li.wz.panel
2020.06.08 13:15:04 1: PERL WARNING: Argument "ok" isn't numeric in numeric gt (>) at (eval 4296636) line 1.
2020.06.08 13:15:33 3: gw.deconz: websocket opened to 192.168.188.220:443
2020.06.08 13:15:33 4: parse status message for li.wz.panel
2020.06.08 13:15:33 3: gw.deconz: websocket: Switching Protocols ok
2020.06.08 13:16:33 4: parse status message for li.wz.panel
2020.06.08 13:17:33 4: parse status message for li.wz.panel
2020.06.08 13:17:57 1: PERL WARNING: Argument "ok" isn't numeric in numeric gt (>) at (eval 4296846) line 1.
2020.06.08 13:18:33 4: parse status message for li.wz.panel
2020.06.08 13:19:33 4: parse status message for li.wz.panel
edit: Der Fehler im Licht-Panel kommt von einem ungültigen Befehl, den die Fernbedienung (milight) hin- und wieder schickt. das macht er so 4-5 mal, dann ist wieder Ruhe. Ist ein Zigbee + Milight Controller :)
Das Setreading ist durchgeführt bzw. sollte ja zumindest mal ein Checkall kommen, so wie bei meinen anderen ca. 30 DOIFs.. :).
lg Thomas
Ein Paar Erklärungen noch, da ich in gute Laune bin ;)
for (my $i = 0; $i <= $max-1; $i++);
führt nur dazu, dass $i hochgezählt wird. Davon wird nix gemacht.
Richtige Syntax, wenn man etwas davon machen will:
for (my $i = 0; $i <= $max-1; $i++) { etwas }
$i ist im Kontext nur innerhalb der "for" Schleife nutzbar.
Wenn ich sowas schreibe:
for (my $i = 0; $i <= $max-1; $i++);
mach etwas mit $i;
ist $i nicht bekannt => Fehlermeldung: er zählt mit $i hoch, aber danach ist $i nicht bekannt.
@ ist für Perl das Zeichen eines Array
Wenn man das in " " nutzt, versucht Perl , es in einem String Kontext zu interpretieren. Du willst aber hier, dass @ als @ interpretiert wird. Dewegen die "single" Hochkommas in meinem Code
Wenn man sowas schreibt:
... "blabla$i_blabla"
schreibt, versucht Perl "$i_blabla" zu interpretieren, und nicht "$i" und dann den Rest.
Deswegen die Vorgehensweise mit String-Konkatenation mit ".", und die single quotes, um zu vermeiden, dass irgendwas interpretiert wird
Ich habe ja (weil auch gute Laune ;) ) "ständig" mein Beispiel von "vorne" versucht "nachzuziehen" und zu kommentieren...
...aber in dem Code ist soviel "nicht gut", da komm ich ja gar nicht hinterher... ;)
Aber jetzt mal sehen was weiter kommt...
EDIT: ein \@ sollte aber auch gehen!? (hab's mal "vorne" so geändert ;) )...
Gruß, Joachim
Naja... immerhin abhängig vom Kontekt des Aufrufs.
my @test = (1, 2, 3);
print \@test;
(print interpretiert es als String)
wird immer zu
ARRAY(0xf0d100)
führen, und nicht zum Inhalt des Arrays
Dagegen wird
my @test = (1, 2, 3);
print ${\@test}[0];
den Wert "1" zurückliefern
Ja schon klar, wenn man Arrays will...
...aber hier geht es doch um ein @-Zeichen beim Versenden!?
Egal...
Wir müssen eh warten wie's weiter geht... ;)
BTW: "heftiger" Avatar ;)
Gruß, Joachim
Hallo,
gut, dass ihr guter Laune seid :) - das hilft schon ungemein.
Mein Konstrukt kam mal prinzipiell daher, dass ich die Variante als "Vorbild" genommen habe:
#!/usr/local/bin/perl -w
use strict;
for(my $i = 1;$i <= 10;$i++) { print "$i\n"; }
Da wird ja sehr wohl hochgezählt und auch ausgegeben... :-\
Das "@" soll ja nicht ausgegeben werden, sondern gehört ja zur Syntax des set Befehls.... das habe ich jetzt mal aus der Klammer raus genommen.
Was mich am meisten irritiert, ist die absolute "Nullmeldung", was Fehler angeht. Das Ding rührt kein Ohrwaschel und meldet nichts, kein Fehler...
Ps: Bitte noch keine Arrays, soweit will ich hier mal gar nicht vordringen. ;D
PPS: Hab noch ein paar Änderungen gemacht, aber weitergekommen bin ich noch nicht... siehe unten. Ach ja, und auch mal die Bedingung gegen !=0 getauscht, hat auch nichts gebracht...
{if ([uwz.neusiedl:WarnCount,0] ne "0")
{
my $max=([uwz.neusiedl:WarnCount:d,0]);
for (my $i = 0; $i < $max; $i++)
{
my $myreading="Warn_".$i."_LongText";
if ($i == 1)
{
fhem_set ("MaLaBot sendImage @#Smart-MaLa-Home /tmp/neusiedl.png");
fhem_set ("MaLaBot message @#Smart-MaLa-Home PERL-WETTERWARNUNG FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl",$myreading, ""));
}
}
}
}
Dein neues for-Beispiel ist ja jetzt auch richtig!
Beachte den Strichpunkt in deinen ersten Schleifen!!
Das @ wird doch benötigt!?
Also entweder "maskieren": \@
Oder wie von amenomade vorgeschlagen einfache Anführungszeichen. Dort werden aber Variablen NICHT ausgewertet...
Mach doch mal Logausgaben in dein DOIF...
Also gleich zu Beginn...
Und ich würde JEDE Variable auch mal loggen.
Wenn es dann läuft kann man ja die Logeinträge wieder rausnehmen...
Wird denn das DOIF getriggert!?
Poste doch mal ein list davon, nachdem es gelaufen ist...
...oder du denkst es sollte gelaufen sein...
EDIT: manche Fehler kommen ja auch erst, wenn das DOIF triggert, also der Code auch durchlaufen wird... Ansonsten kommen nur "Define-Sytax-Fehler"...
Gruß, Joachim
Hallo Joachim,
Zitat von: MadMax-FHEM am 08 Juni 2020, 20:39:46
Beachte den Strichpunkt in deinen ersten Schleifen!!
Das @ wird doch benötigt!?
Also entweder "maskieren": \@
Oder wie von amenomade vorgeschlagen einfache Anführungszeichen. Dort werden aber Variablen NICHT ausgewertet...
Gruß, Joachim
Bin jetzt mal schon ziemlich glücklich, da zumindest der "innere Teil" (also Bild + Warning_0) gesendet wird. Den Hint mit dem ";" in "den ersten Schleifen" schau ich mir morgen an, jetzt geht's ins Bett..
Habe von fhem_set auf
{fhem ("set MaLaBot sendImage @#Smart-MaLa-Home /tmp/burgenland.png");}
umgestellt. Allerdings behauptet das Log jetzt, dass ich "MaLaBot erst definen muss, obwohl die Nachricht gesendet wird... wieder was spannendes.
Wo der Unterschied zum DOIF im "nativen" Modus ist, erschliesst sich mir nicht) - siehe Code.
(set MaLaBot sendImage @#Smart-MaLa-Home /tmp/burgenland.png, set MaLaBot message @#Smart-MaLa-Home WETTERWARNUNG FÜR NEUSIEDL am SEE: [uwz.neusiedl:Warn_0_LongText])
ps: lass dich nicht vom anderen .png namen durcheinander bringen, das habe ich jetzt extra dorthin gelegt mit einer dummy.png, damit ich auch das ausschließen kann.
Das DOIF triggert übrigens über einen event-on-change attribut im UWZ-Modul auf das Reading WarnCount. Hier liegt zum Testen auch ein event-on-update drauf.
Die Fehlermeldung im Log mit aktiviertem Stacktrace poste ich lieber nicht, die sind offensichtlich aus dem Shelly-Modul und da haben sich schon einige die Finger verbrannt.. ;)
Noch einmal ein DANKE:)
Zitat von: shamal2008 am 09 Juni 2020, 00:05:45
Bin jetzt mal schon ziemlich glücklich, da zumindest der "innere Teil" (also Bild + Warning_0) gesendet wird. Den Hint mit dem ";" in "den ersten Schleifen" schau ich mir morgen an, jetzt geht's ins Bett..
Ich meinte eher den Unterschied zwischen deinen ersten geposteten for-Schleifen MIT Strichpunkt direkt HINTER der Schleife, also:
Zitat
for (my $i = 0; $i <= $max-1; $i++);
von hier: https://forum.fhem.de/index.php/topic,111570.msg1062001.html#msg1062001
Im Gegensatz zu der Schleife die jetzt (natürlich) geht:
Zitat
for(my $i = 1;$i <= 10;$i++) { print "$i\n"; }
bzw. dann in dein DOIF eingebaut:
Zitat
for (my $i = 0; $i < $max; $i++)
Und: ein DOIF oder notify wird NICHT von irgendeinem event-on-change Attribut getriggert! Sondern nur von einem EVENT! (oder einer Zeit o.ä.)
Was du mit event-on- Attributen allerdings beeinflusst ist nat. wann Events kommen bzw. wann evtl. keine oder weniger kommen... ;)
Und ich meinte auch nicht Fehler im Log...
...sondern Logausgaben INS fhem Log von DIR bzw. DEINEM Code!
Also:
Log3(undef, 1, "Meine Sub und ich bin an Stelle 1 und das ist der Wert der Variablen XYZ: $XYZ");
Dann kannst du nachverfolgen WO/WIE du bzw. dein Code so abläuft und welche Variablen an welcher Stelle welchen Wert haben...
...denn zu glauben, dass etwas so läuft und diesen Wert haben müsste ist anders als: ich WEISS wo es langläuft und wie die Werte SIND! ;)
Viel Spaß und Erfolg noch, Joachim
Hallo Joachim,
neuer Tag, neues Glück - und das so früh am Morgen ;)
Jetzt funktioniert es, und ich denke, ich habe es auch einigermaßen verstanden ;)
{if ([uwz.neusiedl:WarnCount,0] != "0")
{
my $max=([uwz.neusiedl:WarnCount:d,0]);
{fhem ("set MaLaBot sendImage @#Smart-MaLa-Home /tmp/burgenland.png");}
for (my $i = 0; $i < $max; $i++)
{
my $myreading="Warn_".$i."_LongText";
{
{fhem ("set MaLaBot message @#Smart-MaLa-Home TEST!!! FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl",$myreading, ""));}
}
}
}
}
Danke euch beiden für die tatkräftige und laufende Unterstützung!
WARNING: Ich werde weiter versuchen, einige DOIFs auf Perl umzustellen ;D ;D
PS: 30 Jahre sind eine lange Zeit, und damals hab ich recht viel in C programmiert, Perl hat doch irgendwie ein paar Eigenheiten und mit FHEM gemischt, wird das nochmal schwieriger ;)
lg Shamal
Ich würde noch überflüssige Klammern und evtl. auch überflüssige Variablen weglassen:
{ if ([uwz.neusiedl:WarnCount,0] != "0")
{
fhem ("set MaLaBot sendImage @#Smart-MaLa-Home /tmp/burgenland.png");
for (my $i = 0; $i < [uwz.neusiedl:WarnCount:d,0]; $i++)
{
fhem ("set MaLaBot message @#Smart-MaLa-Home TEST!!! FÜR NEUSIEDL am SEE: ".ReadingsVal("uwz.neusiedl","Warn_".$i."_LongText", ""));
}
}
}
Hallo Damian,
da hast du natürlich völlig recht - dein Code ist aufgeräumt! Mein Ansinnen war es, die Zusammenhänge zwischen "klassischen DOIF" und "Perl-Doif" besser zu verstehen, samt selbst definierter Variablen, etc.
Stehe sowieso vor der nächsten Herausforderung, die aber erst "behirnen" muss. Mein (unser ;D) DOIF funktioniert super, hat jedoch eine Einschränkung, die genau heute passiert ist:
- WarnCount war 2, eine Warnung wurde "verlängert" bzw. neu ausgegeben, damit ist der WarnCount wieder 2 und logischerweise springt das DOIF nicht an. Da werde ich jetzt mal die Attribute von DOIF nocheinmal durchackern bzw. mir den Kopf zerbrechen... Bei einem Event-on-update allein bekomme ich ja bei jedem Fetch die eine Warnung "nachgeschossen"... Ausserdem möchte ich noch einen Zeitraum einbauen, der mir zusätzlich die Warnung über Sonos ausgibt. (ja, könnte man auch in einem eigenen machen, ist aber nur der halbe Lerneffekt)...
ein HERZLICHES Danke an alle aus Wien,
lg Shamal