Hallo.
Ich würde gerne mehrere Else-Bedingungen nacheinander setzen. Ist das richtig, wenn ich die z.B. so in Reihe setze:
define .... notify .... {\
if ......{\
fhem ("....");;\
}\
else {\
fhem ("....");;\
}\
else {\
fhem ("....");;\
}\
else {\
fhem ("....");;\
}\
}}}}
Oder ist das so nicht möglich ?. Mein Ziel ist es, wenn die erste If-Bedingung nicht zutrifft, soll das erste else geprüft werden, tritt das nicht zu, dann das nächste else, trifft das nicht zu, dann bleibt nur noch das letzte else.
Usw...
Danke im Voraus für jede Antwort.
Guckst Du Perl-Programmierung: Kontrollstrukturen (//de.wikibooks.org/wiki/Perl-Programmierung:_Kontrollstrukturen)
Hallo,
möglich ist das durchaus aber ...
Du hast bei deinen Else-Zweigen keine erkennbare Bedingung stehen.
In diesem Fall wird, wenn die If-Prüfung fehlschlägt, jedes else ausgeführt.
Grüße
So klappt es....
define .... notify .... {\
if ..... {\
fhem ("....");;\
}\
elseif {\
if ..... {\
fhem ("....");;\
}\
elseif {\
if ..... {\
fhem ("....");;\
}\
else {\
if ..... {\
fhem ("....");;\
}\
}}}}
ZitatSo klappt es....
define .... notify .... {\
if ..... {\
fhem ("....");;\
}\
elseif {\
if ..... {\
fhem ("....");;\
}\
elseif {\
if ..... {\
fhem ("....");;\
}\
else {\
if ..... {\
fhem ("....");;\
}\
}}}}
Hm.
Wenn ich da mal ein bisschen wiedersprechen darf. Das klappt bei mir so nicht:
Can't call method "elseif" without a package or object reference
Was allerdings geht ist:
define .... notify .... {\
if ..... {\
fhem ("....");;\
}\
else {\
if ..... {\
fhem ("....");;\
}\
else {\
if ..... {\
fhem ("....");;\
}\
else {\
if ..... {\
fhem ("....");;\
}\
}}}}[/quote]
Man muss aber sehr genau aufpassen, welche "Else" genau geprüft werden, wenn welche vorherigen IFs not true sind.
Hi Zrrronggg,
da ist sun1907 nur ein Fehler beim Posten unterlaufen. Er meinte natürlich "elsif" (ohne das "e" bei else), nicht wahr? ;-)
Deine Variante würde ich aus den von dir genannten Gründen wirklich nicht empfehlen. Das wird tierisch unübersichtlich, und ist dazu noch ziemlich ineffizient (das ist hier aber eher nebensächlich).
Allgemein empfehle ich immer bei solchen Konstrukten die logischen Ebenen bei den Vergleichen einzuhalten. Dann versteht man den Code u.U. auch in ein paar Wochen noch...
Also, sowas wie: Auf der ersten Ebene überprüfe ich die Uhrzeiten, auf der zweiten Ebene die Aktoren und auf der dritten die Randbedingungen.
Das hat jetzt nichts konkret mit dem Beispiel hier zu tun...
In welcher Ebene man was prüft, sollte man von Fall zu Fall entscheiden. Ich gehe da immer nach der Umständlichkeit der Ermittlung vor, bzw. womit ich die meiste Aufwandsersparnis erreichen kann. Das ist aber oftmals weder eindeutig noch überhaupt beantwortbar. Hier also Intuition spielen lassen...
Grüße Reinerlein
ich mag aus Gründen der Übersichtlichkeit und Vergleichbarkeit mit anderen Programmiersprachen - z.Bsp VB - select case ... lieber diese Darstellung, wobei ich das im MyUtils habe und nicht in der cfg - ich weiss also nicht ob das mit dem LABEL SWITCH in der CFG auch funktioniert:
define .... notify .... {\
SWITCH: for("%EVENT"){\
if(/blabla1/) {do somehting1; last switch;}
if(/blabla2/) {do somehting2; last switch;}
if(/blabla3/) {do somehting3; last switch;}
dosomethingelse;
}
ging switch in perl nicht irgendwie so?
use Switch;
switch("%EVENT") {
case blabla1 { do 1 }
case blabla2 { do 2 }
...
else { doSomethingElse }
}
Hallo soweit ich es verstanden habe - bin aber auch gerade erst am Lernen von Perl - kann man das mit dem use Switch case; erst ab einer bestimmten Perl Version und Du must das Switch.PM Module implementiert haben - mit dem Label können es aber auch ältere.
Hier das Zitat:
ZitatStarting from Perl 5.10.1 (well, 5.10.0, but it didn't work right), you can say
use feature "switch";
to enable an experimental switch feature. This is loosely based on an old version of a Perl 6 proposal, but it no longer resembles the Perl 6 construct. You also get the switch feature whenever you declare that your code prefers to run under a version of Perl that is 5.10 or later.
aus: http://perldoc.perl.org/perlsyn.html#Compound-Statements (//perldoc.perl.org/perlsyn.html#Compound-Statements)
Gruss Mic :)
Zitatda ist sun1907 nur ein Fehler beim Posten unterlaufen. Er meinte natürlich "elsif" (ohne das "e" bei else), nicht wahr? ;-)
Uff! Tomaten. Danke.
Ich bin gerade dabei eine Funktion in 99_Utils.pm einzubauen.
Dabei brauche ich auch eine größere Auswahlliste, in perl gibt es ja switch/case.
Das Modul Switch.pm liegt bei mir auch im perl Ordner (auf Fritzbox).
Ich habe auch versucht das Modul einzubinden mittels require Switch;
oder use Switch;
doch beides scheint nicht zu funktionieren.
Meine switch-case sieht so aus:
use Switch;
switch ($CommandInput) {
case "GRUEN" { $CommandCode = "123" }
case "BLAU" { $CommandCode = "456" }
case "ROT" { $CommandCode = "789" }
else { $CommandCode = "XXX" }
}
Wie binde ich denn das perl Modul richtig ein?
Per IF ist die zuweisung ja nicht so optimal (da 32werte) dies zieht wohl die Performance nach unten.
Es kann durchaus sein dass eben diese Abfrage auch noch 10x innerhalb kürzester Zeit aufgerufen wird.
Diese IF läuft ohne Fehler, aber gibt immer eine "1" zurück:
if($CommandInput == "GRUEN") {
$CommandCode = 1;
} elsif($CommandInput == "BLAU") {
$CommandCode = 2;
} elsif($CommandInput == "ROT") {
$CommandCode = 3;
} else {
$CommandCode = 9;
}
Laut misc-perl-info.com (//www.misc-perl-info.com/perl-switch.html) sollte am performantesten eine hash Table sein.
Doch leider bekomme ich bei diesem Beispielcode auch Fehler.
# initialize some hash structure
%fruitsColors = (
"apple" => "red",
"banana" => "yellow",
"orange" => "orange",
"plum" => "dark blue"
);
print "Fruit: ";
chomp($fruit = <STDIN>);
$color = $fruitsColors {lc $fruit} || "unknown";
print "The $fruit has the colour $color\n";
Was ist denn der beste ansatz der mit FHEM zu realisieren ist?
Perl ist für mich Neuland!
Grüße
Predi
Ich glaube Perl hat kein switch.
Frag doch mal Google!
If...
Elsif
Ist die Lösung.
Zitat von: Dietmar63 schrieb am So, 02 Juni 2013 18:53Ich glaube Perl hat kein switch.
Frag doch mal Google!
If...
Elsif
Ist die Lösung.
perl kann switch - case
Auf der Seite
misc-perl-info.com sind einige Beispiele unter anderem eben auch switch-case.
FHEM hat ja Perl v5.12.2 installiert und die
Switch.pm ist ja ebenfalls vorhanden.
Im
Blog von hidemail.de wird darüber Diskutiert wann es nun nutzbar ist und wann nicht.
Mir ist unklar warum switch-case durch given-when erweitert/ersetzt wurde/werden soll.
ZUSAMMENFASSUNGNative kann nur
IF
ELSIF
ELSE
verwendet werden.
Wenn man im Header folgendes einbindet hat man auch switch - case und/oder given - when zur verfügung
use Switch 'Perl5', 'Perl6';
[/b]
###############################################
### S W I T C H - C A S E ###
###############################################
switch ($CommandInput) {
case ("GRUEN") { $CommandCode = 4; }
case ("BLAU") { $CommandCode = 5; }
case ("ROT") { $CommandCode = 6; }
else { $CommandCode = "Other"; }
}
###############################################
### G I V E N - W H E N ###
###############################################
given ($CommandInput){
when("GRUEN") { $CommandCode = 4; }
when("BLAU") { $CommandCode = 5; }
when("ROT") { $CommandCode = 6; }
default { $CommandCode = "Other"; }
}
Für größere Szenarien, denke ich, sollte aber eine Hash table verwendet werden, doch leider bekomme ich die nicht zum laufen.
Selbst das einfachste Beispiel bringt bereits einen Fehler - da komme ich gerade nicht weiter.
%ages = ("John", 43, "Paul", 25, "Marie", 22);
%members = (John => "father", Paul => "son",
Marie => "daughter");
Grüße
Predi
Zitat von: mickym schrieb am Di, 12 März 2013 15:52ich mag aus Gründen der Übersichtlichkeit und Vergleichbarkeit mit anderen Programmiersprachen - z.Bsp VB - select case ... lieber diese Darstellung, wobei ich das im MyUtils habe und nicht in der cfg - ich weiss also nicht ob das mit dem LABEL SWITCH in der CFG auch funktioniert:
define .... notify .... {\
SWITCH: for("%EVENT"){\
if(/blabla1/) {do somehting1; last switch;}
if(/blabla2/) {do somehting2; last switch;}
if(/blabla3/) {do somehting3; last switch;}
dosomethingelse;
}
Wie gesagt - mit dem LABEL SWITCH: for() {if(){}} Konstruktion geht es auch ohne Einbindung des
switch.pm moduls und man ist von der Perl Version unabhängig
Für deine Zwecke scheint mir die hash-Tabelle die beste Lösung zu sein: Schnell und in der Regel wenig Code.
Wenn du uns deinen Versuch schickst und die zugehörige Fehlermeldung, dann helfen wir dir gern.
Im Moment habe ich ein funktionierendes given - when in der 99_Utils
In den Header dies hier rein:
use Switch 'Perl5', 'Perl6';
Das ist die (gekürtzte) given when:
given ($CommandInput){
when("POWER") { $CommandCode = 116; } #Taste: POWER ON/OFF
# -----------------------------------------
when("0") { $CommandCode = 11; } #Taste: 0
when("1") { $CommandCode = 2; } #Taste: 1
when("2") { $CommandCode = 3; } #Taste: 2
when("3") { $CommandCode = 4; } #Taste: 3
when("4") { $CommandCode = 5; } #Taste: 4
when("5") { $CommandCode = 6; } #Taste: 5
when("6") { $CommandCode = 7; } #Taste: 6
when("7") { $CommandCode = 8; } #Taste: 7
when("8") { $CommandCode = 9; } #Taste: 8
when("9") { $CommandCode = 10; } #Taste: 9
when("TV") { $CommandCode = 377; } #Taste: Digital-TV
when("RADIO") { $CommandCode = 385; } #Taste: Digital-Radio
when("TEXT") { $CommandCode = 388; } #Taste: "text"
when("HELP") { $CommandCode = 138; } #Taste: "help"
default { $CommandCode = 998; }
}
=> Funktioniert, aber Performance?
Ich habe mal versucht ob ich eine Hash Table anlegen kann mit:
%ages = ("John", 43, "Paul", 25, "Marie", 22);
aber da meldet FHEM (wenn ich über das WI die datei speichern will):
Global symbol "%ages" requires explicit package name at ./FHEM/99_Utils.pm line 180.
Einen anderen Fehler hatte ich bisher nicht bemerkt (da ich die geänderte 99_Utils.pm immer per FTP hochgeladen habe)
Not enough arguments for main::GetHttpFile at ./FHEM/99_Utils.pm line 197, near "$CommandCode) "
Das ist diese Zeile:
fhem( GetHttpFile($receiverIP.$Site.$CommandCode) );
ABER der Befehl an sich funktioniert.
Hat da evtl auch noch einen Tipp parat - ist unschön, so kann ich es nicht ins WIKI stellen.
Danke & Grüße
Predi
Hallo,
auch wenn ich absolut keine Ahnung hab.
Hast du schonmal versucht vor das %ages ein my zu setzen?
Also so
my %ages = ("John", 43, "Paul", 25, "Marie", 22);
Grüße
my davorsetzen und dein hash funktioniert
So wie Puschel es beschrieben hat.
das my sorgt dafür dass eine explizite Definition der Variable erstellt wird.
das my vor jeder erstmaligen Nutzung einer Variablen wird durch use strict; weiter oben erzwungen.
use strict; ist empfehlenswert, weil damit viele Schreibfehler vom Laufzeitsystem entdeckt werden.
OMG - kennt ihr das Gefühl wenn man sich ein Stück Holz aufs Hirn hauen könnte?
Wenn man es liest ist es eigentlich logisch - funktioniert => bastle dann mal meinen given-when um.
DANKE
Einen wunderschönen guten Abend,
ich versuche seit Tagen meine if / else Bedingung ans laufen zu bekommen, bekomme es aber irgendwie nicht hin.
Zur Erklärung, es soll je nach Jahreszeit ein Baum andersfarbig beleuchtet werden.
Mein Code sieht so aus:
*{sunset(-1800)} { if (value("Jahreszeit") eq "Frühling" ) {\
fhem("set HUE_HUEDevice1 on : hue 17994 : sat 254 : bri 254");;\
}\
elsif (value("Jahreszeit") eq "Sommer" ) {\
fhem("set HUE_HUEDevice1 on : hue 17994 : sat 254 : bri 254");;\
}\
elsif (value("Jahreszeit") eq "Herbst" ) {\
fhem("set HUE_HUEDevice1 on : hue 10923 : sat 254 : bri 254");;\
}\
elsif (value("Jahreszeit") eq "Winter" ) {\
fhem("set HUE_HUEDevice1 on : hue 10923 : sat 53 : bri 254");;\
}\
}
Das ganze ist als at angelegt und Jahreszeit ist ein DOIF das den Wert Herbst, Winter, Frühling und Sommer ausgibt. Das DOIF habe ich hier aus dem Forum kopiert und funktioniert auch.
Kann mir irgendjemand weiterhelfen?
Zitat von: commandrefUm auf die Gerätestatus/Attribute zuzugreifen benutzen Sie bitte die folgenden Funktionen:
Value(<devicename>)
gibt den Status eines Gerätes zurück (entsprechend dem Ausdruck in Klammern, den Sie beim List-Befehl sehen).
Vermute hier liegt der Fehler.
Gruß
Thomas
Oh man,
vielen Dank Thomas, das war es.
Manchmal sieht man den Wald vor lauter Bäumen nicht. :P
Könnte man vielleicht im Ausführungsteil so einkürzen:
{ my $out=": hue 17994 : sat 254";;\
$out=": hue 10923 : sat 254" if (Value("Jahreszeit") eq "Herbst" );;\
$out=": hue 10923 : sat 53" if (Value("Jahreszeit") eq "Winter" );;\
fhem("set HUE_HUEDevice1 on $out : bri 254");;\
}
Oder auch so
{ my $out;;\
$out= (Value("Jahreszeit") eq "Herbst" )?": hue 10923 : sat 254":": hue 17994 : sat 254";;\
$out= (Value("Jahreszeit") eq "Winter" )?": hue 10923 : sat 53" :": hue 17994 : sat 254";;\
fhem("set HUE_HUEDevice1 on $out : bri 254");;\
}
Je nach dem was einem in ein paar Wochen logischer erscheint :)