FHEM Forum

FHEM => Frontends => readingsGroup / readingsHistory => Thema gestartet von: pte am 13 März 2021, 16:41:36

Titel: Berechnungen (avg, min, max, ...) in ReadingsGroup
Beitrag von: pte am 13 März 2021, 16:41:36
Ich habe eine ReadingsGroup erstellt, die mir die RSSI-Werte meiner HMLAN's, CUL's pro Device auflistet. Die Spalten der IO's sind manuell angelegt mittels z.B. '!+HMLAN1_RSS' um für jedes Device in jeder Spalte einen Eintrag zu generieren.
Zusätzlich existiert eine Spalte, die mir den besten Wert der erreichbaren IO's mittels $max($ROW:4..$COLUMN-1) ermittelt.
Ich habe folgendes Problem festgestellt:
Nicht alle Devices kennen alle IO's, da sie nicht alle erreichen können. Folglich haben einige Device keinen Eintrag z.B. für 'HMLAN1_RSSI' und das Reading liefert in der Tabelle keinen numerischen Wert.
Die $max-Berechnung schlägt dann aber fehl, da ein (oder mehrere) Wert(e) nicht numerisch sind.
Soweit ich es verstanden habe, beziehen sich die Berechnungsfunktionen auch auf die direkten Readingswerte und nicht auf über valueFormat vorgenommene Ersetzungen.
Nach meiner Ansicht müsste es eine Änderung in der 33_readingsGroup.pm geben, die die Berechnung nur auf numerische Werte beschränkt.
Mein Vorschlag wäre, das "push @values, $value" nur auf numerisch auswertbare Werte zu beschränken (mit --> im Code gekennzeichnet).

use List::Util qw(min max sum);
sub
rgCalc($$$$)
{
  my ($hash,$calc,$cell_row,$cell_column) = @_;
  my $name = $hash->{NAME};

  return undef if( !defined($hash->{helper}{values}) );

  my $args;
  my $cells;
  # format: $<operator>[(<zellen>)][@<alias>]
  if( $calc =~ m/([^@\(]*)(\(([^\(]*)\))?(\(([^\(]*)\))?(@(.*))?/ ) {
    $calc = $1;
    $cells = $5;
    $args = $3 if( defined($cells) );
    $cells = $3 if( !defined($cells) );
  }

  my $firstCalcRow = main::AttrVal($name, "firstCalcRow", 1);

  $cells = '$firstCalcRow..$ROW-1' if( !$cells );

  my @values = ();
  foreach my $cell ( split( ';', $cells ) ) {
    my ($rows,$cols) = split( ':', $cell );
    $rows = '$firstCalcRow..$ROW-1' if( !$rows );
    $cols = $cell_column if( !defined($cols) );

    my $ROW = $cell_row;
    my $COLUMN = $cell_column;
    foreach my $col (eval "($cols)") {
      foreach my $row (eval "($rows)") {
        my $value = $hash->{helper}{values}{orig}[$col][$row];
        if( defined($value) && $value ne '-') {
          #$value =~ s/[^-\.\d]//g;
 -->     push @values, $value if ($value !~ m/[^-\.\d]/);   #der verwendete regex deckt so noch nicht alle nicht auswertbaren Ausdrücke ab, das kann jemand vielleicht besser
        }

        if( ${hash}->{inDetailFn} ) {
          #FIXME: also add indirect cells
          $hash->{helper}{recalc}[$col][$row] .= "," if( $hash->{helper}{recalc}[$col][$row] );
          $hash->{helper}{recalc}[$col][$row] .= "$cell_row:$cell_column";
        }
      }
    }
  }

  if( $calc eq 'avg' ) {
    my $cnt = scalar @values;
    return undef if( !$cnt );
    return ( sum @values ) / $cnt;
  } elsif( $calc eq 'count' ) {
    return rgCount( $args, \@values );
  }

  return eval $calc .' @values';
}

Kann man das in den Standard übernehmen, oder habe ich was übersehen?

Gruß Peter