FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: SabineT am 09 August 2017, 19:31:19

Titel: Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 09 August 2017, 19:31:19
Hallo!

Ich hab mal auf Basis von https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen (https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen) eine Subroutine für die Windrichtung geschrieben, dabei hab ich auch die entsprechende Funktion von pywws mit heran gezogen.

Für die Windrichtung ist ja das normale average nicht vewendbar, wie man leicht erkennen kann, wenn man die Mittelwert von NNW (337.5°) und NNO (22.5°) berechnen will. Ein einfaches average ergäbe dann 180°, also Süd. Tatsächlich ist der Mittelwert aber Nord (0° bzw. 360°). Für die Berechnung muss man daher die Windrichtung in Vektoren zerlegen.

Die einzelenen Parameter werden in den Kommentarzeilen am Anfang beschrieben.

use Math::Trig;

###############################################################################
#
#  Moving myWindDirAverage
#
#  Aufruf: myWindDirAverage(devicename,readingname_windspeed,readingname_winddir,avtime,decay,minspee)
#       z.B.: myWindDirAverage('WH1080','windSpeed','winDirectionDegree',900,0.75,0.5)
#       avtime ist optional, default ist 600 s    Zeitspanne, die berücksichtig werden soll
#       decay ist optional, default ist 1         Parameter, um ältere Werte geringer zu gewichten
#       minspeed ist optional, default ist 0 m/s
#
#  Als Ergebnis wird die Windrichtung zurück geliefert, die aus dem aktuellen und
#  vergangenen Werten über eine Art exponentiellen Mittelwert berechnet werden.
#  Dabei wird zusätzlich die jeweilige Windgeschwindigkeit mit berücksichtigt (höhere Geschwindigkeit
#  bedeutet höhere Gewichtung).
#
#  decay: 1 -> alle Werte werden gleich gewichtet
#         0 -> nur der aktuelle Wert wird verwendet.
#         in der Praxis wird man Werte so um 0.75 nehmen
#
#  minspeed: da bei sehr geringer Windgeschwindigkeit die Windrichtung üblicherweise nicht
#         eindeutig ist, kann mit minspeed ein Schwellwert angegeben werden
#         Ist die (gewichtetete) mittlere Geschwindigkeit < minspeed wird undef zurück geliefert
#
###############################################################################

sub myWindDirAverage($$$;$$$) {
  my ($name, $wsr, $wdr, $avtime, $decay, $minspeed) = @_;

  # default Werte für die optionalen Parameter, falls nicht beim Aufruf mit angegeben
  $avtime = 600 if (!(defined $avtime));
  return $wdr if ($avtime == 0);
  $decay = 1 if (!(defined $decay));
  $decay = 1 if ($decay > 1); # darf nicht >1 sein
  $decay = 0 if ($decay < 0); # darf nicht <0 sein
  $minspeed = 0 if (!(defined $minspeed));

  my $ws = ReadingsVal($name, $wsr, undef);
  if (!defined $ws) {
    Log 0,"myWindDirAverage: Reading $name->$wsr unknown!";
    return undef;
  }
  my $wd = ReadingsVal($name, $wdr, undef);
  if (!defined $wd) {
    Log 0,"myWindDirAverage: Reading $name->$wdr unknown!";
    return undef;
  }
  $wd = deg2rad($wd);
  my $time = ReadingsTimestamp($name, $wdr, undef);

  my $hash = $defs{$name};
  my @new = ($ws,$wd,$time);

  Log 3,"[$name myWDA1] call: Speed=".$ws." Dir=".round($wd,2)." Time=".$time." avtime=".$avtime." decay=".$decay."minspeed=".$minspeed;

  my $ctime = time_str2num($time);
  my $num;
  my $arr;
  #-- initialize if requested
  if( ($avtime eq "-1") ){
    $hash->{READINGS}{$wdr}{"history"}=undef;
  }
  #-- test for existence
  if( !$hash->{READINGS}{$wdr}{"history"}){
    Log 3,"[$name myWDA2] ARRAY CREATED";
    push(@{$hash->{READINGS}{$wdr}{"history"}},\@new);
    $num = 1;
    $arr=\@{$hash->{READINGS}{$wdr}{"history"}};
  } else {
    $num = int(@{$hash->{READINGS}{$wdr}{"history"}});
    $arr=\@{$hash->{READINGS}{$wdr}{"history"}};
    my $stime = time_str2num($arr->[0][2]);       # Zeitpunkt des ältesten Eintrags
    my $ltime = time_str2num($arr->[$num-1][2]);  # Zeitpunkt des letzten Eintrags
    Log 3,"[$name myWDA3] Speed=".$ws." Dir=".round($wd,2)." Time=".$time." minspeed=".$minspeed." ctime=".$ctime."ltime=".$ltime." stime=".$stime." num=".$num;

    if((($ctime - $ltime) > 10) || ($num == 0)) {
      if(($num < 25) && (($ctime-$stime) < $avtime)){
        #Log 1,"ARRAY has $num elements, adding another one";
        Log 3,"[$name myWDA4] push: Speed=".$ws." Dir=".round($wd,2)." Time=".$time." minspeed=".$minspeed." num=".$num;
        push(@{$hash->{READINGS}{$wdr}{"history"}},\@new);

      }else{
        shift(@{$hash->{READINGS}{$wdr}{"history"}});
        push(@{$hash->{READINGS}{$wdr}{"history"}},\@new);
        Log 3,"[$name myWDA5] push: Speed=".$ws." Dir=".round($wd,2)." Time=".$time." minspeed=".$minspeed." num=".$num;
      }
    } else {
      return undef;
    }
  }
  #-- output and average
  my ($anz, $sanz) = 0;
  $num = int(@{$hash->{READINGS}{$wdr}{"history"}});
  my ($sumSin, $sumCos, $sumSpeed, $age, $maxage, $weight) = 0;
  for(my $i=0; $i<$num; $i++){
    ($ws, $wd, $time) = @{ $arr->[$i] };
    $age = $ctime - time_str2num($time);
    if (($time eq "") || ($age > $avtime)) {
      #-- zu alte Einträge entfernen
      Log 3,"[$name myWDA6] i=".$i." Speed=".round($ws,2)." Dir=".round($wd,2)." Time=".substr($time,11)." ctime=".$ctime." akt.=".time_str2num($time);
      shift(@{$hash->{READINGS}{$wdr}{"history"}});
      $i--;
      $num--;
    } else {
      #-- Werte aufsummieren, Windrichtung gewichtet über Geschwindigkeit und decay/"alter"
      $weight = $decay ** ($age / $avtime);
      #-- für die Mittelwertsbildung der Geschwindigkeit wird nur ein 10tel von avtime genommen
      if ($age < ($avtime / 10)) {
        $sumSpeed += $ws * $weight if ($age < ($avtime / 10));
        $sanz++;
      }
      $sumSin += sin($wd) * $ws * $weight;
      $sumCos += cos($wd) * $ws * $weight;
      $anz++;
      Log 3,"[$name myWDA7] i=".$i." Speed=".round($ws,2)." Dir=".round($wd,2)." Time=".substr($time,11)." vec=".round($sumSin,2)."/".round($sumCos,2)." age=".$age." ".round($weight,2);
    }
  }
  my $average = int((rad2deg(atan2($sumSin, $sumCos)) + 360) % 360);
  Log 3,"[$name myWDA8] Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1) if ($num > 0);
  #-- undef zurückliefern, wenn die durchschnittliche Geschwindigkeit zu gering oder gar keine Werte verfügbar
  return undef if (($anz == 0) || ($sanz == 0));
  return undef if (($sumSpeed / $sanz) < $minspeed);
  return $average;
}


Die "Log 3" Zeilen hab ich zum Debuggen eingebaut, die kann man natürlich weg lassen...

Bei meinem Device der Wetterstation WH1080 hab ich dann ein userReading angelegt:
userReadings WH1080 windDirAverage {myWindDirAverage('WH1080','windSpeed','windDirectionDegree',1200,0.75,0.5); }

Ich hab hier Plots von Windgeschwindigkeit und Windrichtung beigefügt, wobei ich bei der Windrichtung zusätzlich zum Vergleich die Werte darstelle, wie sie von der Wetterstation kommen.
Man sieht auch, dass ich die Werte nur anzeige, wenn die Windgeschwindigkeit mehr als 0.5 m/s beträgt.

Update 25.9.2017: Ergänzungen im Code um fehlerhafte Aufrufe abzufangen
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: CQuadrat am 09 August 2017, 19:51:28
Cool wäre es, wenn man die Winddaten wie folgt darstellen könnte:
https://de.wikipedia.org/wiki/Windrose_(Meteorologie)#/media/File:Wind_rose_plot.jpg (https://de.wikipedia.org/wiki/Windrose_(Meteorologie)#/media/File:Wind_rose_plot.jpg)

Ich hatte da mal SQL-Abfragen gebastelt, die die Werte aus dem DbLog-Device generieren. Allerdings hatte ich nichts gefunden, wie das in FHEM auch graphisch dargestellt werden kann.
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: herrmannj am 11 August 2017, 13:59:15
https://www.highcharts.com/demo/polar-wind-rose  & smartVisu
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: CQuadrat am 15 August 2017, 08:17:19
Danke für den Tipp!

Lässt sich das leicht in FHEM integrieren? Gibt es da Erfahrungswerte?

Wenn ich das Lizenzmodell richtig verstehe, ist die Bibliothek für private Nutzung frei.
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: Mexx13 am 07 September 2017, 20:47:27
Hi!

@SabineT: Das ist ein genialer Code. Vielen Danke fürs Teilen!  :D
Das hab ich schon lange gesucht. Scheint als ob das zu Berrechen sehr kompliziert ist. Auf jeden Fall funktioniert es!

Haha: Jz muss ich noch schaffen alles ein Jahr zurückzurechnen, dann wären wieder ein paar 100.000 Datensätze weniger  ;D

Lg Max
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pink99panther am 08 September 2017, 15:20:20
Hallo SabineT,

hab den Codeschnipsel heute mal auf mein FHEM "kopiert"
Läuft mit meiner Ventus266 -> MQTT prima!

Gruß
p99p
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pejonp am 24 September 2017, 01:25:10
Zitat von: SabineT am 09 August 2017, 19:31:19
...
Ich hab mal auf Basis von https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen (https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen) eine Subroutine für die Windrichtung geschrieben, dabei hab ich auch die entsprechende Funktion von pywws mit heran gezogen.

Für die Windrichtung ist ja das normale average nicht vewendbar, wie man leicht erkennen kann, wenn man die Mittelwert von NNW (337.5°) und NNO (22.5°) berechnen will. Ein einfaches average ergäbe dann 180°, also Süd. Tatsächlich ist der Mittelwert aber Nord (0° bzw. 360°). Für die Berechnung muss man daher die Windrichtung in Vektoren zerlegen.
..........
Man sieht auch, dass ich die Werte nur anzeige, wenn die Windgeschwindigkeit mehr als 0.5 m/s beträgt.
Hallo SabineT,

ich habe mal den Code in 99_myUtil.pm kopiert und aufgerufen, leider bekomme ich Div/0. Tritt beim Loglevel=5 auf. Die Berechung beim Log stimmt nicht, bzw. div/0 muß abgefangen werden. Ich habe das mal angepaßt, so das es bei mir läuft. Bei  windDirAverage habe ich aber immer 0.
Könntest du auch  mal die Daten für den Plot mit angeben. Danke.

pejonp
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 24 September 2017, 07:14:31
Hallo pejonp!

Das mit Div/0 schau ich mir an, im Moment herrscht bei mir aber Flaute, muss also warten, bis wieder genug Wind bläst.

Zu den Plot Daten:

Die Definition schaut bei mir so aus:
define gnuPlot_DbLog_Wetterdaten_winddir SVG lp:gnuplot_DbLog_Wetterdaten_winddir:CURRENT
attr gnuPlot_DbLog_Wetterdaten_winddir comment Windrichtung
attr gnuPlot_DbLog_Wetterdaten_winddir plotmode gnuplot-scroll
attr gnuPlot_DbLog_Wetterdaten_winddir plotsize 600,205
attr gnuPlot_DbLog_Wetterdaten_winddir room GnuPlots


Und das Plotfile selber so:
set terminal pngcairo enhanced font "DejaVuSansCondensed,10" rounded transparent size <SIZE> crop
set size 0.94, 1
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set lmargin 8
set rmargin 8
set xtics format "%H:%M"
set xtics 14400
set format y " %3.0f"
set xtics out
set ytics 45 out
set y2tics ('N' 0, 'O' 90, 'S' 180, 'W' 270, 'N' 360) out offset 2
set grid ytics
set ylabel "°"
set y2label ' '
set yrange [0:360]
set y2range [0:360]
set grid x y2 front
set style circle radius 150
set pointsize 0.2
set key outside above right maxrows 1 samplen 2

#lp DbLog:myDbLog:WH1080:windDirAverage

plot "<IN>" using 1:2 axes x1y1 title 'Windrichtung' with circles lc rgb 'blue'


Ich verwende plotmode gnuplot-scroll, weil ich da mehr Möglichkeiten der Formatierung habe (z.B. Legenden ausserhalb des Plots), für plotmode SVG müsste man das dann anpassen.

lg, Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 24 September 2017, 07:48:19
Eigentlich sind mir im Code nur 2 Stellen aufgefallen, wo ein Div/0 passieren könnte:

$weight = $decay ** ($age / $avtime);
passiert aber nur, wenn man beim userReading für avtime 0 angibt.

Das müsste sich mit folgender Änderung abfangen lassen:
~/FHEM$ diff -c 99_myUtils.pm.old 99_myUtils.pm
*** 99_myUtils.pm.old   2017-09-24 07:25:30.763850589 +0200
--- 99_myUtils.pm       2017-09-24 07:33:10.058351197 +0200
***************
*** 274,279 ****
--- 274,280 ----

    # default Werte für die optionalen Parameter, falls nicht beim Aufruf mit angegeben
    $avtime = 600 if (!(defined $avtime));
+   return $wdr if ($avtime == 0);
    $decay = 1 if (!(defined $decay));
    $decay = 1 if ($decay > 1); # darf nicht >1 sein
    $decay = 0 if ($decay < 0); # darf nicht <0 sein

Die Zeile "return $wdr if ($avtime == 0);" an der entsprechenden Stelle einfügen.

Die zweite Stelle ist:
Log 3,"[$name myWDA8] Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1);
Da darf $num nicht 0 sein. Ist aber nur relevant, wenn man verbose >=3 eingestellt hat, das war bei meinen Test während der Entwicklungsphase aber nie der Fall.
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: Ralf9 am 24 September 2017, 09:01:28
ZitatDie zweite Stelle ist:
Log 3,"[$name myWDA8] Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1);

Dies lässt sich abfangen, wenn auf num > 0 geprüft wird:
Log 3,"[$name myWDA8] Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1) if ($num > 0);

Gruß Ralf
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 24 September 2017, 10:31:29
Zitat von: Ralf9 am 24 September 2017, 09:01:28
Dies lässt sich abfangen, wenn auf num > 0 geprüft wird:
Log 3,"[$name myWDA8] Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1) if ($num > 0);

Gruß Ralf
Bei mir ist der Fall nie aufgetreten, hab das aber jetzt mal gemeinsam mit der anderen Änderung im 1. Posting ergänzt.

@pejonp falls bei dir Div/0 immer noch auftritt poste mir bitte mal den Logauszug dazu.

Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pejonp am 24 September 2017, 21:29:39
Zitat von: SabineT am 24 September 2017, 10:31:29
Bei mir ist der Fall nie aufgetreten, hab das aber jetzt mal gemeinsam mit der anderen Änderung im 1. Posting ergänzt.

@pejonp falls bei dir Div/0 immer noch auftritt poste mir bitte mal den Logauszug dazu.

Sabine
Hallo Sabine,

ich habe mal deine Vorschläge ins 14_SD_WS09.pm eingebaut und hänge das hier mal an. Kannst du dir das mal ansehen ?
Ich möchte es noch nicht Einchecken, falls noch Fehler drin sind.

pejonp

PS: Anlage noch einmal angepaßt.
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 24 September 2017, 22:15:20
Zitat von: pejonp am 24 September 2017, 21:29:39
Hallo Sabine,

ich habe mal deine Vorschläge ins 14_SD_WS09.pm eingebaut und hänge das hier mal an. Kannst du dir das mal ansehen ?
Ich möchte es noch nicht Einchecken, falls noch Fehler drin sind.

pejonp

PS: Anlage noch einmal angepaßt.
Ich hab die Version mal bei mir installiert. Jetzt in der Nacht ist nur leider der Wind wieder zu schwach, kann also erst morgen was genaueres dazu sagen.
Ich würde aber für das Reading statt WindDirAverage windDirAverage verwenden, damit es bei den übrigen wind Readings dabei steht (die haben ja alles das w klein geschrieben ;)).

Und statt rainTotal wäre rain_total sinnvoller, dann wird es auch von statistics berücksichtigt!
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pejonp am 25 September 2017, 00:03:40
Hi SabineT,

habe die Readings 14_SD_WS09.pm angepaßt.

Im 99_myUtils.pm habe ich die Version angepaßt und wollte meine W266 damit füttern. Geht nicht so richtig. Ich hänge mal eine Ausschnitt aus dem Log an. Fehler habe ich noch nicht eingrenzen können.
Def:
attr ESPEasy_W266_Wind userReadings windDirAverage {myWindDirAverage('ESPEasy_W266_Wind','Guest','Average',1200,0.75,0.5);; }


2017.09.24 23:36:35.386 1: PERL WARNING: Use of uninitialized value $ws in concatenation (.) or string at ./FHEM/99_myUtils.pm line 287.
2017.09.24 23:36:35.386 1: PERL WARNING: Use of uninitialized value $time in concatenation (.) or string at ./FHEM/99_myUtils.pm line 287.
2017.09.24 23:36:35.387 1: PERL WARNING: Use of uninitialized value $time in string eq at ./FHEM/99_myUtils.pm line 331.
2017.09.24 23:36:35.387 1: PERL WARNING: Use of uninitialized value $v in sprintf at ./FHEM/99_myUtils.pm line 245.
2017.09.24 23:36:35.387 1: PERL WARNING: Use of uninitialized value $time in substr at ./FHEM/99_myUtils.pm line 333.
2017.09.24 23:36:35.388 1: PERL WARNING: substr outside of string at ./FHEM/99_myUtils.pm line 333.
2017.09.24 23:36:35.388 1: PERL WARNING: Use of uninitialized value in concatenation (.) or string at ./FHEM/99_myUtils.pm line 333.
2017.09.24 23:36:35.388 1: PERL WARNING: Use of uninitialized value $sumCos in atan2 at ./FHEM/99_myUtils.pm line 351.
2017.09.24 23:36:35.389 1: PERL WARNING: ESPEasy_W266_Wind userReadings windDirAverage evaluated to undef at fhem.pl line 4288.
2017.09.24 23:36:35.391 5: ESPEasy ESPEasy_W266_Wind: Start internalTimer +304 => 2017-09-24 23:41:40
2017.09.24 23:36:47.368 1: PERL WARNING: Use of uninitialized value $ws in concatenation (.) or string at ./FHEM/14_SD_WS09.pm line 519.
2017.09.24 23:36:47.369 1: PERL WARNING: Use of uninitialized value $time in concatenation (.) or string at ./FHEM/14_SD_WS09.pm line 519.
2017.09.24 23:36:47.369 1: PERL WARNING: Use of uninitialized value $time in string eq at ./FHEM/14_SD_WS09.pm line 564.
2017.09.24 23:36:47.370 1: PERL WARNING: Use of uninitialized value $time in substr at ./FHEM/14_SD_WS09.pm line 566.
2017.09.24 23:36:47.370 1: PERL WARNING: substr outside of string at ./FHEM/14_SD_WS09.pm line 566.
2017.09.24 23:36:47.370 1: PERL WARNING: Use of uninitialized value in concatenation (.) or string at ./FHEM/14_SD_WS09.pm line 566.
2017.09.24 23:36:47.371 1: PERL WARNING: Use of uninitialized value $sumCos in atan2 at ./FHEM/14_SD_WS09.pm line 584.
2017.09.24 23:36:47.371 1: PERL WARNING: Use of uninitialized value $windex in array element at ./FHEM/14_SD_WS09.pm line 408.
2017.09.24 23:36:50.859 5: ESPEasy ESPEasy_W266_Wind: Received: W266_Wind::192.168.2.103::1::1::1::i||unit||0||0|||i||sleep||0||0|||i||build||20000||0|||i||build_git||dev11||0|||i||build_notes|| - Mega||0|||i||version||2||0|||i||node_type_id||17||0|||r||Direction||0.0||6|||r||Average||225.0||6|||r||Guest||0.0||6
2017.09.24 23:36:50.861 1: PERL WARNING: Use of uninitialized value $ws in concatenation (.) or string at ./FHEM/99_myUtils.pm line 307.
2017.09.24 23:36:50.861 1: PERL WARNING: Use of uninitialized value $time in concatenation (.) or string at ./FHEM/99_myUtils.pm line 307.
2017.09.24 23:36:50.862 1: PERL WARNING: Use of uninitialized value $ws in concatenation (.) or string at ./FHEM/99_myUtils.pm line 312.
2017.09.24 23:36:50.862 1: PERL WARNING: Use of uninitialized value $time in concatenation (.) or string at ./FHEM/99_myUtils.pm line 312.
2017.09.24 23:36:50.864 4: ESPEasy ESPEasy_W266_Wind: Direction: 0.0
2017.09.24 23:36:50.865 1: PERL WARNING: Use of uninitialized value $ws in multiplication (*) at ./FHEM/99_myUtils.pm line 342.
2017.09.24 23:36:50.866 1: PERL WARNING: Use of uninitialized value $ws in multiplication (*) at ./FHEM/99_myUtils.pm line 345.
2017.09.24 23:36:50.866 1: PERL WARNING: Use of uninitialized value $ws in multiplication (*) at ./FHEM/99_myUtils.pm line 346.
2017.09.24 23:36:50.867 4: ESPEasy ESPEasy_W266_Wind: Average: 225.0
2017.09.24 23:36:50.868 4: ESPEasy ESPEasy_W266_Wind: Guest: 0.0
2017.09.24 23:36:50.868 5: ESPEasy ESPEasy_W266_Wind: Internals: unit:0 sleep:0 build:20000 build_git:dev11 build_notes: - Mega version:2 node_type_id:17: ESP Easy Mega
2017.09.24 23:36:50.870 4: ESPEasy ESPEasy_W266_Wind: presence: present
2017.09.24 23:37:00.036 1: PERL WARNING: Odd number of elements in hash assignment at ./FHEM/98_HTTPMOD.pm line 1717.
2017.09.24 23:37:22.421 5: ESPEasy ESPEasy_W266_Wind: Received:


pejonp
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 25 September 2017, 07:03:56
Zitat von: pejonp am 25 September 2017, 00:03:40
Hi SabineT,

habe die Readings 14_SD_WS09.pm angepaßt.

Im 99_myUtils.pm habe ich die Version angepaßt und wollte meine W266 damit füttern. Geht nicht so richtig. Ich hänge mal eine Ausschnitt aus dem Log an. Fehler habe ich noch nicht eingrenzen können.
Def:
attr ESPEasy_W266_Wind userReadings windDirAverage {myWindDirAverage('ESPEasy_W266_Wind','Guest','Average',1200,0.75,0.5);; }


2017.09.24 23:36:35.386 1: PERL WARNING: Use of uninitialized value $ws in concatenation (.) or string at ./FHEM/99_myUtils.pm line 287.
2017.09.24 23:36:35.386 1: PERL WARNING: Use of uninitialized value $time in concatenation (.) or string at ./FHEM/99_myUtils.pm line 287.


pejonp
Bei dir passt die Definition des userReadings nicht! Im Log sieht man, dass $ws und $time garnicht initialisiert wird, das passiert im Programm in der Zeile:
my @new = my ($ws,$wd,$time) = ($hash->{READINGS}{$wsr}{VAL},deg2rad($hash->{READINGS}{$wdr}{VAL}),$hash->{READINGS}{$wdr}{TIME});

Du verwendest als Definition:
attr ESPEasy_W266_Wind userReadings windDirAverage {myWindDirAverage('ESPEasy_W266_Wind','Guest','Average',1200,0.75,0.5);; }

Statt 'Guest' müsste der Readingname der Windgeschwindigkeit stehen (bei der WH1080 ist das 'windSpeed').
Statt 'Average' gehört dann der Readingname der Windrichtung (ist bei der WH1080 'windDirectionDegree').
Ich denke, bei der W266 werden die die gleichen Namen haben.
Probier einfach mal
attr ESPEasy_W266_Wind userReadings windDirAverage {myWindDirAverage('ESPEasy_W266_Wind','windSpeed','windDirectionDegree',1200,0.75,0.5);; }


lg, Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: CoolTux am 25 September 2017, 08:01:16
Solche Fehler könnte man vermeiden wenn man die zum auslesen von Readings bestimmten FHEM Funktionen verwendet. Generell empfiehlt es sich nicht unnötig Hash's aus zu lesen oder für Bedingungen zu verwenden. Dafür dann lieber die FHEM Funktionen.
Ein weiterer Grund auf Hash Abfragen zu verzichten ist, das bei der Abfrage von verschachtelten Hash's auch Hash's unnötiger Weise angelegt werden.
if(hash->{READINGS}{$wdr}{VAL})
Sollte aus einem Grund {$wdr} nicht existieren wird es bei der Abfrage von {VAL} angelegt.

Sabine vielleicht schaust Du einmal das Du Deine wirklich gute Sub entsprechend um baust.
ReadingsVal währe hier angebracht. Eventuell kannst Du dann ganz auf den Wert von $hash verzichten. Habe mir aber nicht alles angeschaut. $name sollte dann reichen.



Grüße
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pink99panther am 25 September 2017, 08:19:45
@pejonp
nicht Average sondern Direction brauchst du im userreading.

userReadings windDirAverage {myWindDirAverage('WetterstnNdn','Gust','Direction',1200,0.75,1.8); }

Bei mir läuft das mit MQTT fehlerfrei.

EDIT:

der Vollständigkeit halber häng ich noch ein list vom Device an

Internals:
   IODev      MyBroker
   NAME       WetterstnNdn
   NR         127
   STATE      incoming publish received
   TYPE       MQTT_DEVICE
   Helper:
     DBLOG:
       Average:
         logdb:
           TIME       1506319798.01265
           VALUE      0.0
       Battery:
         logdb:
           TIME       1506319802.10818
           VALUE      0
       Direction:
         logdb:
           TIME       1506319797.94068
           VALUE      135.0
       Distance_in_km:
         logdb:
           TIME       1506319801.20898
           VALUE      40
       Gust:
         logdb:
           TIME       1506319798.08269
           VALUE      0.0
       Humidity:
         logdb:
           TIME       1506319796.98924
           VALUE      27
       Rainfall:
         logdb:
           TIME       1506319799.05028
           VALUE      0.0
       Strike_counter:
         logdb:
           TIME       1506319801.0653
           VALUE      1126
       Strikes_past_5_minutes:
         logdb:
           TIME       1506319801.13818
           VALUE      0
       Temperature:
         logdb:
           TIME       1506319796.90516
           VALUE      11.0
       Total:
         logdb:
           TIME       1506319798.97798
           VALUE      770.0
       UV:
         logdb:
           TIME       1506319800.04946
           VALUE      0.0
       transmission-state:
         logdb:
           TIME       1506319802.07354
           VALUE      incoming publish received
       windDirAverage:
         logdb:
           TIME       1506020788.95284
           VALUE      180
   READINGS:
     2017-09-25 08:09:58   Average         0.0
     2017-09-25 08:10:02   Battery         0
     2017-09-25 08:09:57   Direction       135.0
     2017-09-25 08:10:01   Distance_in_km  40
     2017-09-25 08:09:58   Gust            0.0
     2017-09-25 08:09:56   Humidity        27
     2017-09-25 08:09:59   Rainfall        0.0
     2017-09-25 08:10:01   Strike_counter  1126
     2017-09-25 08:10:01   Strikes_past_5_minutes 0
     2017-09-25 08:09:56   Temperature     11.0
     2017-09-25 08:09:58   Total           770.0
     2017-09-25 08:10:00   UV              0.0
     2017-09-25 08:10:02   transmission-state incoming publish received
     2017-09-21 21:06:28   windDirAverage  180
   message_ids:
   sets:
   subscribe:
     /VentusNdn/Ventus/Average
     /VentusNdn/Ventus/Battery
     /VentusNdn/Ventus/Direction
     /VentusNdn/Ventus/Distance
     /VentusNdn/Ventus/Gust
     /VentusNdn/Ventus/Humidity
     /VentusNdn/Ventus/Rainpasthour
     /VentusNdn/Ventus/Strikecounter
     /VentusNdn/Ventus/Strikespast5
     /VentusNdn/Ventus/Temperature
     /VentusNdn/Ventus/Totalrain
     /VentusNdn/Ventus/UV
   subscribeExpr:
     ^\/VentusNdn\/Ventus\/Average$
     ^\/VentusNdn\/Ventus\/Battery$
     ^\/VentusNdn\/Ventus\/Direction$
     ^\/VentusNdn\/Ventus\/Distance$
     ^\/VentusNdn\/Ventus\/Gust$
     ^\/VentusNdn\/Ventus\/Humidity$
     ^\/VentusNdn\/Ventus\/Rainpasthour$
     ^\/VentusNdn\/Ventus\/Strikecounter$
     ^\/VentusNdn\/Ventus\/Strikespast5$
     ^\/VentusNdn\/Ventus\/Temperature$
     ^\/VentusNdn\/Ventus\/Totalrain$
     ^\/VentusNdn\/Ventus\/UV$
   subscribeReadings:
     /VentusNdn/Ventus/Average:
       cmd
       name       Average
     /VentusNdn/Ventus/Battery:
       cmd
       name       Battery
     /VentusNdn/Ventus/Direction:
       cmd
       name       Direction
     /VentusNdn/Ventus/Distance:
       cmd
       name       Distance_in_km
     /VentusNdn/Ventus/Gust:
       cmd
       name       Gust
     /VentusNdn/Ventus/Humidity:
       cmd
       name       Humidity
     /VentusNdn/Ventus/Rainpasthour:
       cmd
       name       Rainfall
     /VentusNdn/Ventus/Strikecounter:
       cmd
       name       Strike_counter
     /VentusNdn/Ventus/Strikespast5:
       cmd
       name       Strikes_past_5_minutes
     /VentusNdn/Ventus/Temperature:
       cmd
       name       Temperature
     /VentusNdn/Ventus/Totalrain:
       cmd
       name       Total
     /VentusNdn/Ventus/UV:
       cmd
       name       UV
Attributes:
   DbLogInclude .*
   IODev      MyBroker
   room       Wetter
   stateFormat transmission-state
   subscribeReading_Average /VentusNdn/Ventus/Average
   subscribeReading_Battery /VentusNdn/Ventus/Battery
   subscribeReading_Direction /VentusNdn/Ventus/Direction
   subscribeReading_Distance_in_km /VentusNdn/Ventus/Distance
   subscribeReading_Gust /VentusNdn/Ventus/Gust
   subscribeReading_Humidity /VentusNdn/Ventus/Humidity
   subscribeReading_Rainfall /VentusNdn/Ventus/Rainpasthour
   subscribeReading_Strike_counter /VentusNdn/Ventus/Strikecounter
   subscribeReading_Strikes_past_5_minutes /VentusNdn/Ventus/Strikespast5
   subscribeReading_Temperature /VentusNdn/Ventus/Temperature
   subscribeReading_Total /VentusNdn/Ventus/Totalrain
   subscribeReading_UV /VentusNdn/Ventus/UV
   userReadings windDirAverage {myWindDirAverage('WetterstnNdn','Gust','Direction',1200,0.75,1.8); }
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 25 September 2017, 09:05:33
Zitat von: CoolTux am 25 September 2017, 08:01:16
Solche Fehler könnte man vermeiden wenn man die zum auslesen von Readings bestimmten FHEM Funktionen verwendet. Generell empfiehlt es sich nicht unnötig Hash's aus zu lesen oder für Bedingungen zu verwenden. Dafür dann lieber die FHEM Funktionen.
Ein weiterer Grund auf Hash Abfragen zu verzichten ist, das bei der Abfrage von verschachtelten Hash's auch Hash's unnötiger Weise angelegt werden.
if(hash->{READINGS}{$wdr}{VAL})
Sollte aus einem Grund {$wdr} nicht existieren wird es bei der Abfrage von {VAL} angelegt.

Sabine vielleicht schaust Du einmal das Du Deine wirklich gute Sub entsprechend um baust.
ReadingsVal währe hier angebracht. Eventuell kannst Du dann ganz auf den Wert von $hash verzichten. Habe mir aber nicht alles angeschaut. $name sollte dann reichen.

Grüße
Ich hab für meine Sub ja das movingAverage (https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen (https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen)) vom Wiki als Basis genommen und nur für die speziellen Anforderungen für die Windrichtung ergänzt.

Ganz ohne $hash wird das aber vermutlich nicht gehen, da ja dort in {"history"} das Array mit den vorhergehenden Werten gespeichert wird. Ich bin jetzt nicht so firm mit dem Development für fhem, aber vielleicht gibt es ja eine bessere Möglichkeit, das Array beim jeweiligen Device zu speichern.

pejonp hat die Sub ja jetzt in 14_SD_WS09.pm integriert, da können dann ohnehin keine falschen Readingsnamen mehr angegeben werden.

lg, Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: CoolTux am 25 September 2017, 09:12:13
Für hash->{history} kommst Du in der Tat nicht an $hash vorbei, das stimmt.
Vielleicht ergibt es sich aber das Du Dir

$hash->{READINGS}{$wsr}{VAL},deg2rad($hash->{READINGS}{$wdr}{VAL}),$hash->{READINGS}{$wdr}{TIME}

solche Sachen noch einmal an schaust und auf ReadingsVal um baust.
Ich schaue mir den Wiki Artikel einmal genauer an.



Grüße
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 25 September 2017, 09:52:33
Zitat von: CoolTux am 25 September 2017, 09:12:13
Für hash->{history} kommst Du in der Tat nicht an $hash vorbei, das stimmt.
Vielleicht ergibt es sich aber das Du Dir

$hash->{READINGS}{$wsr}{VAL},deg2rad($hash->{READINGS}{$wdr}{VAL}),$hash->{READINGS}{$wdr}{TIME}

solche Sachen noch einmal an schaust und auf ReadingsVal um baust.
Ich schaue mir den Wiki Artikel einmal genauer an.



Grüße
Ich hab jetzt
  my $hash = $defs{$name};
  my @new = my ($ws,$wd,$time) = ($hash->{READINGS}{$wsr}{VAL},deg2rad($hash->{READINGS}{$wdr}VAL}),$hash->{READINGS}{$wdr}{TIME});


durch
  my $ws = ReadingsVal($name, $wsr, undef);
  if (!defined $ws) {
    Log 0,"myWindDirAverage: Reading $name->$wsr unknown!";
    return undef;
  }
  my $wd = ReadingsVal($name, $wdr, undef);
  if (!defined $wd) {
    Log 0,"myWindDirAverage: Reading $name->$wdr unknown!";
    return undef;
  }
  my $time = ReadingsTimestamp($name, $wdr, undef);

  my $hash = $defs{$name};

ersetzt (ist im 1. Posting eingepflegt).
Falsche Angaben bei der Definition des userReadings werden damit abgefangen und im FHEM-Log angezeigt (hab ich getestet ;)).

@pejonp im 14_SD_WS09.pm ist diese Änderung nicht notwendig, dort hast du die Readings je fix vorgegeben.

lg
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: CoolTux am 25 September 2017, 11:56:37
Hallo Sabine,

Ich habe den Wikieintrag (https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen) entsprechend engepasst. Vielleicht magst ja mal drüber schauen.


Grüße
Leon
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 25 September 2017, 12:39:20
Zitat von: CoolTux am 25 September 2017, 11:56:37
Hallo Sabine,

Ich habe den Wikieintrag (https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen) entsprechend engepasst. Vielleicht magst ja mal drüber schauen.


Grüße
Leon
Im Prinzip macht meine letzte Änderung eh das gleiche. Ich hab nur zusätzlich noch eine Logausgabe eingebaut, falls nicht vorhandene Readings angegeben werden und beende dann auch gleich die sub mit "return undef".
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 25 September 2017, 13:26:07
Zitat von: pejonp am 25 September 2017, 00:03:40
Hi SabineT,

habe die Readings 14_SD_WS09.pm angepaßt.

pejonp
Ein paar Sachen sind mir noch aufgefallen:
2017.09.25 12:18:35 4: SD_WS09_WindDirAverage_01 WH1080 :Speed=1.4 DirR=2.36 Time=2017-09-25 12:18:01

Meine sub im myUtils liefert da:
2017.09.25 12:18:35 3: [WH1080 myWDA1] call: Speed=1.4 Dir=1.57 Time=2017-09-25 12:18:35

In der Praxis wirkt sich das aber nicht sonderlich aus.

Durch deinen Code bin ich übrigens drauf gekommen, dass ich bei mir deg2rad vergessen hatte, ist jetzt im 1. Posting mit berücksichtigt.

lg, Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 25 September 2017, 18:12:59
Zitat von: pejonp am 25 September 2017, 00:03:40
Hi SabineT,

habe die Readings 14_SD_WS09.pm angepaßt.

pejonp
Hallo pejonp!

Ich hab jetzt mal die sub SD_WS09_WindDirAverage so umgeschrieben, dass gleich die aktuellen Werte genommen werden. Hab sie hier dran gehängt. Die 1. Zeile wäre der dazugehörige Aufruf.

Beim Plot sieht man, dass die Werte von meiner sub in myUtils (blau) und die aus der SD_WS09 (rot) nachmittags dann praktisch gleich sind (Vormittag ist noch deine Version zu sehen).

lg, Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pejonp am 25 September 2017, 22:13:58
@pink99panther

Der Fehler bei mir war das noch keine Daten geloggt wurden. Als ich diese dann in die DBlog geschrieben habe, hat es auch funktioniert.


Zitat von: SabineT am 25 September 2017, 18:12:59
...
Ich hab jetzt mal die sub SD_WS09_WindDirAverage so umgeschrieben, dass gleich die aktuellen Werte genommen werden. ...

Hallo Sabine,

habe versuchte alle deine Änderungen einzuarbeiten. Vielen Dank für deine Hilfe. Bei der Werteübergabe in die sub hat es bei mir gehakt.
windDirAverage --> windDirectionAverage geändert. So wird er richtiger einsortiert. Neue Datei zum testen hänge ich an.


Was jetzt noch fehlt, wäre das automatische anlegen der Diagramme. gplot siehe Anhang.

in der Datei steht ja:

      $hash->{AutoCreate} =
            { "SD_WS09.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* windKorrektur:.*:0 " , FILTER => "%NAME",

GPLOT => "wind4windDir4:wind/Dir,",  autocreateThreshold => "2:180"} };

Ich bin jetzt aber noch nicht dahinter gestiegen wie der Aufruf ist. Vielleicht gibt es ja einen Wissenden.

1.Versuch der nicht geht: GPLOT => "WH1080wind4:windSpeed/windGust

Jörg
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 26 September 2017, 07:24:56
Zitat von: pejonp am 25 September 2017, 22:13:58
Hallo Sabine,

habe versuchte alle deine Änderungen einzuarbeiten. Vielen Dank für deine Hilfe. Bei der Werteübergabe in die sub hat es bei mir gehakt.
windDirAverage --> windDirectionAverage geändert. So wird er richtiger einsortiert. Neue Datei zum testen hänge ich an.


Was jetzt noch fehlt, wäre das automatische anlegen der Diagramme. gplot siehe Anhang.

in der Datei steht ja:

      $hash->{AutoCreate} =
            { "SD_WS09.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* windKorrektur:.*:0 " , FILTER => "%NAME",

GPLOT => "wind4windDir4:wind/Dir,",  autocreateThreshold => "2:180"} };

Ich bin jetzt aber noch nicht dahinter gestiegen wie der Aufruf ist. Vielleicht gibt es ja einen Wissenden.

1.Versuch der nicht geht: GPLOT => "WH1080wind4:windSpeed/windGust

Jörg
Hallo Jörg,

ich hab jetzt dein 14_SD_WS09.pm bei mir installiert (und auch im DBlog das Reading von windDirAverage auf windDirectionAverage geändert).

Zum automatischen Anlegen der Plots kann ich leider nichts sagen, ich hab meine .gplot Dateien selber erstellt (ich verwende auch gnuplot statt SVG...). Ich würde aber Windgeschwindigkeit und Windrichtung in getrennten Diagrammen darstellen, sonst wird das schnell unübersichtlich. Und windDirectionDegree würde ich ganz weg lassen, das streut speziell bei schwachem Wind viel zu stark (sieht man in meinem Beispiel beim 1. Posting).

lg, Sabine
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: pejonp am 02 Oktober 2017, 22:59:00
Hi Sabine,

habe die 14_SD_WS09.pm angepaßt und auch eingecheckt.

Mach mal bitte ein Update: update all https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/dev-r33/controls_signalduino.txt

Jörg
Titel: Antw:Mittelwertbildung für die Windrichtung
Beitrag von: SabineT am 03 Oktober 2017, 14:04:06
Hi Jörg!

Update durchgeführt. Die Datei hat sich aber gegenüber der bei mir seit 26.9. laufenden Version nicht mehr geändert, daher sollte alles passen.
Danke, dass du meine Vorschläge übernommen hast.

Liebe Grüße,
Sabine