<?php
// PHP-Script fuer das Langweilometer

// Pfad zum Binary (SIUD root)
define("SETDAC", "/home/pi/lwm_setdac");

// Pfad zur Datendatei, diese muss fuer den
// User www-data beschreibbar sein
define("DATAFILE", "/home/pi/boring");

// Anzahl Daten in der Datendatei
define("MAXDATA", "11");

// Passwort-Hash (damit das Passwort geheim bleibt)
$PW = '906072001efddf3e11e6d2b5782f4777fe038739';

// Beginn der HTML-Seiten
vorspann();
print '<div align="center"><H2>Das Langweilometer</H2>';
// Woher kommt die Anfrage
$Client = $_SERVER['REMOTE_ADDR'];
// Formularstatus checken
$Status = (isset($_POST['STATUS']))? $_POST['STATUS']: "NIX";
// Formular wurde ausgefuellt, ensprechende agieren
if ($Status == 'Absenden')
  {
  // Formulardaten pruefen
  // Verarbeitung der Text-Felder
  // Passwort nur von ausserhalb der Fakulteat noetig
  if (preg_match('/^10\.27\./', $Client))
    { $Passwort = $PW; }
  else
    {
  $Passwort = security_filter($_POST['Passwort']);
  $Passwort = trim($Passwort);
  check($Passwort,"Passwort");
  $Passwort = sha1($Passwort);
    }
  if ($Passwort != $PW)
    {
    print '<h1>Sorry, falsches Passwort!</h1>';
    nachspann();
    exit;
    }
  $Level = security_filter($_POST['LEVEL']);
  check($Level,"Level");
  // Analogwert speichern
  insert($Level, DATAFILE);
  }
if ($Status == 'Neueingabe')
  {
  // Formular ausgeben
  print '
   <P>
   <form action="'.$_SERVER['PHP_SELF'].'" method="POST">
   <table border="0" cellspacing="1" cellpadding="2">
     <tr>
      <td bgcolor="#eeeeee"><font size="-1">Passwort<br />
                            (innerhalb der FK04 nicht n&ouml;tig)</font></td>
      <td valign="top" bgcolor="#eeeeee"><input type="text" name="Passwort" value="" size="10"></td>
     </tr>
     <tr>
      <td bgcolor="#eeeeee"><font size="-1">Langeweile-Pegel in Prozent<br />
                            (1 = Super, 100 = Schlaftablette)</font></td>
      <td valign="top" bgcolor="#eeeeee"><input type="text" name="LEVEL" value="50" size="10"></td>
     </tr>
    <tr><td colspan="2" align="center">
         <br /><input type="submit" name="STATUS" value="Absenden"></td>
     <td>&nbsp;</td></tr>
    </table>
    </form>
   </P>
  ';
  }

// Mittelungs-Algorithmus aufrufen
list ($Level, $Mittel, $Min, $Max) = calculate_median(DATAFILE);
// Anzeigeinstrument setzen ...
$cmd = SETDAC . ' ' . $Mittel;
system($cmd, $retval);
// ... und auf der Webseite anzeigen
print '<p><b>Derzeitiger Langeweile-Pegel:</b><br /><br />
       <table border="1" cellpadding="0" cellspacing="0"
       style="border-collapse: collapse;">
       <tr><td width="33%" bgcolor="#ccffcc" align="center">KURZWEILIG</td>
       <td bgcolor="#ffffcc" align="center">GEHT SO</td>
       <td width="33%" bgcolor="#ffcccc" align="center">LANGWEILIG</td></tr>
       <tr><td colspan="3">';
balken($Mittel);
print '</td></tr>
       <tr><td align="left"> &nbsp; Minimum: ' . $Min . ' %</td>
           <td align="center"> Letzte Eingabe: ' . $Level . ' %</td>
           <td align="right">Maximum: ' . $Max . ' % &nbsp; </td></tr>
       <tr><td colspan="3" align="center">Letzte &Auml;nderung: ' .
       date ("d.m.Y, H:i", filemtime(DATAFILE)) . ' Uhr</td></tr>
       </table><br />
       ';
       if ($Status != "Neueingabe")
         {
         print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST"><br />
         <input type="submit" name="STATUS" value="Neueingabe"></form>';
         }
print '</div>';

nachspann();

// ================================== Funktionen =================================

// Check auf leeren String, ggf. Fehlermeldung und EXIT
function check($TVar, $Description)
 {
  if(empty($TVar))
    {
    print '<b><font color="#CC0000">
           Formular unvollst&auml;ndig ausgef&uuml;llt - bitte ' . $Description .
          ' angeben/korrigieren.<br />Nichts gespeichert!</b></font><br /><br />' .
          '<a href="javascript:history.back();"><B>Zur&uuml;ck</B></a><br />'."\n";
    nachspann();
    exit;
    }
  }

// HTML-Vorspann am Anfang
function vorspann()
{
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="content-type" CONTENT="text/html; CHARSET=iso-8859-1">
<META NAME="keywords" CONTENT="Elektrotechnik,Informationstechnik,FH,Hochschule Mnchen">
<title>Langweilometer</title>
<style type="text/css">
h1,h2,h3,h4 { font-family: "Helvetica,Arial,sans-serif"; }
p,li { font-family: "Helvetica,Arial,sans-serif"; }
td { font-family: "Helvetica,Arial,sans-serif"; }
</style>
</head>

<body text="#000000" bgcolor="#ffffff" link="#000000" vlink="#000000" alink="#000000">
';
}

// HTML-Nachspann am Ende
function nachspann()
{
print '<BR /><BR /><BR />
<table align="center" width="80%" border="0" cellpadding="0" cellspacing="0">
  <tr>
   <td bgcolor="#CCCCCC" align="center">
   Das Chaos will anerkannt, will gelebt sein, ehe es sich in eine neue
    Ordnung bringen l&auml;&szlig;t.
    </td>
  </tr>
  <tr>
   <td align="center">
    Eine Dokumentation finden Sie unter 
    <a href="http://www.netzmafia.de/skripten/hardware/RasPi/Projekt-Langweilometer/">
    www.netzmafia.de/skripten/hardware/RasPi/Projekt-Langweilometer/</a>
    </td>
  </tr>
</table>
</body>
</html>
';
}

// Entfernt aus einem gequoteten String alle Quotes
function my_remove_slashes($st)
  {
  if (get_magic_quotes_gpc()) { return stripslashes($st); }
  else { return $st; }
  }

// Filtert "boese" Dinge
function security_filter($st)
  {
  $attribs = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|'.
             'onmousemove|onmouseout|onkeypress|onkeydown|onkeyup';

  $st = my_remove_slashes($st);
  $st = stripslashes(preg_replace("/$attribs/i", 'forbidden', $st));
  $st = strip_tags($st);
  $st = preg_replace('/;/',',',$st);
  return $st;
  }

// "Zeichnet" einen horizontalen Balken mit zwei Farben (CSS)
function balken($prozentsatz)
  {
  // $gesamtbreite: Breite des Balkens in Pixel (ohne Einheit)
  // $prozentsatz: Eingabe-Wert
  // $border: Rahmendefinition in CSS (OHNE abschliessendes ; )
  //           -> "none" fr keinen Rahme
  // $farben: Der Balken kann je nach Prozentzahl gefrbt werden.

  $gesamtbreite = 600;
  $border = "2px solid #000000; background-color: #EEEEEE";
  $farben = array("0-20"   => "#00ff00",
                  "21-40"  => "#ffff00",
                  "41-60"  => "#ff9900",
                  "61-80"  => "#ff0000",
                  "81-100" => "#ff00ff"
                  );

  $balkenbreite = intval(($prozentsatz * $gesamtbreite)/100);
  foreach($farben AS $bereich => $farbe)
    {
    $grenzwerte = explode("-", $bereich);
    if(($grenzwerte[0] <= $prozentsatz) && ($prozentsatz <= $grenzwerte[1]))
      {
      $balken_farbe = $farbe;
      break;
      }
    }
  if(!isset($balken_farbe)) { $balken_farbe = "orange"; }
  print '<div style="text-align: left; border: ' . $border . '; width: ' .
        $gesamtbreite . 'px; height: auto; padding: 0px;">' . "\n" .
        '<div style="text-align: center; width: ' . $balkenbreite .
        'px; background-color: ' . $balken_farbe . ';"> &nbsp; ' .
        $prozentsatz . " %</div>\n" .
        "</div>\n";
  }

// Datenmittelung mit gleitendem Durchschnitt
function calculate_mean($datafile)
  {
  // Datei einlesen
  $lines = array();
  if (is_readable($datafile))
    { $lines = file($datafile); }
  // sind es (anfangs) noch wenige Elemente, mit 50%-Werten ergaenzen
  while (count($lines) < MAXDATA)
    { $lines[] = 50; }
  $aktual = $lines[0];
  // Leerzeichen weg
  for ($i = 0; $i < MAXDATA; $i++)
    { $lines[$i] = trim($lines[$i]); }
  // aufsteigend sortieren
  sort($lines);
  // Maxima berechnen
  $min = $lines[0];
  $max = $lines[MAXDATA-1];
  $sum = 0;
  foreach ($lines as $line)
    { $sum = $sum + $line; }
  $mean = intval($sum/MAXDATA);
  // aktueller Wert, Mittelwert, Minimum, Maximum
  return array ($aktual, $mean, $min, $max);
  }

// Datenmittelung mit Median
function calculate_median($datafile)
  {
  // Datei einlesen
  $lines = array();
  if (is_readable($datafile))
    { $lines = file($datafile); }
  // sind es (anfangs) noch wenige Elemente, mit 50%-Werten ergaenzen
  while (count($lines) < MAXDATA)
    { $lines[] = 50; }
  $aktual = $lines[0];
  // Leerzeichen weg
  for ($i = 0; $i < MAXDATA; $i++)
    { $lines[$i] = trim($lines[$i]); }
  // aufsteigend sortieren
  sort($lines);
  // Maxima berechnen
  $min = $lines[0];
  $max = $lines[MAXDATA-1];
  if(MAXDATA % 2 == 0)
    {
    //gerade Anzahl => der Median ist das arithmetische Mittel der beiden mittleren Zahlen
    $mean = ($lines[(MAXDATA/2) - 1] + $lines[MAXDATA/2])/2;
    } 
  else 
    {    
    //ungerade Anzahl => der mittlere Wert ist der Median    
    $mean = $lines[MAXDATA/2];
    }
  // aktueller Wert, Mittelwert, Minimum, Maximum
  return array ($aktual, $mean, $min, $max);
  }

// Neuen Datenwert in die Datei einfuegen
// Die Datei enthaelt immer die letzten MAXDATA Werte
function insert($newvalue, $datafile)
  {
  // Datei einlesen
  $lines = array();
  if (is_readable($datafile))
    { $lines = file($datafile); }
  // sind es (anfangs) noch wenige Elemente, mit 50%-Werten ergaenzen
  while (count($lines) < MAXDATA)
    { $lines[] = 50; }
  // neuen Wert hinzufuegen, letzten Wert entfernen
  for ($i = MAXDATA - 1; $i > 0; $i--)
    { $lines[$i] = $lines[$i-1]; }
  $lines[0] = $newvalue;
  // Datei aktualisieren
  if (is_writable($datafile))
    {
    $handle = @fopen($datafile, "w");
  for ($i = 0; $i < count($lines); $i++)
      { fwrite($handle, trim($lines[$i]) . "\n"); }
    fclose($handle);
    }
  }
?>


