Mehrere if / else Bedingungen

Begonnen von sun1907, 06 Februar 2013, 14:24:45

Vorheriges Thema - Nächstes Thema

sun1907

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.


Puschel74

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
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

sun1907

So klappt es....


define .... notify .... {\
   if ..... {\
   fhem ("....");;\
   }\
elseif {\
   if ..... {\
   fhem ("....");;\
   }\
elseif {\
   if ..... {\
   fhem ("....");;\
   }\
else {\
   if ..... {\
   fhem ("....");;\
   }\
}}}}

Zrrronggg!

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.
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Reinerlein

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

mickym

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;
}

jhohn

ging switch in perl nicht irgendwie so?


use Switch;
switch("%EVENT") {
  case blabla1 { do 1 }
  case blabla2 { do 2 }
  ...
  else { doSomethingElse }
}
FHEM auf Synology Diskstation DS413j (DSM4.3), HM LAN Adapter
Steuerung für Nachtspeicheröfen:
Ladung:   HM-WDS10-TH-O, HM-LC-Sw4-DR, Weather-Modul
Gebläse: HM-CC-TC, HM-LC-SW1-FM, HM-Sec-RHS
FHEM auf FritzBox 7390 für Telefon Funktionen

mickym

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

Gruss Mic :)

Zrrronggg!

Zitatda ist sun1907 nur ein Fehler beim Posten unterlaufen. Er meinte natürlich "elsif" (ohne das "e" bei else), nicht wahr? ;-)

Uff! Tomaten. Danke.
FHEM auf Linkstation Mini, CUL 868 SlowRF, 2xCUL 868 RFR, CUL 433 für IT, 2xHMLAN-Configurator mit VCCU, ITV-100 Repeater, Sender und Aktoren von FHT, FS20, S300, HM, IT, RSL

Predictor

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 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
FHEM auf Fritz!Box 7390
FS20 per CUL

Dietmar63

Ich glaube Perl hat kein switch.
Frag doch mal Google!

If...
Elsif

Ist die Lösung.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Predictor

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.

ZUSAMMENFASSUNG
Native 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
FHEM auf Fritz!Box 7390
FS20 per CUL

mickym

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

Dietmar63

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.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Predictor

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
FHEM auf Fritz!Box 7390
FS20 per CUL

Puschel74

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
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

Dietmar63

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.

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Predictor

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
FHEM auf Fritz!Box 7390
FS20 per CUL

Mike85

#19
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?

TomLee

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

Mike85

Oh man,

vielen Dank Thomas, das war es.

Manchmal sieht man den Wald vor lauter Bäumen nicht. :P

Otto123

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 :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz