[LUA] Regulation chauffage PID

Vous avez créé un script LUA dont vous êtes fier, un .sh génial, un programme Python hors du commun, un Tuto, c'est ici que vous pouvez les partager.
Guitoo
Messages : 4
Inscription : 20 févr. 2015, 08:46

[LUA] Regulation chauffage PID

Message par Guitoo »

Bonjour à tous,

Je domoticz depuis janvier avec un raspberry B+ et j’ai planché sur un contrôle de température à base de PID. Je voulais vraiment pouvoir piloter à distance la température : genre couper le weekend sans qu’il fasse 13°C lorsqu’on rentre le dimanche soir.
Mon installation se compose d’une chaudière à gaz avec relais de contrôle, d’une sonde de température intérieure dans le salon, d’un RFXtrx433e et une piface en guise de carte I/O.

Principe de base :
Un script_device suit l’évolution de la température de la sonde oregon par rapport à la consigne et détermine une consigne de chauffage de 0 à 100 en fonction :
1 : de l’écart avec la consigne (Proportionnel) jusqu’ici tout la bien
2 : de la somme des écarts (Intégral) ça ce n’est pas trop dur non plus
3 : de la variation de l’écart (Dérivée) la ça se corse
Commande de chauffage = Kp*Erreur + Ki*Somme des erreurs + Kd*Delta de l’erreur
Les variables Kp, Ki et Kd sont fonction de chaque installation.

Code : Tout sélectionner

-- script_device_thermostatv3.lua ------------------------------------
----------------------------------------------------------------------
-- G PETREMENT 2015 --------------------------------------------------
-- This script is a heating regulation use to maintain temperatur ----
-- at a specific value. ----------------------------------------------
----------------------------------------------------------------------

--------------------------------
--- Variables utilisateur ------
--------------------------------
local VarConsigne =  "ConsigneThermostat" --Température de consigne
local sonde = 'Sonde salon'               --Nom de la sonde de température
local IDerreur = '62'                     --IDX de l'afficheur d'erreur
local IDSomerreur = '77'                  --IDX de l'afficheur Somme d'erreur
local IDDeltaErreur = '90'                --IDX de l'afficheur Différence d'erreur
local IDCmdChauff = '78'                  --IDX de l'afficheur Proportionnel Commande Chauffage
local domoticz_url = '192.168.0.4:8080'   --Adresse IP:port de Domoticz
local VarKp = "Kp"                        --Variable Domoticz : Gain proportinnel
local VarKi = "Ki"                        --Variable Domoticz : Gain intégral
local VarKd = "Kd"                        --Variable Domoticz : Gain dérivé
local VarTempErr = 'TemperatureErreur'    --Variable domoticz pour l'erreur de temperature
local VarSomErr = 'SommeErreur'           --Variable domoticz pour la somme des erreurs
local VarDeltaErr = 'DeltaErreur'         --Variable domoticz pour la différences des erreurs
local VarCmdChauff = 'CmdChauff'          --Variable Domoticz de commande du chauffage : permet de passer la commande à script_time_chauff.lua
local VarCmdImax = 'CmdImax'              --Variable domoticz qui défini le gain intégral maximum
local fichier = '/var/tmp/dom_tmperr.txt' --Chemin d'acces du fichier sur un RAMdisque pour réduire l'usure de la carte SD
local nbr_stk = 22                        --Quantité de valeurs utilisées pour le calcul de la dérivée de l'erreur (ne pas mettre 0!!)

--------------------------------------------------------------
-- Fonction pour arrondir un nombre à la décimale souhaitée --
--------------------------------------------------------------
math.round = function(number, precision)
	precision = precision or 0
	local decimal = string.find(tostring(number), ".", nil, true);
	
	if ( decimal ) then	
		local power = 10 ^ precision;  
		if ( number >= 0 ) then 
			number = math.floor(number * power + 0.5) / power;
		else 
			number = math.ceil(number * power - 0.5) / power;		
		end
		
		-- convert number to string for formatting
		number = tostring(number);			
		-- set cutoff
		local cutoff = number:sub(decimal + 1 + precision);
		-- delete everything after the cutoff
		number = number:gsub(cutoff, "");
	else
		-- number is an integer
		if ( precision > 0 ) then
			number = tostring(number);
			number = number .. ".";
			for i = 1,precision
			do
				number = number .. "0";
			end
		end
	end		
	return number;
end

---------------------------------------------------------
---  Fonction pour calculer la commande de chauffage  ---
---------------------------------------------------------
Chauff = function(Kp,Err,Ki,SomErr, Kd, DifErr)
	local cmd = Kp*Err + Ki*SomErr + Kd*DifErr
	-- La commande de chauffage est un nombre entier compris entre 0 et 100
	if cmd < 0 then 
		cmd = 0
	elseif cmd > 100 then
		cmd = 100
	else
		cmd = math.round(cmd, 0)
	end
	return cmd
end

-----------------------------
---- Programme principal ----
-----------------------------
commandArray = {}
--La sonde Oregon 'Salon' emet toutes les 40 secondes. Ce sera approximativement la fréquence d'exécution de ce script.

if (devicechanged[sonde]) then
  
  -- Initialisation des variables
  local t = {} --Table buffer avec le fichier texte
  local SomErreur = tonumber(uservariables[VarSomErr]) --Somme des erreurs
  local Kp = tonumber(uservariables[VarKp])
  local Ki = tonumber(uservariables[VarKi])
  local Kd = tonumber(uservariables[VarKd])
  local CmdImax = tonumber(uservariables[VarCmdImax]) --Limitation de l'action intégrale (debug)
  local consigne =  otherdevices_svalues[VarConsigne]  --Température de consigne
    
  ---------------------------------
  ---  Calcul du proportionnel  ---
  ---------------------------------
  --Temperature relevée dans le salon
  local temperature = devicechanged[sonde..'_Temperature'] 
  temperature = tonumber(math.round(temperature,2))

  -- Update de la sonde d'erreur
  local TmpErreur = consigne - temperature
  local url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDerreur..'&nvalue=0&svalue='..TmpErreur
  commandArray[1]={['OpenURL']=url }
  
  ------------------------------
  ---  Calcul de la dérivée  ---
  ------------------------------
  --Creation si le ficher n'existe pas
  local f = io.open(fichier, "a+")
  f:close()
  --Lecture du fichier et remplissage de la table t
  f = io.open(fichier, "r")
  for line in f:lines() do
    if line ~= nil then
      table.insert(t,line)
    end
  end
  f:close()
  -- Ajout de la nouvelle ligne a la table
  table.insert(t,tostring(os.time()..";"..math.round(TmpErreur,2)))  
  --Suppression de l'élement le plus vieu
  while #t > nbr_stk do
      table.remove(t,1)
  end
    -- Eriture dans fichier'
  f = io.open(fichier,"w")
  for key,value in pairs(t) do
	  f:write(value.."\n")
  end
  f:close()
  -- Calcul Difference entre deux erreurs à 15min d'interval + calibration
  local MoyErr1 = 0
  local MoyErr2 = 0
  for i=1,#t/2 do
    MoyErr1 = MoyErr1 + tostring(string.sub(t[i],string.find(t[i], ";")+1))
    MoyErr2 = MoyErr2 + tostring(string.sub(t[#t+1-i],string.find(t[#t+1-i], ";")+1))
  end
  --Le delta erreur est calculé sur la moyenne de 22 erreurs ce qui permet de 'lisser' la variation
  local DeltaErreur = tonumber(math.round(((MoyErr2 / (#t/2)) - (MoyErr1 / (#t/2)))*8 ,2)) --Delta en d°/heure
  print('--DeltaErreur = ('..MoyErr2..'/'..(#t/2)..') - ('..MoyErr1..'/'..(#t/2)..') * 8= '..DeltaErreur)
  -- Update de la sonde DeltaErreur
  url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDDeltaErreur..'&nvalue=0&svalue='..DeltaErreur
  commandArray[2]={['OpenURL']=url }
  
  -------------------------------
  ---  Calcul de l'intégrale  ---
  -------------------------------
  -- Calcul de la somme des erreurs + Update de la sonde Somme d'erreur
  -- Si la l'erreur est supérieure à +-1° on ne somme pas pour limiter l'impact des changements de consigne
  if ((TmpErreur > -1) and (TmpErreur < 1) and (Ki ~= 0)) then
    SomErreur = tonumber(math.round(TmpErreur + SomErreur,2))
    if (SomErreur > (CmdImax/Ki)) then
        SomErreur = CmdImax/Ki
    elseif (SomErreur < 0) then
      SomErreur = 0
    end
  end
  url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDSomerreur..'&nvalue=0&svalue='..SomErreur
  commandArray[3]={['OpenURL']=url }

  ------------------------------------------
  --- Calcul de la commande de chauffage ---
  ------------------------------------------
  print('Consigne = '..consigne..' Temperature = '..temperature)
  local CmdChauff = Chauff(Kp, TmpErreur, Ki, SomErreur, Kd, DeltaErreur)
  -- Update de la mesure Commande
  url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDCmdChauff..'&nvalue=0&svalue='..CmdChauff
  commandArray[4]={['OpenURL']=url }
  print('--Commande de chauffage : '..CmdChauff..' / Kp ='..tostring(Kp*TmpErreur)..' / Ki ='..tostring(Ki*SomErreur)..' / Kd ='..tostring(Kd*DeltaErreur))
  --Passage des variables à domoticz
  commandArray['Variable:'..VarTempErr]= tostring(TmpErreur)
  commandArray['Variable:'..VarSomErr]= tostring(SomErreur)
  commandArray['Variable:'..VarDeltaErr]= tostring(DeltaErreur)
  commandArray['Variable:'..VarCmdChauff]= tostring(CmdChauff)
  
end
return commandArray
Un script_time se déclenche toute les 15min pour lancer (ou non) la chaudière pendant un certain temps via un des relais du Piface.
C’est un genre de modulation PWM avec une base de temps assez longue.
PWM
PWM
PWM.PNG (66.32 Kio) Consulté 35265 fois
C’est un peu obligé pour éviter l’usure de la chaudière, on ne peut pas démarrer et arrêter le bruleur tous les 10s, ce n’est pas une résistance électrique. En plus j’ai ajouté deux protections, une pour éviter les cycles trop courts (ça de toute façon il doit y avoir une protection matérielle sur la chaudière mais je n’ai pas trouvé d’info mais je suis preneur si certains connaisse) dans mon cas on évitera les cycles de chauffe inférieur à 3min, et une deuxième pour éviter les temps d’arrêt très court à la fin des cycles de presque 15min.

Code : Tout sélectionner

-- script_time_cmdchauffv2.lua ---------------------------------------
-- G PETREMENT -------------------------------------------------------
----------------------------------------------------------------------
-- Permet de commander relais de pilotage de chaudiere à gaz ---------
-- Le cycle fait 900s / 15min  ---------------------------------------
-- La commande est un nombre de 0 à 100 ------------------------------
-- Le cycle minimum de la chaudière est de 3min pour réduire l'usure -
----------------------------------------------------------------------

local InterOnOff = 'Chauffage On/Off'     --Interrupteur général de mise en route du chauffage
local VarCmdChauff = 'CmdChauff'          --Variable de commande de chauffage définie par script_device_thermostat
local CycleMini = 180                     --Durée de chauffe minimum en secondes (fonction de la chaudière)
local InterRelais = 'Piface RelayChaud'   --Sortie vers relais chaudière
local domoticz_url = '192.168.0.4:8080'   --Adresse IP:port de Domoticz

-- Fonction retourant la differrence de temps en secondes
function timedifference(s)
   year = string.sub(s, 1, 4)
   month = string.sub(s, 6, 7)
   day = string.sub(s, 9, 10)
   hour = string.sub(s, 12, 13)
   minutes = string.sub(s, 15, 16)
   seconds = string.sub(s, 18, 19)
   t1 = os.time()
   t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
   difference = os.difftime (t1, t2)
   return difference
end

commandArray = {}
--  Recuperation des variables
local CmdChauff = uservariables[VarCmdChauff]
local OnOff = otherdevices[InterOnOff]

--  Recuperation des minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))

-- Execution de cette partie du script toutes les 15 minutes
-- Contacte la chaudière et modifie la variable domoticz Cycle
if( (minutes==15) or (minutes==0) or (minutes==30) or (minutes==45) ) then
	print('-- Lancement du script à '..hours..'h'..minutes)
	print('-- OnOff ='..OnOff..' / CmdChauff ='..CmdChauff)
	
	if  OnOff == 'On' then  --Si l'inter général est ON
		local Cycle = CmdChauff * 9  --Calcul du temps de cycle en seconde
        
		if Cycle < CycleMini then --Si le cycle est trop court on coupe
			commandArray[InterRelais]='Off'
			commandArray['Variable:'..VarCycle]= tostring('0')
      print('Cycle :'..Cycle..'s >> Chaudière Off')
		
    elseif Cycle > 870 then --Si le cycle est trop long (> 14min30) on allume sans coupure
      commandArray[InterRelais]='On'
			commandArray['Variable:'..VarCycle]= tostring(Cycle)
      print('Cycle :'..Cycle..'s >> Chaudière On')
    
    else --Enfin on lance pour X seconde
			print('Cycle lancé pour : '..Cycle..'secondes')
			commandArray[1]={[InterRelais]='On'}
      commandArray[2]={[InterRelais]='Off AFTER '..tostring(Cycle)}
		end
	else
		commandArray[InterRelais]='Off'
		commandArray['Variable:'..VarCycle]= tostring('0')
		print('Chaudière Off')	 
	end
end

return commandArray
Enfin un script_device réagit sur 2 boutons dummy :
Le premier est un bouton programmé. Quand c’est ON, la consigne passe à la valeur « Confort » (stocké en variable), quand c’est OFF on passe en Eco. On peut aussi agir sur le bouton manuellement. Un bouton HorsGel qui désactive le bouton programmé et passe la température en mode « Pas La ». On peut toujours agir sur la consigne en manuel et à tout moment.

Code : Tout sélectionner

-- script_device_conschauf.lua ---------------------------------------
-- G PETREMENT -----------------------------------------------2015----
----------------------------------------------------------------------
-- Pilotage d'un Thermostat setpoint Consigne pour pilotage regul ----
-- en fonction d'une programation journaliere ------------------------
----------------------------------------------------------------------
-- Le programme est basé sur l'action de 2 switchs (virtuels ou non) -
-- Le Switch EcoConfort dispose d'une programation mais peut aussi ---
-- être actionné manuellement. ---------------------------------------
-- Le switch HorsGel est un mode vacance qui stope la programmation --
-- Les temperatures de consignes sont stockées en variable direct ----
-- dans domoticz pour être modifiées par l'interface web. ------------
----------------------------------------------------------------------

----------------------------------------------------------------------
-- VARIABLES UTILISATEUR : mettre les nom des dispositifs ici --------
----------------------------------------------------------------------
local VarConsJour = 'ConsigneJour'       --Variable consigne jour
local VarConsNuit = 'ConsigneNuit'       --Variable consigne nuit
local VarConsVac = 'ConsigneVacance'     --Variable consigne vacances
local VarSomErr = 'SommeErreur'          --Variable Somme des erreurs
local SondeCons = 'ConsigneChauffage'    --Sonde de temperature
local InterEcoConfort = 'EcoConfort'     --Interrupteur programmé Off:eco On:confort
local InterHorsGel = 'HorsGel'           --Interrupteur On:mode hors gel>> plus de programmation, consigne vacance ou manuelle
local domoticz_url = '192.168.0.4:8080'  --Adresse IP:port de Domoticz
local IDXcons = '96'                     --IDx de l'afficheur de consigne
----------------------------------------------------------------------

-- Fonction retourant la differrence de temps en secondes ------------
function timedifference(s)
   year = string.sub(s, 1, 4)
   month = string.sub(s, 6, 7)
   day = string.sub(s, 9, 10)
   hour = string.sub(s, 12, 13)
   minutes = string.sub(s, 15, 16)
   seconds = string.sub(s, 18, 19)
   t1 = os.time()
   t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
   difference = os.difftime (t1, t2)
   return difference
end

commandArray = {}
--  Recuperation des variables ---------------------------------------
local ConsJour = uservariables[VarConsJour]
local ConsNuit = uservariables[VarConsNuit]
local ConsVac = uservariables[VarConsVac]
local Consigne = otherdevices_temperature[SondeCons]
local t1 = os.date("%H:%M")

-- Lorsqu'un interrupteur est manipulé on modifie la temperature de consigne.
-- La variable SommeErreur utilisée pour calculer le gain intégral est aussi remise à 0 >> Gain intégral=0
if (((devicechanged[InterEcoConfort] == 'On') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort] == 'On'))) then
	print("-------------- Temperature modifiée vers Confort à "..t1)
	-- Mise a jour de l'afficheur via JSON -----------------------------
	local url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsJour
	commandArray[1]={['OpenURL']=url }
	commandArray['Variable:'..VarSomErr]='0'

elseif (((devicechanged[InterEcoConfort] == 'Off') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort]=='Off' ))) then
	print("-------------- Temperature modifiée vers Eco à "..t1)
	-- Mise a jour de l'afficheur via JSON -----------------------------
	local url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsNuit
	commandArray[1]={['OpenURL']=url }
	commandArray['Variable:'..VarSomErr]='0'
  
elseif (devicechanged[InterHorsGel] == 'On') then
	print("-------------- Temperature modifiée vers HorsGel à "..t1)
	-- Mise a jour de l'afficheur via JSON -----------------------------
	local url = domoticz_url..'/json.htm?type=command&param=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsVac
	commandArray[1]={['OpenURL']=url }
	commandArray['Variable:'..VarSomErr]='0'
end
return commandArray
Panneau de controle :
Ecran Chauffage.PNG
Ecran Chauffage.PNG (217.2 Kio) Consulté 35265 fois
Vous aurez besoin de 3 dummy switch, une sortie relais, 3 sondes T° dummy, 1 sonde Oregon, 1 mesure dummy % et un thermostat setpoint dummy.

Variables domoticz :
J'utilise les variable pour deux choses : transmettre des valeurs entre deux scripts et choisir les constantes des scripts (ce qui évite d'aller bidouiller dans nano)
VariablePID
VariablePID
Variable1.PNG (35.21 Kio) Consulté 35265 fois
Résultats du système :
J’ai implémenté le coef Kp en premier. Déjà là avec un gain suffisant on arrive à avoir une erreur de 0,3°C seulement et un réel confort de chauffage. Contrairement aux systèmes «hystérésis» ou on lutte contre l’inertie de la maison (la mienne est en pierre ce qui joue pas mal), là on allume la chaudière quelque minutes tous les ¼ d’heure ce qui permet de maintenir une sensation de chaud agréable.
L’ajout du Ki permet de réduire l’écart résiduel. La cmd intégrale va augmenter progressivement (on somme l’écart avec les écarts précédants) puis se stabiliser lorsque la consigne est atteinte (écart = 0). Par contre on augmente l’instabilité du système cad une ondulation de la température sur 1/2heure ou 1 heure. C’est un peu gênant et oblige à choisir un Ki pas trop fort au détriment du temps d’obtention de la consigne (effet retardateur). J’ai ajouté des limites à l’action du Ki car cette action peut vraiment mettre le cayon surtout si le système commence à onduler méchamment avec une amplitude de l’ordre du degré. Donc j’ai limité l’action du Ki à 60% de la commande de chauffage, je remets le Ki à 0 à chaque changement programmé de température (surtout utile durant la période de réglage, j’ai vu des Gain intégrale à 3 ou 4 zéro !!) enfin la somme des erreurs ne se fait que si on est dans un intervalle de 1° autour de la consigne. Je pense qu’une fois équilibrée ces limites doivent pouvoir dégager sans risque mais comme ça ne nuit pas…
Le Kd « stabilise » le système. Je l’ai finalement ajouté car j’avais des problèmes de dépassement du point de consigne. Soit à la chauffe avec un dépassement positif ou au refroidissement avec un dépassement négatif. Le Kd s’oppose à la variation de température donc lorsque les deux autres termes sont faibles il ralentit la courbe de montée ou de décente. La commande dérivée a été le plus complexe à calculer car l’écart entre deux températures successives est nul la plupart du temps (précision à 0,1). J’ai donc fait un calcul basé sur la moyenne des 22 dernières mesures (fichier texte stocké sur RAMdisk). Du coup le deltaT à un peu de « retard » mais ça à l’air de marcher.

Et maintenant ?
Maintenant ça marche tout seul, le dépassement de température est vraiment minime (0,2° max) le confort est la et on « vois » bien le système moduler en fonction de la température extérieure. Je pense qu’il faudrait refaire un réglage des coef en suivant une méthode de calcul mais je n’ai pas vraiment le temps. De plus je me demande si ça fonctionnera toujours aussi bien lorsqu’il fera moins froid.
Pour le moment la programmation est super simple mais on peut imaginer greffer un GoogleCal là-dessus pour personnaliser au maximum.
Je pense aussi faire un afficheur bien design à base de matrice de led mais j’ai pas encore défini le cahier des charges histoire de pouvoir faire un réglage simple sans allumer l’ipad.

Limitations du système
Le premier danger c’est qu’est qui se passe si le bazard plante ? Coupure d’élec, usure SD, relais HS, sonde morte… Une analyse des risques rapide montre que le danger existe. La chaudière possède des sécurités qui devraient limiter le risque d’incendie. Par contre de la surconsommation avec une baraque à 35°C pendant 10jours de vacance c’est possible. Ou pire, chauffage à l’arrêt, maison à -5 et tous les tuyaux qui éclatent. Il faut donc mettre des sécurités à tous les niveaux :
En premier lieu je pense modifier le programme pour qu’il ne dépende pas complétement d’une seule sonde. Je vais intégrer la possibilité utiliser d’autres sondes en cascades (en y appliquant des offsets si besoin) voir même on peut utiliser la température du core du raspi si celui-ci est dans une des pièces chauffées (le delta est constant avec la température ambiante, ça pourrai servir de sécurité supplémentaire).
Ensuite il faudrait intégrer un script (python, shell…) pour le cas ou domoticz planterai catastrophiquement et ne se relance pas.
Pour finir je pense mettre un système de sécurité externe (genre vieux thermostat d’ambiance) qui pourrai prendre la main lorsque le raspi est éteint (utilisation du relais 2 du piface en position NF). Je pourrais utiliser aussi un script sur le NAS pour vérifier le bon fonctionnement de domoticz… à voir.
patrice
Messages : 1720
Inscription : 22 sept. 2014, 21:51

Re: Regul chauffage PID

Message par patrice »

Je n'ai qu'un mot : Magnifique !!
et clair de surcroit.
Raspberry pi 3, Dongle RfxCom et Zigate +, plugin de pipiche, Volets Roulants profalux, contrôle d'éclairage, détecteurs de présence, alarme incendie, pilotage livebox ...
Objectif : WAF > 1
vil1driver
Messages : 5661
Inscription : 30 janv. 2015, 11:07
Localisation : Rennes (35)

Re: Regul chauffage PID

Message par vil1driver »

Salut,

Pas mieux :-)

Ayant passé de très nombreuses heures sur un projet similaire je suis sensible au travail fournis et à ta réflection sur le sujet.

Bravo et un grand merci pour le partage.
MAJ = VIDER LE CACHE(<-Clicable)
/!\Les mises à jour de Domoticz sont souvent sources de difficultés, ne sautez pas dessus
modules.lua

Un ex domoticzien
mulot35
Messages : 200
Inscription : 20 déc. 2014, 00:27

Re: Regul chauffage PID

Message par mulot35 »

Je suis tous électrique pour l'instant mais c'est un vrai bonheur a lire.
Bravo.
Suis sur le cul.
Raspi B+ avec Domoticz ,6 Chacon 2300W , 6 Sondes Oregon, 1 Sonde DIY Oregon ds18b20, Téléinfo sur photovoltaique, script backup ftp & anti offline.
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Regul chauffage PID

Message par deennoo »

Chapeau !

Voici ce que je cherchais avant d'avoir la regulation de ma chaudiere et mon blackout radio.

Pour les sécuritées de fonctionnement :

Une sonde 1 wire sur le départ d'eau de chauffage, 1 autre sur le retour du chauffage, une limite basse et haute de temperature dans le temps pour activer ou non ton relais 2 de PI Face qui donne la main a ton vieux thermostat en position constante a 16°c.

Il existe un script qui vérifie l age des données reçu de sondes radio (une sorte de batterie check), cela peut aider, sinon te servir d'un service weather underground au moins pour la temperature extérieur.

L'idée de déporté la vérification :?: de fonctionnement du PI et de Domoticz sur un autre system me semble la meilleur, surtout que l'investissement d'un pi dédier a la régulation du chauffage n'atteindra pas le prix d'une régulation complete, l'intégration de ce PI de chauffage est facile dans domoticz.

Super boulot, tu as autant de precision que la regul de ma chaudiere ...
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
Guitoo
Messages : 4
Inscription : 20 févr. 2015, 08:46

Re: Regul chauffage PID

Message par Guitoo »

Merci pour vos compliments, j'ai posté surtout pour chalenger les scripts et pour partager avec ceux qui planchent sur un sujet similaire. J'ai chercher un moment avant de me lancer mais on trouve finalement peu de tuto précis. Beaucoup de théorie pas tellement de pratique. Et pour mon installation, la régul hystrésis était vraiment insuportable. Je crois que c'est du au déphasage important entre la commande et le retour capteur ( :idea: tiens il faudra que je mesure à l'occas)
deennoo a écrit : Pour les sécuritées de fonctionnement :

Une sonde 1 wire sur le départ d'eau de chauffage, 1 autre sur le retour du chauffage, une limite basse et haute de temperature dans le temps pour activer ou non ton relais 2 de PI Face qui donne la main a ton vieux thermostat en position constante a 16°c.

Il existe un script qui vérifie l age des données reçu de sondes radio (une sorte de batterie check), cela peut aider, sinon te servir d'un service weather underground au moins pour la temperature extérieur.
J'ai éffectivement pensé aux 1wire sur les tuyaux, ça me botte bien rien que pour monitorer la chaudière. Le prochain truc que j'implémente c'est un checktime de la dernière mesure avec des sénarios de remplacement.
PS: J'ai eu un "domoticz Offline" cette semaine avec un 14° au réveil... pas cool :( Encore du boulot pour verrouiller tout ça!
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Regul chauffage PID

Message par deennoo »

j'ai mis du 1 wire pour monitorer mon chauffage hydrolique, voici le type de graphique que cela donne avec une regul fabricant sur un bruleur modulant et une chaudiere a condensation :
courbe temp chauffage.PNG
courbe temp chauffage.PNG (136.6 Kio) Consulté 35163 fois
la temp exterieur est celle d'une sonde oregon placer juste a coter de celle de la chaudiere
les coubres de temp depart et retour chauffage sont des sondes 1wire ds18b20 fixer avec du scotch alu sur les tuyaux en cuivre au plus proche de la chaudiere
La coubre chambre oscar, est une sonde de temp oregon placer juste a coter du thermostat qui pilote la chaudiere, la temperature demandé le vendredi samedi dimanche est de 19°c en constant, le pic de baisse est du a l ouverture d'une fenetre pour aéré la chambre.

J'ai egalement cree un faux interrupteur appeller "fonctionnement chaudiere" qui s'allume et s'eteint grace a une regle blocky et fonction de la temperature limite basse du depart de la chaudiere
fonctionnement chaudiere.PNG
fonctionnement chaudiere.PNG (80.29 Kio) Consulté 35162 fois
A mon avis perso, un PI avec ton script dédier au chauffage, qui ne fait cela, sur une version stable, en mode esclave dans ta domotique, devrait t'apporter de la fiabilité.
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
BenjaminV
Messages : 21
Inscription : 24 févr. 2015, 22:08

Re: Regul chauffage PID

Message par BenjaminV »

Très intéressant effectivement ! Petites questions
-le fonctionnement de ta chaudière en tout ou rien suppose que tu ne possèdes pas de brûleur modulant ?
-pourquoi ne pas laisser la chaudière réaliser sa propre régulation au niveau de la température de ton collecteur ? As-tu eu de meilleurs résultats avec ta régul ? Selon moi la vraie plus value d'un PID se situe au niveau de chaque départs de ton collecteur pour avoir une régulation pièce par pièce.

Enfin attention aussi au choix de ton gain dérivatif Kd. Il faut savoir qu'un simple PI bien optimisé est souvent plus efficace qu'un PID. L'action dérivative est surtout intéressante pour des systèmes lents ou possédant un grand temps mort (ce qui est probablement le cas vu que tu régules visiblement à partir de ta chaudière et pas à partir de tes vannes) et permet d'arriver à la consigne plus rapidement.

Sur un système plus "rapide", pour la régulation d'une pièce sans trop d'inertie par exemple, il vaut mieux utiliser un PI car un PID destabiliserait d'avantage ton système. Si tu as trop de dépassement, c'est que ton gain proportionnel est probablement trop important. Les oscillations peuvent être quant à elle dues à un Ki trop élevé. Pour l'anectote, une vanne thermostatique est généralement un PI et pas un PID.

Je pense aussi que ton raisonnement sur le plantage du pi est excellent. Personnellement je n'aurais pas osé baser mon installation sur Domoticz. Un système basé sur 2 PI se pingant l'un l'autre afin de repérer d'éventuels plantages pourrait être une solution ?
atlantis007
Messages : 65
Inscription : 11 janv. 2015, 22:31
Localisation : biarritz (64)

Re: Regul chauffage PID

Message par atlantis007 »

bonjour

j ai un soucie j ai utilise tes scripts pour installation dont j ai modifier les variables pour mon installation et j ai cette erreur quand la chaudière doit se mettre en marche


2015-04-03 19:01:38.436 Error: ...e/pi/domoticz/scripts/lua/script_device_thermostatv3.lua:156: attempt to perform arithmetic on local 'CmdImax' (a nil value)

si on peut m aide merci :o
Guitoo
Messages : 4
Inscription : 20 févr. 2015, 08:46

Re: Regul chauffage PID

Message par Guitoo »

atlantis007 a écrit :
2015-04-03 19:01:38.436 Error: ...e/pi/domoticz/scripts/lua/script_device_thermostatv3.lua:156: attempt to perform arithmetic on local 'CmdImax' (a nil value)

si on peut m aide merci :o
Salut atlantis007,

As-tu créé une variable utilisateur CmdImax avec un entier dedans?
Répondre