<?
/*
 * graph.php:
 * reads wp-entries from database and plots different graphs with jpgraph (version 1.26)
 * time resolution: minute
 * parameters given by _GET:
 * - only minutes: graph will be plot from now to x minutes in the past
 * - only start: graph will be plot from start up to now
 * - start & minutes: graph will be plot from start until x minutes
 * - no parameters: graph will be plot from now to 6 hours in the past
 *
 * thanks to the developers of jpgraph for saving me a lot of time!
 *
 * (c) 2008 alexander.philipp.lintenhofer
 */
 
    require_once("_includes/db_handle.php");        // wrapper-functions for mysql (not included)
    include("_includes/arrLineValues.inc.php");
    include("_includes/globals.inc.php");
    include("_includes/jpgraph/jpgraph.php");       // jpgraph version 1.26
    include("_includes/jpgraph/jpgraph_line.php");
    include("_includes/jpgraph/jpgraph_date.php");

    DEFINE( "USE_CACHE", true);
    DEFINE("READ_CACHE", true);
    DEFINE( "CACHE_DIR", "/tmp/jpgraph_cache/");

    set_time_limit(60);

    $width  = 980;
    $height = 510;

    $arrGraphs = array(
//=============================================================================================
        array(
                'title'      => 'Hzg/Ww',
                'lines'      => array('tempeinsatz','tempaussen','vorlauf','rlSoll','ruecklauf','warmwasser','delta_vl_rl'),
                'idleVals'   => true
        ),
//---------------------------------------------------------------------------------------------
        array(
                'title'      => 'Erdsonde',
                'lines'      => array('wq_ein','wq_aus','delta_wqein_wqaus'),
                'idleVals'   => false
        ),
//---------------------------------------------------------------------------------------------
        array(
                'title'      => 'Vorlauf/Kondensator',
                'lines'      => array('kondensator','vorlauf','delta_kondensator_vl'),
                'idleVals'   => false
        ),
//---------------------------------------------------------------------------------------------
        array(
                'title'      => 'Wärmequelle aus/Verdampfer',
                'lines'      => array('wq_aus','verdampfer','delta_wqaus_verdampfer'),
                'idleVals'   => false
        ),
//---------------------------------------------------------------------------------------------
        array(
                'title'      => 'Carnot-Wirkungsgrad',
                'lines'      => array('kondensator','verdampfer','leistungsaufnahme','carnot'),
                'idleVals'   => false
        )
//=============================================================================================
    );

    $graphID = intval($_GET['graph']);
    if (($graphID < 0)||($graphID>(count($arrGraphs)-1))) exit;

    if (($start=intval($_GET['start']))&&(($start>(time()-120))||($start<1226707200))) $start = time()-(3600*6);    
    $minutes = ($_GET['minutes'])?abs(intval($_GET['minutes'])):(($start)?0:360);

//=============================================================================================
// ==== fetch data ============================================================================
    $sql     = "SELECT tsp_0501_0500 AS tsp, m_0900 AS betriebszustand, m_0100 AS tempaussen, m_0101 AS tempaussen24h, m_0102 AS tempaussen1h, m_0201 AS tempeinsatz";
    foreach ($arrGraphs[$graphID]['lines'] as $key) $sql .= ','.$arrLineValues[$key]['select_expr'].' AS '.$key;   
    $sql     .= " FROM $db_getTable";
    if ($start)
    {
        $sql .= " WHERE tsp_0501_0500 > $start";
        if ($minutes) $sql .= " AND tsp_0501_0500 < ".($start+(60*$minutes));
        $sql .= " ORDER BY tsp_0501_0500 ASC";
    }
    // Attention: result set will be in reverse order, but jpgraph_date.php fixes it! 
    else $sql .= " WHERE tsp_0501_0500 > ".(time()-($minutes*60))." ORDER BY tsp_0501_0500 DESC";

    $arrQ = wrapper_query_in_hash($sql);

    if (count($arrQ)<1)
    {
        $sql = "SELECT m_0501, m_0500 FROM $db_getTable ORDER BY tsp_0501_0500 ASC";
        $arrQ = wrapper_query_in_hash($sql);
        if (($lastIndex = count($arrQ)-1)>0)
        {
            echo "Daten zwischen <strong>".$arrQ[0]['m_0501'].", ".$arrQ[0]['m_0500']."</strong> und <strong>".$arrQ[$lastIndex]['m_0501'].", ".$arrQ[$lastIndex]['m_0500']."</strong> verf&uuml;gbar";
        }
        else echo "Keine Daten verf&uuml;gbar";
        exit;
    }

//=============================================================================================
// ==== prepare data arrays ===================================================================
    for ($i=$minVal=$maxVal=0; $i < count($arrQ); $i++)
    {
        $arrXLabels[$i]  = $arrQ[$i]['tsp'];

        foreach ($arrGraphs[$graphID]['lines'] as $key)
        {
            // put values dependend on machine activity
            if (!$arrLineValues[$key]['idleVals'] && (($arrQ[$i]['betriebszustand'] & 0x03)==0))
            {
                ${$key}[$i] = 'x';
            }
            else
            {
                ${$key}[$i] = round($arrQ[$i][$key],1);
                if ($arrQ[$i][$key] < $minVal) $minVal = $arrQ[$i][$key];
                if ($arrQ[$i][$key] > $maxVal) $maxVal = $arrQ[$i][$key];
            }
        }
    }

    // prepare display-arrays to display machine-activity
    $minVal = floor($minVal)-1;
    $activeMinsHzg = $activeMinsWW = 0;

    for ($i=0,$tendence=0; $i < count($arrQ); $i++)
    {
        $arrActHotWater[$i] = $arrActHeating[$i] = $arrHeatingNotSummer[$i] = 'x';

        if ($arrQ[$i]['betriebszustand'] & 0x03)
        {
            if ($arrQ[$i]['betriebszustand'] & 0x01)
            {
                $arrActHotWater[$i] = $minVal;
                $activeMinsWW++;
            }
            else if ($arrQ[$i]['betriebszustand'] & 0x02)
            {
                $arrActHeating[$i] = $minVal;
                $activeMinsHzg++;
            }
        }

        # increasing temp -> tempaussen1h; decreasing temp -> tempaussen
        $tendence = (($i>=10)&&($arrQ[($i-10)]['tempaussen1h']>$arrQ[$i]['tempaussen1h']))?-1:1;
        # toggle, if db-resultset is in reverse order
        if (!$start) $tendence *= -1;

        $currTempaussen = ($tendence<0)?$arrQ[$i]['tempaussen']:$arrQ[$i]['tempaussen1h'];

        if (($currTempaussen<=$arrQ[$i]['tempeinsatz'])
         &&($arrQ[$i]['tempaussen24h']<=$arrQ[$i]['tempeinsatz']))
        {
            $arrHeatingNotSummer[$i] = $minVal;
        }
    }

    $timeDisplay = intval($activeMinsHzg/60).':'.(sprintf("%02d",$activeMinsHzg%60)).'/'.
                   intval($activeMinsWW/60).':'.(sprintf("%02d",$activeMinsWW%60));

//=============================================================================================
// ==== prepare graph =========================================================================

    $graph  = new Graph($width, $height,"auto",1);
    $graph->img->SetAntiAliasing();
    $graph->SetScale("datlin",$minVal,ceil($maxVal+($maxVal/20)));
    $graph->SetTickDensity(TICKD_DENSE);
    $graph->SetMargin(40,35,35,110);
    $graph->SetMarginColor('white');
    $graph->SetFrame(false);

    $graph->legend->SetLayout(LEGEND_HOR);
    $graph->legend->SetShadow('gray@0.4',5);
    $graph->legend->SetPos(0.01,0.01,'right','top');

    $graph->SetAxisStyle(AXSTYLE_BOXOUT); 
    $graph->xaxis->SetTickSide(SIDE_BOTTOM);

    $graph->xaxis->SetPos('min');
    $graph->xaxis->scale->SetTimeAlign(MINADJ_10);
    $graph->xaxis->scale->SetDateFormat('d.m. H:i');
    $graph->xaxis->SetTextLabelInterval(1);
    $graph->xaxis->SetLabelAngle(90);
    $graph->xaxis->SetTickSide(SIDE_TOP);

    $graph->yaxis->HideFirstTicklabel();
    $graph->yaxis->HideLastTicklabel();

    $graph->Add(new PlotLine (HORIZONTAL,0, "gray",1));

    $graph->xgrid->Show(true,false);
    $graph->xgrid->SetLineStyle('dashed'); 
    $graph->ygrid->SetFill(true,'#FFFFFF@0.4','#F8F8F8@0.4');
    $graph->ygrid->Show(true, true);
    $graph->ygrid->SetLineStyle('dashed');
    
//=============================================================================================
// ==== prepare plots =========================================================================

    foreach ($arrGraphs[$graphID]['lines'] as $key)
    {
        $lineplot[$key] = new LinePlot($$key,$arrXLabels);
        $lineplot[$key]->SetColor($arrLineValues[$key]['color']);
        $lineplot[$key]->SetLegend($arrLineValues[$key]['attribute']); 
        $graph->Add($lineplot[$key]);
    }

    $heatingNotSummerplot = new LinePlot($arrHeatingNotSummer,$arrXLabels);
    $heatingNotSummerplot->SetColor('yellow');
    $heatingNotSummerplot->SetWeight(4);
    $graph->Add($heatingNotSummerplot);

    $actHotWaterplot = new LinePlot($arrActHotWater,$arrXLabels);
    $actHotWaterplot->SetColor('red');
    $actHotWaterplot->SetWeight(4);
    $graph->Add($actHotWaterplot);

    $actHeatingplot = new LinePlot($arrActHeating,$arrXLabels);
    $actHeatingplot->SetColor('orange');
    $actHeatingplot->SetWeight(4);
    $graph->Add($actHeatingplot);

    $graph->tabtitle->Set($arrGraphs[$graphID]['title'].' ('.$timeDisplay.')');

//==============================================================================================
// ==== paint ==================================================================================
    $graph->Stroke();
?>
