Behöver lite hjälp att komma igång med "flot"

Generella Linux-frågor och frågor gällande Linuxmjukvara som saknar egen forumkategori skall postas i detta forum
Kategoriregler
Vill du visa bilder i ditt inlägg? Använd funktionen "Ladda upp bilaga" nedanför textrutan!
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

Hej.

Har nu stångat pannan blodig i ett par timmar på att försöka skrapa ihop ett fungerande flot-exempel mha Herr Google, men tvingats ge upp... :oops:

Tror mig ha lyckats hämta data med PHP och därefter stoppat in det i en array sizeof($arr) ger samma värde som antalet rader motsvarande SQL sats returnerar i terminalläget mot MySQL.

Det som skiter sig är att min IE (o andra browsers) inte verkar gilla anropet från Java-skriptet(på klienten) till PHP (på servern).

...
<script type="text/javascript">
$(function () {
var dataset_json=<?php echo json_encode($dataset); ?>;
$.plot($("#placeholder"), [ dataset_json ]
});
</script>

...

Så här ser felet ut:
Message: Syntax error
Line: 29
Char: 18
Code: 0

Vad kan ha gått snett här?

Är ingen duvunge på programmering, men detta är mina första trevare på Java-skript o PHP...

Eller skall man gå direkt på AJAX för att få möjlighet till dynamik på köpet?
AJAX-exemplet (http://people.iola.dk/olau/flot/examples/ajax.html) ser ju mycket "flott" ut, men innehåller inget exempel på MySQL-integration som jag känner att jag skulle vilja ha för att komma igång.

Har någon nått exempel att bjuda på så vore jag ytterst tacksam!
Om traktorn stjälper; håll i ratten, hoppa ej!
ekdahl
Gillar hemautomation
Inlägg: 43
Blev medlem: 03 nov 2011, 16:52
Ort: Tidaholm

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av ekdahl »

Här kommer ett exempel:

Kod: Markera allt

<h2>Värmesystem</h2>
<div id="placeholder" style="width:100%;height:450px;"></div>

<?php
mysql_connect("server", "username", "password");
mysql_select_db("database");

// Framledning
$query = "SELECT time, data FROM samples WHERE name='framledning_rad' AND time > NOW() - INTERVAL 1 DAY ORDER by time";
$result = @mysql_query ($query);
$framledning = array();
while($row = mysql_fetch_object($result))
	$framledning[] = array((strtotime($row->time))*1000, $row->data);

// Utetemp
$query = "SELECT time, data FROM samples WHERE name='utetemp' AND time > NOW() - INTERVAL 1 DAY ORDER by time";
$result = @mysql_query ($query);
$utetemp = array();
while($row = mysql_fetch_object($result))
	$utetemp[] = array((strtotime($row->time))*1000, $row->data);

// Börvärde
$query = "SELECT time, data FROM samples WHERE name='framledning_bv_rad' AND time > NOW() - INTERVAL 1 DAY ORDER by time";
$result = @mysql_query ($query);
$borvarde = array();
while($row = mysql_fetch_object($result))
	$borvarde[] = array((strtotime($row->time))*1000, $row->data);

// Shunt
$query = "SELECT time, data FROM samples WHERE name='shunt' AND time > NOW() - INTERVAL 1 DAY ORDER by time";
$result = @mysql_query ($query);
$shunt = array();
while($row = mysql_fetch_object($result))
	$shunt[] = array((strtotime($row->time))*1000, $row->data);

// Panna
$query = "SELECT time, data FROM samples WHERE name='panna' AND time > NOW() - INTERVAL 1 DAY ORDER by time";
$result = @mysql_query ($query);
$panna = array();
while($row = mysql_fetch_object($result))
	$panna[] = array((strtotime($row->time))*1000, $row->data);

mysql_close();
?>

<script type="text/javascript">
	$(function () {
		var framledning = <?php echo json_encode($framledning); ?>;
		var utetemp = <?php echo json_encode($utetemp); ?>;
		var borvarde = <?php echo json_encode($borvarde); ?>;
		var shunt = <?php echo json_encode($shunt); ?>;
		var panna = <?php echo json_encode($panna); ?>;

		$.plot($("#placeholder"),
			[ { label: "Framledning [°C]", data: framledning },
			  { label: "Börvärde [°C]", data: borvarde },
			  { label: "Ute [°C]", data: utetemp },
			  { label: "Panna [°C]", data: panna },
			  { label: "Shunt [%]", data: shunt, yaxis: 2 } ],
			{
		        xaxis: { mode: "time", timezone: "browser" },
		        yaxes: [ { tickFormatter: degreeFormatter }, { tickFormatter: percentFormatter, position: "right", min: 0, max: 100 } ],
				legend: { position: "nw", backgroundColor: "gray" },
				grid: { color: "white" }
			}
		);
	});
</script>
Och här är formaterarna som jag glömde skicka med:

Kod: Markera allt

function degreeFormatter(v, axis) { return v.toFixed(axis.tickDecimals) +" °C"; }
function percentFormatter(v, axis) { return v.toFixed(axis.tickDecimals) +" %"; }
function mibFormatter(v, axis) { return v.toFixed(axis.tickDecimals) +" MiB"; }
I min html-kod inkluderar jag dessa filer:

Kod: Markera allt

		<script src="flot/jquery.js"></script>
		<script src="flot/jquery.flot.js"></script>
		<script src="flot/jquery.flot.time.js"></script>
riro
Tar hemautomation på allvar
Inlägg: 161
Blev medlem: 19 feb 2008, 15:35
Ort: Falun

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av riro »

Min gissning är fnuttifiering. Vet inte riktigt hur kompatibla php och JavaScript är när det gäller json.
Ibland är det stor skillnad på' och "
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

Det var då #!"&%"#¤¤!"# att det skall vara så svårt att få flot att fungera! :D

Har skapat en testtabell med det enklaste tänkbara:

Kod: Markera allt

mysql> select * from flot;
+------+------+
| x    | y    |
+------+------+
|    1 |    1 |
|    2 |    2 |
|    3 |    5 |
+------+------+
3 rows in set (0.00 sec)
Jag försöker plotta detta med följande PHP/Java som till mycket stämmer på pricken med Ekdahls kod (layout.css har jag tagit direkt från flot exemplet o tagit bort referensen till nån bitmap som inte behövdes):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples</title>
<link href="layout.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.time.js"></script>
</head>
<body>
<h1>Flot Examples</h1>

<div id="placeholder" style="width:600px;height:300px;"></div>

<?php
$db = mysql_connect("localhost", "user", "password");
mysql_select_db("onewire",$db);
$query = "SELECT x, y from flot";
$result = mysql_query($query,$db);
while($row = mysql_fetch_array($result))
{
$arr[] = array($row['x'],$row['y']);
}
?>

<script type="text/javascript">
$(function () {
var dataset1 = <?php echo json_encode($arr); ?>;
$.plot($("#placeholder"), [ dataset1 ] );
});
</script>
</body>
</html>


I mina försök att "escapea" specialtecknen i anropet från Java till PHP på riros förslag får jag ibland till en tom graf (-1 till +1 på båda axlarna med upplösningen 0.5).

Kod: Markera allt

var dataset1 = '<?php echo json_encode($arr); ?>';
var dataset1 = "<?php echo json_encode($arr); ?>";
var dataset1 = \<?php echo json_encode($arr); ?\>;
var dataset1 = \<\?php echo json_encode($arr); \?\>;

Vad gör jag för fel; är det dags att få huvet röntgat eller "FORMAT C: /y"? :lol:
Om traktorn stjälper; håll i ratten, hoppa ej!
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

Skar ännu mer med skalpellen o nu finns det inte mycket kvar

Kod: Markera allt

<html>
 <head>
    <title>Flot Examples</title>
    <script src="../jquery.js"></script>
    <script src="../jquery.flot.js"></script>
    <script src="../jquery.flot.time.js"></script>
 </head>
 
 <body>
    <h1>Flot Examples</h1>
    <div id="placeholder" style="width:600px;height:300px;"></div>
 
<?php
    $db = mysql_connect("localhost", "user", "password");
    mysql_select_db("onewire",$db);
    $query = "SELECT x, y from flot";
    $result = mysql_query($query,$db);
    while($row = mysql_fetch_array($result))
    {
        $arr[] = array($row['x'],$row['y']);
    }
?>
 
<script type="text/javascript"> 
$(function () {
    var dataset1 = <?php echo json_encode($arr); ?>;
    $.plot($("#placeholder"), [ dataset1 ] );
});
</script>
</body>
</html>
Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; BRI/2)
Timestamp: Tue, 3 Sep 2013 20:49:56 UTC


Message: Syntax error
Line: 26
Char: 20
Code: 0
URI: HåttettepekolonslashslashminIPadress/1wire/flot/mytest/flot.html
Om traktorn stjälper; håll i ratten, hoppa ej!
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

Äntligen lite framgång!

Tog Ajax-exemplet och bytte ut de statiska .json filerna till PHP skript som hämtar data.
Nu fick jag upp data i trenden! Fick nästan en chock efter snart 3 kvällars "slit"...

Men kan någon förklara varför X-axeln inte visar rätt klockslag?

Källkolumnen har typen "Timestamp" och jag hämtar datat med följande SQL sats:

... SELECT UNIX_TIMESTAMP(time)*1000 ...

Och .json strömmen blir som följer:

"label": "Inomhustemp",
"data": [[1377961200000,22.017],[1377964800000,22.1021]...

I trenden har jag satt följande format på X-axeln:

xaxis: {
mode: "time",
timeformat: "%Y/%m/%d %H:%M"
}
...

Är inte dessa tidsstämplar korrekta?
2013-08-31 17:00:00 = 1377961200000
2013-08-31 18:00:00 = 1377964800000

Kod: Markera allt

mysql> select unix_timestamp('2013-08-31 17:00:00')*1000;
+--------------------------------------------+
| unix_timestamp('2013-08-31 17:00:00')*1000 |
+--------------------------------------------+
|                              1377961200000 |
+--------------------------------------------+
Jag hade förväntat mig att X-axeln börjar med 2013-08-31 17:00:00 o slutar med 2013-09-04 01:00:00 men det blir så här istället...
Bilagor
Första floten
Första floten
Om traktorn stjälper; håll i ratten, hoppa ej!
ekdahl
Gillar hemautomation
Inlägg: 43
Blev medlem: 03 nov 2011, 16:52
Ort: Tidaholm

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av ekdahl »

flyvert skrev: Är inte dessa tidsstämplar korrekta?
2013-08-31 17:00:00 = 1377961200000
2013-08-31 18:00:00 = 1377964800000
Skumt. Om man fyller i tiden du får på x-axeln i grafen och konverterar till unix time (http://www.onlineconversion.com/unix_time.htm)så får man: 1377960
Ta sedan det gånger 1000 så har du 1377960000. Det är tre siffror färre än vad det borde vara. Är du säker på att det i json-datan blir 13 siffror? Har du en länk där man kan se den genererade koden?
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

ekdahl skrev:
flyvert skrev: Är inte dessa tidsstämplar korrekta?
2013-08-31 17:00:00 = 1377961200000
2013-08-31 18:00:00 = 1377964800000
Skumt. Om man fyller i tiden du får på x-axeln i grafen och konverterar till unix time (http://www.onlineconversion.com/unix_time.htm)så får man: 1377960
Ta sedan det gånger 1000 så har du 1377960000. Det är tre siffror färre än vad det borde vara. Är du säker på att det i json-datan blir 13 siffror? Har du en länk där man kan se den genererade koden?
Jag klippte faktiskt in en snutt på vad PHP skriptet returnerar:

"label": "Inomhustemp",
"data": [[1377961200000,22.017],[1377964800000,22.1021]...

Slänger man siffrorna direkt i onlineconversion får man: 1377961200000 -> Thu, 8 Nov 45635 00:00:00 UTC
Dividerar man med 1000 ser det bättre ut: 1377961200 -> Sat, 31 Aug 2013 15:00:00 UTC

Så varför blir det 1970 i flot?
Om traktorn stjälper; håll i ratten, hoppa ej!
ekdahl
Gillar hemautomation
Inlägg: 43
Blev medlem: 03 nov 2011, 16:52
Ort: Tidaholm

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av ekdahl »

flyvert skrev:Jag klippte faktiskt in en snutt på vad PHP skriptet returnerar:

"label": "Inomhustemp",
"data": [[1377961200000,22.017],[1377964800000,22.1021]...
Jag menade en länk där man kan se hela den genererade sidan.
Slänger man siffrorna direkt i onlineconversion får man: 1377961200000 -> Thu, 8 Nov 45635 00:00:00 UTC
Ja, eftersom flot använder sig av javascript timestamps, millisekunder sedan 1970.
Så varför blir det 1970 i flot?
Det jag försökte säga var att flot beter sig som att det får unix timestamps istället för javascript timestamps, dvs tre nollor för lite. Jag kan inte se var felet kan ligga med det du har klippt in, så om vi kan få se hela sidan skulle det underlätta.
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

Äntligen lite frukt från allt slit!

Fick till slut ordning på det mesta - dom felaktiga tidsstämplarna får jag inte längre fram idag - tror att IE / MS Java buggar ur ibland - startar man om IE kan fel försvinna lika fort som dom dök upp. T.ex. ser jag ibland i Apache-loggarna att IE inte skickar någon databegäran när man laddar en sida, inte ens på ny tab, men startar jag om IE om börjar den hämta data igen. Kanske något med nån cachefunktion som jag inte begripit mig på?

Är mycket tacksam för all hjälp jag fått - och känner mig faktiskt glad att jag "tvingades in" på AJAX när PHP anropen från Java inte fungerade av någon besynnerlig anledning. Med AJAX i botten kan man lätt fixa uppdatering av kurvan i realtid samt lägga in knappar för zoom, panorering, val av data, statistikfunktion, etc. Skall nog försöka lägga in mer funktioner framöver o se vad man kan uppnå. Närmast på tapeten står dock nog att få elförbrukningsgivaren på plats på 1wire nätet.

Tack för denna gång!
Bilagor
Flott!
Flott!
Om traktorn stjälper; håll i ratten, hoppa ej!
gus
Wannabe
Inlägg: 23
Blev medlem: 21 dec 2012, 16:51
Ort: Kumla

Re: Sv: Behöver lite hjälp att komma igång med "flot"

Inlägg av gus »

Snyggt jobbat!


Skickat från min GT-I9100 via Tapatalk 2
hellgun
Tar hemautomation på allvar
Inlägg: 76
Blev medlem: 22 apr 2010, 12:16

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av hellgun »

flyvert skrev:Äntligen lite frukt från allt slit!

Fick till slut ordning på det mesta - dom felaktiga tidsstämplarna får jag inte längre fram idag - tror att IE / MS Java buggar ur ibland - startar man om IE kan fel försvinna lika fort som dom dök upp. T.ex. ser jag ibland i Apache-loggarna att IE inte skickar någon databegäran när man laddar en sida, inte ens på ny tab, men startar jag om IE om börjar den hämta data igen. Kanske något med nån cachefunktion som jag inte begripit mig på?

Är mycket tacksam för all hjälp jag fått - och känner mig faktiskt glad att jag "tvingades in" på AJAX när PHP anropen från Java inte fungerade av någon besynnerlig anledning. Med AJAX i botten kan man lätt fixa uppdatering av kurvan i realtid samt lägga in knappar för zoom, panorering, val av data, statistikfunktion, etc. Skall nog försöka lägga in mer funktioner framöver o se vad man kan uppnå. Närmast på tapeten står dock nog att få elförbrukningsgivaren på plats på 1wire nätet.

Tack för denna gång!
Har du lust att lägga ut exempel för din lösning? Jag har testat att grafa lite från min MySQL-databas men inte nått någon större framgång ännu.
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

hellgun skrev:Har du lust att lägga ut exempel för din lösning? Jag har testat att grafa lite från min MySQL-databas men inte nått någon större framgång ännu.
Absolut (när kvällsmaten är i magen, barnen i sängarna, huset blivit städat och skafferiet påfyllt) - kolla tidsstämplarna på mina inlägg så ser du när jag får tid för detta... :)

Jag kommer (ännu) inte åt min Pi från internet (har inte fått tid att skapa SSL-certifikat, etc. för att stävja ev. hackers som råkar springa på min IP adress o portnummer).

Sen måste jag nog oxo slänga in en brasklapp så att mina första tafatta trevanden i PHP o Java inte skall tas som "referensmaterial" o "best practise"... :roll:
Om traktorn stjälper; håll i ratten, hoppa ej!
hellgun
Tar hemautomation på allvar
Inlägg: 76
Blev medlem: 22 apr 2010, 12:16

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av hellgun »

flyvert skrev: Absolut (när kvällsmaten är i magen, barnen i sängarna, huset blivit städat och skafferiet påfyllt) - kolla tidsstämplarna på mina inlägg så ser du när jag får tid för detta... :)
Ja, ta det om/när du har tid.
flyvert skrev: Sen måste jag nog oxo slänga in en brasklapp så att mina första tafatta trevanden i PHP o Java inte skall tas som "referensmaterial" o "best practise"... :roll:
Då är vi på samma nivå :)
flyvert
Hemautomation - det är mer än en hobby
Inlägg: 393
Blev medlem: 22 aug 2013, 00:48
Ort: Västerås

Re: Behöver lite hjälp att komma igång med "flot"

Inlägg av flyvert »

På begäran, här kommer info om mitt experiment.

OBS: designen är fortfarande endast grovt tillyxad - detta är mitt första encounter med PHP, Java, MySQL, etc.

Databasformat:

Kod: Markera allt

mysql> desc data;
+-----------+-------------+------+-----+-------------------+-----------------------------+
| Field     | Type        | Null | Key | Default           | Extra                       |
+-----------+-------------+------+-----+-------------------+-----------------------------+
| time      | timestamp   | NO   | MUL | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| sensorid  | smallint(6) | NO   |     | NULL              |                             |
| property  | smallint(6) | NO   |     | NULL              |                             |
| value     | float       | NO   |     | NULL              |                             |
| aggregate | smallint(6) | NO   |     | NULL              |                             |
+-----------+-------------+------+-----+-------------------+-----------------------------+
Jag har även skapat lite hjälptabeller för att hålla reda på sensorer o properties

Kod: Markera allt

mysql> desc sensors;
+-----------+-------------+------+-----+-------------------+-----------------------------+
| Field     | Type        | Null | Key | Default           | Extra                       |
+-----------+-------------+------+-----+-------------------+-----------------------------+
| time      | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| sensorid  | smallint(6) | NO   |     | NULL              |                             |
| name      | varchar(20) | NO   |     | NULL              |                             |
| onewireid | varchar(15) | YES  |     | NULL              |                             |
+-----------+-------------+------+-----+-------------------+-----------------------------+
4 rows in set (0.01 sec)

mysql> desc properties;
+------------+-------------+------+-----+-------------------+-----------------------------+
| Field      | Type        | Null | Key | Default           | Extra                       |
+------------+-------------+------+-----+-------------------+-----------------------------+
| time       | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| propertyid | smallint(6) | NO   |     | NULL              |                             |
| name       | varchar(20) | NO   |     | NULL              |                             |
| enhet      | varchar(4)  | YES  |     | NULL              |                             |
| sensorid   | varchar(15) | NO   |     | NULL              |                             |
+------------+-------------+------+-----+-------------------+-----------------------------+

För tilfället går datainsamligen som ett cronjob som läser givarna och gör en "fulinsert" utan några krusiduller

Kod: Markera allt

#!/bin/bash

sens1temp=$(cat /mnt/1wire/7E.C42600001000/EDS0068/temperature)
sens1humi=$(cat /mnt/1wire/7E.C42600001000/EDS0068/humidity)
sens1lite=$(cat /mnt/1wire/7E.C42600001000/EDS0068/light)
sens1pres=$(cat /mnt/1wire/7E.C42600001000/EDS0068/pressure)

# Central heating, outgoing
sens2temp=$(cat /mnt/1wire/28.6E5495040000/temperature)

# District heating, incoming
sens3temp=$(cat /mnt/1wire/28.3083D6020000/temperature)

mysql --user=user --password=password << ENDSQL
  use onewire
  insert into data ( time, sensorid, property, value, aggregate ) values ( now(), 1, 1, $sens1temp, 1 );
  insert into data ( time, sensorid, property, value, aggregate ) values ( now(), 1, 2, $sens1humi, 1 );
  insert into data ( time, sensorid, property, value, aggregate ) values ( now(), 1, 3, $sens1lite, 1 );
  insert into data ( time, sensorid, property, value, aggregate ) values ( now(), 1, 4, $sens1pres, 1 );
  insert into data ( time, sensorid, property, value, aggregate ) values ( now(), 2, 1, $sens2temp, 1 );
  insert into data ( time, sensorid, property, value, aggregate ) values ( now(), 3, 1, $sens3temp, 1 );
ENDSQL
Varje hel timme o dygn kör jag stored procedures som skapar medelvärden per timme o dag samt sparar in min/max punkter. Tanken är att om datamängden skulle bli för stor kan jag droppa minutvärdena o ändå ha timmedel samt dygnsmedel, max o min kvar under en längre tid utan att fylla disken.

Här är skriptet som lägger in timproceduren i databasen.

Kod: Markera allt

USE onewire
DROP PROCEDURE IF EXISTS updatehourdata;
DELIMITER //

CREATE PROCEDURE updatehourdata()
BEGIN
  DECLARE thissensor SMALLINT;
  DECLARE thisproperty SMALLINT;
  DECLARE thistime TIMESTAMP;
  DECLARE thisvalue FLOAT;

  DECLARE sensorcur   CURSOR FOR select sensorid from sensors order by sensorid;
  DECLARE propertycur CURSOR FOR select propertyid from properties where sensorid = thissensor order by propertyid;
  DECLARE EXIT HANDLER FOR NOT FOUND CLOSE sensorcur;

  OPEN sensorcur;
  REPEAT
    FETCH sensorcur INTO thissensor;
    BEGIN
      DECLARE EXIT HANDLER FOR NOT FOUND CLOSE propertycur;
      OPEN propertycur;
      REPEAT
        FETCH propertycur INTO thisproperty;
        -- Find most recent hourvalue
        SELECT MAX(time) + interval 1 hour  INTO thistime FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 2;
        IF ISNULL(thistime) THEN
          -- No previous hourvalue found -> fallback on oldest minutevalue
          SELECT min(time) + interval 1 hour INTO thistime FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 1;
        END IF;
        -- Check if still NULL -> there is no data available -> do not proceed with calculating any averages.
        IF NOT ISNULL(thistime) THEN
          -- Shave off any minutes or seconds
          SET thistime = DATE_SUB(thistime, interval minute(thistime) minute);
          SET thistime = DATE_SUB(thistime, interval second(thistime) second);
          -- Thistime does now point to next hourly average to compute
          WHILE thistime < NOW() DO
            -- Calculate an hourly average for this sensor, property and time frame.
            SELECT AVG(value) INTO thisvalue FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 1
              AND time >= thistime - interval 1 hour AND time < thistime;
            -- Update data table
            INSERT INTO data ( time, sensorid, property, value, aggregate ) VALUES ( thistime, thissensor, thisproperty, thisvalue, 2 );
            -- Increment hour
            SET thistime = DATE_ADD(thistime, interval 1 hour);
          END WHILE;
        END IF;
      UNTIL false END REPEAT;
      CLOSE propertycur;
    END;
  UNTIL false END REPEAT;
  CLOSE sensorcur;
END //
Dygnsproceduren är ganska lik, men innehåller min/max loggningen

Kod: Markera allt

USE onewire
DROP PROCEDURE IF EXISTS updatedaydata;
DELIMITER //

CREATE PROCEDURE updatedaydata()
BEGIN
  DECLARE thissensor SMALLINT;
  DECLARE thisproperty SMALLINT;
  DECLARE thistime TIMESTAMP;
  DECLARE peaktime TIMESTAMP;
  DECLARE thisvalue FLOAT;

  DECLARE sensorcur   CURSOR FOR select sensorid from sensors order by sensorid;
  DECLARE propertycur CURSOR FOR select propertyid from properties where sensorid = thissensor order by propertyid;
  DECLARE EXIT HANDLER FOR NOT FOUND CLOSE sensorcur;

  OPEN sensorcur;
  REPEAT
    FETCH sensorcur INTO thissensor;
    BEGIN
      DECLARE EXIT HANDLER FOR NOT FOUND CLOSE propertycur;
      OPEN propertycur;
      REPEAT
        FETCH propertycur INTO thisproperty;
        -- Find most recent dayvalue
        SELECT MAX(time) + interval 1 day  INTO thistime FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 3;
        IF ISNULL(thistime) THEN
          -- No previous dayvalue found -> fallback on oldest hourvalue
          SELECT min(time) + interval 1 day INTO thistime FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 2;
        END IF;
        -- Check if still NULL -> there is no data available -> do not proceed with calculating any averages.
        IF NOT ISNULL(thistime) THEN
          -- Shave off any hours, minutes and seconds
          SET thistime = DATE_SUB(thistime, interval hour(thistime) hour);
          SET thistime = DATE_SUB(thistime, interval minute(thistime) minute);
          SET thistime = DATE_SUB(thistime, interval second(thistime) second);
          -- Thistime does now contain next daily average to compute
          WHILE thistime < NOW() DO
            -- Calculate an daily average for this sensor, property and time frame.
            SELECT AVG(value) INTO thisvalue FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 2
              AND time >= thistime - interval 1 day AND time < thistime;
            -- Update data table
            INSERT INTO data ( time, sensorid, property, value, aggregate ) VALUES ( thistime, thissensor, thisproperty, thisvalue, 3 );

            -- Find day low value
            SELECT MIN(value) INTO thisvalue FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 1
              AND time >= thistime - interval 1 day AND time < thistime;
            -- Find first occurrence of day low value
            SELECT MIN(time) INTO peaktime FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 1
              AND value = thisvalue AND time >= thistime - interval 1 day AND time < thistime;
            -- Update data table
            INSERT INTO data ( time, sensorid, property, value, aggregate ) VALUES ( peaktime, thissensor, thisproperty, thisvalue, 4 );

            -- Find day high value
            SELECT MAX(value) INTO thisvalue FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 1
              AND time >= thistime - interval 1 day AND time < thistime;
            -- Find first occurrence of day high value
            SELECT MIN(time) INTO peaktime FROM data WHERE sensorid=thissensor AND property=thisproperty AND aggregate = 1
              AND value = thisvalue AND time >= thistime - interval 1 day AND time < thistime;
            -- Update data table
            INSERT INTO data ( time, sensorid, property, value, aggregate ) VALUES ( peaktime, thissensor, thisproperty, thisvalue, 5 );

            -- Increment one day
            SET thistime = DATE_ADD(thistime, interval 1 day);
          END WHILE;
        END IF;
      UNTIL false END REPEAT;
      CLOSE propertycur;
    END;
  UNTIL false END REPEAT;
  CLOSE sensorcur;
END //
Cronjobben:

Kod: Markera allt

* * * * * /usr/local/bin/loggatemp > /tmp/loggatemp.log 2>&1
0 * * * * /usr/bin/mysql --user=user --password=password -e'call updatehourdata;' onewire > /tmp/updatehourdata.log 2>&1
1 0 * * * /usr/bin/mysql --user=user --password=password -e'call updatedaydata;' onewire > /tmp/updatedaydata.log 2>&1
Här är HTML/PHP/Java koden som ritar flot diagrammet:
(för tillfället lever sidan i Ajax-exempelkatalogen som följer med flot distributionen, t.ex. har jag inte ändrat något i ../examples.css)

Kod: Markera allt

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Signaler från EDS0068</title>
        <link href="../examples.css" rel="stylesheet" type="text/css">
        <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
        <script language="javascript" type="text/javascript" src="../../jquery.js"></script>
        <script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
        <script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
        <script type="text/javascript">

        $(function() {
                function degreeFormatter(v, axis)  { return v.toFixed(axis.tickDecimals) +" °C"; }
                function percentFormatter(v, axis) { return v.toFixed(axis.tickDecimals) +" %"; }
                function hPaFormatter(v, axis)     { return v.toFixed(axis.tickDecimals) +" hPa"; }
                function luxFormatter(v, axis)     { return v.toFixed(axis.tickDecimals) +" lux"; }

                var options = {
                        lines: { show: true },
                        xaxis: { mode: "time",
                                 timeformat: "%a-%d %H:%M" },
                        yaxes: [ { tickFormatter: degreeFormatter  },
                                 { tickFormatter: percentFormatter },
                                 { tickFormatter: hPaFormatter, position: "right" },
                                 { tickFormatter: luxFormatter, position: "right" } ] };

                var data = [];

                function onDataReceived(series) {
                  data.push(series);
                  $.plot("#placeholder", data, options);
                }

                $.ajax({url: "rumstemp.php",      type: "GET", dataType: "json", success: onDataReceived });
                $.ajax({url: "luftfuktighet.php", type: "GET", dataType: "json", success: onDataReceived });
                $.ajax({url: "ljusstyrka.php",    type: "GET", dataType: "json", success: onDataReceived });
                $.ajax({url: "lufttryck.php",     type: "GET", dataType: "json", success: onDataReceived });
        });
        </script>
</head>
<body>
                <div class="demo-container">
                        <div id="placeholder" class="demo-placeholder"></div>
                </div>
</body>
</html>
I samma katalog har jag grovt yxat till 4 ytterst rudimentära PDP skript som läser upp en kurva och JSON-kodar den o dumpar den rätt ut "i Ajax-etern". Observera att jag först o sist lägger ut etikett, färg o axelnummer med lite råa "echo" anrop. Detta kan säkerligen göras på ett bättre sätt - men som sagt, detta är ihophackat under några kvällar efter att ungarna o sambon gått o lagt sig o man får lite "kvalitetstid" för sig själv... :lol:

Här är koden till rumstemp.php, dom andra tre är väldigt lika - i pricip skiljer sensorid o property samt label/axel/färg.

Kod: Markera allt

<?php
    $db = mysql_connect("localhost", "user", "password");
    mysql_select_db("onewire",$db);
    $query = "SELECT UNIX_TIMESTAMP(time)*1000 \"time\", value from data where sensorid=1 and property=1 and aggregate=2 order by time";
    $result = @mysql_query ($query);
    $arr = array();
    while($row = mysql_fetch_object($result))
    {
        $arr[] = array($row->time*1,$row->value*1);
    }

    echo "{\n\"label\": \"Inomhustemp (°C)\",";
    echo "\n\"data\": ";
    echo json_encode($arr);
    echo ",\n\"color\": 0,\n";
    echo "\"yaxis\": 1\n}\n";

    mysql_close();
?>
Observera att aggregate 2 motsvarar timmedelvärde (dygnsmedel, min o max följer med 3, 4 o 5).
Initiala test indikerar att prestandan blir lidande med minutdata i en veckotrend - därför har jag valt timvärden i detta exempel.


Fick jag med allt? :?:
Om traktorn stjälper; håll i ratten, hoppa ej!
Skriv svar