Grafische Anzeige eines Temperatur-Logfiles

Durch 'lm-sensors' läßt sich u.a. die Temperatur des Prozessors auslesen. Wenn man diese Temperatur(en) in ein Logfile schreiben läßt, kann man dieses Logfile auch grafish in einer Kurve darstellen lassen. Dazu benötigen wir lediglich Perl::Tk. und ein paar Script-Zeilen.

Das Logfile hat folgende Struktur:

      04/22/2002 12:30 CET
      60.0 39.0 45.3
      04/22/2002 12:20 CET
      60.0 39.0 46.3
      04/22/2002 12:10 CET
      60.0 39.0 44.3
      04/22/2002 12:00 CET
      60.0 39.0 45.5
      04/22/2002 11:50 CET
      60.0 39.0 39.3
      04/22/2002 11:40 CET
      60.0 39.0 40.3
      04/22/2002 11:30 CET
      60.0 39.0 42.7
      04/22/2002 11:20 CET
      60.0 39.0 45.0
      [...]
    

Das Logfile zeigt also pro Eintrag zwei Zeilen. Einmal die Zeit der Aufzeichnung und einmal die Temperaturen. Die Temperaturen stehen in folgender Reihenfolge: maximale Temperatur, minimale-Temperatur, aktuelle Temperatur.

Ziel ist die Ausgabe der drei Temperaturwerte des gesamten Logfiles in einer Grafik:

Grafik der Temperaturverläufe

Script - Teil 1

 #! /usr/bin/perl
 use strict;
 use diagnostics;

 use Tk;

 # Pfad zum Logfile
 # Dieser muß natürlich angepaßt werden!
 my $logfile = "/home/martin/.temperature.log"; 

 # Zoom-Faktor
 # stellt die Größe der Anzeige ein ... kann eigentlich so bleiben
 my $zoom = 2; 

 # Breite der Anzeige
 my $graph_width = 10000;

 # Logfile einlesen und in Arrays aufteilen ...
 open (LOG, "<$logfile");
 my @temperature_log = <LOG>;
 close (LOG);

 my (@max_temp, @min_temp, @akt_temp);

 foreach (@temperature_log)
 {
   if ($_ =~ m/(\d\d\.\d) (\d\d\.\d) (\d\d\.\d)/i)
   {
     push (@max_temp, $1);
     push (@min_temp, $2);
     push (@akt_temp, $3);
   }
 }
    

Im ersten Teil des Scriptes wird zunächst das Logfile geöffnet, eingelesen und die Zeilen mit den Temperaturen werden nacheinander in die Arrays '@max_temp', '@min_temp' und '@akt_temp' geschrieben. Insgesamt also nichts Spektakuläres.

Script - Teil 2

 # Jetzt wird gezeichnet
 my $graph_window = MainWindow -> new;
 $graph_window -> title ("TempWatch by Martin Holz \&lt;martin\@martinholz.de\&gt;");
 my $button_bar = $graph_window -> Frame (-relief => 'raise') -> pack (-anchor => 'nw');
 $button_bar -> Button (
                        -text => 'Beenden', 
                        -command => sub {exit}
                        ) -> grid (-column => 0, -row => 0);
 $button_bar -> Button (
                        -text => 'Als PostScript speichern', 
                        -command => \&saveas
                        ) -> grid (-column => 1, -row => 0);

 my $canvas = $graph_window -> Scrolled('Canvas') -> pack(-anchor => 'n');

 my ($graph_max, $graph_min, $graph_akt, $v_scale, $v_scale_text);

 my $v_zero = 200;
 my $last_max_degree = 200;
 my $last_min_degree = 200;
 my $last_akt_degree = 200;
 my $timestamp = 30;
 my $last_timestamp = 30;

 my $meridian = $canvas -> createLine(0,$v_zero,$graph_width,$v_zero);
 my $meridian_text = $canvas -> createText(15,210, -text => "0°C");

 # Legende
 $canvas -> createLine(10,240,20,240, -fill => 'red');
 $canvas -> createText(30,240, -text => "= maximale Temperatur", -anchor => 'w');
 $canvas -> createLine(10,255,20,255, -fill => 'green');
 $canvas -> createText(30,255, -text => "= minimale Temperatur", -anchor => 'w');
 $canvas -> createLine(10,270,20,270, -fill => 'blue');
 $canvas -> createText(30,270, -text => "= aktuelle Temperatur", -anchor => 'w');

 for (my $i = 200 - (10*$zoom); $i > 0; $i = $i - (10*$zoom))
 {
   $v_scale = $canvas -> createLine(0,$i,$graph_width,$i, -fill => 'gray80');
   my $scale_degree = (200 - $i)/$zoom;
   $v_scale_text = $canvas -> createText(15,$i, -text => "$scale_degree°C");
 }
    

Der zweite Teil des Scriptes erstellt die eigentliche Grafische Oberfläche. Zuerst wird ein Fenster ($graph_window) erstellt. Darin wiederum eine Leiste mit zwei Schaltfächen ('Beenden' und 'Als PostScript speichern'). Danach wird ein Canvas-Widget erzeugt. In dem Canvas-Widget kann gezeichnet werden (wird also für die Ausgabe der Kurven benötigt.). Es folgen einige Definitionen für die Anfangswerte und dann wird die Legende und das Koordinatenkreuz erzeugt.

Script - Teil 3

 my $cnt = -1;
 foreach (@akt_temp)
 {
   $cnt++;
   $timestamp = $timestamp+(10*$zoom);

   chomp $max_temp[$cnt];
   chomp $min_temp[$cnt];
   chomp $akt_temp[$cnt];

   my $max_degree = $max_temp[$cnt] * $zoom;
   $max_degree = $v_zero - $max_degree;

   my $min_degree = $min_temp[$cnt] * $zoom;
   $min_degree = $v_zero - $min_degree;

   my $akt_degree = $akt_temp[$cnt] * $zoom;
   $akt_degree = $v_zero - $akt_degree;

   # Kurven zeichnen ...
   $graph_max = $canvas -> createLine($last_timestamp,$last_max_degree,$timestamp,$max_degree,-fill => 'red');
   $graph_min = $canvas -> createLine($last_timestamp,$last_min_degree,$timestamp,$min_degree,-fill => 'green');
   $graph_akt = $canvas -> createLine($last_timestamp,$last_akt_degree,$timestamp,$akt_degree,-fill => 'blue');

   $last_max_degree = $max_degree;
   $last_min_degree = $min_degree;
   $last_akt_degree = $akt_degree;

   $last_timestamp = $timestamp;
 }
 MainLoop;
    

Der dritte Teil des Scripts erzeugt nun die Kurven. Die Werte dazu stammen aus dem in Teil 1 eingelesenen Arrays. Die Kurven werden ausschließlich über Werte aus Variablen Erzeugt. Die Anfangswerte stehen in Teil 2. Danach werden jeweils die alten Werte und die Werte aus den Arrays genutzt, damit die Kurven auch jeweils beim alten Wert starten. (Anm.: Die Variablen 'time_stamp' und 'last_timestamp' werden im Moment noch nicht aus Zeitwerten erzeugt, sondern jeweils mit '+10' erhöht.)

Script - Teil 4

 sub saveas {
   my $save_file = $graph_window -> getSaveFile (
				-defaultextension => ".ps",
				-filetypes        => [['PostScript', '.ps'],],
				-initialfile      => "temperatures_graph.ps",
			        );
   my $postscript = $canvas->postscript(-file => "$save_file");
 }
    

Der vierte Teil des Scriptes besteht nur aus einem kleinen SUB, welches die Grafik über einen Speichern-Dialog als PostScript-Datei speichert.

Screenshot

Nun fehlt nur noch ein Screenshot des fertigen Programms:

Screenshot

Download

Das komplette Script zum Download: tempwatch.pl


Martin Holz | Impressum

Valid HTML 4.01!