Durchschnittswert für ein Reading über eine vorgegebene Zeit bilden

Begonnen von Dani338, 29 August 2024, 17:42:15

Vorheriges Thema - Nächstes Thema

Dani338

Hallo,

wie kann ich für ein bestimmtes Reading einen Durchschnittswert bilden?

Das Problem ist, dass ich die Rollladensteuerung einbinden will. Es soll aber nicht jede kleine Sonnenänderung dazu führen, dass die Rollläden ständig hoch und runter fahren. Daher wäre es super, wenn die Lux-Werte des Lichtsensors z. B. für 15 Minuten oder einen anderen beliebigen Zeitpunkt beobachtet werden und dann der Durchschnittswert für die Steuerung genommen wird und nicht - wie aktuell der Live-Wert.

Sorry, ich kann nicht wirklich programmieren. Ich bin jetzt schon froh, dass ich das soweit hinbekommen habe, dass es mit dem Live-Wert theoretisch zumindest funktioniert.

Gibt es hier eine einfache Lösung?

Viele Grüße
Dani

 

Adimarantis

Ich hab das mit einem DOIF mit 15min wait gelöst.
Dann lösen die Rollos erst aus, wenn der Lux Wert über die Zeit stabil bleibt. Jedesmal wenn die jeweils andere Bedingung wahr wird setzt sich das wait zurück.
Mittelwert ist m.E. nicht sehr sinnvoll, weil die Schwankungen  bei wechselnder Bewölkung ziemlich groß sind
Raspberry 4 + HM-MOD-RPI-PCB (pivCCU) + RfxTrx433XL + 2xRaspberry 1
Module: 50_Signalbot, 52_I2C_ADS1x1x , 58_RPI_1Wire, (50_SPI_MAX31865)

Dani338


Prof. Dr. Peter Henning

ZitatMittelwert ist m.E. nicht sehr sinnvoll, weil die Schwankungen  bei wechselnder Bewölkung ziemlich groß sind
Da muss ich doch widersprechen, das ist in dieser Allgemeinheit falsch.

Der TE spricht von "kleinen Sonnenänderungen" und ist sich auch nicht im Klaren darüber, ob das nun "kleine" oder "kurze" Änderungen sind.

Tipp: Den Wiki-Artikel zum Thema Gleitender Mittelwert ansehen. https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen

Und nicht mit einem DOIF arbeiten.

LG

pah


eisman

hi,

ich habe das mal in FHEM gefunden und läuft bei mir seit langer Zeit:

defmod Lux.Hof dummy
attr Lux.Hof alias Helligkeit Hof:
attr Lux.Hof devStateIcon { my $STRG = "";; my $T1 = ReadingsVal($name,"lux-1h",0);; my $T2 = ReadingsVal($name,"state",0);;\
  \
  $STRG = "<span style='font-size:10px;;font-weight:bold;;color:#FFA500;;'>Ø Stunde: </span>"\
        . "<span style='font-weight:bold;;font-size:12px;;color:#00FF00;;'>" . $T1 . "</span>"\
        . "<span style='font-size:10px;;font-weight:bold;;color:#FFA500;;'> lx</span><br>"\
        . "<span style='font-size:10px;;font-weight:bold;;color:#FFA500;;'>Aktuell: </span>"\
        . "<span style='font-weight:bold;;font-size:12px;;color:#00FF00;;'>" . $T2 . "</span>"\
        . "<span style='font-size:10px;;font-weight:bold;;color:#FFA500;;'> lx</span>";; \
  return $STRG;;\
}
attr Lux.Hof devStateStyle style="text-align:right;;"
attr Lux.Hof group sensor
attr Lux.Hof readingList state
attr Lux.Hof room wetterstation
attr Lux.Hof setList state
attr Lux.Hof stateFormat state
attr Lux.Hof userReadings lux-1h { sprintf("%.0f",movingAverage($name,"state",3600))}

setstate Lux.Hof 0
setstate Lux.Hof 2024-09-08 20:00:15 lux-1h 17
setstate Lux.Hof 2024-09-08 20:00:15 state 0

defmod no.Wetter.Lux.Hof notify Wetterstation:lux-hof:.* setreading Lux.Hof state [Wetterstation:lux-hof];;
attr no.Wetter.Lux.Hof devStateStyle style="text-align:right;;"
attr no.Wetter.Lux.Hof room wetterstation

setstate no.Wetter.Lux.Hof 2024-09-08 20:02:10
setstate no.Wetter.Lux.Hof 2024-09-05 11:14:15 state active
setstate no.Wetter.Lux.Hof 2024-09-08 20:02:10 triggeredByDev Wetterstation
setstate no.Wetter.Lux.Hof 2024-09-08 20:02:10 triggeredByEvent lux-hof: 0

#############################################################################################
#
#  Moving average
#
#  Aufruf: movingAverage(devicename,readingname,zeitspanne in s)
#
#############################################################################################
sub movingAverage($$$) {
  my ($name,$reading,$avtime) = @_;
  my $hash = $defs{$name};
  my @new = my ($val,$time) = (ReadingsVal($name,$reading,undef),ReadingsTimestamp($name,$reading,undef));
  my ($cyear, $cmonth, $cday, $chour, $cmin, $csec) = $time =~ /(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})/;
  my $ctime = $csec+60*$cmin+3600*$chour;
  my $num;
  my $arr;
  #-- initialize if requested
  if(($avtime eq "-1")) {
    $hash->{helper}{history}=undef;
  }
  #-- test for existence
  if( !$hash->{helper}{history}) {
    #Log 1,"ARRAY CREATED";
    push(@{$hash->{helper}{history}},\@new);
    $num = 1;
    $arr = \@{$hash->{helper}{history}};
  } else {
    $num = int(@{$hash->{helper}{history}});
    $arr = \@{$hash->{helper}{history}};
    my $starttime = $arr->[0][1];
    my ($syear, $smonth, $sday, $shour, $smin, $ssec) = $starttime =~ /(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})/;
    my $stime = $ssec+60*$smin+3600*$shour;
    #-- correct for daybreak
    $stime-=86400 if( $stime > $ctime);
    if( ($num < 25)&&( ($ctime-$stime)<$avtime) ) {
      #Log 1,"ARRAY has $num elements, adding another one";
      push(@{$hash->{helper}{history}},\@new);
    } else {
      shift(@{$hash->{helper}{history}});
      push(@{$hash->{helper}{history}},\@new);
    }
  }
  #-- output and average
  my $average = 0;
  for(my $i=0;$i<$num;$i++) {
    $average+=$arr->[$i][0];
    Log 4,"[$name moving average] Value = ".$arr->[$i][0]." Time = ".$arr->[$i][1];
  }
  $average=sprintf( "%5.3f", $average/$num);
  #--average
  Log 4,"[$name moving average] calculated over $num values is $average"; 
  return $average;
 }

das geht immer nur für ein reading im Device!
geht bestimmt auch besser

gruss
1x FHEM Debian, Homematic,ZigBee,FS20 / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian, Homematic,ZigBee         / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian,MQTT                               / 1X Raspberry, i2c,onewire,gpio
1x auf Windows 2012 Hyper-V-S