Hauptmenü

Funktionsaufrufe im DEF-Block?

Begonnen von gestein, 18 Februar 2022, 13:05:03

Vorheriges Thema - Nächstes Thema

gestein

Hallo,

ich bräuchte bei meinem Projekt noch bitte ein paar Schubser in die richtige Richtung.

Soweit scheint mein DOIF zur Berechnung des Stromverbrauchs schon mal zu funktionieren.
Momentan noch sehr rudimentär mit etlichen Baustellen:
defmod di_counter DOIF DEF TPL_stat (midnight_$1_$2 { [00:00:05];;\
  set_Reading("$1_$2_counter",[?$1:$2]);;\
  set_Reading("$1_$2_last_day",get_Reading("$1_$2_day",0),1);;\
  set_Reading("$1_$2_day",0,1);;\
  set_Reading("$1_$2_month",get_Reading("$1_$2_month",0)+get_Reading("$1_$2_last_day",0),1);;\
  if ($mday == 1) {\
    set_Reading("$1_$2_last_month",get_Reading("$1_$2_month",0),1);;\
    set_Reading("$1_$2_month",0,1);;\
    set_Reading("$1_$2_year",get_Reading("$1_$2_year",0)+get_Reading("$1_$2_last_month",0),1);;\
  }\
  if ($yday == 1) {\
    set_Reading("$1_$2_last_year",get_Reading("$1_$2_year",0),1);;\
    set_Reading("$1_$2_year",0,1);;\
  }\
}\
\
hour_$1_$2 { [:00];;\
  set_Reading("$1_$2_hour_counter",[?$1:$2]);;\
  set_Reading("$1_$2_last_hour",get_Reading("$1_$2_hour",0),1);;\
  set_Reading("$1_$2_hour",0);;\
}\
\
quarter_$1_$2 { [+:15];;\
  set_Reading("$1_$2_quarter_counter",[?$1:$2]);;\
  set_Reading("$1_$2_last_quarter",get_Reading("$1_$2_quarter",0),1);;\
  set_Reading("$1_$2_quarter",0);;\
}\
\
update_counters_$1_$2 {\
##  Log 1, "update_counters_$1_$2: [?$1:$2];;".get_Reading("$1_$2_counter",0).";;".get_Reading("$1_$2_hour_counter",0).";;".get_Reading("$1_$2_quarter_counter",0);;\
  set_Reading("$1_$2_day",int(([$1:$2,0]-get_Reading("$1_$2_counter",0))*1000)/1000,1);;\
  set_Reading("$1_$2_hour",int(([$1:$2,0]-get_Reading("$1_$2_hour_counter",0))),1);;\
  set_Reading("$1_$2_quarter",int(([$1:$2,0]-get_Reading("$1_$2_quarter_counter",0))),1);;\
}\
\
init_$1_$2 {\
  if (!get_Reading("$1_$2_counter","")) {\
    set_Reading("$1_$2_quarter_counter",[?$1:$2]);;\
set_Reading("$1_$2_hour_counter",[?$1:$2]);;\
    set_Reading("$1_$2_counter",[?$1:$2]);;\
set_Reading ("$1_$2_quarter",0);;\
set_Reading ("$1_$2_hour",0);;\
    set_Reading ("$1_$2_day",0);;\
    set_Reading ("$1_$2_month",0);;\
    set_Reading ("$1_$2_year",0);;\
set_Reading ("$1_$2_last_quarter",0);;\
set_Reading ("$1_$2_last_hour",0);;\
set_Reading ("$1_$2_last_day",0);;\
    set_Reading ("$1_$2_last_month",0);;\
    set_Reading ("$1_$2_last_year",0);;\
set_Reading ("last_quarter_sum",0);;\
set_Reading ("last_hour_sum",0);;\
set_Reading ("last_day_sum",0);;\
  } \
}\
)\
CalculateSums {\
  my $Reading=::AttrVal("$SELF","EnergyReading","");;\
  my $Prefix=::AttrVal("$SELF","SummaryPrefix","");;\
\
##  my $readings = $::defs{$d}->{READINGS};;\
  my @Categories=split /,/, ::AttrVal("$SELF","SummaryList","");;\
\
  if (@Categories > 0) {\
    foreach my $Category (@Categories) {\
  my ($Name,$Filter)=split /;;/, $Category;;\
  my @Devices = ::devspec2array($Filter);;\
      my $counter_temp=0;;\
      my $hour_temp=0;;\
      my $hour_counter_temp=0;;\
      my $quarter_temp=0;;\
      my $quarter_counter_temp=0;;\
\
      foreach my $Device (@Devices) {\
        $counter_temp+=get_Reading("$Device\_$Reading\_counter",0);;\
        $hour_temp+=get_Reading("$Device\_$Reading\_hour",0);;\
        $hour_counter_temp+=get_Reading("$Device\_$Reading\_hour_counter",0);;\
        $quarter_temp+=get_Reading("$Device\_$Reading\_quarter",0);;\
        $quarter_counter_temp+=get_Reading("$Device\_$Reading\_quarter_counter",0);;\
  }\
      set_Reading($Prefix."$Name\_counter",$counter_temp);;\
      set_Reading($Prefix."$Name\_hour",$hour_temp);;\
      set_Reading($Prefix."$Name\_hour_counter",$hour_counter_temp);;\
      set_Reading($Prefix."$Name\_quarter",$quarter_temp);;\
      set_Reading($Prefix."$Name\_quarter_counter",$quarter_counter_temp);;\
##foreach my $readingname (keys %{$hash->{READINGS}}) { \
## loop über readings mit $readingname zur Weiterverarbeitung\
##  }\
  }\
  }\
}\
\
##https://forum.fhem.de/index.php/topic,84969.msg1208710.html#msg1208710\
CalculateQuarterSums { [([+:15]+[00:01])];;\
set_Reading("Summary_Total_last_quarter_sum",[?#sum:"^$SELF$":"last_quarter$"]);;\
CalculateSums();;\
}\
CalculateHourSums { [:01];;\
set_Reading("Summary_Total_last_hour_sum",[?#sum:"^$SELF$":"last_hour$"]);;\
CalculateSums();;\
}\
\
FOR(::devspec2array("MQTT2_shelly.*:FILTER=group=Haushaltsgeräte"), TPL_stat ($_,energy_total))\
##FOR(::devspec2array("MQTT2_shelly.*:FILTER=group=Haushaltsgeräte"), TPL_stat ($_,::AttrVal("$SELF","EnergyReading","energy")))\
##TPL_stat (MQTT2_shellyswitch25_E098068CF1A1,energy_total)\
##TPL_stat (MQTT2_shellyswitch25_E098068CF1A1_CH2,energy_total)
attr di_counter userattr SummaryList SummaryPrefix EnergyReading
attr di_counter EnergyReading energy_total
attr di_counter SummaryList Wohnzimmer;;room=Wohnzimmer,Schlafzimmer;;room=Schlafzimmer,Badezimmer;;room=Badezimmer,Vorzimmer;;room=Vorzimmer,Kueche;;room=Küche,Haushaltsgeraete;;group=Haushaltsgeräte
attr di_counter SummaryPrefix Summary_
attr di_counter comment https://forum.fhem.de/index.php/topic,126199.msg1208225.html#msg1208225
attr di_counter room Verbrauch
attr di_counter uiTable {package ui_Table;;}\
\
card([[MQTT2_shelly1pm_8CAAB50568DC:relay_0_power:144col1d]],"Leistung in kW","fa_bolt\@silver",-3.6,3.6,0,90,["Solar","Netz"],[(-1,0,-0.01,30,1,60,3.6,90)],"2","130,,1,0,1,0","1,,1,0,1")|\
card([[$SELF:MQTT2_shelly1pm_8CAAB50568DC_relay_0_power_day:col1w]],"Energie in kWh pro Tag","fa_bolt\@silver",-20,20,0,90,["Ertrag","Bezug"],undef,"1","130,,1,0,1","0,0,0,0,2")|\
card([[$SELF:MQTT2_shelly1pm_8CAAB50568DC_relay_0_power_month:col365d]],"Energie in kWh pro Monat","fa_bolt\@silver",-300,600,0,90,["Ertrag","Bezug"],undef,"1","130,,1,0,1","0,0,0,0,2")


Folgendes klappt noch nicht:
- Aufruf einer Subroutine (in dem Fall "CalculateSums ") aus einer anderen heraus (z.B. "CalculateQuarterSums").
  Ich bekomme immer den Fehler: "block_CalculateHourSums; condition c03: Undefined subroutine &DOIF::CalculateSums called, line 3."
- ich würde gerne beim Erstellen der Instanzen der Templates den Wert eines Attributs übergeben.
  Wie muss ich "::AttrVal" angeben?

Danke für die vielen Hilfe bisher und natürlich im Voraus
lg, Gerhard

Damian

CalculateSums {...

ist keine sub-Routine, sondern ein DOIF-Block.

Den kann man mit dem FHEM-Befehl set <DOIF-Device> <blockname> ausführen.

Besser wäre es, eine echte Perl-Sub-Routine im Block subs zu erstellen. Und die wiederum aufrufen:

subs {

sub mysub {...}

}

CalculateSums { mysub ([$1:$2],...)}

mysub kann man dann auch gesondert aufrufen. Zu bedenken ist, dass Perl-Routinen keine DOIF-spezifische Syntax kennen, die muss man beim Aufruf, wegen der notwendigen Trigger angeben (wie im Beispiel).


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