Compare commits

...

29 Commits

Author SHA1 Message Date
agp8x fadffc6346 improved handling of missing values 2015-09-25 00:20:07 +02:00
agp8x f5e186ceae fixed mixed days in month-view 2015-09-02 11:57:52 +02:00
agp8x bb0bfa4818 month-view: fixed missing last day 2015-09-02 11:45:14 +02:00
agp8x 718552a90e fixed version-dump 2015-09-02 11:14:52 +02:00
agp8x 57336de413 added version-dump-pre-commit 2015-09-02 11:13:36 +02:00
agp8x 4bffffc256 added todo 2015-05-07 18:28:57 +02:00
agp8x 82418d8d1a bugfix: future-detection of months in same year 2015-01-01 03:41:10 +01:00
agp8x 0e0a7a5138 see #5: fix remaining parameter 2014-12-13 12:29:51 +01:00
agp8x 18a110c2f1 addressess issue #5: enable next day, and next month if last day of prev month 2014-11-30 11:53:44 +01:00
agp8x 904bca171f fixed missalign in clima-diagram 2014-11-29 12:31:32 +01:00
agp8x 5661298dc5 fixes issue #5: remove links to pages in the future, keep those to future days in the current month anyways 2014-11-29 12:18:04 +01:00
agp8x 4eebfe79ff moved grouplens-algorithm to own class 2014-08-27 00:38:42 +02:00
agp8x df16d71f35 formatting output 2014-08-27 00:30:28 +02:00
agp8x 620d0e779b added prediction (based on current month) 2014-08-26 23:55:37 +02:00
agp8x 1dab64041e added config to update.php 2014-08-26 21:49:22 +02:00
agp8x 60e0a722fd added climaDiagram-mode 2014-08-26 15:15:03 +02:00
agp8x 6fb1fb8a63 updated gitignore to ensure privacy of config 2014-08-26 14:52:11 +02:00
agp8x 98f0a3c717 moved database-informations to config.php, added sample config 2014-08-26 14:50:45 +02:00
agp8x f7774cfc38 fixed missalign, upgraded DBLib 2014-08-21 22:53:00 +02:00
agp8x 01272e92b9 fixing #4 *really* *tested*
added gitignore
2014-08-03 01:01:50 +02:00
agp8x ac148bee7c improved future-message 2014-08-02 17:20:53 +02:00
agp8x 4ce242a7f0 fixing #4 2014-08-02 17:16:18 +02:00
agp8x 54aa5c1314 fixed future-bug 2014-08-01 01:01:20 +02:00
agp8x 3b3cec391d enabled check for summaries, fixing #2 2014-07-28 22:00:51 +02:00
agp8x 6c78358ab7 added check for partial empty summaries, disabled 2014-07-28 21:58:27 +02:00
agp8x 1c84e1d74a added todo 2014-07-28 21:36:49 +02:00
agp8x 1a902e0aae fixed spelling errors 2014-07-28 21:33:46 +02:00
agp8x ac31d04370 fixed future-leak 2014-07-28 21:24:15 +02:00
agp8x 8109e077cd nicer output if no values are present at a sensor 2014-07-28 21:04:36 +02:00
15 changed files with 588 additions and 71 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
data/
*~
*.png
*.svg
charts/
config.php
newData

1
PREV_VERSION Normal file
View File

@ -0,0 +1 @@
bb0bfa4

View File

@ -1,3 +1,8 @@
#WeatherstationServer
##Overview
PHP, CSS, psChart, pChart, DBLib
# TODO
* http://www.clemensklug.de/temp/new/?mode=month&year=2014&month=5
* wrong min_temp | 04.05.14

11
config.default.php Normal file
View File

@ -0,0 +1,11 @@
<?php
$database = array(
'host' => "localhost",
'user' => "temp",
'password' => "temppw",
'database' => "temp",
);
$start_year_of_recordings=2012;

View File

@ -4,4 +4,4 @@ get-modifiers:<br>
-lib (+force) : use custom svg-lib<br>
-short : linked (png only)<br>
-abs : absolut values instead of rounded<br>
-mode=last + num=[x] : dispolay last x hours
-mode=last + num=[x] : display last x hours

View File

@ -11,13 +11,13 @@ function generateChart($today,$mode,$hours=0,$dateInput){
global $day;
global $month;
global $year;
global $db;
$diffuse=0; # 10min -+ start/end time
$types=array('ambi1','ambi2','humi1','temp1','temp2','baro1');
$dummy=array(array(),array());
$db=new DBLib('localhost','temp','temppw','temp');
$stats="";
$selectionStart=$selectionEnd=0;
$chartname="";
@ -44,7 +44,7 @@ function generateChart($today,$mode,$hours=0,$dateInput){
}elseif($mode==3){
$selectionStart=mktime(0,0,0,$dateInput[1],1,$dateInput[0]);
$days=date("t",$selectionStart);
$selectionEnd=$selectionStart+($days*24*60*60);
$selectionEnd=$selectionStart+(($days)*24*60*60);
$chartname="month_".$type."_".$month.".".$year;
$chartdistance=60*24;
}else{
@ -57,15 +57,13 @@ function generateChart($today,$mode,$hours=0,$dateInput){
$datas[]=$db->selectRange($type.$i,'*',$rangeSelector);
if($datas[$i-1]===false){
$html.='No values ('.$type.$i.')';
if($type!="ambi"){
return;
}
$datas[$i-1]=array(0,0);
}
}
}else{
$where=array('year'=>$year,'month'=>$month);
$db->toggleDevmode();
$summary=$db->select('summary','*',$where);
//$db->toggleDevmode();
$summary=$db->select('summary','*',$where,"ORDER BY day");
if($summary===false){
$html.="No values (".$type.")";
return;
@ -86,7 +84,9 @@ function generateChart($today,$mode,$hours=0,$dateInput){
$data_tmp=array();
$data_tmp1=array();
$data_tmp2=array();
#var_dump(sizeof($summary));
foreach($summary as $daysum){
#var_dump($daysum);
$mintmp= (str_replace($unit,'',$daysum[$name.'-min']));
if($min[0]>$mintmp){
$min[0]=$mintmp;
@ -129,7 +129,14 @@ function generateChart($today,$mode,$hours=0,$dateInput){
$date_array=array('year'=>$year,'month'=>$month,'day'=>$day);
$summary=$db->select('summary','*',$date_array,'ORDER BY id DESC');
if($summary===false ||isset($_GET['totalforce'])){
$recentSummary=true;
foreach($types as $tmp){
if($tmp==$types[1]){
continue;
}
$recentSummary=($summary[0][$tmp.'-min-time'] > 0) && $recentSummary;
}
if($summary===false ||isset($_GET['totalforce']) || ! $recentSummary){
//stats are not in db, generate new, also redraw graph
$forceRedraw=true;
$db->delete('summary',$date_array);//avoid multiple (outdated) entries
@ -212,13 +219,14 @@ function generateChart($today,$mode,$hours=0,$dateInput){
//only redraw, if new data was added, indicated by 'newData' token left by update.php
$newData=false;
if(file_exists('newData')){
unlink('newData');
@unlink('newData');
$newData=true;
}
$file_exists=false;
$svg=false;
if(isset($_GET['lib'])){
$svg=true;
$clima = $_GET['lib'] === "clima";
if(file_exists("charts/".$chartname.".svg")){
$file_exists=true;
}
@ -233,7 +241,22 @@ function generateChart($today,$mode,$hours=0,$dateInput){
#if((date("d.m.Y")==$date &&$force) || !file_exists($chartname) || $force){
#if(true){#always redraw
if($svg){
include('ownlib.php');
if($clima && $mode == 1){
include('lib/climaDiagram.php');
$cd = new ClimaDiagram();
$cd->setLocation('Bischberg','Deutschland','50`, 50`', 'north');
$cd->setMode('day');
$values=prepareData($datas[1],$div,$selectionStart,$selectionEnd,$chartdistance);
foreach($values as $i=>$value){
if(!($i == 0 || $i == 1)){
$day_values[]=$value;
}
}
$cd->setTemperatureData($day_values);
file_put_contents("charts/".$chartname.".svg", $cd->getGraph());
}else{
include('ownlib.php');
}
}else{
chdir('pchart');
include("class/pData.class.php");
@ -250,13 +273,15 @@ function generateChart($today,$mode,$hours=0,$dateInput){
$labels=getLabels($datas[0],$selectionStart,$selectionEnd,$chartdistance);
if($mode==3){
$selectionStart+=60*60*24;
$div=1;
$selectionEnd+=60*60*24;
$div=0;
}
foreach($datas as $key=>$dataset){
#file_put_contents('data'.$type.($key+1),var_export($dataset,true));
$values=prepareData($dataset,$div,$selectionStart,$selectionEnd,$chartdistance);
//TODO: replace $type.($key+1) with actual name
$myData->addPoints($values,$type.($key+1));
#file_put_contents('val1',var_export($values,true));
#file_put_contents('val'.$type.($key+1),var_export($values,true));
}
$myData->addPoints($labels,"Labels");

2
dump-version.sh Executable file
View File

@ -0,0 +1,2 @@
#pre-commit
git log -n 1 --format=format:"%h" HEAD > PREV_VERSION

View File

@ -30,7 +30,7 @@ function importLogfileToDatabase($fileImport){
foreach($file as $line){
$line=explode(";",$line);
if($emptyDB){
$db->insert($logtype[0],array('time'=>$line[1],'value'=>$line[0]));
}else{
@ -39,7 +39,7 @@ function importLogfileToDatabase($fileImport){
}
}
}
}
function validFile($filename){
$humi=(strpos($filename,'humi')===false);
@ -54,9 +54,10 @@ function validFile($filename){
function logStats($datas,$type,$alt=false,$outlineAlt=0,$mode=1){
$output="";
$left=80;
$left=10;
$max=getMax($type);
for($num=0;$num<=$max;$num++){
$printValues=true;
if($num>0){
$left+=300;
}
@ -69,18 +70,23 @@ function logStats($datas,$type,$alt=false,$outlineAlt=0,$mode=1){
}else{
$stat=$alt[$num];
$timePoints=$outlineAlt[$num];
$printValues = $stat['min'][1]!=0;
}
$output.="<div style='position:absolute;left:".$left."px;'>\n";
$output.=$type.($num+1)."<br>\n";
$output.="minimum: ".$stat['min'][0]." @ ".ttdls((int) $stat['min'][1],$mode)."<br>\n";
$output.="maximum: ".$stat['max'][0]." @ ".ttdls((int) $stat['max'][1],$mode)."<br>\n";
$output.="average: ".$stat['avg']." @ ".ttdls2($stat['min'][1],$mode)."<br>\n";
$output.="Logpoints: ".$stat['size']."&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".ttdls3((int) $stat['min'][1],$mode);
$output.="<br><br><br>";
if($mode==1){
foreach($timePoints as $point){
$output.=date("H:i:s",(int) $point[1])." - ".$point[0]/$div.$unit."<br>\n";
if($printValues){
$output.="minimum: ".$stat['min'][0]." @ ".ttdls((int) $stat['min'][1],$mode)."<br>\n";
$output.="maximum: ".$stat['max'][0]." @ ".ttdls((int) $stat['max'][1],$mode)."<br>\n";
$output.="average: ".$stat['avg']." @ ".ttdls2($stat['min'][1],$mode)."<br>\n";
$output.="Logpoints: ".$stat['size']."&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".ttdls3((int) $stat['min'][1],$mode);
$output.="<br><br><br>";
if($mode==1){
foreach($timePoints as $point){
$output.=date("H:i:s",(int) $point[1])." - ".$point[0]/$div.$unit."<br>\n";
}
}
}else{
$output.="Keine Daten</div>";
}
$output.="</div>\n";
}
@ -208,7 +214,7 @@ function getDay(){
global $year;
return array($month,$day,$year);
}
function getNearest($data,$time,$last=-1){
function getNearest($data,$time,$last=-1){
if(!is_array($data)){
return array(0,$time);
}
@ -245,7 +251,11 @@ function prepareData($data,$div,$start=0,$end=0,$chartdistance=60){
$values=array();
$rawdata=outlinedLogPoints($data,$chartdistance,$start,$end);
foreach($rawdata as $set){
$values[]=round($set[0]/$div,1);
if($div==0){
$values[]=$set[0];
}else{
$values[]=round($set[0]/$div,1);
}
}
return $values;
}
@ -279,9 +289,9 @@ function drawChart($myData,$target,$date,$type){
$width=1200;
$height=600;
$fontsize=12;
$myData->setSerieDescription("Labels","Stunde");
$myData->setAbscissa("Labels");
$myData->setAbscissa("Labels");
$myPicture = new pImage($width,$height,$myData);
#$myPicture->Antialias = FALSE;#antialiasing off
$Settings = array("R"=>170, "G"=>183, "B"=>87, "Dash"=>1, "DashR"=>190, "DashG"=>203, "DashB"=>107);
@ -291,7 +301,7 @@ function drawChart($myData,$target,$date,$type){
$myPicture->drawGradientArea(0,0,$width,$height,DIRECTION_VERTICAL,$Settings);
$myPicture->drawGradientArea(0,0,$width,20,DIRECTION_VERTICAL,array("StartR"=>0,"StartG"=>0,"StartB"=>0,"EndR"=>50,"EndG"=>50,"EndB"=>50,"Alpha"=>80));
$myPicture->drawRectangle(0,0,$width-1,$height-1,array("R"=>0,"G"=>0,"B"=>0));#border
/* Write the chart title */
/* Write the chart title */
$myPicture->setFontProperties(array("FontName"=>"fonts/Forgotte.ttf","FontSize"=>$fontsize,"R"=>255,"G"=>255,"B"=>255));
$myPicture->drawText(10,16,"Durchschnittliche ".typeToFullName($type)." @ ".$date,array("FontSize"=>11,"Align"=>TEXT_ALIGN_BOTTOMLEFT));
$myPicture->drawText($width-200,16,"erzeugt @ ".date("H:i:s d.m.Y"),array("FontSize"=>11,"Align"=>TEXT_ALIGN_BOTTOMLEFT));
@ -308,9 +318,13 @@ function drawChart($myData,$target,$date,$type){
$myPicture->Render($target);
}
function calendarDay($day,$year,$month,$selection){
function calendarDay($day,$year,$month,$selection, $future){
$baselink="&amp;year=".$year."&amp;month=".$month."&amp;day=".$day."'";
return tempLink($baselink,$day,($selection=="temp")).humiLink($baselink,($selection=="humi")).ambiLink($baselink,($selection=="ambi")).baroLink($baselink,($selection=="baro"));
if($future){
return $day." (H A B)";
}else{
return tempLink($baselink,$day,($selection=="temp")).humiLink($baselink,($selection=="humi")).ambiLink($baselink,($selection=="ambi")).baroLink($baselink,($selection=="baro"));
}
}
function tempLink($baselink,$day,$selected=false){
$link="<a href='?type=temp".$baselink;
@ -341,6 +355,8 @@ function baroLink($baselink,$selected=false){
return $link." >B</a>)";
}
function calendarNav($month,$year){
global $start_year_of_recordings;
$prevMonth=$prevYear=$nextMonth=$nextYear=0;
if($month==12){
$prevMonth=$month-1;
@ -358,7 +374,27 @@ function calendarNav($month,$year){
$nextMonth=$month+1;
$nextYear=$year;
}
return "<div id='calendarNav'>\n\t<a href='?mode=month&amp;year=".$prevYear."&amp;month=".$prevMonth."'>&lt;&lt;</a>&nbsp; <a href='?mode=month&amp;year=".$year."&amp;month=".$month."'>".$month."</a> &nbsp; <a href='?mode=month&amp;year=".$nextYear."&amp;month=".$nextMonth."'>&gt;&gt;</a>\n</div>\n";
$show['prev']=$prevYear >= $start_year_of_recordings;
$show['next']=! isFuture(array(date("j"),date("n"),date("Y")), 0, $nextMonth, $nextYear);
$links="<div id='calendarNav'>\n\t";
if ($show['prev']){
$links.="<a href='?mode=month&amp;year=".$prevYear."&amp;month=".$prevMonth."'>&lt;&lt; (".monthToName($prevMonth).")</a>";
}else{
$links.=monthToName($prevMonth);
}
$links.="&nbsp; <a href='?mode=month&amp;year=".$year."&amp;month=".$month."'>".monthToName($month)."</a> &nbsp; ";
if ($show['next']){
$links.="<a href='?mode=month&amp;year=".$nextYear."&amp;month=".$nextMonth."'>&gt;&gt; (".monthToName($nextMonth).")</a>";
}else{
$links.=monthToName($nextMonth);
}
$links.="\n</div>\n";
return $links;
}
function monthToName($month){
$dateObj = DateTime::createFromFormat('!m', $month);
$monthName = $dateObj->format('F');
return $monthName;
}
function prependZero($number){
return ($number<10)? "0".$number : $number;
@ -372,7 +408,7 @@ function drawCalendar($date,$type){
$today=array('match'=>($month==date("n") && $year==date("Y")),date("j"),date("n"),date("Y"));
$first=mktime(0,0,0,$month,1,$year);
$firstDay=date("w",$first);
$calendar="<div id='calendar'><br/>\n".calendarNav($month,$year);
$day=1;
#$day=0;
@ -387,7 +423,8 @@ function drawCalendar($date,$type){
}else{
$calendar.="\t\t<td>";
}
$calendar.=calendarDay($day,$year,$month,($day==$selectedDay)? $type : false);
$future=isFuture($today, $day, $month, $year);
$calendar.=calendarDay($day,$year,$month,($day==$selectedDay)? $type : false, $future);
$day++;
}else{
$calendar.="\t\t<td> &nbsp;";
@ -400,6 +437,34 @@ function drawCalendar($date,$type){
Letzte: <a href='?mode=last&amp;num=24&amp;type=temp'>24h</a> <a href='?mode=last&amp;num=48&amp;type=temp'>48h</a> <a href='?mode=last&amp;num=96&amp;type=temp'>96h</a> &nbsp;&nbsp;&nbsp;<a href='?'>Temperatur Heute</a></div>";
return $calendar;
}
function isFuture($today, $day, $month, $year){
$dateObj = DateTime::createFromFormat('!m', $month-1);
$numDays = $dateObj->format("t");
# check year
if ($today[2] < $year){
return true;
}
if ($today[2] == $year){
# check month
if ($today[1] < $month){
# last day of month => enable next month
if($today[0] == $numDays){
return $day != 0 && $day != 1;
}
return true;
}
if($today[1] == $month){
# enable next day anyways
if($today[0]+1 == $day){
return false;
}
# check day
return $today[0] < $day;
}
}
# base case
return false;
}
function typeToSensorCount($type){
switch($type){
@ -417,4 +482,3 @@ function fileToLastSet($file){
$temp=explode(";",$last);
return $temp[0];
}

View File

@ -3,6 +3,7 @@
header("Cache-Control: no-cache, must-revalidate");
$start=microtime(true);
date_default_timezone_set("Europe/Berlin");
include('config.php');
include('lib/DBLib.php');
include('draw.php');
include('function.php');
@ -50,8 +51,10 @@ if(isset($_GET['mode']) && $_GET['mode']=='last'){
}else if($type!='none' && ($type=="temp" || $type=="ambi" || $type=="humi" || $type=="baro")){
//mode: day
$mode=1;
}else if (isset($_GET['mode']) && $_GET['mode']=='predict'){
$mode=4;
}else{
$html.="No/invalid type, default to temperature/today";
$html.="Keine weiteren Angaben: Heutige Temperatur wird angezeigt";
$mode=1;
$type="temp";
}
@ -62,8 +65,21 @@ if($mode==1){
$date=array($_GET['year'],$_GET['month'],1);
}else{
$date=array($_GET['year'],$_GET['month'],$_GET['day']);
if(($_GET['day']>$today[0])&&($_GET['month']>=$today[1])&&($_GET['year']>=$today[2])){
$error="future";
$future=false;
#TODO: replace logic?
if($_GET['year']>$today[2]){
$future=true;
}else{
if($_GET['month']>$today[1] && $_GET['year']==$today[2]){
$future=true;
}else{
if($_GET['day']>$today[0] && $_GET['month']==$today[1]){
$future=true;
}
}
}
if($future){
$error="Gewähltes Datum liegt in der Zukunft.";
$mode=0;
}
}
@ -71,14 +87,15 @@ if($mode==1){
$date=array(date("Y"),date("n"),date("j"));
}
}
$db=new DBLib($database['host'],$database['user'],$database['password'],$database['database']);
if(!$error===false){
$html.=$error;
}else{
}else if($mode != 4){
$html.=generateChart($today,$mode,$num,$date);
}else{
include('predict.php');
}
$runtime=microtime(true)-$start;
$html.="<div style='position:fixed;bottom:20px;right:50px;' >Runtime: ".$runtime." s</div>";
$html.=$calendar."</body>";
echo $html;

View File

@ -11,6 +11,7 @@
#08.08.12 OOP, proper Link handling #v4
#25.08.12 construct;toString;set/getPrefix;noExecute added, LinkHandling fixed #v5
#04.09.12 various improvments #v5.2
#04.02.14 port to mysqli #v6.1
class DBLib{
@ -18,15 +19,20 @@ class DBLib{
private $devmode=false;
private $dbprefix="";
private $connected=false;
const version=5.2;
const version=6.1;
private $dbinfo=null;
private $execute=true;
public function __construct($host="",$user="",$pass="",$database=""){
if(($host!="" || $user!="" || $pass!="" || $database!="")){
$this->connect($host,$user,$pass,$database);
}else{
$this->dbLink=new mysqli();
}
}
public function __destruct(){
$this->close();
}
public function connect($host,$user,$pass,$database){
if(!$this->checkExecute('connect')){
@ -34,8 +40,8 @@ class DBLib{
$this->dbinfo=array('user'=>'noExecute','host'=>'noExecute','dbbase'=>'noExecute');
return true;
}
$this->dbLink=@mysql_connect($host, $user, $pass);
if ($this->dbLink===false || !@mysql_select_db($database)) {
$this->dbLink=new mysqli($host, $user, $pass, $database);
if ($this->dbLink->connect_errno != 0) {
$this->echoDev('Connection failed!');
$this->connected=false;
}else{
@ -46,11 +52,13 @@ class DBLib{
}
public function close(){
$this->connected=false;
if ($this->dbLink instanceof mysqli) {
$this->connected=$this->dbLink->close();
$this->dbLink=null;
}
if(!$this->checkExecute('close')){
return false;
}
mysql_close($this->dbLink);
}
public function update($table, $values, $identifier=array(), $increment=false,$escapeIdentifier=true) {
@ -75,12 +83,7 @@ class DBLib{
if(!$this->checkExecute($sql)){
return false;
}
$result=mysql_query($sql,$this->dbLink);
if(mysql_errno()){
return false;
}else{
return true;
}
return $this->executeSQL($sql);
}
public function insert($table, $values) {
@ -101,12 +104,7 @@ class DBLib{
if(!$this->checkExecute($sql)){
return false;
}
$result = mysql_query($sql,$this->dbLink);
if (mysql_errno()) {
return false;
} else {
return true;
}
return $this->executeSQL($sql);
}
public function delete($table,$identifier,$extra="",$escapeIdentifier=true){
if(empty($table) || !$this->connected){
@ -119,12 +117,7 @@ class DBLib{
if(!$this->checkExecute($sql)){
return false;
}
$result=mysql_query($sql,$this->dbLink);
if(mysql_errno()){
return false;
}else{
return true;
}
return $this->executeSQL($sql);
}
public function select($table, $values, $identifier=array(), $extra="",$escapeIdentifier=true) {
@ -142,9 +135,9 @@ class DBLib{
if(!$this->checkExecute($sql)){
return false;
}
$result = mysql_query($sql,$this->dbLink);
if (!mysql_errno()) {
while($out=mysql_fetch_assoc($result)){
$result = $this->dbLink->query($sql);
if ($this->dbLink->errno == 0) {
while($out=$result->fetch_assoc()){
$output[]=$out;
}
if(sizeof($output)==0){
@ -152,6 +145,16 @@ class DBLib{
}
return($output);
} else {
$this->echoDev("query failed: ".$this->dbLink->error);
return false;
}
}
private function executeSQL($sql){
$this->dbLink->query($sql);
if ($this->dbLink->errno == 0) {
return true;
}else{
return false;
}
}
@ -166,7 +169,7 @@ class DBLib{
public function dbEscape($string) {
if($this->connected && $this->execute){
return(mysql_real_escape_string($string,$this->dbLink));
return($this->dbLink->escape_string($string));
}else{
return $string;
}

71
lib/Grouplens.php Normal file
View File

@ -0,0 +1,71 @@
<?php
class Grouplens{
public function r($p,$i,$data){
return $this->average($p,$p) + $this->c($p,$i,$data);
}
public function wrapR($subject, $item, $data){
return $this->r($data[$subject], $item, $data);
}
private function sim($a, $b){
$averageA=$this->average($a,$b);
$averageB=$this->average($b,$a);
$div=0.0;
$sumA=0;
$sumB=0;
foreach($a as $i=>$value){
if(!empty($value) && !empty($b[$i])){
$div+=($value - $averageA)*($b[$i] - $averageB);
$sumA+=pow(($value-$averageA), 2);
$sumB+=pow(($b[$i]-$averageB), 2);
}
}
return ($div / (sqrt($sumA) * sqrt($sumB)));
}
private function c($p,$i,$data){
$divident=$divisor=0.0;
foreach($data as $q){
if (empty($q[$i]) || $p===$q){
continue;
}
$simPQ=$this->sim($p,$q);
$averageQ=$this->average($q,$p);
$divisor+=abs($simPQ);
$divident+=(($q[$i]-$averageQ)*$simPQ);
}
return ($divident / $divisor);
}
private function average($set, $controlSet){
$average=0.0;
$count=0;
foreach($set as $i=>$value){
if (!empty($value) && !empty($controlSet[$i])){
$average+=$value;
$count+=1;
}
}
return ($average / $count);
}
}
#$ratings=array(
# "alice"=>array(5, 1, 0, 3, 2),
# "bob"=>array(3, 1, 5, 4, 2),
# "carol"=>array(4, 0, 5, 0, 3),
# "chuck"=>array(1, 4, 0, 0, 2),
# "dave"=>array(0, 4, 3, 0, 1),
# "eve"=>array(5, 4, 5, 4, 3),
# "fran"=>array(4, 0, 0, 0,2),
# "gordon"=>array(3, 4, 0, 5, 1),
# "isaac"=>array(5, 0, 4, 3, 0),
# "ivan"=>array(3, 1, 1, 0, 1)
#);
#echo sim($ratings['alice'],$ratings['ivan']);
#echo "<br>";
#echo "<br>";
#echo wrapR('alice', 2, $ratings);
#

254
lib/climaDiagram.php Normal file
View File

@ -0,0 +1,254 @@
<?php
# Klimadiagramm (wie Beispielsweise in: http://commons.wikimedia.org/wiki/File:Klimadiagramm_darwin.jpg )
class ClimaDiagram{
const version="0.1";
private $months=array('J','F','M','A','M','J','J','A','S','O','N','D');
private $modes=array('year'=>array(1, 600),'month'=>array(2.6, 1337),'day'=>array(2, 1050));
private $mode='year';
private $languages=array('de');
private $language='de';
private $temperatureData=array();
private $rainData=array();
private $locationName="";
private $locationCountry="";
private $locationHeight="";
private $locationCoordinates="";
private $hemisphere='north';
private $result="";
private function drawBase(){
foreach ($this->modes as $mode => $prop) {
if ($this->mode==$mode) {
$xOffset=$prop[0];
$width=$prop[1];
}
}
$base='<rect x="0" y="0" width="'.$width.'" height="750" id="background" />
<text x="15" y="15">'.$this->locationName.','.$this->locationCountry.' ('.$this->locationHeight.' m)</text>
<text x="450" y="15">'.$this->locationCoordinates.'</text>
<rect x="40" y="90" width="'.(480*$xOffset).'" height="630" id="border" />
<text x="18" y="85">T in C</text>
<text x="'.(20+480*$xOffset).'" y="85">N in mm</text>'."\n";
$horizontalLines="";
$rainIndex=400; // Text Höchster Niederschlag
$rainMarker=0;
$temperatureMarker=240;
$temperatureIndex=50; // Text Höchste Temperatur
for ($i=90+30; $i < 740; $i+=30) {
$horizontalLines.='<line x1="40" y1="'.$i.'" x2="'.(40+480*$xOffset).'" y2="'.$i.'" class="horizontalLine '.(($i==540? 'zeroLine' : '')).'" />'."\n";
if ($i>=$temperatureMarker) {
$horizontalLines.='<text x="15" y="'.($i+3).'">'.$temperatureIndex.'</text>'."\n";
$temperatureMarker=$i+60;
$temperatureIndex-=10;
}
if ($i>=$rainMarker && $rainIndex>=0) {
$horizontalLines.='<text x="'.(45+480*$xOffset).'" y="'.($i+3).'">'.$rainIndex.'</text>'."\n";
if ($i<180) {
$rainMarker=$i+30;
$rainIndex-=100;
} elseif ($i<240) {
$rainMarker=$i+30;
$rainIndex-=50;
}else {
$rainMarker=$i+60;
$rainIndex-=20;
}
}
}
$base.=$horizontalLines;
$horizontalLines=null;
if ($this->mode=='year'){
$base.=$this->yearDiagram()."\n";
}elseif ($this->mode=='day') {
$base.=$this->dayDiagram()."\n";
}else{
$base.='<text x="200" y="200">TODO: modes</text>'."\n";
}
$this->result=$base;
$base=null;
}
private function yearDiagram(){
$verticalLines="";
foreach ($this->months as $index => $month) {
$verticalLines.='<line x1="'.(80+$index*40).'" y1="90" x2="'.(80+$index*40).'" y2="720" class="verticalLine" />'."\n";
$verticalLines.='<text x="'.(60+$index*40).'" y="740">'.$month.'</text>'."\n";
}
$verticalLines.=$this->drawRain();
$verticalLines.=$this->drawTemperature();
return $verticalLines;
}
private function dayDiagram(){
$verticalLines="";
for($i=1;$i<=24;$i++) {
$verticalLines.='<line x1="'.(40+$i*40).'" y1="90" x2="'.(40+$i*40).'" y2="720" class="verticalLine" />'."\n";
$verticalLines.='<text x="'.(10+$i*40).'" y="740">'.$i.'</text>'."\n";
}
$verticalLines.=$this->drawRain();
$verticalLines.=$this->drawTemperature();
return $verticalLines;
}
private function drawTemperature(){
$zero=540;
$max=240;
$difference=50;
$resolution=($zero-$max)/$difference;
$startX=40;
$path='';
$lastX=0;
$lastY=0;
$i=0;
foreach ($this->temperatureData as $index=>$value) {
$x=20+$startX*($i+1);
$y=$zero+$resolution*-$value;
if (empty($path)) {
$path="M ".($x-20).' '.$y.' L '.$x.' '.$y.' ';
}else{
$path.=$x.' '.$y.' ';
}
$lastX=$x;
$lastY=$y;
$i++;
}
$path.=($lastX+20).' '.$lastY;
return '<path d="'.$path.'" id="temperatureChart"/>';
}
private function drawRain(){
$rain="";
$startX=40;
$startY=540;
foreach ($this->rainData as $index => $value) {
if ($value==0) {
continue;
}
if($value>200){
$localvalue=$value-200;
$value=200;
$zero=180;
$max=90;
$difference=300;
$resolution=($max-$zero)/$difference;
$height=($localvalue*$resolution);
$rain.='<rect x="'.($startX*($index+1)).'" y="'.($zero+$height).'" width="'.$startX.'" height="'. ($height*-1).'" class="rainChart rainScaleTiny" />'."\n";
}if ($value>100) {
$localvalue=$value-100;
$value=100;
$zero=240;
$max=180;
$difference=100;
$resolution=($max-$zero)/$difference;
$height=($localvalue*$resolution);
$rain.='<rect x="'.($startX*($index+1)).'" y="'.($zero+$height).'" width="'.$startX.'" height="'. ($height*-1).'" class="rainChart rainScaleSmall" />'."\n";
}
if($value<=100){
$zero=540;
$max=240;
$difference=100;
$resolution=($max-$zero)/$difference;
$height=($value*$resolution);
$rain.='<rect x="'.($startX*($index+1)).'" y="'.($zero+$height).'" width="'.$startX.'" height="'. ($height*-1).'" class="rainChart rainScaleNormal" />'."\n";
}
}
return $rain;
}
public function getGraph(){
foreach ($this->modes as $mode => $prop) {
if ($this->mode==$mode) {
$width=$prop[1];
}
}
$this->drawBase();
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".
'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n".
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" width="'.$width.'px" height="750px">'."\n".
'<style type="text/css">
#background{
fill: white;
fill: lightgreen;
}
#border{
fill:none;
stroke:black;
stroke-width:3px;
}
.horizontalLine, .verticalLine{
stroke:black;
stroke-width:1px;
}
.zeroLine{
stroke-width:2px;
}
#temperatureChart{
stroke:red;
stroke-width:2px;
fill:none;
}
.rainScaleNormal{
fill:lightblue;
}
.rainScaleSmall{
fill:blue;
}
.rainScaleTiny{
fill:darkblue;
}
.rainChart{
stroke:black;
}
</style>'."\n".
$this->result."\n".
'</svg>';
}
public function setLocation($city,$country,$height,$coordinates,$hemisphere='north'){
$this->locationName=$city;
$this->locationCountry=$country;
$this->locationHeight=$height;
$this->locationCoordinates=$coordinates;
$this->hemisphere=$hemisphere;
}
public function setTemperatureData($data){
if (is_array($data) && !empty($data)) {
$this->temperatureData=$data;
}
}
public function setRainData($data){
if (is_array($data) && !empty($data)) {
$this->rainData=$data;
}
}
public function setMode($mode){
if (array_key_exists($mode, $this->modes)) {
$this->mode=$mode;
return true;
echo "TRUE";
}
return false;
}
}
################
## TESTING ##
################
#$test=new ClimaDiagram();
#$test->setLocation('Ort','Land','100','50`, 50`' ,'north');
#// $temp=array(25,30,40,-10,5,6.75,50,20,-5,-15.9,-12,-8);
#// $rain=array(1,5,17,48,100,155,425,320,280,76,8,4);
#$temp=array(25,30,40,-10,5,6.75,50,20,-5,-15.9,-12,-8,25,30,40,-10,5,6.75,50,20,-5,-15.9,-12,-8);
#$rain=array(1,5,17,48,100,155,425,320,280,76,8,4,1,5,17,48,100,155,425,320,280,76,8,4);
#$test->setMode('day');
#// $test->setMode('month');
#$test->setRainData($rain);
#$test->setTemperatureData($temp);
#echo $test->getGraph();
?>

54
predict.php Normal file
View File

@ -0,0 +1,54 @@
<?php
include('lib/Grouplens.php');
$start=microtime(true);
echo "<title>[BETA] prediction</title>";
$date=array(date("Y"),date("n"),date("j"));
$diffuse=0;
$selectionStart=mktime(0,0,0,$date[1],$date[2],$date[0]);
$selectionEnd=$selectionStart+(60*60*(24+date("I",$selectionStart)));
$rangeSelector=array('time',$selectionStart-$diffuse,$selectionEnd+$diffuse);
$data= $db->selectRange('temp2','*',$rangeSelector);
foreach($data as $record){
$tupel=$record;
}
$data=null;
$month=date('n', $tupel['time']);
$year=date('Y', $tupel['time']);
$day=date('j', $tupel['time']);
#$div=getdiv('temp');
$div=1;
for($i=1; $i<=$day;$i++){
$selectionStart=mktime(0,0,0,$month,$i,$year);
$selectionEnd=$selectionStart+(60*60*(24+date("I",$selectionStart)));
$rangeSelector=array('time',$selectionStart-$diffuse,$selectionEnd+$diffuse);
$data= $db->selectRange('temp2','*',$rangeSelector);
$sumary[]=prepareData($data,$div,$selectionStart,$selectionEnd);
}
$gl=new Grouplens();
$div=getdiv('temp');
echo "prediction for ".date("d.m.Y");
echo "<table border='border-collapse'>\n";
echo "<tr><th>hour</th> <th>prediction</th> <th>difference</th><th>actual measurement</th></tr>\n";
for ($i=0;$i<25;$i++){
$r=$gl->wrapR($day-1,$i,$sumary);
$r=$r/$div;
$r=round($r,2);
$a=$sumary[$day-1][$i+1]/$div;
$a=round($a,2);
echo "<tr><td>".$i."</td><td>".$r."</td><td>".round($r-$a,2)."</td><td>".$a."</td></tr>\n";
}
echo "</table>\n";
$runtime=microtime(true)-$start;
echo "<div style='position:fixed;bottom:20px;right:50px;' >Runtime: ".$runtime." s</div>";
$db->close();
die();

1
recent
View File

@ -0,0 +1 @@
Temperatur: 22.81 C<br>Luftfeuchtigkeit: 0 %<br>Helligkeit: 0.01 Lux<br>Luftdruck: 0mbar

View File

@ -1,17 +1,18 @@
<?php
#v1.3
include('config.php');
include('lib/DBLib.php');
include('function.php');
$db=new DBLib();
$db->connect('localhost','temp','temppw','temp');#lokal
$db=new DBLib($database['host'],$database['user'],$database['password'],$database['database']);
$dir=scandir('data');
$temp=$humi=$ambi=$baro=0;
foreach($dir as $file){
if(validFile($file)){
file_put_contents('newData',"");
#echo "parsing file: ".$file."\n";
echo "parsing file: ".$file."\n";
importLogfiletoDatabase('data/'.$file);
//recent records on frontpage:
if($file[0].$file[1].$file[2].$file[3].$file[4] == "temp2"){
@ -26,7 +27,7 @@ foreach($dir as $file){
///
unlink('data/'.$file);
}else{
#echo "invalidFile: ".$file." \n";
echo "invalidFile: ".$file." \n";
}
}
$db->close();