Cosm/pachube c'est naze. Faisons mieux :)

Bla bla sur la domotique. La section ou on se trompe jamais !

Cosm/pachube c'est naze. Faisons mieux :)

Messagede psykokwak » 10 Juil 2012, 20:24

UPDATE: VOIR UPDATE A LA FIN DE CE POST


Salut Ă  tous,
Peut être que certains d'entre vous connaissent ce type de service qui permet d'envoyer des données provenant de capteurs (au travers de requêtes HTTP) pour ensuite faire des graphiques.
On peut ainsi facilement intégrer ce genre de services dans nos systèmes domotique et en sortir des statistiques.
Bon, c'est bien sympa, d'autant que c'est gratuit. Mais forcé d’admettre que c'est assez naze pour plusieurs raisons :
- Impossible de customiser les graphs. On ne peut mĂŞme pas afficher plusieurs courbes sur un seul graph...
- Ca raaammmmmmeeeeeeeee.
- La rétention de la donnée est limitée dans le temps.

Bref, ayant un petit serveur web équipé de PHP et de mysql, je me suis dit : "hey, pourquoi pas faire un truc nettement plus modulaire ?".
Et bien voila qui est fait :)

Le principe est exactement le même que pour Cosm : On envoie à intervalle régulier nos valeurs provenant de capteurs via une requête http vers un script PHP qui va se charger de mettre ça dans une base de donnée.
Ensuite un autre script php ira lire les données et affichera un joli graph.
Avantages :
- Vous hébergez vos données pendant la durée qui vous fait plaisir.
- Vous pouvez customiser vos graph à l'infini : type de graph, taille, affichage, nombre de courbes, intervalle de temps, valeurs moyennes, cumulées, covariances, écart types, min, max, ....
- Ça rame pas :)




Bon, maintenant passons Ă  l'explication des scripts :


Voici le script php (qu'on appellera "logger.php") qu'il faudra appeler pour enregistrer vos données et les mettre en base de donnée mysql (qu'il faudra avoir préalablement créé) :
Code: Tout sélectionner
<?php

$db_name  = "graph";
$db_login = "graph";
$db_passw = "graph";
$db_table = "graph_tbl";

if (!isset($_GET['f']) || !isset($_GET['v']))
    die ("v or f is null");

$feed = $_GET['f'];
$value = $_GET['v'];

$db = mysql_connect('localhost', $db_login, $db_passw);
mysql_select_db($db_name, $db) or die('Erreur SQL !<br>'.mysql_error());

$sql = "CREATE TABLE IF NOT EXISTS " . $db_table . "(ffeed varchar(128), ftimestamp TIMESTAMP, fvalue DOUBLE)";
mysql_query($sql, $db) or die('Erreur SQL !<br>'.mysql_error());

$sql = "INSERT INTO ".$db_table." (ffeed, ftimestamp, fvalue) VALUES (\"".$feed."\", NOW(), ".$value.")";
mysql_query($sql, $db) or die('Erreur SQL !<br>'.mysql_error());

?>


Il suffit de l'appeler de la manière suivante : logger.php?f=myfeedname&v=42
- myfeedname est le nom de votre capteur.
- 42 est la valeur Ă  sauvegarder.
Exemple pour une sonde de température : http://myserver/logger.php?f=OutdoorTemperature&v=18.2

Pour les possesseurs d'une box micasaverde (vera), il suffit de placer dans votre script LUA de startup la fonction suivante :
Code: Tout sélectionner
function my_graph_sensor (feed, value)
  local url = "http://myserver/logger.php?" -- remplacez ici par votre serveur
  luup.inet.wget(url .. "f="..feed.."&v="..value)
end

Et de l'appeler à intervalle régulier dans vos scenes ou triggers ou schedules, ...



Le script suivant (est un peu plus long) va lire les données stockées dans votre base mysql et faire de beaux graphs.
Avant tout ce script (qu'on va appeler ... "graph.php") exploite une bibliothèque PHP qui permet de faire des graphiques : http://www.pchart.net/
Il vous faudra la télécharger et la placer dans le dossier où vous placerai votre script "graph.php"
Code: Tout sélectionner
<?php

include("pChart2.1.3/class/pData.class.php");
include("pChart2.1.3/class/pDraw.class.php");
include("pChart2.1.3/class/pImage.class.php");


class MyGraph
{
    var $_db_name;
    var $_db_login;
    var $_db_passw;
    var $_db_table;

    var $_title;
    var $_feeds;
    var $_nbdays;
    var $_type;
    var $_dateformat;

    var $_dataset;
    var $_data;

    function _computeMysql()
    {
        // Liste uniquement les feeds qui m'interessent
        $sql_feeds = "";
        reset($this->_feeds);
        while (list($k, $v) = each($this->_feeds))
        {
            $sql_feeds .= ($sql_feeds == "" ) ? "(" : "OR ";
            $sql_feeds .= 'ffeed="' . $k . '" ';
        }
        $sql_feeds .= ")";

        // Uniquement sur la periode qui m'interesse
        $sql_date = "AND (`ftimestamp` > DATE_SUB(NOW(), INTERVAL " . floor($this->_nbdays * 24) . " HOUR))";

        // Connecte
        $db = mysql_connect('localhost', $this->_db_login, $this->_db_passw);
        mysql_select_db($this->_db_name, $db) or die('Erreur SQL !<br>'.mysql_error());

        // Create query
        $interval = $this->_computeInterval();
        $sql  = 'SELECT ' . $this->_type . '(fvalue) AS computed, ffeed, UNIX_TIMESTAMP(ftimestamp) AS utimestamp';
        $sql .= ' FROM ' . $this->_db_table . ' WHERE ' . $sql_feeds . " " . $sql_date;
        $sql .= ' GROUP BY FLOOR(utimestamp / ' . $interval . '), ffeed;';

        // Execute query
        $req = mysql_query($sql) or die('Erreur SQL !<br>' . $sql . '<br>' . mysql_error());

        // aggrate datas
        $this->_dataset = array();
        while($data = mysql_fetch_assoc($req))
        {
            $this->_dataset[$data['ffeed']]["value"][] = floor(($data['computed'] * 1000)) / 1000;

            $t = date($this->_dateformat, $data['utimestamp']);
            $this->_dataset[$data['ffeed']]["time"][] = $t;
        }
       
        //echo ("<pre>" . $sql . "<br><br>"); print_r($this->_dataset);
        //exit ();
    }

    function _computeInterval()
    {
        //return $this->_nbdays * 3600; // interval in hour.
        if ($this->_nbdays <= 1) return 3600 * $this->_nbdays;
        if ($this->_nbdays <= 31) return 3600 * 24 * ($this->_nbdays / 31);
        if ($this->_nbdays <= 365) return 3600 * 24 * 31 * ($this->_nbdays / 365);
    }

    function _addData($name)
    {
        $this->_data->addPoints($this->_dataset[$name]["value"], $name);
        $this->_data->setSerieDescription($name, $this->_feeds[$name]);
        $this->_data->setSerieOnAxis($name, 0);
        $this->_data->setSerieWeight($name, 1);
    }

    function _computeGraph($width, $height)
    {
        $this->_data->setAxisPosition(0,AXIS_POSITION_LEFT);
        $this->_data->setAxisName(0,$this->_title);
        $this->_data->setAxisUnit(0,"");

        $picture = new pImage($width,$height,$this->_data,TRUE);

        $settings = array("R"=>170, "G"=>183, "B"=>87, "Dash"=>1, "DashR"=>190, "DashG"=>203, "DashB"=>107);
        $picture->drawFilledRectangle(0,0,$width,$height,$settings);

        $settings = array("StartR"=>219, "StartG"=>231, "StartB"=>139, "EndR"=>1, "EndG"=>138, "EndB"=>68, "Alpha"=>50);
        $picture->drawGradientArea(0,0,$width,$height,DIRECTION_VERTICAL,$settings);

        $picture->drawRectangle(0,0,$width - 1,$height - 1,array("R"=>0,"G"=>0,"B"=>0));

        $picture->setFontProperties(array("FontName"=>"pChart2.1.3/fonts/Forgotte.ttf","FontSize"=>14));
        $textSettings = array("Align"=>TEXT_ALIGN_MIDDLEMIDDLE, "R"=>255, "G"=>255, "B"=>255);
        $picture->drawText($width / 2, 25,$this->_title,$textSettings);

        $picture->setGraphArea(30,60,$width - 25, $height - 30);
        $picture->setFontProperties(array("R"=>0,"G"=>0,"B"=>0,"FontName"=>"pChart2.1.3/fonts/pf_arma_five.ttf","FontSize"=>6));

        $settings = array("Pos"=>SCALE_POS_LEFTRIGHT, "Mode"=>SCALE_MODE_FLOATING, "LabelingMethod"=>LABELING_ALL,
                          "GridR"=>255, "GridG"=>255, "GridB"=>255, "GridAlpha"=>50, "TickR"=>0, "TickG"=>0, "TickB"=>0, "TickAlpha"=>50,
                          "LabelRotation"=>0, "CycleBackground"=>1, "DrawXLines"=>1, "DrawSubTicks"=>1,
                          "SubTickR"=>255, "SubTickG"=>0, "SubTickB"=>0, "SubTickAlpha"=>50, "DrawYLines"=>ALL, "LabelSkip"=>1);
        $picture->drawScale($settings);

        $config = array(); //array("DisplayValues"=>1);
        $picture->drawSplineChart($config);

        $Config = array("FontR"=>0, "FontG"=>0, "FontB"=>0, "FontName"=>"pChart2.1.3/fonts/pf_arma_five.ttf", "FontSize"=>6,
                        "Margin"=>6, "Alpha"=>30, "BoxSize"=>5, "Style"=>LEGEND_NOBORDER, "Mode"=>LEGEND_HORIZONTAL);
        $picture->drawLegend($width - 120,15,$config);

        $picture->stroke();
    }

    function __construct($title)
    {
        $this->_db_name  = "graph";
        $this->_db_login = "graph";
        $this->_db_passw = "graph";
        $this->_db_table = "graph_tbl";

        $this->_title = "Untitled";
        $this->_feeds = array();
        $this->_type = "AVG";

        $this->_dataset = array();
        $this->_data = null;

        $this->_title = $title;

        $this->setWindowTime(1);
    }

    function setFeeds($feeds)
    {
        $this->_feeds = $feeds;
    }

    // $time in days (double)
    function setWindowTime($time)
    {
        $this->_nbdays = $time;

        if ($this->_nbdays <= 365) $this->_dateformat = "F Y";
        if ($this->_nbdays <= 31) $this->_dateformat = "F j Y";
        if ($this->_nbdays <= 7) $this->_dateformat = "F j Y\n    H:i";
    }

    function setTypeAvg()
    {
        $this->_type = "AVG";
    }

    function setTypeSum()
    {
        $this->_type = "SUM";
    }

    function compute()
    {
        $this->_computeMysql();

        // Add data to graph
        $this->_data = new pData();
        $lastfeed = null;
        reset($this->_feeds);
        while (list($n, $d) = each($this->_feeds))
        {
            $lastfeed = $n;
            $this->_addData($n, $d);
        }
        $this->_data->addPoints($this->_dataset[$lastfeed]["time"], "Absissa");
//        $this->_data->addPoints(str_replace(" ", "\n  ", $this->_dataset[$lastfeed]["time"]), "Absissa");
        $this->_data->setAbscissa("Absissa");

        $this->_computeGraph(800, 300);
    }
}

if (!isset($_GET['feeds'])) die(
"<pre><b>Usage:</b> <i>script.php?title=mytitle&windowtime=7&feeds[feedname1]=feeddesc1&feeds[feedname2]=feeddesc2&feeds[feedname3]=feeddesc3</i>
<b>With:</b>
    <i>title</i> (string) which is the graph name.
    <i>windowtime</i> (double) which is the graph period in days.
    <i>feeds</i> (array) which is an array that contain the feed name as key and the feed description as value.
    <i>type</i> (string) optional parameter that can have 'sum' value to compute sum instead of average.</pre>");


if (isset($_GET['title']))
    $title = $_GET['title'];
else
    $title = "Sans titre";

$myGraph = new MyGraph($title);

$myGraph->setFeeds($_GET['feeds']);

if (isset($_GET['type']) && $_GET['type'] == "sum")
    $myGraph->setTypeSum();

if (isset($_GET['windowtime']))
    $myGraph->setWindowTime($_GET['windowtime']);

$myGraph->compute();


?>


Ce script tel qu'il est présenté ici s'appelle de la manière suivante :
script.php?title=mytitle&windowtime=7&feeds[feedname1]=feeddesc1&feeds[feedname2]=feeddesc2&feeds[feedname3]=feeddesc3
Avec :
- title: (string) which is the graph name.
- windowtime: (double) which is the graph period in days.
- feeds: (array) which is an array that contain the feed name as key and the feed description as value.
- type: (string) optional parameter that can have 'sum' value to compute sum instead of average.

Et il retourne une image au format png correspondant au graph.

En reprenant notre exemple précédent avec notre sonde de température on veut afficher 4 graphs :
- la température sur les dernières 24h : http://myserver/graph.php?title=Temperature%20Day&windowtime=1&feeds[OutdoorTemperature]=Temp%20Ext
- la température sur la dernière semaine : http://myserver/graph.php?title=Temperature%20Week&windowtime=7&feeds[OutdoorTemperature]=Temp%20Ext
- la température sur le dernier mois : http://myserver/graph.php?title=Temperature%20Day&windowtime=31&feeds[OutdoorTemperature]=Temp%20Ext
- la température sur les dernière année : http://myserver/graph.php?title=Temperature%20Year&windowtime=365&feeds[OutdoorTemperature]=Temp%20Ext

Vous pouvez ensuite customiser le script pour adapter le graph Ă  vos besoins.
La bibliothèque pchart est vraiment très puissante et plutôt simple à utiliser. D'ailleurs il existe même un "générateur de graph" où vous pourrez très facilement créer le graph qui vous convient et inserer le code correspondant dans le script.



Voici maintenant quelques exemples de graph chez moi :

- Températures des pièces sur 24h et 7 jours. (Ça ne fait que quelques jours que je log mes capteurs donc je n'ai pas encore assez de recule pour avoir de jolis graphs sur des périodes plus longues) :
Image
Image

- Coût en euro de la consommation électrique heures par heure sur une journée et jour par jour sur un mois :
Image
Image
Ce graph est intéressant car le logger log le coût (en euro) par tranche de 15 minutes. J'ai donc appelé le script "graph.php" avec le paramètre "type=sum" pour demander au graph de calculer la somme plutôt que la moyenne sur la période donnée. Comme ça je connais ma consommation journalière, mensuelle et annuelle :)

Libre à vous d'utiliser ces scripts et de les modifier à volonté ;)


UPDATE :
- 2012/12/28 : Update du script "graph.php" : http://www.touteladomotique.com/forum/viewtopic.php?p=77441#p77441
Dernière édition par psykokwak le 28 Déc 2012, 11:16, édité 5 fois.
Avatar de l’utilisateur
psykokwak
Dieu de domotique
 
Messages: 388
Inscription: 29 Avr 2012, 15:35
Localisation: IDF

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede psykokwak » 10 Juil 2012, 20:27

Et comme je suis bon : voici le package complet (scripts + bibliothèque) à télécharger : http://www.psykokwak.com/blog/images/vera/graph.zip :)
Dernière édition par psykokwak le 26 Aoû 2012, 19:40, édité 1 fois.
Avatar de l’utilisateur
psykokwak
Dieu de domotique
 
Messages: 388
Inscription: 29 Avr 2012, 15:35
Localisation: IDF

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede fatal25 » 10 Juil 2012, 22:16

Salut Psyk,

je sais pas si tu as pensé à ça suite à mon post sur le forum "solution mcv" mais c'est exactement ce que je voulais :)

Un grand merci et hésites pas à mettre un lien pour faire un don, ce serait avec grand grand plaisir ^^
Créateur du SmartVT (virtual thermostat); Repris et amélioré par Antor.
Créateur du VR dimmable pour IPX800v3 / Veralite.

Si vous aimez le travail fourni pour vous faciliter la vie, faites un don svp.
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2K6F9KCEZYTG6&lc=FR&item_name=fatal25&item_number=domotique&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
fatal25
Dieu de domotique
 
Messages: 1268
Inscription: 12 Mar 2012, 16:08

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede psykokwak » 10 Juil 2012, 22:27

Nop, j'ai découvert ton topic juste après. Comme quoi on est sur la même longueur d'onde ;)
Pour les dons, mon paypal : jc_mammana[arobaz]hotmail.com :D Lachez vous, la caisse est vide :mrgreen:

Bon, maintenant je vais aller crossposter mon truc sur le forum de micasaverde. (Apres avoir googletranslaté le truc, pas le courage de traduire à la mano :/)
Avatar de l’utilisateur
psykokwak
Dieu de domotique
 
Messages: 388
Inscription: 29 Avr 2012, 15:35
Localisation: IDF

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede Cyb » 11 Juil 2012, 07:37

Salut,
Dommages que les images ne sont pas visibles sur ton 1er post (ou je suis peut-être le seul à avoir le problème?)
Cyb
P'tit Dieu de domotique
 
Messages: 177
Inscription: 21 Oct 2010, 19:52
Localisation: Thimister-Clermont (Belgique)

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede psykokwak » 11 Juil 2012, 18:32

Voila qui est réglé :)
Dsl.
Avatar de l’utilisateur
psykokwak
Dieu de domotique
 
Messages: 388
Inscription: 29 Avr 2012, 15:35
Localisation: IDF

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede fatal25 » 11 Juil 2012, 23:19

ahahah

je rigole tout seul avant de poser ma question ^^

Bon, j'ai créé une base qui s'appelle graph + une table graph_tbl avec les ffeed, ftimestamp & fvalue
un user qui s'appelle aussi graph avec mot de passe graph

Mais quand je lance un logger

http://myserver/logger.php?f=temp_salon&v=23 (j'ai bien remplacé myserver hein ^^)

il me dit :

Erreur SQL !
Access denied for user 'graph'@'localhost' (using password: YES)

Tu as une solution?
Créateur du SmartVT (virtual thermostat); Repris et amélioré par Antor.
Créateur du VR dimmable pour IPX800v3 / Veralite.

Si vous aimez le travail fourni pour vous faciliter la vie, faites un don svp.
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2K6F9KCEZYTG6&lc=FR&item_name=fatal25&item_number=domotique&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
fatal25
Dieu de domotique
 
Messages: 1268
Inscription: 12 Mar 2012, 16:08

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede psykokwak » 12 Juil 2012, 07:02

T'as donné les droits de jouer avec la base "graph" à ton user "graph" ?
Avatar de l’utilisateur
psykokwak
Dieu de domotique
 
Messages: 388
Inscription: 29 Avr 2012, 15:35
Localisation: IDF

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede fatal25 » 12 Juil 2012, 13:14

Oui. J'ai créé la base graph, la table et j'ai créé l'utilisateur graph avec le mdp graph dans les privilèges de la base...
Créateur du SmartVT (virtual thermostat); Repris et amélioré par Antor.
Créateur du VR dimmable pour IPX800v3 / Veralite.

Si vous aimez le travail fourni pour vous faciliter la vie, faites un don svp.
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2K6F9KCEZYTG6&lc=FR&item_name=fatal25&item_number=domotique&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
fatal25
Dieu de domotique
 
Messages: 1268
Inscription: 12 Mar 2012, 16:08

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede coxifred » 12 Juil 2012, 18:20

Encore un truc de plus Ă  faire tourner sur nos serveurs
coxifred
Membre Actif
 
Messages: 26
Inscription: 04 Jan 2010, 10:04

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede jojoflyhigh » 12 Juil 2012, 20:53

Moi j'ai implémenté ça avec l'API highcharts.

Voici un lien avec des exemples : http://www.highcharts.com/demo
Il y a le code source et les différentes possibilités d'affichage.
Joli, efficace et rapide à implémenté. J'ai couplé ça avec une base Mysql.

J'ai aussi implémenté l'API Canvas Steel pour afficher les valeurs en temps réel (température, baro, conso electrique ....)
C'est dispo ici et y'a aussi des exemples : http://harmoniccode.blogspot.fr/2011/01/canvas-steel.html

Si vous avez des pb pour implémenter, je peux vous aider, vu que j'ai déjà mis les mains dedans pour mes besoins perso.

ça devrait vous intéresser .....
Ver aPlus
RFXcom
1 PCR800 - 3 THGR122NX - 1 THGR328N - 1 BTHR918
3 CH54581
1 Foscam FI8918W + FI9900P
Arduino MEGA+ W5100 + 8 relay + DS18B20
Arduino UNO + W5100 + 13.56MHZ RFID
Arduino UNO + W5100 + téléinfo
Raspberry Pi B

http://jojoflyhigh.blogspot.fr/
Avatar de l’utilisateur
jojoflyhigh
P'tit Guru de domotique
 
Messages: 64
Inscription: 13 DĂ©c 2011, 11:20

Re: Cosm/pachube c'est naze. Faisons mieux :)

Messagede fatal25 » 12 Juil 2012, 22:49

Pour ceux qui auraient le même problème que moi càd être novice en mysql ^^

voici comment régler le problème d'accès denied :

http://javafoo.wordpress.com/2005/06/30/mysql-access-denied-for-user-using-password-yes/

Quand vous créez votre utilisateur, ne mettez pas "tout client" mais "local"

bug mysql apparemment...
Créateur du SmartVT (virtual thermostat); Repris et amélioré par Antor.
Créateur du VR dimmable pour IPX800v3 / Veralite.

Si vous aimez le travail fourni pour vous faciliter la vie, faites un don svp.
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2K6F9KCEZYTG6&lc=FR&item_name=fatal25&item_number=domotique&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
fatal25
Dieu de domotique
 
Messages: 1268
Inscription: 12 Mar 2012, 16:08

Suivante

Retourner vers Discussions Générales

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 7 invités

Copyright © 2011 - Touteladomotique.com - Tous droits rĂ©servĂ©s
Les blogs partenaires : Abavala, Domo-Blog, Domotique34, Maison et Domotique