Régulation d'une chaudière au fioul - Partage de ma réalisation

Au programme la régulation de température, la climatisation, les chauffe-eau...

Modérateur : Francois

Avatar du membre
ComteZera
Messages : 40
Enregistré le : dim. 10 mai 2015 18:49
Localisation : BZH (29)

Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par ComteZera » lun. 25 sept. 2017 22:44

Bonjour,

Depuis 2015, j'utilise ma petite framboise pour réguler ma chaudière au fioul, je vais vous présenter mon projet ici et donner mes codes sources pour aider des personnes qui voudraient ce lancer dans un projets similaire ;)

Je suis conscient qu'il y a beaucoup de chose que l'on peut améliorer, optimiser dans ce projet, mais je le fait avec mes connaissances et sur mon temps libre, d'ailleurs je l'améliore un peu chaque année :)

Partie 1 :

Mon matériel : (principal)

1) Raspberry pi 2
2) Une sonde de température DS18B20 (1wire)
3) Une carte 2 relais TOR

Système d'exploitation :

2015-05-05-raspbian-wheezy

Langage de programmation utilisé :

- Python
- PHP

Serveur WEB :

Apache

Base de donnée :

MySQL

Voici le squelette du programme, écrit en Python :

Code : Tout sélectionner

#!/usr/bin/python
# -*- coding: utf8 -*-

import os
import glob
import time
import datetime
import MySQLdb
import RPi.GPIO as GPIO  # bibliothèque pour utiliser les GPIO

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

SEUIL_DE_SECU = 22.0 #Seuil max de gestion de la température
SEUIL = 19.5 #Seuil réglé
DELTA = 0.5 #Delta qui permet de réguler la température afin d'éviter un déclenchement intempestive.
ETAT_REGULATION = 0 # 0 chauffage à l'arrêt / 1 chauffage en marche

# a adapter a la configuration
RELAIS_1 = 20
RELAIS_2 = 21
LEDverte = 17
LEDrouge = 22

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28-0115524b7dff')[0]
device_file = device_folder + '/w1_slave'

GPIO.setmode(GPIO.BCM)   # mode de numérotation des pins
GPIO.setup(LEDverte,GPIO.OUT) #Declaration de la pin en sortie
GPIO.setup(LEDrouge,GPIO.OUT)
GPIO.setup(RELAIS_1,GPIO.OUT)
GPIO.setup(RELAIS_2,GPIO.OUT)

#Valeurs initiales
GPIO.output(LEDverte,GPIO.LOW)
GPIO.output(RELAIS_1,GPIO.HIGH)

def read_temp_raw():
 f = open(device_file, 'r')
 lines = f.readlines()
 f.close()
 return lines

def read_temp():
 lines = read_temp_raw()
 while lines[0].strip()[-3:] != 'YES':
   time.sleep(0.2)
   lines = read_temp_raw()
 equals_pos = lines[1].find('t=')
 if equals_pos != -1:
   temp_string = lines[1][equals_pos+2:]
   temp_c = float(temp_string) / 1000.0
   return temp_c

def reguation(SEUIL_DE_SECU, SEUIL, DELTA, ETAT_REGULATION):
 if SEUIL >= SEUIL_DE_SECU:
	SEUIL = SEUIL_DE_SECU
 if (TEMPERATURE >= SEUIL_DE_SECU):
	return 0
 if (TEMPERATURE <= (SEUIL - DELTA) and ETAT_REGULATION == 0):
	return 1
 if (TEMPERATURE >= (SEUIL + DELTA) and ETAT_REGULATION == 1):
	return 0
 if ETAT_REGULATION == 0:
	 return 0
 if ETAT_REGULATION == 1:
	 return 1
	 
while True:
 TEMPERATURE = read_temp()
 TEMPERATURE = float (TEMPERATURE)
 DATE = time.strftime('%Y-%m-%d %H:%M:%S') #formating date for mySQL
 print DATE, "-> ", TEMPERATURE, "°C"
 #Connection à la base de données "temperature" pour enregistrer les températures
 try:
	db = MySQLdb.connect(host="127.0.0.1", user="XXXX", passwd="XXXXXXXX", db="Raspberry_pi")
 except Exception:
	print "Erreur connexion MySQL en 127.0.0.1"
 else:
	cur = db.cursor() 
	cur.execute("INSERT INTO temperature (date, temperature) VALUES (%s, %s)", (DATE, TEMPERATURE))
	db.commit()
	db.close()
	
 #Connection à la base de données "regulation" pour récupérer le seuil de régulation
 try:
	db = MySQLdb.connect(host="127.0.0.1", user="XXXX", passwd="XXXXXXXX", db="Raspberry_pi")
 except Exception:
	print "Erreur connexion MySQL en 127.0.0.1"
 else:
	cur = db.cursor()
	cur.execute("select regulation from regulation where date < %s order by date desc",(DATE, )) #Je récupère la valeur de régulation depuis la base régulation classé selon toute les date inférieur à l'actuel par ordre décroissant.
	SEUIL_temp=cur.fetchone()
	SEUIL=SEUIL_temp[0] #La valeur récupéré est un tulpe, je selectionne donc la 1ère valeur de mon tulpe qui ne contient qu'une valeur
	SEUIL = float (SEUIL)
	print "Le seuil à réguler est de :", SEUIL, "°C"
	db.commit()
	db.close()

 ETAT_REGULATION=reguation(SEUIL_DE_SECU, SEUIL, DELTA, ETAT_REGULATION)
 
 if ETAT_REGULATION == 1:
	GPIO.output(LEDverte,GPIO.HIGH)
	GPIO.output(RELAIS_1,GPIO.LOW)
	try:
		db = MySQLdb.connect(host="127.0.0.1", user="XXXX", passwd="XXXXXXXX", db="Raspberry_pi")
	except Exception:
		print "Erreur connexion MySQL en 127.0.0.1"
	else:
		cur = db.cursor()
		cur.execute("select temps_de_fonctionnement from compteur where id=2")
		TEMPS_DE_FONCTIONNEMENT_temp=cur.fetchone()
		TEMPS_DE_FONCTIONNEMENT=STEMPS_DE_FONCTIONNEMENT_temp[0]
		TEMPS_DE_FONCTIONNEMENT=STEMPS_DE_FONCTIONNEMENT+10
		cur.execute("UPDATE compteur SET temps_de_fonctionnement=%s WHERE id=2", (TEMPS_DE_FONCTIONNEMENT))
		db.commit()
		db.close()
 if ETAT_REGULATION == 0:
	GPIO.output(LEDverte,GPIO.LOW)
	GPIO.output(RELAIS_1,GPIO.HIGH)
	
 time.sleep(599)
Alors qu'est-ce que ce code fait :

Déjà, j'initialise mes valeurs initiales et définit mes ports sur le GPIO du Raspberry PI. (Un œil averti verra que je déclare 2 sorties pour la carte relais et que j'en utilise qu'une et une sortie pour une LED rouge que je n'utilise pas non plus, pour le moment ...)

J'ai une fonction qui me permet de récupérer la température par la sonde DS18B20, une fonction qui gère la régulation de manière très simple avec un hystérésis.

Le programme tourne dans une boucle sans fin, toute les 10 minutes, il va récupérer la température et la date (et l'heure) de la prise de mesure et l'afficher dans la console Python ainsi que le seuil de régularisation désiré.

La valeur de la température de régularisation et récupéré dans une base de donnée, elle est sélectionnée en fonction de la date et l'heure d'exécution du programme.

Lorsque la température mesurée est en dessous du seuil de déclenchement, j'active la sortie de mon relais (et j'allume la LED verte).
J'en profite pour enregistrer dans une autre base de données le temps de fonctionnement de la chaudière.

Partie 2 :

Le reste de l'interface ce fait par des pages WEB :

La 1ère me permet de visualiser les températures sur la journée :

Image

Code : Tout sélectionner

<div id="corps">
		<h1>Température</h1>
		<canvas id = "schema" height="600" width="576" style="border:1px solid">
	    	Votre navigateur ne supporte pas la balise canvas
		 </canvas>
		 <script>
			var zone_dessin = document.getElementById("schema");
			var graphe= zone_dessin.getContext("2d");
			graphe.strokeStyle = "#0098f8";
			graphe.lineWidth=2;
			graphe.beginPath(); // Début du chemin
			graphe.moveTo(0,600); // Le tracé part du point 0,600
			<?php
						try
						{
							// On se connecte à MySQL
							$bdd = new PDO('mysql:host=localhost;dbname=Raspberry_pi;charset=utf8', 'XXXX', 'XXXXXXXX');
						}
						catch(Exception $e)
						{
							// En cas d'erreur, on affiche un message et on arrête tout
							die('Erreur : '.$e->getMessage());
						}
						$long_tab=0;
						date_default_timezone_set('UTC');
						$Debut = date ("Y-m-d");
						$Fin = date("Y-m-d", strtotime("+1 day"));
						$reponse = $bdd->query('SELECT * FROM temperature WHERE date BETWEEN "' . $Debut .'" AND"' . $Fin. '"');
						
						$espacement=0;
						
						//creation des points pour le tracage de la courbe
						$reponse = $bdd->query('SELECT * FROM temperature WHERE date BETWEEN "' . $Debut .'" AND"' . $Fin. '"');
						while ($donnees = $reponse->fetch())
						{
							$temperature=$donnees['temperature'];
							$temperature2=600-($temperature*15);?>
							graphe.lineTo(<?php echo $espacement; ?>,<?php echo $temperature2; ?>);<?php
							$espacement=$espacement+4;
						}
						$reponse->closeCursor();
			?>
			graphe.stroke();
		</script>
			
			
			
		<?php
					try
				{
					// On se connecte à MySQL
					$bdd = new PDO('mysql:host=localhost;dbname=Raspberry_pi;charset=utf8', 'XXXX', 'XXXXXXXXX');
				}
				catch(Exception $e)
				{
					// En cas d'erreur, on affiche un message et on arrête tout
						die('Erreur : '.$e->getMessage());
				}
				// Si tout va bien, on peut continuer
				$reponse = $bdd->query('SELECT * FROM temperature ORDER BY id DESC');
				$donnees = $reponse->fetch();
				$date=$donnees['date'];
				$temperature=$donnees['temperature'];
				echo '<br />La dernière mesure de température à été faite le : ' . $date . '<br />La température mesurée était de : ' . $temperature .'°C';
				$reponse = $bdd->query('SELECT temperature, date FROM temperature ORDER BY temperature DESC, date ASC'); //tri température décroissant
				$donnees = $reponse->fetch();
				$date=$donnees['date'];
				$temperature=$donnees['temperature'];
				echo '<br /><br />La température la plus haute à été mesurée le : ' . $date . '<br />La température mesurée était de : ' . $temperature .'°C';
				$reponse = $bdd->query('SELECT temperature, date FROM temperature ORDER BY temperature ASC, date ASC');
				$donnees = $reponse->fetch();
				$date=$donnees['date'];
				$temperature=$donnees['temperature'];
				echo '<br /><br />La température la plus basse à été mesurée le : ' . $date . '<br />La température mesurée était de : ' . $temperature .'°C';
				$reponse->closeCursor();
		?>		
		<p>
		Pour consulter des valeurs sur une plage de temps cliquez ici : <a href="raspberry_temp.php">Plage de température</a>
		</p>
		</div>
Je crois que j'ai un petit bug sur la durée affichée :oops: mais ça me suffit pour visualiser d'un coup d’œil l'évolution de la température et cela me permet immédiatement de voir le nombre de fois que la chaudière c'est déclenchée dans la journée.
Je renvoie également la dernière mesure de température effectuée ainsi que l'heure de mesure, cela me permet de savoir si le programme python tourne toujours.
Pour information, j'affiche la dernière température minimum et maximum mesurée.

Si j'ai besoin d'analyser l'évolution de la température sur une durée déterminé, je me rends sur cette page :

Image

Code : Tout sélectionner

<div id="corps">
		<h1>Température</h1>
			<p>
				Inserez une date de début et de fin sous le format suivant : YYYY-MM-JJ HH:MM:SS
			</p>	
			<form action="raspberry_temp2.php" method="post">
				<p>
					Date de début : <input type="text" name="Debut" />
					Date de fin :   <input type="text" name="Fin" />
					<br /><input type="submit" value="Valider" />
				</p>
			</form>
		</div>
		
		<div id="pied_de_page">
Elle ne fait que m'envoyer des données sur une autre page qui va les traiter :

Image

Code : Tout sélectionner

<div id="corps">
		<h1>Température</h1>
		 <canvas id = "schema" height="600" width="700" style="border:1px solid">
	    	Votre navigateur ne supporte pas la balise canvas
		 </canvas>
		 <script>
			var zone_dessin = document.getElementById("schema");
			var graphe= zone_dessin.getContext("2d");
			graphe.strokeStyle = "#0098f8";
			graphe.lineWidth=2;
			//graphe.strokeRect(20, 50, 220,200);
			graphe.beginPath(); // Début du chemin
			graphe.moveTo(0,600); // Le tracé part du point 50,50
			//graphe.stroke();
			//graphe.moveTo(100,120);
		<?php
				
				if (isset($_POST['Debut'])!= false AND isset($_POST['Fin'])!= false) //Il y a donc des informations des renseigné
				{
					$Debut=$_POST['Debut'];
					$Fin=$_POST['Fin'];
					
					if ($Debut!=NULL AND $Fin!=NULL)
					{
						try
						{
							// On se connecte à MySQL
							$bdd = new PDO('mysql:host=localhost;dbname=Raspberry_pi;charset=utf8', 'XXXX', 'XXXXXXXX');
						}
						catch(Exception $e)
						{
							// En cas d'erreur, on affiche un message et on arrête tout
							die('Erreur : '.$e->getMessage());
						}
				         // Si tout va bien, on peut continuer
						$Debut=htmlspecialchars($_POST['Debut']);
						$Fin=htmlspecialchars($_POST['Fin']);
						$long_tab=0;
						$reponse = $bdd->query('SELECT * FROM temperature WHERE date BETWEEN "' . $Debut .'" AND"' . $Fin. '"');
						
						//calcul de la taille du tableau
						while ($donnees = $reponse->fetch())
						{
							$long_tab=$long_tab+1;
						}
						$espacement=(int)(700/$long_tab); // calcul de l'espacement pour tracer la courbe
						$espacement_val=$espacement;
						
						//creation des points pour le tracage de la courbe
						$reponse = $bdd->query('SELECT * FROM temperature WHERE date BETWEEN "' . $Debut .'" AND"' . $Fin. '"');
						while ($donnees = $reponse->fetch())
						{
							$temperature=$donnees['temperature'];
							$temperature2=600-($temperature*15);?>
							graphe.lineTo(<?php echo $espacement; ?>,<?php echo $temperature2; ?>);<?php
							$espacement=$espacement+$espacement_val;
						}
						?>
						graphe.stroke();
						</script>
						<?php
						$reponse = $bdd->query('SELECT * FROM temperature WHERE date BETWEEN "' . $Debut .'" AND"' . $Fin. '"');
						while ($donnees = $reponse->fetch())
						{
							$date=$donnees['date'];
							$temperature=$donnees['temperature'];
							echo 'Le ' . $date . ' la température était de : ' . $temperature . '°C<br />';
						}
						$reponse->closeCursor();
					}
				}
				else
				{
						echo "Vous n'avez pas saisie de valeur !";
				}
		?>		
		<p>
		Pour consulter des valeurs sur une plage de temps cliquez ici : <a href="raspberry_temp.php">Plage de température</a>
		</p>
		</div>
De la façon dont j'ai construit le code, je suis limité à un affichage sur 4 jours environ de la courbe de température (encore un point qui serait sympa d'améliorer par la suite :) )
Mais il me sort très bien la plage de valeurs désiré.

L'affichage des valeurs c'est bien, maintenant place aux consignes de régulations (celle que l'on récupère dans le programme en python) :

Image

Code : Tout sélectionner

<div id="corps">
		<h1>Gestion de la régulation</h1>
		<h2>Insertion d'une nouvelle règle de régulation</h2>
		<p>
		Pour insérer une nouvelle règle de régulation, remplir le formulaire suivant :
		<form action="regulation_2.php" method="post">
				<p>
					Date de début : <input type="text" name="Debut" />
					Seuil :   <input type="text" name="Seuil" />
					<br /><input type="submit" value="Valider" />
				</p>
			</form>
		
		<h2>Visualisation des règles de régulation</h2>
				<table>
				<tr>
					<th>Date</th>
					<th>Seuil de température</th>
				</tr>
				<?php
					try
				{
					// On se connecte à MySQL
					$bdd = new PDO('mysql:host=localhost;dbname=Raspberry_pi;charset=utf8', 'XXXX', 'XXXXXXXX');
				}
				catch(Exception $e)
				{
					// En cas d'erreur, on affiche un message et on arrête tout
						die('Erreur : '.$e->getMessage());
				}

				// Si tout va bien, on peut continuer
				$reponse = $bdd->query("SELECT * FROM regulation ORDER BY date ASC"); // Requête SQL
				while ($donnees = $reponse->fetch())
				{
					?>
					<p>
					<tr>
					<?php $id_bdd=$donnees['id'];
					      $date=$donnees['date'];
						  $date=stripslashes($date); //enlève les slashes rajouter précédemment
						  echo '<td>';
						  echo $date;
						  echo '</td>';
						  $regulation=$donnees['regulation'];
						  $regulation=stripslashes($regulation); //enlève les slashes rajouter précédemment
						  echo '<td>';
						  echo $regulation;
						  echo "°C";
						  echo '</td>';
					?>
					</tr>
					</p>
				<?php
				}
				?>
		</table>
		<h2>Temps de fonctionnement hiver 2017</h2>
			<?php
				$reponse = $bdd->query('SELECT * FROM compteur WHERE id=2');
				$donnees = $reponse->fetch();
				$temps=$donnees['temps_de_fonctionnement'];
				$jour = $temps / 60 / 24;
				$jour = (int) $jour;
				$heure = $temps / 60 % 24;
				$heure = (int) $heure;
				$minute = $temps % 60; 
				$minute = (int) $minute;
				echo 'La chaudière a tourné pendant : '. $jour.' jours '. $heure.' heures et '. $minute.' minutes';
			?>
		<h2>Temps de fonctionnement hiver 2015-2016</h2>
		<?php
				$reponse = $bdd->query('SELECT * FROM compteur WHERE id=1');
				$donnees = $reponse->fetch();
				$temps=$donnees['temps_de_fonctionnement'];
				$jour = $temps / 60 / 24;
				$jour = (int) $jour;
				$heure = $temps / 60 % 24;
				$heure = (int) $heure;
				$minute = $temps % 60; 
				$minute = (int) $minute;
				echo 'La chaudière a tourné pendant : '. $jour.' jours '. $heure.' heures et '. $minute.' minutes';
				$reponse->closeCursor(); // Termine le traitement de la requête
			?>
		</div>
A partir d'ici, j'insère mes règles de régulation. C'est le programme python qui se charge ensuite de récupérer la bonne valeur dans la base que j'alimente.
(Là encore, une amélioration serait à apporter, il me manque la suppression des règles :oops: )

En bonus, j'affiche mes compteurs de temps de fonctionnement ( :? amélioration à faire : gestion automatique)

Voici l'autre morceau du code qui ajoute les règles de régulation dans la base de donnée :

Code : Tout sélectionner

<div id="corps">
		<h1>Gestion de la régulation</h1>
		
		<?php
				
				if (isset($_POST['Debut'])!= false AND isset($_POST['Seuil'])!= false) //Il y a donc des informations des renseigné
				{
					$Debut=$_POST['Debut'];
					$Seuil=$_POST['Seuil'];
					
					if ($Debut!=NULL AND $Seuil!=NULL)
					{
						try
						{
							// On se connecte à MySQL
							$bdd = new PDO('mysql:host=localhost;dbname=Raspberry_pi;charset=utf8', 'XXXX', 'XXXXXXXX');
						}
						catch(Exception $e)
						{
							// En cas d'erreur, on affiche un message et on arrête tout
							die('Erreur : '.$e->getMessage());
						}
				         // Si tout va bien, on peut continuer
						$date=htmlspecialchars($_POST['Debut']);
						$regulation=htmlspecialchars($_POST['Seuil']);
						$regulation=floatval($regulation);
						echo $date;
						echo "<br />";
						echo $regulation;
						echo "°C";
						$bdd->exec("INSERT INTO regulation VALUES('', '$date', '$regulation')");
						//$bdd->closeCursor();
					}
				}
				else
				{
						echo "Vous n'avez pas saisie de valeur !";
				}
		?>		
		<p>
		Si pas de message d'erreur, les valeurs ont bien été enregistré !
		</p>
		</div>
Dernier né, l'estimation de mon niveau de cuve :

Image

Code : Tout sélectionner

<div id="corps">
		<h1>Estimation du niveau de la cuve</h1>
			<?php
					try
				{
					// On se connecte à MySQL
					$bdd = new PDO('mysql:host=localhost;dbname=Raspberry_pi;charset=utf8', 'XXXX', 'XXXXXXXX');
				}
				catch(Exception $e)
				{
					// En cas d'erreur, on affiche un message et on arrête tout
						die('Erreur : '.$e->getMessage());
				}

				// Si tout va bien, on peut continuer
				$reponse = $bdd->query('SELECT * FROM compteur WHERE id=2');
				$donnees = $reponse->fetch();
				$temps=$donnees['temps_de_fonctionnement'];
				$pourcent_consomme=$temps*100/68510;
				$pourcent_consomme=round($pourcent_consomme, 2);
				$pourcent_restant=100-$pourcent_consomme;
				$pourcent_consomme2=(int) $pourcent_consomme;
				$litre_restant=$pourcent_restant*1200/100;
				echo 'Il reste environ '. $pourcent_restant.' % de fioul dans la cuve soit approximativement '. $litre_restant. ' litres.';
				echo "<br />";
				$reponse->closeCursor(); // Termine le traitement de la requête
			?>
			
		<canvas id = "schema" height="100" width="8" style="border:2px solid">
	    	Votre navigateur ne supporte pas la balise canvas
		 </canvas>
		 <script>
			var zone_dessin = document.getElementById("schema");
			var graphe= zone_dessin.getContext("2d");
			graphe.strokeStyle = "#ff0000";
			graphe.lineWidth=8;
			graphe.beginPath(); // Début du chemin
			graphe.moveTo(4,100); // Le tracé part du point 2,0
			graphe.lineTo(4,<?php echo $pourcent_consomme2; ?>);
			graphe.stroke();
		</script>
		
		</div>
Depuis mon dernier plein (aïe le portefeuille :lol: ) je me suis servi de mon temps de fonctionnement pour estimer mon niveau de cuve, avec un petit barre graph pour que se soit plus visuel ;)

Voilà ou j'en suis pour le moment, je pense qu'a partir des informations fournit, vous avez aussi les moyen de vous amuser avec votre framboise.

destroyedlolo
Raspinaute
Messages : 1583
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par destroyedlolo » mar. 26 sept. 2017 11:24

Salut,

Jolie réalisation et merci pour le partage :)

Juste une remarque / commentaire concernant mySQL : j'imagine qu'elle est stockée sur la SD, non ?
Dans ce cas, elle risque de lacher à plus ou moins long terme car une SD n'est pas adapté pour stocker une BDD.

Pour les config, je serai parti sur une base clef/valeurs comme BerkerlyDB ou gdbm.

Pour les données dynamiques, je serai parti pour un stockage uniquement en mémoire (surement par un code maison, mais il existe aussi Memcached si tu veux un truc tout fait) : évidement les données sont perdues au reboot mais ... est-ce génant ?

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par Bud Spencer » mar. 26 sept. 2017 15:12

Même si je ne peux être que critique vis-à-vis des méthodes utilisées que je trouve totalement inadapté, je te félicite pour ce boulot et surtout pour sa mise en ligne. C’est tellement rare de voir ici un user décrire son projet en donnant les exemples et les codes que je pense qu’il est important de le faire remarquer.

Juste pour t’aider à améliorer, voici quelques petits conseils concernant quelques points qui m’ont interpelé à la lecture sommaire de tes codes :

Le premier point concerne les connexions à la dbase dans ton code python. Dans ta boucle while, tu ouvres et fermes la connexion à la base pour chaque requête (3 fois), ce qui est totalement inutile. Une seule connexion en début de boucle et sa fermeture en fin de boucle serait plus rapide et moins stressant a tous les niveaux.

Les requetes dans ton script php sont une catastrophe. Exemple :
- SELECT temperature, date FROM temperature ORDER BY temperature DESC, date ASC
Tu charges un jeu d’enregistrement qui contient toutes des lignes de ta table alors que tu n’as besoin que du premier enregistrement ordonné.
Modifie ta requête en ajoutant au moins LIMIT 0,1 a la fin de celle-ci. Tu ne chargeras plus que l’enregistrement dont tu as besoin
- SELECT temperature, date FROM temperature ORDER BY temperature DESC, date ASC LIMIT 0,1

Tu pourrais aussi avoir le retour des date/température mini et max avec une seule requête select …

C’est du bon boulot dans le sens où tu es partie d’une idée et tu arrives à un résultat (ça change de ceux qui veulent faire et qui échoue avant de commencer). Pour le reste, c’est l’histoire du marteau pilon et de la mouche, mais je ne veux pas te blâmer, c’est ce qu’on vous vend sur tous les forums. Ton serveur Apache t’as permis de découvrir PHP et c’est très bien, mais au-delà de ça, il ne te sert rien que quelques lignes de plus dans ton code python n'aurait sut faire. Idem pour MySQL. C’est un très bon outil mais totalement démesuré ici. Un fichier JSON suffirait largement pour la config et l’agrégation et l’utilisation de fichiers journalisés te donnerais les mêmes résultats en consommant moins de ressource et surtout en préservant ta SD.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Avatar du membre
ComteZera
Messages : 40
Enregistré le : dim. 10 mai 2015 18:49
Localisation : BZH (29)

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par ComteZera » mar. 26 sept. 2017 21:09

Merci pour votre retour ;)

Si j'ai appris tous ça, c'est en parti grâce à ce que j'ai pu trouver sur le net à droite et à gauche, donc je trouve normal de partager à mon tour :)

Alors effectivement, la base de donnée est bien stockée sur la SD, je suis conscient du risque de destruction de celle-ci (c'est en autre pour ça que j'ai une autre carte SD en stock et une sauvegarde de la SD configuré avec tout ce qu'il faut pour restaurer les données rapidement). Mais je suis curieux de voir la résistance de la carte, pour le moment, c'est toujours la 1ère depuis mai 2015.

Si j'ai choisi Apache et MySQL c'est uniquement parce que j'avais quelques connaissances dessus et que j'avais trouver ça très "puissant" à l'époque. Alors que ça ne soit pas adapté au projet, je le comprends parfaitement, cela à juste eu l'avantage d'arriver plus vite à ce que je voulais, et je savais également que c'était faisable.

Merci pour les conseils, effectivement, pour la parti python, il faut que je teste ça, du à mon manque de connaissance je pensais qu'il fallait se connecter à la base à chaque fois que l'on voulait interroger une table différente.

Pour les requêtes PHP, bien vu, je n'y avais pas pensé (encore un manque de maitrise, mais c'est en faisant des erreurs que l'on apprend et en voici la preuve :mrgreen: )

Je ne suis pas contre apprendre de nouveaux langages, nouvelles méthodes et je pense qu'une 2ème framboise serait bien pour m'amuser un peu, enfin, dès que j'aurai assez de temps pour m'y consacrer :(

destroyedlolo
Raspinaute
Messages : 1583
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par destroyedlolo » mar. 26 sept. 2017 22:41

Salut,
ComteZera a écrit :Alors effectivement, la base de donnée est bien stockée sur la SD, je suis conscient du risque de destruction de celle-ci (c'est en autre pour ça que j'ai une autre carte SD en stock et une sauvegarde de la SD configuré avec tout ce qu'il faut pour restaurer les données rapidement). Mais je suis curieux de voir la résistance de la carte, pour le moment, c'est toujours la 1ère depuis mai 2015.
Une carte de qualité (ce qui n'est pas forcement reliée à son prix :) ), devrait compenser les pertes de cellules voir même étaler les écritures pour éviter une défaillance : ca peut donc durer un moment.

Pour le reste, Apache/MySQL ou quoi que soit d'autre, tu auras autant de solutions que de gens pour commenter :)
Même si je ne serai sans doute pas parti dans cette direction, c'est a toi de voir celle qui te conviens !

Par contre concernant
(encore un manque de maitrise, mais c'est en faisant des erreurs que l'on apprend et en voici la preuve :mrgreen: )
Il est important d'avoir une solution de replie :)
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

nexen
Raspinaute
Messages : 175
Enregistré le : lun. 29 sept. 2014 13:58

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par nexen » mer. 27 sept. 2017 08:46

Bonjour à tous,

Merci déjà pour ton partage, je travail moi aussi sur ce type de sujet et avec les mêmes techno en vu (PHP/Mysql/Python) pour piloter mon poële à pellet.

Merci aux bien pensant de la technologie de ne pas juger sur une partie des information et de nous dire moi j'aurais pas fais ... j'aurais utilisé ..... vous n'avez pas toutes les informations en mains et vous ne savez pas quels sont les paramètres qui l'on amener à choisir cette solution.

Par exemple, pour mon cas le choix de PHP et de mysql est naturel car je suis un ancien dev et un Admin de base de données ... donc j'ai fait un choix de fainéant : reprendre les technos que je maîtrise. par contre je maîtrise mieux le perl que le python mais ce n'est pas un soucis il est facile ....

je partage l'avis de bud, il serait utile pour ton code de n'ouvrir ta base que 1 fois en début de boucle et d'optimisé tes requêtes => tu seras plus rapide et tu consommera moins ta SD
je partage l'avis de destroy ( aussi parce que je l'ai fais depuis plus de 2 ans) : Passe ta base sur un disque !!!!! la mienne tourne depuis 3 ans et j'ai des millions de données régulièrement qui transites (en lecture et en écriture)

Petite idée d'évolution : avoir la courbe de température extérieure pour calculer ton inertie ;)

@ bientôt

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par Bud Spencer » mer. 27 sept. 2017 20:56

ComteZera a écrit : Merci pour les conseils, effectivement, pour la parti python, il faut que je teste ça, du à mon manque de connaissance je pensais qu'il fallait se connecter à la base à chaque fois que l'on voulait interroger une table différente.
Pour les requêtes PHP, bien vu, je n'y avais pas pensé (encore un manque de maitrise, mais c'est en faisant des erreurs que l'on apprend et en voici la preuve :mrgreen: )
Bien sur. Personne n'a dit qu'il ne devait y avoir que des gourous du code et on a tous débuté un jour. Maintenant que l'idée t'as été suggérée, je suis sur que tu vas te replonger dans ton code pour l'améliorer et quand tu viendras généreusement nous présenter ton nouveau code pour nous faire part des améliorations, je t'expliquerais que tu pourrais tout aussi bien créer une vue dans ta dbase ou faire une requête plus 'composée' de façon a récupérer toutes tes données en une seule requête. C'est comme ca que l'on apprend le mieux, "step by step"

nexen a écrit :Merci aux bien pensant de la technologie de ne pas juger sur une partie des information et de nous dire moi j'aurais pas fais ... j'aurais utilisé ..... vous n'avez pas toutes les informations en mains et vous ne savez pas quels sont les paramètres qui l'on amener à choisir cette solution.
Il ne s’agit pas absolument pas de juger mais plutôt de donner des avis ‘éclairés’, proposer des choix et pousser à la découverte de solutions plus efficaces et plus adaptées tout en étant plus simple a mettre en œuvre. On pourrait aussi ne rien dire du tout mais je ne suis pas sûr que cela aiderai beaucoup à avancer et relever le niveau …
ComteZera a écrit :j'ai choisi Apache et MySQL c'est uniquement parce que j'avais quelques connaissances dessus
nexen a écrit :... j'ai fait un choix de fainéant : reprendre les technos que je maîtrise...
Très bien, mais techniquement parlant ça vaut quoi ?
Pour moi c'est un bel exercice réussi mais ce serait clairement un échec d'en rester la ;)
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

nexen
Raspinaute
Messages : 175
Enregistré le : lun. 29 sept. 2014 13:58

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par nexen » jeu. 28 sept. 2017 11:20

Bonjour,
Il ne s’agit pas absolument pas de juger mais plutôt de donner des avis ‘éclairés’, proposer des choix et pousser à la découverte de solutions plus efficaces et plus adaptées tout en étant plus simple a mettre en œuvre.

Un avis éclairé de ton point de vu .... avec seulement 10% d'informations .... et on aura 25 autres versions .... autant mettre un droid, un mac et un windows dans la même salle et leur demander le même projet ....
Très bien, mais techniquement parlant ça vaut quoi ?
Pour moi c'est un bel exercice réussi mais ce serait clairement un échec d'en rester la ;)
ça donne :
C’est du bon boulot dans le sens où tu es partie d’une idée et tu arrives à un résultat (ça change de ceux qui veulent faire et qui échoue avant de commencer)
tu demande pourquoi nous restons dans nos domaines ... et bien parce-que nous voulons finalisé nos projets dans un temps imparties sans être obliger d’inonder les forums de questions ;)
Un fichier JSON suffirait largement
Mode TROLL : Quoi un fichier pour de la base de données ... pourquois pas du CSV ou de l'access ???
Mode Donneur d'avis éclairé : Moi j'aurais utilisé un RRD .... c'est tellement plus simple <-- Oui pour toi qui maîtrise cette techno ....
Mode sympa : Et que pense tu du JSON ? cela devrais couvrir ta demande, As-tu besoins d'aide pour le mettre en place ? En plus tu sauverais une SD card !

Je m'excuse de polluer ce poste en jouant sur les mots ... mais quand une personne nous fait dont de son travail, il est important de le remercier (ce qui à était fait), de l'aider à évoluer dans ses domaines de compétences avant de lui dire 'xxx aurait suffit' ... il le savait peut-être déjà avant :)

@comteZera
Le programme tourne dans une boucle sans fin, toute les 10 minutes, il va récupérer la température et la date (et l'heure) de la prise de mesure et l'afficher dans la console Python ainsi que le seuil de régularisation désiré.
J'aimerai relever cette information car lors de mes tests avec des boucles sans fin j'ai déjà eu des soucis ( le script plante et ta régul ne fonctionne plus ....) tu reboot et ça ne fonctionne plus ....
Je supprime donc les boucles sans fins avec notion de temps et je remplace par des scripts one-shoot sur la crontab. ça soulage ton cpu (Bon un wait ça consomme que dalle ...) mais tu es sur que ton script fonctionne tous le temps même la nuit ;) et qu'il est relancé en cas de reboot :)
Si tu as besoins d'aide pour migrer sur cette solution, je suis disponible :)

@ bientôt

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par Bud Spencer » jeu. 28 sept. 2017 14:00

Qu’est-ce que tu veux que je te dise ? SI tu n’es pas capable d’explorer d’autres solution sans avoir besoin d’inonder les forums ou que tu te trouves trop vieux ou pas suffisamment motivé pour vouloir étudier autre chose, c’est toi que ça regarde. Doit-on pour autant ne rien proposer aux autres ?
nexen a écrit :... quand une personne nous fait dont de son travail, il est important de le remercier (ce qui à était fait), de l'aider à évoluer dans ses domaines de compétences avant de lui dire 'xxx aurait suffit' ...
C’est exactement ce que j’ai fait en lui faisant remarquer les anomalies sur ces connexions et ses requêtes. Ensuite, je n’ai fait que lui proposer l’exploration d’autres pistes pour l’amélioration son projet, rien de plus et c’est à lui de décider s’il le fera ou pas (ce don finalement je me fout totalement)
nexen a écrit :Je m'excuse de polluer ce poste en jouant sur les mots ...
T’inquiète pas, c’est une habitude ici. C’est peut-être un peu pour ça que peu de gens sont vraiment assidu sur ce forum, que l’on y trouve toujours les mêmes ringardises et que le niveau affiché dans ces domaines stagne globalement au ras des pâquerettes.

m'enfin ...
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

destroyedlolo
Raspinaute
Messages : 1583
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Régulation d'une chaudière au fioul - Partage de ma réalisation

Message par destroyedlolo » jeu. 28 sept. 2017 19:46

Salut,
nexen a écrit :
comteZera a écrit :Le programme tourne dans une boucle sans fin, toute les 10 minutes, il va récupérer la température et la date (et l'heure) de la prise de mesure et l'afficher dans la console Python ainsi que le seuil de régularisation désiré.
J'aimerai relever cette information car lors de mes tests avec des boucles sans fin j'ai déjà eu des soucis ( le script plante et ta régul ne fonctionne plus ....) tu reboot et ça ne fonctionne plus ....
Oui, mais ...
nexen a écrit :Je supprime donc les boucles sans fins avec notion de temps et je remplace par des scripts one-shoot sur la crontab. ça soulage ton cpu (Bon un wait ça consomme que dalle ...) mais tu es sur que ton script fonctionne tous le temps même la nuit ;) et qu'il est relancé en cas de reboot :)
... non, forker un nouveau process est extrêmement glouton surtout avec Python dont la VM est relativement lourde par rapport par exemple à Lua.
Une solution peut passer par :
  • démarrage au boot par un "service" (le plus standard)
  • par une entrée dans /etc/rc.local (le plus simple mais un peu désuet)
  • par une entrée @reboot ou @startup (non standard, dépend de la version de ton démon cron)
Pour qu'il continue a tourner pendant un crash, on peut jouer sur un script du genre :

Code : Tout sélectionner

#!/bin/bash

while true
do
	ton_script.py
done
Pour le reste, malheureusement, tu joue au "Don Quichotte" :(
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Répondre

Retourner vers « Gestion de la température »