neue Features: Generalisierung mit Templates

Begonnen von Damian, 16 Mai 2020, 18:16:51

Vorheriges Thema - Nächstes Thema

Damian

Es tritt immer wieder das Problem auf, dass man mehrere DOIFs definieren muss, die ähnlich aber nicht ähnlich genug sind, um sie über ein konventionelles DOIF zusammenzufassen.

Es gibt jetzt die Möglichkeit im DOIF-Perl-Modus eine Definition für mehrerer DOIFs vorzunehmen.

Anwendungsbeispiel:

Bisher habe ich für die Beschattung des Hauses mehrere DOIFs definieren müssen, weil bestimmte Parameter von Zimmer zu Zimmer, von Fenster zu Fenster unterschiedlich sind.

Bei mir fahren die Rollläden bei Sonneneinstrahlung nur einmal am Tag in Beschattungsposition. Mehr Automatisierung möchte ich beim Beschatten nicht haben. Vorweg: Natürlich lässt sich die untere Definition für mehr Automatisierung oder andere Anwendungen beliebig anpassen.

Das neue generalisierte DOIF sieht jetzt so aus:

defmod di_beschattung2 DOIF DEF TPL_shutter ( ## Definition des Templates namens TPL_shutter\
{  ## DOIF Block\
  if ([$2:measured-temp] > 24 and [$3] eq "on" and [$4-$5] and !$VAR{$1}) { ## Wenn die Zimmertemperatur über 24 und Sonne scheint innherhalb des Zeitfensters und das Fenster noch nicht heruntergefahren wurde\
    fhem_set("$6 $7");;  ## Fenster herunterfahren\
    $VAR{$1}=1;;         ## Merker setzen, dass Fenster bereits heruntergefahren wurde\
  }\
}\
) ## Ende der Templatedefinition\
\
{[00:01];;delete $VAR;;}    ## nachts alle Merker löschen\
\
## Definition einzelner DOIF-Blöcke mit Hilfe des Templates\
##          $1 $2        $3      $4    $5    $6    $7\
TPL_shutter (1,TH_Bad_HM,Sonne_s,12:00,21:00,R_Bad,30)\
TPL_shutter (2,TH_DG_HM,Sonne_s,12:00,21:00,R_DG,30)\
TPL_shutter (3,TH_Kueche_HM,Sonne_s,09:00,14:00,R_Kueche,50)\
TPL_shutter (4,TH_Kz_o_HM,Sonne_s,09:00,14:00,R_Kinderzimmer1_O,30)\
TPL_shutter (5,TH_Kz_o_HM,Sonne_s,12:00,21:00,R_Kinderzimmer1_S,25)\
TPL_shutter (6,TH_Kz_w_HM,Sonne_s,12:00,21:00,R_Kinderzimmer2_S,25)\
TPL_shutter (7,TH_Kz_w_HM,Sonne_w,15:30,21:00,R_Kinderzimmer2_W.*,25)\
TPL_shutter (8,TH_WZ_HM,Sonne_s,12:30,21:00,R_W_S,25)\
TPL_shutter (9,TH_WZ_HM,Sonne_w,15:30,21:00,R_W_W.*,25)\


Hier wird zunächst ein DOIF-Template namens "TPL_shutter" mit mehreren Platzhaltern für die Steuerungslogik erstellt. Danach wird pro Fenster/Fenstergruppe das Template mit unterschiedlichen Parametern (Temperatursensor im Zimmer, Sonneneinstrahlung, Zeiten, Rollladen, Position) aufgerufen. Auf diese Weise werden mehrere DOIF-Blöcke innerhalb des DOIFs definiert, die die Funktionalität mehrerer unabhängiger DOIFs haben. Auch bei Template-Nutzung wird die gesamte Definition vom Modul in Perl übersetzt, so dass zur Laufzeit reines Perl mit maximaler Performance abgearbeitet wird.

Mit der oberen Definition konnte ich 9 konventionelle DOIFs durch ein einziges ersetzen, was die Pflege bzw. Anpassungen der Steuerung erheblich vereinfacht.

Wenn man jetzt noch über das uiTable-Attribut, das übrigens schon lange das Template-Konzept nutzt, die dazugehörige Oberfläche im gleichen Modul definiert, so hat man Steuerung und Visualisierung an einer Stelle: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Visualisierung_und_Steuerung_von_Rolll.C3.A4den
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

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

Damian

#2
Hier mal ein weiteres Beispiel für eine Zeitschaltuhr zum Setzen von Zimmertemperaturen:

zuvor konventionell:

defmod di_Heizung DOIF ([05:00|8] or [05:30|7])\
  (set TH_Kueche_HM desired-temp 21,\
   set TH_Bad_HM desired-temp 22,\
   set TH_DG_HM desired-temp 21,\
   set TH_WZ_HM desired-temp 21,\
   set TH_Kz_w_HM desired-temp 21,\
   set TH_Kz_o_HM desired-temp 21)\
DOELSEIF ([08:00|8] or [09:00|7])\
   (set TH_Kueche_HM desired-temp 20,\
   set TH_Bad_HM desired-temp 20,\
   set TH_DG_HM desired-temp 20,\
   set TH_WZ_HM desired-temp 21,\
   set TH_Kz_w_HM desired-temp 20,\
   set TH_Kz_o_HM desired-temp 20)\
DOELSEIF ([12:00])\
   (set TH_Kueche_HM desired-temp 21,\
   set TH_Bad_HM desired-temp 20,\
   set TH_DG_HM desired-temp 21,\
   set TH_WZ_HM desired-temp 22,\
   set TH_Kz_w_HM desired-temp 21,\
   set TH_Kz_o_HM desired-temp 21)\
DOELSEIF ([20:00])\
    (set TH_Kueche_HM desired-temp 21,\
   set TH_Bad_HM desired-temp 20,\
   set TH_DG_HM desired-temp 20,\
   set TH_WZ_HM desired-temp 20,\
   set TH_Kz_w_HM desired-temp 20,\
   set TH_Kz_o_HM desired-temp 20)\


jetzt mit Templates:

defmod di_Heizung_neu DOIF DEF TPL_set_temp ( ## Template zum Setzen der Zimmertemperaturen\
{$1;;   ## Zeitangabe\
fhem_set"TH_Kueche_HM desired-temp $2";;\
fhem_set"TH_Bad_HM desired-temp $3";;\
fhem_set"TH_DG_HM desired-temp $4";;\
fhem_set"TH_WZ_HM desired-temp $5";;\
fhem_set"TH_Kz_o_HM desired-temp $6";;\
fhem_set"TH_Kz_w_HM desired-temp $7";;\
}\
)\
##            Zeit      Ku,Ba,DG,WZ,Ko,Kw\
TPL_set_temp ([05:00|8] or [05:30|7],21,22,21,22,21,21)\
TPL_set_temp ([08:00|8] or [09:00|7],20,20,20,21,20,20)\
TPL_set_temp ([12:00],               21,20,21,22,21,21)\
TPL_set_temp ([20:00],               21,20,20,20,20,20)


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

moonsorrox

Hallo Damian, dass ist eine Super tolle Sache mit der Beschattung, ich setze sie momentan auch mit diversen DOIFs um und habe natürlich dadurch jede Menge DOIFs am Start.
Ich werde mir das mal anschauen, obwohl ich Perl als Feind habe  ;) was nicht heißen soll das ich mich damit nicht beschäftige, aber lernen wollte ich es jetzt nicht, weil es mir nicht liegt.
Mal schauen ob ich es schaffe das mal umzusetzen und es dann praktisch auch einsetze...
Intel-NUC i5: FHEM-Server 6.1 :: Perl v5.18.2

Homematic: HM-USB-CFG2,HM-CFG-LAN Adapter, HM-LC-BL1-FM, HM-LC-Sw1PBU-FM, HM-LC-Sw1-PI-2, HM-WDS10-TH-O, HM-CC-TC, HM-LC-SW2-FM

Damian

Zitat von: moonsorrox am 25 Mai 2020, 18:23:16
Hallo Damian, dass ist eine Super tolle Sache mit der Beschattung, ich setze sie momentan auch mit diversen DOIFs um und habe natürlich dadurch jede Menge DOIFs am Start.
Ich werde mir das mal anschauen, obwohl ich Perl als Feind habe  ;) was nicht heißen soll das ich mich damit nicht beschäftige, aber lernen wollte ich es jetzt nicht, weil es mir nicht liegt.
Mal schauen ob ich es schaffe das mal umzusetzen und es dann praktisch auch einsetze...

Die erforderlichen Perl-Kenntnisse halten sich in Grenzen. Hier ist fast schon mehr DOIF-Kenntnis von Nutzen.

Ich versuche bei mir die restlichen DOIFs zu generalisieren. Im Beschattungsmodul kann man auch das morgendliche Hochfahren und das abendliche Runterfahren der Rollläden unterbringen. Jetzt muss ich noch die  Lichtsteuerung in ein DOIF stecken, dann ist meine Haus-Automatisierung mit wenigen DOIFs abgedeckt ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

moonsorrox

Ok, ich habe es mir angeschaut, ist trotzdem kompliziert.
Ich stelle es gerne auch mit einem Dummy um... entweder steuert es Fhem oder ich stelle es auf Beschattung, oder komplett aus, bei einigen habe ich noch eine Weihnachten Option.
Morgens fahre ich zu flexibel einstellbaren Zeiten die Rollläden hoch, soll heißen entweder 7.45, 8 Uhr oder 8.15 usw. und abends immer zu Astro Civil, ist das mit dem DOIF so möglich...?
Intel-NUC i5: FHEM-Server 6.1 :: Perl v5.18.2

Homematic: HM-USB-CFG2,HM-CFG-LAN Adapter, HM-LC-BL1-FM, HM-LC-Sw1PBU-FM, HM-LC-Sw1-PI-2, HM-WDS10-TH-O, HM-CC-TC, HM-LC-SW2-FM

Damian

Zitat von: moonsorrox am 25 Mai 2020, 22:21:22
Ok, ich habe es mir angeschaut, ist trotzdem kompliziert.
Ich stelle es gerne auch mit einem Dummy um... entweder steuert es Fhem oder ich stelle es auf Beschattung, oder komplett aus, bei einigen habe ich noch eine Weihnachten Option.
Morgens fahre ich zu flexibel einstellbaren Zeiten die Rollläden hoch, soll heißen entweder 7.45, 8 Uhr oder 8.15 usw. und abends immer zu Astro Civil, ist das mit dem DOIF so möglich...?
Natürlich geht das :)
In einem Perl-DOIF könntest du im Prinzip dein ganzes FHEM unterbringen, weil dort im Gegensatz zum FHEM-Modus keine Abhängigkeiten der Blöcke existieren. Ob das allerdings sinnvoll wäre, ist eine andere Frage. Es kann ebenso übersichtlicher sein, Steuerungen, die wenig Gemeinsamkeiten haben, in einzelnen DOIFs zu belassen.

Ich würde damit anfangen ähnlich aufgebaute DOIFs zu generalisieren, wie in meinem Beschattungsbeispiel, dort ist die Steuerung durch eine if-Zeile abgedeckt, der Rest sind im Wesentlichen fenster- und zimmerabhängige Parameter. Wenn das läuft, kann man versuchen es zu erweitern, wenn es sinnvoll erscheint, aber das muss man im Einzelfall sehen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Man kann in der kommenden DOIF-Version im Perl-Modus, wie im FHEM-Modus, einzelne Blöcke manuell per set-Befehl ausführen. Das erleichtert das Überprüfen einer neuen Definition.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

eddy242

#8
Hallo Damian,

kannst Du Dir bitte mal diesen kurzen Code anschauen. Ich habe 2 Fragen. 1) der else-Block wird pro Template Line aufgelöst, richtig? Ich könnte den Code eigentlich mit dem ?: Operator noch kürzer machen, das würde die Dopplung von Reading-Update ersparen. und 2), wie würde ich die wait- und die homebridgemappings aus dem Original-Code umsetzen (wenn letzteres überhaupt geht, das müssten ja eigentlich für Homebridge separate Geräte sein)? Vielleicht könntest Du bitte auch noch einen Hinweis geben wie die Integration mit uiTable genau geht. Würde ich im Ausführungsteil Modulvariablen setzen und im uiTable-Teil auslesen oder die eigenen Readings lesen? Danke!

vorher

defmod DOIF_Sonne_W DOIF (\
  ([Sensor_Eltako_West:brightness:d] < 27000) and\
  ([DOIF_IstEsEineHitzeWelle:state] eq "off")\
)(\
setreading $SELF Sonnenschutz GanzAuf\
) DOELSE (\
setreading $SELF Sonnenschutz [DOIF_IstEsEineHitzeWelle:Besch_Position]\
)
attr DOIF_Sonne_W DbLogExclude .*
attr DOIF_Sonne_W DbLogInclude cmd
attr DOIF_Sonne_W alias Sonnenschutz: West?
attr DOIF_Sonne_W cmdState off|on
attr DOIF_Sonne_W devStateIcon on:weather_sun@yellow off|initialized:weather_sun@grey
attr DOIF_Sonne_W genericDeviceType ContactSensor
attr DOIF_Sonne_W group Sonne,KeyStatusInfo
attr DOIF_Sonne_W homebridgeMapping clear \
ContactSensorState=state,values=off:CONTACT_DETECTED;;on:CONTACT_NOT_DETECTED \
history:size=1024
attr DOIF_Sonne_W icon weather_sun
attr DOIF_Sonne_W room ControlCenter,Tagesablauf,Homekit
attr DOIF_Sonne_W wait 900:900

nachher

defmod DOIF_TEST_Sonne DOIF DEF TPL_Sonne (\
{\
  if (([$2:brightness:d] < $3) and ([DOIF_IstEsEineHitzeWelle:state] eq "off")) {\
  set_Reading_Begin;;\
  set_Reading_Update("$4_Sonne", "off");;\
  set_Reading_Update("$4_Beschattungsposition", "GanzAuf");;\
  set_Reading_End(1);;\
  set_State("Last Change: $4 Sonne weg");;\
  } else {\
  set_Reading_Begin;;\
  set_Reading_Update("$4_Sonne", "on");;\
  set_Reading_Update("$4_Beschattungsposition", [DOIF_IstEsEineHitzeWelle:Besch_Position]);;\
  set_Reading_End(1);;\
  set_State("Last Change: $4 Sonne da");;\
  }\
}\
) ## Ende der Templatedefinition\
\
\
## Definition einzelner DOIF-Blöcke mit Hilfe des Templates\
##               $1 $2               $3     $4\
TPL_Sonne (1,Sensor_Eltako_Ost,27000,Ost)\
TPL_Sonne (2,Sensor_Eltako_West,27000,West)\
TPL_Sonne (3,Sensor_Eltako_Sued,27000,Süd)\

attr DOIF_TEST_Sonne DbLogExclude .*

setstate DOIF_TEST_Sonne 2020-06-01 07:56:57 mode enabled


Damian

1. ? geht nicht, da es keine Variablenzuweisung ist, sondern das Setzen von Readings mit einer Funktion (set_Reading)
2. wait gibt es im Perl-Modus nicht, stattdessen set_Exec ("Timer1",Sekunden,"Auszuführender Befehl") verwenden, siehe: https://fhem.de/commandref_DE.html#DOIF_set_Exec
3. uiTable arbeitet nicht mit Modulvariablen, sondern mit Readings (hier kann man $SELF für eigene Readings verwenden), zu uiTable gibt es sehr viele Beispiele: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg

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

Damian

Zitat von: Damian am 27 Mai 2020, 23:04:54
Man kann in der kommenden DOIF-Version im Perl-Modus, wie im FHEM-Modus, einzelne Blöcke manuell per set-Befehl ausführen. Das erleichtert das Überprüfen einer neuen Definition.

neue Version wurde eingecheckt
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

eddy242

Hallo zusammen,

ich habe mein Beispiel weiterentwickelt und laufe auf ein Problem. Ich bekomme folgenden Fehler:

error         in readingsupdate("SüdWest","on",5): Undefined subroutine &DOIF::readingsupdate called at (eval 7703032) line 1.             2020-06-18 10:56:04


Habe ich die subs an der falschen Stelle? Ich hatte auch diese Variante ausprobiert, hat aber den gleichen Fehler gegeben.

set_Exec("$1_$2_timer_Sonne_aus",60,'$SELF::readingsupdate("$2","off",$1)');



Internals:
   DEF        subs {
  sub readingsupdate {
    my ($Richtung,$OnOff,$indexer) = @_;
set_Reading_Begin;
set_Reading_Update("$Richtung_Sonne", $OnOff);
set_Reading_Update("$Richtung_Beschattungsposition", ($OnOff eq "on" ? [DOIF_IstEsEineHitzeWelle:Besch_Position] : "GanzAuf"));
set_Reading_End(1);
set_State("Last Change: $Richtung Sonne $OnOff");
$VAR{$indexer} = ($OnOff eq "on" ? 1 : 0);
  }
}

DEF TPL_Sonne (
{
  if (
  ([$3:brightness:d] < $4) and
  ([$5:brightness:d] < $6) and
([DOIF_IstEsEineHitzeWelle:state] eq "off")
  ) {
    ## hier ist der Threshold unterschritten, also Sonne AUS
## wenn die Sonne noch an ist dann ist $VAR{$1} == 1 - sonst müssten wir keinen Timer starten
## Wenn wir schon einen Timer haben, starten wir natürlich keinen neuen
if ($VAR{$1} and (get_Exec("$1_$2_timer_Sonne_aus") == 0)) {
  set_Exec("$1_$2_timer_Sonne_aus",60,'readingsupdate("$2","off",$1)');
  fhem("setreading $SELF DEBUG_$1_$2_timer_Sonne_aus started");
}
## Allerdings müssen wir dann auch den eventuell laufenden Timer "Sonne an" löschen
if (get_Exec("$1_$2_timer_Sonne_an") > 0) {
  del_Exec("$1_$2_timer_Sonne_an");
  fhem("setreading $SELF DEBUG_$1_$2_timer_Sonne_an deleted");
}
  } else {
    ## hier ist der Threshold überschritten, also Sonne AN
## wenn die Sonne noch aus ist dann ist $VAR{$1} == 0 - sonst müssten wir keinen Timer starten
## Wenn wir schon einen Timer haben, starten wir natürlich keinen neuen
if (!$VAR{$1} and (get_Exec("$1_$2_timer_Sonne_an") == 0)) {
  set_Exec("$1_$2_timer_Sonne_an",60,'readingsupdate("$2","on",$1)');
  fhem("setreading $SELF DEBUG_$1_$2_timer_Sonne_an started");
}
## Allerdings müssen wir dann auch den eventuell laufenden Timer "Sonne aus" löschen
if (get_Exec("$1_$2_timer_Sonne_aus") > 0) {
  del_Exec("$1_$2_timer_Sonne_aus");
  fhem("setreading $SELF DEBUG_$1_$2_timer_Sonne_aus deleted");
}
  }
}
) ## Ende der Templatedefinition


## Definition einzelner DOIF-Blöcke mit Hilfe des Templates
##         $1  $2        $3             $4             $5             $6
##         Nr, Richtung, Sensor1Device, Sensor1Thresh, Sensor2Device, Sensor2Thresh
TPL_Sonne (1,Ost,Sensor_Eltako_Ost,27000,Sensor_Eltako_Ost,27000)
TPL_Sonne (2,West,Sensor_Eltako_West,27000,Sensor_Eltako_West,27000)
TPL_Sonne (3,Süd,Sensor_Eltako_Sued,27000,Sensor_Eltako_Sued,27000)
TPL_Sonne (4,SüdOst,Sensor_Eltako_Sued,25000,Sensor_Eltako_Ost,15000)
TPL_Sonne (5,SüdWest,Sensor_Eltako_Sued,27000,Sensor_Eltako_West,15000)

   FUUID      5ed49803-f33f-0759-b909-b7f02681c0e751b7
   MODEL      Perl
   NAME       DOIF_TEST_Sonne
   NOTIFYDEV  global,Sensor_Eltako_Sued,Sensor_Eltako_Ost,DOIF_IstEsEineHitzeWelle,Sensor_Eltako_West
   NR         534
   NTFY_ORDER 50-DOIF_TEST_Sonne
   STATE      Last Change: Ost Sonne weg
   TYPE       DOIF
   VERSION    22161 2020-06-11 12:49:48
   OLDREADINGS:
   READINGS:
     2020-06-18 10:53:19   DEBUG_1_Ost_timer_Sonne_an started
     2020-06-18 10:55:04   Device          Sensor_Eltako_West
     2020-06-17 22:07:04   Ost_Beschattungsposition GanzAuf
     2020-06-17 22:07:04   Ost_Sonne       off
     2020-06-17 22:06:13   Süd_Beschattungsposition GanzAuf
     2020-06-17 22:06:13   Süd_Sonne      off
     2020-06-17 22:05:19   West_Beschattungsposition GanzAuf
     2020-06-17 22:05:19   West_Sonne      off
     2020-06-18 10:53:19   block_01        executed
     2020-06-18 10:55:04   block_02        executed
     2020-06-18 10:53:21   block_03        executed
     2020-06-18 10:53:21   block_04        executed
     2020-06-18 10:55:04   block_05        executed
     2020-06-18 10:53:19   e_Sensor_Eltako_Ost_brightness 30002
     2020-06-18 10:53:21   e_Sensor_Eltako_Sued_brightness 30002
     2020-06-18 10:55:04   e_Sensor_Eltako_West_brightness 14976
     2020-06-18 10:56:04   error           in readingsupdate("SüdWest","on",5): Undefined subroutine &DOIF::readingsupdate called at (eval 7703032) line 1.

     2020-06-18 10:51:39   mode            enabled
     2020-06-17 22:07:04   state           Last Change: Ost Sonne weg
   Regex:
     accu:
     cond:
       DOIF_IstEsEineHitzeWelle:
         0:
           state      ^DOIF_IstEsEineHitzeWelle$:^state:
         1:
           state      ^DOIF_IstEsEineHitzeWelle$:^state:
         2:
           state      ^DOIF_IstEsEineHitzeWelle$:^state:
         3:
           state      ^DOIF_IstEsEineHitzeWelle$:^state:
         4:
           state      ^DOIF_IstEsEineHitzeWelle$:^state:
       Sensor_Eltako_Ost:
         0:
           brightness ^Sensor_Eltako_Ost$:^brightness:
         1:
         2:
         3:
           brightness ^Sensor_Eltako_Ost$:^brightness:
         4:
       Sensor_Eltako_Sued:
         0:
         1:
         2:
           brightness ^Sensor_Eltako_Sued$:^brightness:
         3:
           brightness ^Sensor_Eltako_Sued$:^brightness:
         4:
           brightness ^Sensor_Eltako_Sued$:^brightness:
       Sensor_Eltako_West:
         0:
         1:
           brightness ^Sensor_Eltako_West$:^brightness:
         2:
         3:
         4:
           brightness ^Sensor_Eltako_West$:^brightness:
   condition:
     0         
  if (
  (::ReadingValDoIf($hash,'Sensor_Eltako_Ost','brightness','','d') < 27000) and
  (::ReadingValDoIf($hash,'Sensor_Eltako_Ost','brightness','','d') < 27000) and
(::ReadingValDoIf($hash,'DOIF_IstEsEineHitzeWelle','state') eq "off")
  ) {
      if ($hash->{var}{1} and (get_Exec("1_Ost_timer_Sonne_aus") == 0)) {
  set_Exec("1_Ost_timer_Sonne_aus",60,'readingsupdate("Ost","off",1)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_1_Ost_timer_Sonne_aus started");
}
if (get_Exec("1_Ost_timer_Sonne_an") > 0) {
  del_Exec("1_Ost_timer_Sonne_an");
  fhem("setreading DOIF_TEST_Sonne DEBUG_1_Ost_timer_Sonne_an deleted");
}
  } else {
      if (!$hash->{var}{1} and (get_Exec("1_Ost_timer_Sonne_an") == 0)) {
  set_Exec("1_Ost_timer_Sonne_an",60,'readingsupdate("Ost","on",1)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_1_Ost_timer_Sonne_an started");
}
if (get_Exec("1_Ost_timer_Sonne_aus") > 0) {
  del_Exec("1_Ost_timer_Sonne_aus");
  fhem("setreading DOIF_TEST_Sonne DEBUG_1_Ost_timer_Sonne_aus deleted");
}
  }

     1         
  if (
  (::ReadingValDoIf($hash,'Sensor_Eltako_West','brightness','','d') < 27000) and
  (::ReadingValDoIf($hash,'Sensor_Eltako_West','brightness','','d') < 27000) and
(::ReadingValDoIf($hash,'DOIF_IstEsEineHitzeWelle','state') eq "off")
  ) {
      if ($hash->{var}{2} and (get_Exec("2_West_timer_Sonne_aus") == 0)) {
  set_Exec("2_West_timer_Sonne_aus",60,'readingsupdate("West","off",2)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_2_West_timer_Sonne_aus started");
}
if (get_Exec("2_West_timer_Sonne_an") > 0) {
  del_Exec("2_West_timer_Sonne_an");
  fhem("setreading DOIF_TEST_Sonne DEBUG_2_West_timer_Sonne_an deleted");
}
  } else {
      if (!$hash->{var}{2} and (get_Exec("2_West_timer_Sonne_an") == 0)) {
  set_Exec("2_West_timer_Sonne_an",60,'readingsupdate("West","on",2)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_2_West_timer_Sonne_an started");
}
if (get_Exec("2_West_timer_Sonne_aus") > 0) {
  del_Exec("2_West_timer_Sonne_aus");
  fhem("setreading DOIF_TEST_Sonne DEBUG_2_West_timer_Sonne_aus deleted");
}
  }

     2         
  if (
  (::ReadingValDoIf($hash,'Sensor_Eltako_Sued','brightness','','d') < 27000) and
  (::ReadingValDoIf($hash,'Sensor_Eltako_Sued','brightness','','d') < 27000) and
(::ReadingValDoIf($hash,'DOIF_IstEsEineHitzeWelle','state') eq "off")
  ) {
      if ($hash->{var}{3} and (get_Exec("3_Süd_timer_Sonne_aus") == 0)) {
  set_Exec("3_Süd_timer_Sonne_aus",60,'readingsupdate("Süd","off",3)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_3_Süd_timer_Sonne_aus started");
}
if (get_Exec("3_Süd_timer_Sonne_an") > 0) {
  del_Exec("3_Süd_timer_Sonne_an");
  fhem("setreading DOIF_TEST_Sonne DEBUG_3_Süd_timer_Sonne_an deleted");
}
  } else {
      if (!$hash->{var}{3} and (get_Exec("3_Süd_timer_Sonne_an") == 0)) {
  set_Exec("3_Süd_timer_Sonne_an",60,'readingsupdate("Süd","on",3)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_3_Süd_timer_Sonne_an started");
}
if (get_Exec("3_Süd_timer_Sonne_aus") > 0) {
  del_Exec("3_Süd_timer_Sonne_aus");
  fhem("setreading DOIF_TEST_Sonne DEBUG_3_Süd_timer_Sonne_aus deleted");
}
  }

     3         
  if (
  (::ReadingValDoIf($hash,'Sensor_Eltako_Sued','brightness','','d') < 25000) and
  (::ReadingValDoIf($hash,'Sensor_Eltako_Ost','brightness','','d') < 15000) and
(::ReadingValDoIf($hash,'DOIF_IstEsEineHitzeWelle','state') eq "off")
  ) {
      if ($hash->{var}{4} and (get_Exec("4_SüdOst_timer_Sonne_aus") == 0)) {
  set_Exec("4_SüdOst_timer_Sonne_aus",60,'readingsupdate("SüdOst","off",4)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_4_SüdOst_timer_Sonne_aus started");
}
if (get_Exec("4_SüdOst_timer_Sonne_an") > 0) {
  del_Exec("4_SüdOst_timer_Sonne_an");
  fhem("setreading DOIF_TEST_Sonne DEBUG_4_SüdOst_timer_Sonne_an deleted");
}
  } else {
      if (!$hash->{var}{4} and (get_Exec("4_SüdOst_timer_Sonne_an") == 0)) {
  set_Exec("4_SüdOst_timer_Sonne_an",60,'readingsupdate("SüdOst","on",4)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_4_SüdOst_timer_Sonne_an started");
}
if (get_Exec("4_SüdOst_timer_Sonne_aus") > 0) {
  del_Exec("4_SüdOst_timer_Sonne_aus");
  fhem("setreading DOIF_TEST_Sonne DEBUG_4_SüdOst_timer_Sonne_aus deleted");
}
  }

     4         
  if (
  (::ReadingValDoIf($hash,'Sensor_Eltako_Sued','brightness','','d') < 27000) and
  (::ReadingValDoIf($hash,'Sensor_Eltako_West','brightness','','d') < 15000) and
(::ReadingValDoIf($hash,'DOIF_IstEsEineHitzeWelle','state') eq "off")
  ) {
      if ($hash->{var}{5} and (get_Exec("5_SüdWest_timer_Sonne_aus") == 0)) {
  set_Exec("5_SüdWest_timer_Sonne_aus",60,'readingsupdate("SüdWest","off",5)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_5_SüdWest_timer_Sonne_aus started");
}
if (get_Exec("5_SüdWest_timer_Sonne_an") > 0) {
  del_Exec("5_SüdWest_timer_Sonne_an");
  fhem("setreading DOIF_TEST_Sonne DEBUG_5_SüdWest_timer_Sonne_an deleted");
}
  } else {
      if (!$hash->{var}{5} and (get_Exec("5_SüdWest_timer_Sonne_an") == 0)) {
  set_Exec("5_SüdWest_timer_Sonne_an",60,'readingsupdate("SüdWest","on",5)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_5_SüdWest_timer_Sonne_an started");
}
if (get_Exec("5_SüdWest_timer_Sonne_aus") > 0) {
  del_Exec("5_SüdWest_timer_Sonne_aus");
  fhem("setreading DOIF_TEST_Sonne DEBUG_5_SüdWest_timer_Sonne_aus deleted");
}
  }

   defs:
     tpl:
       TPL_Sonne 
{
  if (
  ([$3:brightness:d] < $4) and
  ([$5:brightness:d] < $6) and
([DOIF_IstEsEineHitzeWelle:state] eq "off")
  ) {
      if ($VAR{$1} and (get_Exec("$1_$2_timer_Sonne_aus") == 0)) {
  set_Exec("$1_$2_timer_Sonne_aus",60,'readingsupdate("$2","off",$1)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_$1_$2_timer_Sonne_aus started");
}
if (get_Exec("$1_$2_timer_Sonne_an") > 0) {
  del_Exec("$1_$2_timer_Sonne_an");
  fhem("setreading DOIF_TEST_Sonne DEBUG_$1_$2_timer_Sonne_an deleted");
}
  } else {
      if (!$VAR{$1} and (get_Exec("$1_$2_timer_Sonne_an") == 0)) {
  set_Exec("$1_$2_timer_Sonne_an",60,'readingsupdate("$2","on",$1)');
  fhem("setreading DOIF_TEST_Sonne DEBUG_$1_$2_timer_Sonne_an started");
}
if (get_Exec("$1_$2_timer_Sonne_aus") > 0) {
  del_Exec("$1_$2_timer_Sonne_aus");
  fhem("setreading DOIF_TEST_Sonne DEBUG_$1_$2_timer_Sonne_aus deleted");
}
  }
}

   helper:
     DEVFILTER  ^global$|^DOIF_IstEsEineHitzeWelle$|^Sensor_Eltako_Ost$|^Sensor_Eltako_Sued$|^Sensor_Eltako_West$
     NOTIFYDEV  global|DOIF_IstEsEineHitzeWelle|Sensor_Eltako_Ost|Sensor_Eltako_Sued|Sensor_Eltako_West
     event      brightness: 14976,14976,luminance: 14976 Lux
     globalinit 1
     last_timer 0
     sleeptimer -1
     triggerDev Sensor_Eltako_West
     triggerEvents:
       brightness: 14976
       14976
       luminance: 14976 Lux
     triggerEventsState:
       brightness: 14976
       state: 14976
       luminance: 14976 Lux
   internals:
   perlblock:
     0          block_01
     1          block_02
     2          block_03
     3          block_04
     4          block_05
   ptimer:
     1_Ost_timer_Sonne_an:
       name       1_Ost_timer_Sonne_an
       subname    readingsupdate("Ost","on",1)
       time       1592470459.65157
       hash:
     1_Ost_timer_Sonne_aus:
     2_West_timer_Sonne_an:
     3_Süd_timer_Sonne_an:
       name       3_Süd_timer_Sonne_an
       subname    readingsupdate("Süd","on",3)
       time       1592470461.8714
       hash:
     3_Süd_timer_Sonne_aus:
     4_SüdOst_timer_Sonne_an:
       name       4_SüdOst_timer_Sonne_an
       subname    readingsupdate("SüdOst","on",4)
       time       1592470441.68786
       hash:
     4_SüdOst_timer_Sonne_aus:
     5_SüdWest_timer_Sonne_an:
       name       5_SüdWest_timer_Sonne_an
       subname    readingsupdate("SüdWest","on",5)
       time       1592470564.87365
       hash:
     5_SüdWest_timer_Sonne_aus:
   readings:
     all         Sensor_Eltako_Ost:brightness DOIF_IstEsEineHitzeWelle:state Sensor_Eltako_West:brightness Sensor_Eltako_Sued:brightness
   trigger:
   uiTable:
     package    package ui_Table;
     shownostate 1
     table:
       0:
         0:
           0:
             0          package ui_Table;"Richtung"
         1:
           0:
             0          package ui_Table;"Sonne"
         2:
           0:
             0          package ui_Table;""
         3:
           0:
             0          package ui_Table;"Beschattungsposition"
         4:
           0:
             0          package ui_Table;"Letzte Änderung"
       1:
         0:
           0:
             0          package ui_Table; "Ost"
         1:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "Ost_Sonne", "")
         2:
           0:
             0          package ui_Table; ICON("weather_sun\@".(::ReadingsVal("DOIF_TEST_Sonne", "Ost_Sonne", "") eq "on" ? "yellow" : "grey"))
         3:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "Ost_Beschattungsposition", "")
         4:
           0:
             0          package ui_Table; ::ReadingsTimestamp("DOIF_TEST_Sonne", "Ost_Sonne", "")
       2:
         0:
           0:
             0          package ui_Table; "West"
         1:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "West_Sonne", "")
         2:
           0:
             0          package ui_Table; ICON("weather_sun\@".(::ReadingsVal("DOIF_TEST_Sonne", "West_Sonne", "") eq "on" ? "yellow" : "grey"))
         3:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "West_Beschattungsposition", "")
         4:
           0:
             0          package ui_Table; ::ReadingsTimestamp("DOIF_TEST_Sonne", "West_Sonne", "")
       3:
         0:
           0:
             0          package ui_Table; "Süd"
         1:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "Süd_Sonne", "")
         2:
           0:
             0          package ui_Table; ICON("weather_sun\@".(::ReadingsVal("DOIF_TEST_Sonne", "Süd_Sonne", "") eq "on" ? "yellow" : "grey"))
         3:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "Süd_Beschattungsposition", "")
         4:
           0:
             0          package ui_Table; ::ReadingsTimestamp("DOIF_TEST_Sonne", "Süd_Sonne", "")
       4:
         0:
           0:
             0          package ui_Table; "SüdOst"
         1:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "SüdOst_Sonne", "")
         2:
           0:
             0          package ui_Table; ICON("weather_sun\@".(::ReadingsVal("DOIF_TEST_Sonne", "SüdOst_Sonne", "") eq "on" ? "yellow" : "grey"))
         3:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "SüdOst_Beschattungsposition", "")
         4:
           0:
             0          package ui_Table; ::ReadingsTimestamp("DOIF_TEST_Sonne", "SüdOst_Sonne", "")
       5:
         0:
           0:
             0          package ui_Table; "SüdWest"
         1:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "SüdWest_Sonne", "")
         2:
           0:
             0          package ui_Table; ICON("weather_sun\@".(::ReadingsVal("DOIF_TEST_Sonne", "SüdWest_Sonne", "") eq "on" ? "yellow" : "grey"))
         3:
           0:
             0          package ui_Table; ::ReadingsVal("DOIF_TEST_Sonne", "SüdWest_Beschattungsposition", "")
         4:
           0:
             0          package ui_Table; ::ReadingsTimestamp("DOIF_TEST_Sonne", "SüdWest_Sonne", "")
     tc:
       0          style='font-size: large'
       1          style='font-size: large'
       2          style='font-size: large'
       3          style='font-size: large'
       4          style='font-size: large'
     td:
       0:
       1:
       2:
       3:
       4:
       5:
     tpl:
       TPL_line   
"$1"| ::ReadingsVal("DOIF_TEST_Sonne", "$1_Sonne", "")| ICON("weather_sun\@".(::ReadingsVal("DOIF_TEST_Sonne", "$1_Sonne", "") eq "on" ? "yellow" : "grey"))| ::ReadingsVal("DOIF_TEST_Sonne", "$1_Beschattungsposition", "")| ::ReadingsTimestamp("DOIF_TEST_Sonne", "$1_Sonne", "")

     tr:
   var:
Attributes:
   DbLogExclude .*
   uiTable    {
package ui_Table;           ## Package für uiTable-Funktionen
$TC{0..4} = "style='font-size: large'";

## Ausblenden des Status in der Statuszeile
$SHOWNOSTATE=1;
}

DEF TPL_line (
"$1"|
::ReadingsVal("$SELF", "$1_Sonne", "")|
ICON("weather_sun\@".(::ReadingsVal("$SELF", "$1_Sonne", "") eq "on" ? "yellow" : "grey"))|
::ReadingsVal("$SELF", "$1_Beschattungsposition", "")|
::ReadingsTimestamp("$SELF", "$1_Sonne", "")
)

"Richtung"|"Sonne"|""|"Beschattungsposition"|"Letzte Änderung"
TPL_line (Ost)
TPL_line (West)
TPL_line (Süd)
TPL_line (SüdOst)
TPL_line (SüdWest)

Damian

#12
Template-Definitionen müssen als erstes kommen und dann der Rest.

d. h. hier konkret: den subs-Block einfach hinter DEF TPL_Sonne verschieben.

Dann fallen dir weitere Fehler auf zu: $Richtung_Sonne, $Richtung_Beschattungsposition und [DOIF_IstEsEineHitzeWelle:Besch_Position]

DOIF-Syntax ist im subs-Block nicht erlaubt, d. h. [DOIF_IstEsEineHitzeWelle:Besch_Position] durch ReadingsVal ersetzen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

münster

Hallo Damian,

danke für das Modul. Ich bin gerade dabei, meine DOIF Wecker mit Hilfe von Templates zu generalisieren. Leider kann ich nur auf die ersten 9 Parameter zugreifen: $10 wird als $1 0 interpretiert. Gibt es einen Trick, wie ich auf $10 und höher zugreifen kann?

Vielen Dank

münster

Damian

#14
Zitat von: münster am 18 Juni 2020, 15:33:51
Hallo Damian,

danke für das Modul. Ich bin gerade dabei, meine DOIF Wecker mit Hilfe von Templates zu generalisieren. Leider kann ich nur auf die ersten 9 Parameter zugreifen: $10 wird als $1 0 interpretiert. Gibt es einen Trick, wie ich auf $10 und höher zugreifen kann?

Vielen Dank

münster

Wer braucht denn schon mehr als neun Parameter  :o

Neue Version hochgeladen  ;D
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF