[partage] graph superposant 3 ans de mesures pour comparer l'evolution

Bonjour a tous.
Je cherchais depuis un moment à suivre l’evolution des mes consommations de gaz et d’edf d’une année sur l’autre. Le problème est que nativement, il n’est pas possible de superposer une année sur l’autre pour comparer directement. (les années se suivent et le graph aussi.)

Du coup en reprenant un peu tout de 0, je suis arrivé a la version finale non sans effort et manipulations tordues. (la suite requiert peu être un peu d’expertise):

les 2 graphs du bas, permettent de voir en un coup d’oeil les evolutions d’une année sur l’autre. La granularité retenue est le mois.

Pour y arriver, j’ai fait les choses suivantes :

Crée une requête SQL qui me permet d’aller piocher les données directement dans la BD de Jeedom.

SELECT EXTRACT(YEAR FROM datetime) AS year, 
			month(datetime) AS month, datetime, MAX(CAST(value AS int))-min(CAST(value AS int)) as value,cmd_id 
			FROM historyArch
			WHERE cmd_id IN ('5669') -- gaz meter
			GROUP BY cmd_id,year,month(datetime)"

Dans mon cas, cette requête permet de recuperer la consommation en récupérant le niveau du compteur minimum dans le mois, et son maximum, puis en faire la difference.
Notez que la requête va récupérer les données d’un composant jeedom. a vous de voir quel est l’ID du compteur que vous souhaitez suivre : pour moi c’etait le 5669.

Une fois cette requête fonctionnelle, il me fallait la mettre en forme dans un document php qui saura faire la connexion a la BD, pour transmettre a la volée les résultats au générateur de graph high charts (c’est celui qu’utilise Jeedom, mais je récupère ma propre instance.)

au final le document PHP resemble a celui ci.

<!DOCTYPE html>
<html>
<head>
        <?php
            //the usual stuff 
			// note : if the webpage with this graph is served from a different server than the DB server IP, then the DB needs to be "openned" to remote connections and the user must have proper priviledges.
			$servername = "### l'ip de votre serveur DB/Jeedom###";
			$username = "### login pour acceder a votre DB qui a acces a la bd jeedom###";
			$password = "### MDP du login###";
			$dbname = "jeedom";
			
			$thisyear = date("Y");
			$prevyear = date("Y")-1;
			$beforeyear = date("Y")-2;

            
			$con = new mysqli($servername, $username, $password, $dbname);
            if (!$con) {   die('Could not connect: ' . mysql_error()); }
           
// the SQL Request for Gaz Meter (id 5669)
			$sql = "SELECT EXTRACT(YEAR FROM datetime) AS year, 
			month(datetime) AS month, datetime, MAX(CAST(value AS int))-min(CAST(value AS int)) as value,cmd_id 
			FROM historyArch
			WHERE cmd_id IN ('5669')-- gaz meter
			GROUP BY cmd_id,year,month(datetime)";

// Storing the SQL results.
            $result = $con->query($sql);
            $data = array();
            $data2 = array();
// Parsing each row from the results.             
            while($row = $result->fetch_assoc())  {
               
        extract($row);
        $datetime1 = date('Y, n, j', strtotime($datetime)); //converts date from 2012-01-10 (mysql date format) to the format Highcharts understands 2012, 1, 10
		$yeartime = date('Y', strtotime($datetime));
        $datetime2 = 'Date.UTC('.$datetime1.')'; //getting the date into the required format for pushing the Data into the Series
		
		// uncomment to get a control results from the sql output before the graph is drawn.
		// echo $datetime1 . " " . $datetime2 . " " . $month . " " . $value . "<br>";
		
		$xmonth = ($month - 1); // aligns "fake months" jan to X coordinates : 0. 

// Create 3 data series for each year, and allow them to overlay (getting rid of the real date marker)
		if ($yeartime == $thisyear){ 
			$data[] = "[$xmonth,$value]";}
		elseif ($yeartime == $prevyear) {
			$data2[] = "[$xmonth,$value]";}
		elseif ($yeartime == $beforeyear) {
			$data3[] = "[$xmonth,$value]";}
            }
		
            $con->close();
        ?>

        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script type="text/javascript">
            $(function () {
                var chart;
                $(document).ready(function() {
                    chart = new Highcharts.Chart({
                        chart: {
                            renderTo: 'container',
                            type: 'spline',
                            marginRight: 130,
                            marginBottom: 25,
							height : '180px',
							backgroundColor: 'transparent'
							},
						    title: {
							text: '',

							},
						    subtitle: {
							text: '',
							},
						    
							plotOptions: {
								series: {
									marker: {
										enabled: false
										}
									}
								},
						xAxis: {
							categories: ['jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
							floor: 0
						
					},
                        
                        yAxis: {
                            title: {
                                text: 'Conso Gaz m2'
                            },
                            min: 0
                        },
                        tooltip: {
                            formatter: function() {
                                    return '<b>'+ this.series.name +'</b><br/>'+
                                    this.x +': '+ this.y +' m²';
                            }
                        },
                        legend: {
                            layout: 'vertical',
                            align: 'right',
                            verticalAlign: 'top',
                            x: -0,
                            y: 0,
                            borderWidth: 0,
							color : 'lightgrey'
                        },
                        series: [{
                            name: <?php echo $beforeyear ?>, 
                            data: [<?php echo join($data3, ',') ?>],
							lineWidth: 2,
							color : '#a0adfc'
							
                        },{
                            name: <?php echo $prevyear ?>,
                            data: [<?php echo join($data2, ',') ?>],
							lineWidth: 3,
							color : '#5066fb'
                        },{
                            name: <?php echo $thisyear ?>,
                            data: [<?php echo join($data, ',') ?>],
							lineWidth: 4,
							color : '#bada55'
                        }
	         	]

                    });
                });
                
            });

            </script>
    </head>
    <body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>

<div id="container" style="width: 100%; height: 100%; margin: 0 auto"></div>

</body>
</html>

pour faire ce fichier, il vous suffit de le deposer sur la racine de votre serveur jeedom : /var/www/html/
via un putty ou n’importe quel outil SSH.
Vous pouvez nommer le fichier comme bon vous semble. pour moi c’etait gdf.php

A partir de la, vous devriez d’ores et déjà pouvoir accéder au document en allant sur
http://ip du jeedom/gdf.php

Enfin vient l’etape de l’insertion de ce beau graph dans votre design .
Pour des raisons de sécurité, on ne peut injecter du PHP (qui est du code exécuté coté serveur) dans une page ou un widget.
Du coup, il faudra utiliser le widget webview.
dans le widget webview, il faudra indiquer l’URL (ne pas ajouter le Code PHP directement - car il ne passera pas - toute la partie PHP sera désactivée - et posera des problèmes.)
Pour finir , dans votre design, insérez le composant webview dans votre page, et voila.
Note : Par défaut, webview force un background Blanc. C’est dommage.
Le seul moyen que j’ai trouver pour le rendre transparent c’est d’aller modifier le core du widget :
Le fichier a modifier :
/var/www/html/plugins/webview/core/class/webview.class.php

chercher le pavé :

public function toHtmlCmd($_version = 'dashboard', $transparent = false) {
                $top = $transparent ? 0 : 30;
                return ' <div class="code" style="position:absolute; top:'.$top.'px;left:0px;right:0px;bottom:0px; width:100%; height:100%; background-color: white; color: black;">
                        '.$this->getCode().'
                        </div> ';
         }

Et remplacez le background-color: white par background-color: transparent

C’est a peu près tout pour le moment.

Quelques notes toutefois.
Si vous posez la page PHP sur un serveur qui n’est pas celui du Jeedom, il faudra disposer du user root de la base de données, pour ensuite ajuster les privileges du user pour qu’il puisse se connecter en remote.
Il faudra aussi modifier la conf BD pour qu’elle accepte les connections distantes.
Notez que procéder de la sorte réduit aussi la sécurité de l’installation puisque vous réduisez les conditions d’accès a la BD.

7 « J'aime »

Joli boulot et partage :+1:

Bonjour,

Merci pour ce tuto.
J’ai une question car lorsque j’essaie d’accéder à la page (après avoir configuré le fichier à la racine du serveur) http://ip du jeedom/gdf.php celle-ci reste blanche sous Edge. C’est normal ?

Dans le webview il n’y a rien également, c’est un problème de droit d’accès à la DB ?

Merci pour les conseils

Joël

Ce serait une chouette amelioration pour la 4.4

Tu as fait un beau boulot. A voir si ce sera facilement integrable dans le core de Jeedom !!??