Feinstaub messen – Auswertungen und Graph

In dem ursprünglichen Artikel zum Thema Feinstaub ist die Auswertung der aufgezeichneten Daten etwa zu kurz gekommen. Daher hier ein paar Infos wie die Auswertungen und der Graph bei folgendem Screenshot zustande gekommen sind:


Tabellenstruktur

Die Tabellenstruktur zur Speicherung der Werte in der Datenbank ist wie immer einfach gehalten. Hier das Create-Table-Script:

[cc lang=”sql” escaped=”true”]
CREATE TABLE ‘feinstaub’ (
‘timestamp’ datetime NOT NULL,
‘ppm25’ float NOT NULL,
‘ppm10’ float NOT NULL
)
[/cc]

Auswertung

Die folgenden SQL-Querys sind Beispiele zur Abfrage von MySQL-Datenbanken.

Die aktuell gespeicherten Sensorwerte werden wie folgt ausgelesen:
[cc lang=”sql” escaped=”true”]
SELECT DATE_FORMAT(timestamp, ‘%d.%m.%Y %H:%i:%s’),ppm25,ppm10 FROM feinstaub ORDER BY timestamp DESC LIMIT 1
[/cc]

Die Werte für das Jahresmittel selektieren:
[cc lang=”sql” escaped=”true”]
SELECT avg(ppm25),avg(ppm10) FROM feinstaub WHERE YEAR(timestamp) = YEAR( CURDATE())
[/cc]

Die Werte für das Tagesmittel selektieren:
[cc lang=”sql” escaped=”true”]
SELECT avg(ppm25),avg(ppm10) FROM feinstaub WHERE DATE(timestamp) = CURDATE()
[/cc]

Graph

Hier ein PHP-Code-Beispiel für das Zeichnen des Graphen mit dem Verlauf beider Feinstaubwerte der letzten 96 Stunden. Dazu nutze ich, wie meistens, pChart http://www.pchart.net/). Die Datenbankabfrage ist noch mit dem inzwischen in PHP 5.7 veralteten Funktion mysql_connect realisiert. Das sollte auf mysqli_connect umgestellt werden (ich habe dafür bei meiner Anwendung aber aktuell keine Muse zu…):

<?
include("../class/pData.class.php");
include("../class/pDraw.class.php");
include("../class/pImage.class.php");

$connection=mysql_connect("","","") or die ("Verbindungsversuch fehlgeschlagen");
$mysqldb="";
mysql_select_db($mysqldb,$connection) or die("Konnte die Datenbank nicht waehlen.");
$sql = "SELECT ppm25,ppm10, hour(timestamp) FROM feinstaub WHERE DATE_ADD(timestamp, INTERVAL 96 HOUR) >= NOW()";
$query = mysql_query($sql) or die("Anfrage 1 nicht erfolgreich");
while ($wert = mysql_fetch_array($query)) {
	$pm25[]=$wert[0];
	$pm10[]=$wert[1];
	if ($zeit_tmp==$wert[2]) {
		$zeit_tmp=NULL;
	} else {
		$zeit_tmp=$wert[2];
	}
	$zeit[]=$zeit_tmp;
}

//Graph für Feinstaubwerte
$MyData = new pData();
$MyData->addPoints($pm25,"PM2,5");
$MyData->addPoints($pm10,"PM10");
$MyData->setAxisName(0,"Feinstaub &micro;m/m&sup3;");
$MyData->addPoints($zeit,"Labels");
$serieSettings = array("R"=>229,"G"=>11,"B"=>11,"Alpha"=>100);
$MyData->setPalette("PM2,5",$serieSettings);
$serieSettings = array("R"=>129,"G"=>111,"B"=>211,"Alpha"=>100);
$MyData->setPalette("PM10",$serieSettings);
$MyData->setSerieDescription("Labels","Uhrzeit");
$MyData->setAbscissa("Labels");
$myPicture = new pImage(1025,380,$MyData);
$myPicture->Antialias = TRUE;
$myPicture->setFontProperties(array("FontName"=>"../heizung/fonts/verdana.ttf","FontSize"=>10));
$myPicture->setGraphArea(50,30,1010,355);
$labelSkip = round(count($zeit)/48);
$scaleSettings = array("XMargin"=>10,"YMargin"=>10,"Floating"=>TRUE,"GridR"=>200,"GridG"=>200,"GridB"=>200,"DrawSubTicks"=>FALSE,"CycleBackground"=>TRUE,"LabelSkip"=>$labelSkip);
$myPicture->drawScale($scaleSettings);
$myPicture->Antialias = FALSE;
$myPicture->setShadow(TRUE,array("X"=>1,"Y"=>1,"R"=>0,"G"=>0,"B"=>0,"Alpha"=>10));
$myPicture->drawSplineChart();
$BoundsSettings = array("MaxDisplayR"=>237,"MaxDisplayG"=>23,"MaxDisplayB"=>48, "MinDisplayR"=>23,"MinDisplayG"=>144,"MinDisplayB"=>237);
$myPicture->writeBounds(BOUND_BOTH,$BoundsSettings);
$myPicture->drawLegend(650,20,array("Style"=>LEGEND_NOBORDER,"Mode"=>LEGEND_HORIZONTAL));
$Settings = array("R"=>229,"G"=>11,"B"=>11,"Align"=>TEXT_ALIGN_BOTTOMLEFT);
$myPicture->drawText(800,35,"Max : ".ceil($MyData->getMax("PM2,5")),$Settings);
$myPicture->drawText(880,35,"Min : ".ceil($MyData->getMin("PM2,5")),$Settings);
$myPicture->drawText(940,38,"Avg : ".ceil($MyData->getSerieAverage("PM2,5")),$Settings);
$Settings = array("R"=>129,"G"=>111,"B"=>211,"Align"=>TEXT_ALIGN_BOTTOMLEFT);
$myPicture->drawText(800,20,"Max : ".ceil($MyData->getMax("PM10")),$Settings);
$myPicture->drawText(880,20,"Min : ".ceil($MyData->getMin("PM10")),$Settings);
$myPicture->drawText(940,23,"Avg : ".ceil($MyData->getSerieAverage("PM10")),$Settings);
$myPicture->Render("feinstaub.png");
?>

Viel Spaß beim Auswerten der Daten!

Gruß
Chris

3 Gedanken zu „Feinstaub messen – Auswertungen und Graph

  • 29. Dezember 2017 um 13:55 Uhr
    Permalink

    Hallo zusammen,

    ich steh auf dem Schlauch, die Tabelle habe ich angelegt, doch wie bekomme ich die Werte in die Datenbank?
    Kann mir hier jemand weiterhelfen?

    Vielen Dank

    Antwort
    • 29. Dezember 2017 um 22:46 Uhr
      Permalink

      Hi,
      die Daten per JSON wie im ersten Artikel beschrieben mit einen Script auslesen und die Werte in der Datenbank speichern. Das Script dann alle x Minuten per CRON aufrufen. In PHP schaut das dann z.B. so aus:

      /data.json’);
      $json_ergebnis=json_decode($json);
      $PPM10=$json_ergebnis->sensordatavalues[0]->value;
      $PPM25=$json_ergebnis->sensordatavalues[1]->value;

      $servername = ““;
      $username = ““;
      $password = ““;
      $dbname = ““;

      $connection = new mysqli($servername, $username, $password, $dbname);
      if ($connection->connect_error) {
      die(“Connection failed: ” . $connection->connect_error);
      }
      $sql = “INSERT INTO feinstaub (timestamp,ppm25,ppm10) VALUES (CURRENT_TIMESTAMP,$PPM25,$PPM10)”;
      if ($connection->query($sql) === TRUE) {
      //echo “INSERT war erfolgreich”;
      } else {
      echo “Error: ” . $sql . “
      ” . $connection->error;
      }
      ?>

      Hoffe das hilft.

      Gruß
      Chris

      Antwort
      • 30. Dezember 2017 um 14:32 Uhr
        Permalink

        Hallo Chris,

        super vielen Dank. Jetzt funktioniert es wunderbar.
        Mit JSON hatte ich noch keine Berührungspunkte deswegen hatte
        es geklemmt.
        Auf weitere tolle Projekte.

        Gruß Joachim

        Antwort

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert