Hauptmenü

mehrere doifs vereinen

Begonnen von hackepeter, 15 November 2019, 20:31:35

Vorheriges Thema - Nächstes Thema

hackepeter

Guten Abend,

ich habe 100 fast identische doifs und frage mich (euch), ob sich diese aus Performancegründen vereinen lassen.

Die doifs reagieren auf 100 s7 devices und senden anschließend eine Mail mit Text aus einem Dummy:

doif1:

{if (["Event001:on"] and [?Event001_Type] eq "1"){
my $ReceiverNr = ReadingsVal("Event001_Receiver","state","0");;
my $MailAddr = ReadingsVal("Receiver$ReceiverNr","1","bla\@bla.de");;
my $MsgSubject = ReadingsVal("Message1","1","0");;
my $MsgText = ReadingsVal("Message1","2","0");;
fhem_set("Event001 off");;
::DebianMail($MailAddr,$MsgSubject,$MsgText,"/home/pi/Logo.jpg")}}


doif2:

{if (["Event002:on"] and [?Event002_Type] eq "1"){
my $ReceiverNr = ReadingsVal("Event002_Receiver","state","0");;
my $MailAddr = ReadingsVal("Receiver$ReceiverNr","1","bla\@bla.de");;
my $MsgSubject = ReadingsVal("Message2","1","0");;
my $MsgText = ReadingsVal("Message2","2","0");;
fhem_set("Event002 off");;
::DebianMail($MailAddr,$MsgSubject,$MsgText,"/home/pi/Logo.jpg")}}



Damian

Wer macht denn so was?

Du brauchst nur eine Triggerdefinition, die zu allen deinen s7 Devices passt. Im Code beziehst du dich dann auf das triggernde Device  ($device). Evtl. wirst du aus dem Device-Namen deine Nummern extrahieren müssen, um auf die entsprechenden Readings zuzugreifen.

Und dann kommt es auf die Nebenbemerkung an: 
Zitat...fast identische doifs...

Um die Performance der 100 DOIFs würde ich mir keine Sorgen machen, aber um die Wartbarkeit ;)



Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

Danke, das werde ich probieren.
Die Wartbarkeit ist kein Problem, da ich die definitionen im excel einmal für alle 100 erstelle - muss ich eh machen für die s7 bits.
Und die Performance ist auf einem RPI3 sehr schlecht - bei einem doif ist die Ausführungszeit <1sek, bei 100 doifs zwischen 3 und 5 sek.

Damian

Zitat von: hackepeter am 15 November 2019, 22:14:38
Und die Performance ist auf einem RPI3 sehr schlecht - bei einem doif ist die Ausführungszeit <1sek, bei 100 doifs zwischen 3 und 5 sek.

Das wundert mich aber, da bei einem passenden Trigger die anderen 99 "schlafen". Du kannst mit apptime messen, wo die Performance bleibt.

Wenn du schon generalisieren willst, dann würde ich das in DOIF-Perl machen, das ist noch mal performanter, da bei der Definition bereits alles in Perl übersetzt wird.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

hackepeter

#4
Zitat von: Damian am 15 November 2019, 22:45:00
Das wundert mich aber, da bei einem passenden Trigger die anderen 99 "schlafen". Du kannst mit apptime messen, wo die Performance bleibt.

Wenn du schon generalisieren willst, dann würde ich das in DOIF-Perl machen, das ist noch mal performanter, da bei der Definition bereits alles in Perl übersetzt wird.

Die Zeit werde ich noch messen.

Ich habe es jetzt entsprechend umgebaut:

{if (["Event*:on"]){
my $TriggerdeviceNr = substr($device, -3);;
my $ReceiverNr = ReadingsVal("Event$TriggerdeviceNr._Receiver","state","0");;
my $MailAddr = ReadingsVal("Receiver$ReceiverNr","1","bla\@bla.de");;
my $MsgSubject = ReadingsVal("Message$TriggerdeviceNr","1","0");;
my $MsgText = ReadingsVal("Message$TriggerdeviceNr","2","0");;
fhem_set("Event$TriggerdeviceNr off");;
{if ([?Event$TriggerdeviceNr._Type] eq "1"){::DebianMail($MailAddr,$MsgSubject,$MsgText,"/home/pi/Logo.jpg")}}
{if ([?Event$TriggerdeviceNr._Type] eq "2"){fhem_set("myTelegramBot message @#Testgroup $MsgSubject $MsgText")}}
}}

Allerdings funktioniert

{if ([?Event$TriggerdeviceNr._Type] eq "1")...

nicht:

condition c01: Can't locate object method "Event" via package "002" (perhaps you forgot to load "002"?), line 8.

Mir fällt gerade die passende Syntax nicht ein :(

Vorher war es:
{if ([?Event001_Type] eq "1")...

$TriggerdeviceNr = 001

amenomade

if (Value("Event".$TriggerdeviceNr."_Type") eq "1")
sollte gehen

Ob man an der Stelle [] nutzen kann, bin ich nicht sicher.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

hackepeter

Vielen Dank, es funktioniert!

Damian

#7
Zitat von: amenomade am 16 November 2019, 01:18:54
if (Value("Event".$TriggerdeviceNr."_Type") eq "1")
sollte gehen

Ob man an der Stelle [] nutzen kann, bin ich nicht sicher.

In [] gehen solche Dinge nicht.

Die letzten beiden if-Zeilen braucht man nicht unnötig in geschweifte Klammern setzen.

Das Performanceproblem der 100 DOIFs könnte durch die Triggerdefinition verursacht sein.

Bei allgemeinen Eventabfragen der Art: ["Event001:on"] greifen die FHEM-Filter nicht (NOTIFYDEV), jedes Event wird an DOIF durchgereicht und muss dort gefiltert werden und das bei 100 "gleichen" DOIFs.

Dagegen wird bei einer Definition [Event001:"on"]  nach triggerndem Device bereits in fhem.pl gefiltert, fremde Events kommen bei DOIF erst gar nicht an (Voraussetzung ist ein aktuelles DOIF).

Wenn du dagegen nur ein DOIF, statt hundert definierst, dann wird die allgemeine Eventtriggerdefinition ["Event*:on"]  (* solltest du weglassen) nicht sonderlich ins Gewicht fallen - ist ja nur einer, der etwas zu tun hat ;)

Nachtrag:

ReadingsVal("Event$TriggerdeviceNr._Receiver","state","0")

wird nicht gut funktionieren, du meinst wohl:

ReadingsVal("Event".$TriggerdeviceNr."_Receiver","state","0")
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF