logFromArray

Aus FHEMWiki
Version vom 28. Mai 2025, 11:58 Uhr von Pahenning (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „{{SEITENTITEL:logFromArray}} Häufig besteht in FHEM das Problem, dass man in einem Plot, dargestellt durch das SVG-Modul, zusätzliche Daten darstellen möchte. Das Hilfsmodul logProxy bietet dafür u.a. die Möglichkeit, eine horizontale oder vertikale Linie zu ziehen. Mit dem folgenden Code kann man nun beliebige Array-Daten aus irgendeinem Device passgenau so umwandeln, dass sie in einen Plot eingefügt werden können. Das Perl-Programm ''lo…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

Häufig besteht in FHEM das Problem, dass man in einem Plot, dargestellt durch das SVG-Modul, zusätzliche Daten darstellen möchte. Das Hilfsmodul logProxy bietet dafür u.a. die Möglichkeit, eine horizontale oder vertikale Linie zu ziehen.

Mit dem folgenden Code kann man nun beliebige Array-Daten aus irgendeinem Device passgenau so umwandeln, dass sie in einen Plot eingefügt werden können. Das Perl-Programm logFromArray wird mit mehreren Parametern aufgerufen:

  • filename - der Name der zu beschreibenden Log-Datei
  • device - Der Name des FHEM-Device, welches die zu schreibenden Array-Daten enthält
  • reading - Der Name des Readings, in welchem die zu schreibenden Array-Daten liegen. Diese Daten müssen in Form einer durch einen Separator (z.B. ein Komma) getrennten Liste vorliegen.
  • optional: fcsep - Ein String, der den Separator enthält (default=Komma)
  • optional: fcday - Eine Zahl, die angibt, wie viele Tage in die Zukunft das Log verschoben werden soll. 0=default heißt, die Log-Datei wird für den heutigen Tage angelegt, 1 bedeutet den folgenden Tag, etc.
  • optional: fcstart - Eine Uhrzeitangabe, wann das Log beginnen soll. 00:00 ist der Default-Wert
  • optional: fctype - 0=default oder 1. Wenn man die configDB verwendet, schreibt FHEM Daten gerne in diese. Um das zu vermeiden, kann mit einem Wert 1 erzwungen werden, dass das Logfile im Dateisystem landet.

Hier nun zunächst der Code: (Klicke auf "Ausklappen", um die Anzeige auszuklappen)

Code:
###############################################################################
#
#  Log file format from array
#  
#  Parameter: filename:obvious, isn't it? 
#             device:  FHEM device for reading data
#             reading: Name of the reading containing a data array
#      optional
#             fcsep:   separator for the array, default= ","
#             fcres:   time resolution for the array in minutes, 1..1440;
#                      deafult= 60
#                      ==> Determines the number of expected values
#             fcday:   0=today=default,1=tomorrow,2=day after tomorrow, etc.
#             fcstart: starting time for log xx:xx, default= 00:00
#             fctype:  0=default or 1. In case of using configDB, a value
#                      of 1 enforces writing to the file system instead of the 
#                      configdb
#
###############################################################################

sub logFromArray($$$;$$$$$){
  my ($filename,$device,$reading,$fcsep,$fcres,$fcday,$fcstart,$fctype) = @_;
  
  #-- get data
  my $raw = ReadingsVal($device,$reading,undef);
  if( !$raw){
    Log 1,"[logFromArray] no data available in reading $reading of device $device";
    return
  }
  
  #-- default values
  $fcsep = ","
    if(!$fcsep);
  $fcres = 60
    if(!$fcres);
  $fcday = 0
    if(!defined($fcday));
  $fcstart = "00:00"
    if(!defined($fcstart));
  $fctype = 1
    if(!defined($fctype));
    
  #-- check data
  my $num = int(1440/$fcres);
  if( $num < 1 || $num > 1440){
    Log 1,"[logFromArray] invalid time resolution, must be 1..1440";
    return
  }
  
  if( $fcstart !~ /(\d\d):(\d\d)/){
    Log 1,"[logFromArray] improper start time specification, must be xx:xx with x=digit";
    return
  }
  my $lhour=$1;
  my $lmin=$2;  
  
  my @data = split($fcsep,$raw);
  if( int(@data)!=$num){
    Log 1,"[logFromArray] invalid data number in reading $reading of device $device, expecting $num values sepatated by $fcsep";
    return
  }
  
  #-- prepare output
  my @ldata=();
  my $lstart=int(time-time%86400-7200)+$fcday*86400+$lhour*3600+$lmin*60;
  for (my $i=0;$i<$num;$i++){
    push(@ldata,strftime( "%Y-%m-%d_%H:%M:%S",localtime( $lstart+$i*$fcres*60))." $device $reading $data[$i]");
  }
  
  #-- write data
  my $ret;
  if( $fctype !=1 ){
    $ret=FileWrite($filename,@ldata);
  }else{
    my $param = { FileName => $filename, ForceType => "file", NoNL => 0 };
    $ret=FileWrite($param,@ldata);
  }
  return $ret
}

Diese Code sollte in eine Utils-Datei eingefügt werden, z.B. in die 99_myUtils.pm. Nicht vergessen, diese neu zu laden.