Aller au contenu

Messages recommandés

Posté(e)

Ah mon avis, la seule possibilité est d'appeler l'API HTTP, en passant par un serveur externe. De toutes façon, un serveur externe sera nécessaire pour stocker et afficher les graphs.

 

URL à  appeler :

 

Pour lister tous les thermomètres :

http://<IP>/api/devices?type=temperature_sensor

Pour lister seulement un module donné :

http://<IP>/api/devices?ID=<id_du_module>
Posté(e)

bonjour Lazer

 

ça c cool, je peux effectivement récupérer les infos.

quand tu parles serveur externe, je suppose qu'1 NAS peut faire l'affaire.

 

Mais comment implémenter ce truc ?

je n'ai rien trouver de pratique.

Posté(e)

Oui, un NAS tout à  fait.

Un synology par exemple ferait parfaitement l'affaire, car tu peux avoir le serveur Web Apache, le langage PHP, la base de donnée MySQL/MariaDB, et l'accès à  la crontab pour scheduler les tâches de récupérations des infos à  intervalle fixe (toutes les minutes par ex).

 

Par contre, je ne pense que pas qu'il existe de tuto pour ce que tu veux faire, tout est à  créer.

Tu peux t'inspirer de mon tuto pour la structure de la DB et des pages Web, mais par contre il faudra que tu écrives les scripts de récupération des données via l'API que je t'ai donné hier.

[Tuto Multimédia] Graph De Température, Humidité, Consommation...sur NAS

Posté(e)

salut Lazer

 

alors j'ai réussi à  créer le serveur Web, la base mySQL, le module virtuel sur le HCL, ok

 

par contre, je suis coincé sur la création de la scène car il s'agit d'un code LUA qui n'existe pas sur le lHCL.

Du coup si quelqu'un peut m'aider à  créer le script.....

 

Merci d'avance.

Posté(e)

Je ne suis pas persuadé que tu puisses sur HCL.

Envoyé de mon iPhone àl'aide de Tapatalk

Posté(e)

tomcat,

Ce que Lazer à  fait :

  1. push depuis HC2 vers NAS des données
  2. traitement des données et mise en graphique, ...

Avec une HCL, tu ne sais pas faire le push des données vers le NAS, car nous n'avons pas de LUA.

 

MAIS, 

on pourrait faire un pull de ces données. Avec les url qu'il t'a données c'est possible :

  1. http://<IP>/api/devices?type=temperature_sensor : te permet de lister toutes les sondes de température
  2. http://<IP>/api/devices?ID=<id_du_module> : pour une sonde particulière, tu as ,"value":"19.50",

"Il n'y a plus qu'à " faire une requête (toutes les 15-30 min) en scannant ce que tu veux, et tu stockes tout cela dans la DB de Lazer.

Et ensuite tu peux réutiliser ce qu'il a déjà  fait pour le traitement des données.

 

Mais moi, je ne peux que donner des idées, car c'est de la programmation de haut vol (pour moi).

 

Maintenant, si Lazer pouvait nous faire une liste exhaustive des "devices?type=", ce serait super.

 

Aller Tomcat, au boulot  ;) (YAK, faut qu'on)

  • Upvote 1
Posté(e)

Bravo Jojo, tu as parfaitement résumé la situation.

 

J'ai pas trop le temps d'écrire ce script, mais en gros il faudrait convertir les scripts LUA que je fournis dans le Virtual Device, pour les convertir en langage PHP et les faire exécuter sur le NAS. Ensuite, utiliser Crontab pour exécuter ces scripts à  intervalle régulier (1 minute fait très bien l'affaire)

Posté(e)

@Jojo: En regardant dans le panneau des évènements tu auras une idée de la fréquence de changement de température.

A mon avis toutes les 10 à15mn c'est largement suffisent.

Posté(e)

10-15 minutes c'est suffisant pour des statistiques de température à  la journée.

Par contre, si tu veux réguler du chauffage (par exemple avec les modules liés et le panneau de chauffage), alors tu risques d'avoir une inertie trop grande, et un intervalle de 1 minute devrait être plus judicieux.

De plus, sur une HC Lite, le script sera externe, donc la seule charge de la HCL c'est de fournir la liste des devices via l'API.

Tu lances Firefox ou Chrome avec les outils de développer, tu tapes l'adresse /api/devices et tu regardes le nombre de millisecondes que ça a pris.

Tu divises ce temps par 60 secondes et tu auras la charge moyenne. Alors peut-être que la HCL est biens moins performante que la HC2, mais à  mon avis pour une tâche aussi simple ça ne fera pas de différence.

 

Reste toujours à  trouver un motivé pour "convertir" mon script LUA en PHP :ph34r:

Posté(e)

 

Reste toujours à  trouver un motivé pour "convertir" mon script LUA en PHP :ph34r:

ça c'est un job pour Tomcat, il a l'air chaud ...  :icon1010: 

Posté(e)

bonsoir à  tous, 

 

ne rigolez pas, je n'y connais rien en Apache, Sioux et autres indiens.

Déjà  que j'ai réussi à  avoir mon serveur Web et ma base mySLQ sur mon QNAP !

 

ce soir, je me bats avec mon accès putty, pour accéder à  crontab......

va me falloir des jours, et des jours..... :rolleyes:

Posté(e)

@Tomcat

Vu les mots très techniques que tu utilises, tu sembles avoir beaucoup plus de qualification en la matière que moi ...

 

@Lazer

N'aurais-tu pas le courage de t'y coller ? Je m'engage à  t'envoyer plein de petits coeurs de remerciement, et Tomcat sà»rement aussi.

Posté(e)

si je veux bien m'y coller mais j'ai tellement de truc en cours que ca va etre long.

 

une petite question, j'ai regardé le script LUA pour push des infos vers le serveurs web, mais sauf si je n'ai pas bien regardé, je ne vois pas le lien vers la base mySQL.

a quel niveau se fait le lien entre le script et la base ?

Posté(e)

L'injection des données dans la base MySQL se fait dans les pages PHP data_post_XXX.php, puisque sur les pages PHP ont accès la base de données MySQL du serveur Web.

La HC n'a aucun accès direct à  la base de données.

 

 

Autrement, je suggère d'attendre la sortie de la v4, je tenterai de convertir mon module virtuel en plugin, ce qui devrait permettre à  tout le monde de bénéficier de ces graphiques.

  • Upvote 2
  • 1 mois après...
Posté(e)

Bonjour,

 

Je me suis rapidement attelé à  la tâche, niveau code php un script de ce style fera l'affaire :

<?php

$db_name  = "NOM_DB";
$db_login = "LOGIN_DB";
$db_passw = "PASSWORD_DB";
$db_table = "TABLE_DB";

$feed = $argv[1];
$value = $argv[2];

$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());

?>

Le script à  la base était fait pour un autre type de graph, mais l'idée est de stocker les valeurs avec un type, une valeur et un timestamp. Après sur le site il suffira de faire un select where type=tonType pour récupérer les données associées. Ca évite de faire 50 tables différentes.

 

Ensuite niveau script, il suffit de croner un truc comme ça :

*/2 * * * * php -f /home/domotique/www/loggerCL.php [type] [valeur]

Avec par exemple [type] = tempSalon et [valeur]=21, et l'adresse du fichier php sur le serveur.

 

 

Maintenant l'intérêt est limité, le but est de récupérer dynamiquement la valeur sur la box mais puisque le script s’exécute sans problème il suffira simplement de récupérer en tête du fichier php les valeurs en appelant l'api de la box.

 

Mais pour le moment je ne peux pas le faire car mon serveur est un dédié qui n'est pas sur mon réseau local et je ne trouve pas comment contacter ma box via le web?

 

Est-ce possible?

 

Merci

  • 2 semaines après...
Posté(e)

Voila donc le fichier de log,  appelons le loggerCL.php :

<?php
//Setup database connexion credentials
$db_name  = "NOM_DB";
$db_login = "LOGIN_DB";
$db_passw = "PASSWORD_DB";
$db_table = "graph_tbl";

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

// Create table if not already done
$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());

// Setup fibaro connexion credentials
$url = "IP_BOX_FIBARO";
$username = "USERNAME_BOX_FIBARO";
$password = "PASSWORD_BOX_FIBARO";

// Sensors definition : "database name", "query for fibaro api", "value name under properties array"
$sensors = [
	['Battery_Thermo','/api/devices?id=4','batteryLevel'],
	['Temp_Salon','/api/devices?id=5','value'],
	['Humid_Salon','/api/devices?id=6','value'],
	['Statut_Radiateurs','/api/devices?id=25','value'],
	['Conso_Radiateurs','/api/devices?id=25','valueSensor'],
	['Cumul_Radiateurs','/api/devices?id=25','valueMeter'],
	['Statut_Chauffe_Eau','/api/devices?id=21','value'],
	['Conso_Chauffe_Eau','/api/devices?id=21','valueSensor'],
	['Cumul_Chauffe_Eau','/api/devices?id=21','valueMeter'],
	['Puissance_Halo_Chambre','/api/devices?id=31','value'],
	['Puissance_Halo_Salon','/api/devices?id=28','value']
];

// For each sensor,  retrieve data and send it to database
foreach ($sensors as list($name,$query,$location)) {
	$result = json_decode(file_get_contents("http://".$username.":".$password."@".$url.$query));
	$value = $result->properties->$location;
	$sql = "INSERT INTO ".$db_table." (ffeed, ftimestamp, fvalue) VALUES (\"".$name."\", NOW(), ".$value.")";
	mysql_query($sql, $db) or die('Erreur SQL !<br>'.mysql_error());
}
?>

Ce dernier va créer automatiquement une table si inexistante, puis logger les différentes valeurs contenues dans le tableau "sensors". Il faudra remplir le tableau avec autant de sous tableau pour chaque information à  logger. Par exemple :

['Temp_Salon','/api/devices?id=5','value'] --> correspond à  ma sonde de température.

 

La 1ere valeur "Temp_Salon" correspond à  l'id que l'on va stocker dans la table.

La 2e valeur "/api/devices?id=5" correspond à  l'url du flux json du device concerné

La 3e valeur "value" correspond au nom de la valeur recherché dans le tableau properties du flux json, dans cet exemple cela correspond à  la température.

 

Ensuite il faut croner un appel au script sur le serveur, pour cela :

crontab -e

Et l'éditer en ajoutant la ligne suivante, pour un appel toutes les 2 mn :

*/2 * * * * php -f /home/domotique/www/loggerCL.php

Note : bien penser à  changer le path pour votre serveur, ainsi que modifier la durée de 2mn si nécessaire.

 

 

A partir de la il suffit de récupérer les données sur le serveur web, ici un exemple avec la température, dans un fichier json_table_temp.php :

        <?php
        $con=mysql_connect("localhost","LOGIN_DB","PASSWORD_DB") or die("Failed to connect with database!!!!");
        mysql_select_db("graph_tbl", $con);

        $sth = mysql_query("SELECT MONTH(ftimestamp) as DateMois, YEAR(ftimestamp) as DateAnnee, DAYOFMONTH(ftimestamp) as DateJour, HOUR(ftimestamp) as DateHeure, MINUTE(ftimestamp) as DateMinute, SECOND(ftimestamp) as DateSeconde, fvalue as Temperature FROM graph_tbl WHERE ffeed = 'Temp_Salon'");

        $results = [
                'cols' => [
                        ['label' => 'Date', 'type' => 'datetime'],
                        ['label' => 'Température', 'type' => 'number']
                ],
                'rows' => array()
        ];

         while($row = mysql_fetch_assoc($sth)) {
                $year = (int) $row['DateAnnee'];
                $month = (int) $row['DateMois'] - 1; // subtract 1 to make month compatible with javascript months
                $day = (int) $row['DateJour'];
                $hour = (int) $row['DateHeure'];
                $minute = (int) $row['DateMinute'];
                $second = (int) $row['DateSeconde'];

                $results['rows'][] = array('c' => array(
                        array('v' => "Date($year, $month, $day, $hour, $minute, $second)"),
                        array('v' => $row['Temperature'])
                ));
        }

        $results_lisse = $results;
        $degre_lissage = 6;

        for ($i = 0; $i < count($results['rows']); $i++) {
                $temp_tab = array();
                for($j = 0-$degre_lissage; $j < $degre_lissage; $j++) {
                        if (($i+$j) >= 0 and ($i+$j) < count($results['rows']))
                        {
                                array_push($temp_tab, $results['rows'][$i+$j]['c'][1]['v']);
                        }
                }
                $results_lisse['rows'][$i]['c'][1]['v'] = round(array_sum($temp_tab)/count($temp_tab), 2);;
        }

        $jsonTable = json_encode($results_lisse, JSON_NUMERIC_CHECK);
        echo $jsonTable;
        ?>

Note : la partie basse du fichier peut être enlevé elle transforme $results en $results_lisse en appliquant un lissage par arrondi en fonction de $degre_lissage. Pour cela il faut directement retourner dans le json_encode $results.

 

 

Ensuite dans un fichier HTML en chargeant les api google, on fait appel au fichier de récupération en ajax pour mettre à  jour une div qui va contenir notre graphique.

<div id="flot-chart"></div>

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">

// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});

// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);

function drawChart() {
    $.ajax({
			url: 'json_table_temp.php',
			dataType: 'json',
			success: function (jsonData) {
					// Create our data table out of JSON data loaded from server.
					var data = new google.visualization.DataTable(jsonData);

					var options = {
							height: 400,
							legend: { position: 'bottom' },
							pointSize: 0,
							explorer: {actions:['dragToZoom', 'rightClickToReset']},
							hAxis: {format:'dd/MM'},
							chartArea:{left:40,top:10,width:'94%'},
					};

					// Instantiate and draw our chart, passing in some options.
					var chart = new google.visualization.LineChart(document.getElementById('flot-chart'));
					chart.draw(data,options);
			}
	});
}

$(window).resize(function(){
		drawChart();
});

Voila !

 

J'essaierai de faire un tutoriel complet un de ces 4, mais en attendant ça peut servir à  certaines personnes.

  • Upvote 1
  • 2 ans après...
Posté(e) (modifié)

salut @cdlsal

 

j'ai crée avec l'aide de la communauté, un script pour exporter des donné de la HC2 vers une base SQL

 

Mai voila je souhaite réaliser le contraire, récupéré des données dans un bas sql vers une étiquette du module virtuel.

 

pourrais-tu me donner quelques tuyaux

 

--[[
%% properties
%% globals
--]]

------- HC2 vers une bas SQL --------



local deviceID = 107
----local message = fibaro:getGlobal("PAW2_VAR")

local times1 = os.date("%H%M%S")
local timestamp = os.date("%Y%m%d")





local nomdevice1 = fibaro:getName(deviceID) 
local piece1     = fibaro:getRoomName( fibaro:getRoomID(deviceID) )
------------------NOM de la SECTION-------
local SectionId = fibaro:getSectionID(deviceID) 
print("SectionId : " ..SectionId)
local json = api.get("/sections/"..SectionId)
--local section1 = ("Nom : " ..json.name)
local section1 = ("" ..json.name)
-----------------------------------------------
local val   = fibaro:getValue(deviceID, "value")

-------------------------------------------
local valuefib     = fibaro:getName(deviceID)
local power     = fibaro:getValue(deviceID, "power")
local energy       = fibaro:getValue(deviceID, "energy")

function urlencode(str)
	if (str) then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w ])",
		function (c) return string.format ("%%%02X", string.byte(c)) end)  
		str = string.gsub (str, " ", "+")
	end
	return str
end



 -- http requete
   local http = net.HTTPClient()
http:request("http://192.168.0.16:8080/domotiquefibaro/fibaro_add.php?times="..times1.."&timestamp="..timestamp.."&nomdevice="..urlencode(tostring(nomdevice1 or "empty")).."&piece="..urlencode(tostring(piece1 or "empty")).."&section="..urlencode(tostring(section1 or "empty")).."&value="..val.."&power="..power.."&energy="..energy.."", {options = {
-----http:request("http://192.168.0.16:8080/domotiquefibaro/fibaro_add.php?times="..times1.."&timestamp="..timestamp.."&nomdevice="..urlencode(tostring(nomdevice1 or "empty")).."&piece="..urlencode(tostring(piece1 or "empty")).."&section="..urlencode(tostring(section1 or "empty")).."&value="..val.."", {options = {
method = 'GET'
},
success = function(response) fibaro:debug("OK") end,
error = function(err) fibaro:debug("Error: " ..err) end
})

 

Modifié par 971jmd
×
×
  • Créer...