[DzVents] Gestion de Chauffage TPI

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.
Soyez précis quant aux prérequis, les manips à faire pour que votre bijou fonctionne (des chmod ?, un apt-get à faire ...)
Décrivez précisément son fonctionnement.
Merci d'utiliser la balise correspondante à votre sujet : [Tuto], [Plugin], [DzVents], [LUA], [Python], [Bash] ...
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
Répondre
Neutrino
Messages : 2154
Enregistré le : 10 juil. 2015, 15:42
Localisation : Les Herbiers(85)

[DzVents] Gestion de Chauffage TPI

Message par Neutrino »

Bonjour à tous,

L'hiver vient !
Après avoir passer toute la saison dernière à essayer de stabiliser le script de Vil1driver, j'en suis venu à la conclusion que je n'aurais jamais de coefficients PID fixes.
Avec un poêle à bois, les apports extérieurs aux chauffages électriques sont impossibles à anticiper et corriger.

J'ai donc cherché un autre algorithme et je suis tombé sur celui d'Argonaute du forum HACF.
Il s'agit d'une approche TPI (Time Propostional & Integration).
Il explique à merveille son fonctionnement et j'ai donc décidé de l'adapter à Domoticz en m'inspirant du très bon travail de Vil1driver.

Pré-requis :
- Une sonde de température intérieure de la pièce à chauffer
- Une sonde de température extérieure (optionnelle) pour prendre en compte les pertes
- Un interrupteur virtuel de mise en route du chauffage
- Un thermostat virtuel pour régler la consigne.

Il faudra quand même régler 3 variables :
local coeffC = 0.60 -- coeff qui dépend de la puissance du chauffage et de la surface. A augmenter si la consigne n'est pas atteite.
local coeffT = 0.01 -- dépend lui de l’isolation de la pièce et des pertes thermiques. A augmenter si la consigne est difficile à atteindre par grand froid.
local bandeProportionnelle = 1.5 -- différence de température entre la lecture et la consigne où la chauffe est permanente. Peut être réduite si la consigne n'est pas dépassée après la montée en température. Permet une chauffe plus rapide.
Pour une installation standard aux normes, on a coeffC = 0,6 et coeffT = 0,01.

Vous pouvez également modifier la durée de cycle et la durée minimum entre 2 ordres.

TPIZone.lua

Code : Tout sélectionner

--[[
	Prerequisits
	==================================
	Domoticz v2020.2 or later (dzVents version 3.1 or later)

	Chauffage TPI
	Le principe vient d'Agonaute du forum HACF.
	https://forum.hacf.fr/t/gestion-de-bout-en-bout-du-chauffage/4897
	
-- Authors  ----------------------------------------------------------------
	V1.0 - Argonaute - Version Home Assistant
	V2.0 - Neutrino - Adaptaption pour Domoticz en DzVents
]]--


-- Variables to customize --------------------------------------------------

local zone = "Chambre"
local sonde = {'Temp Chambre'} -- Nom de la ou des sondes de température
local sonde_ext = {'Temp_ext','Temp Extérieure'} -- Nom de la ou des sondes de température ext si présente (option)
local OnOff = 'Chauffage' -- Nom de l'interrupteur virtuel de mise en route (été/hiver)
local thermostat = 'Thermostat Chambre' -- nom du thermostat virtuel

-- actionneur
local radiateur = 'Chauffage Chambre' -- Nom de l'interrupteur de chauffage

--Pour une installation standard aux normes, on a coeffC = 0,6 et coeffT = 0,01
local coeffC = 0.60 -- coeff qui dépend de la puissance du chauffage et de la surface.
local coeffT = 0.01 -- dépend lui de l’isolation de la pièce et des pertes thermiques.
local bandeProportionnelle = 1.5 -- différence de température entre la lecture et la consigne où la chauffe est permanente.

local cycle = 10 -- temps en minutes d'un cycle TPI
local secu = 30 -- temps minimum en secondes entre 2 ordres opposés
	
------------------------------------------------------------------------------
local scriptName = 'TPI'..zone
local scriptVersion = '2.0'

-- contraindre
local function constrain(x, a, b)
	if (x < a) then
		return a
	elseif (x > b) then
		return b
	else
		return x
	end
end

local function averageTemp(domoticz,t)
  local sum = 0
  local taille = 0
  for _,v in pairs(t) do -- Get the sum of all numbers in t
    if domoticz.devices(v).lastUpdate.minutesAgo < 60 
	and tonumber(domoticz.devices(v).temperature) ~= nil then
		sum = sum + domoticz.devices(v).temperature
		taille = taille + 1
	else
		domoticz.log(domoticz.devices(v).name .." "..domoticz.devices(v).temperature.." "..domoticz.devices(v).lastUpdate.minutesAgo,domoticz.LOG_INFO)
	end
  end
  return sum / taille
end

return {
	active = true,
	logging = {
		level = domoticz.LOG_DEBUG, -- Uncomment to override the dzVents global logging setting
		--level = domoticz.LOG_ERROR, -- Uncomment to override the dzVents global logging setting
		--level = domoticz.LOG_INFO, -- Uncomment to override the dzVents global logging setting
		marker = scriptName..' '..scriptVersion
	},
	on = {
		timer = {
			'every 1 minutes',  
		},
		devices ={thermostat,
		},
	},

	execute = function(domoticz, item)
		local heatTime
		-- récupération température
		local temp = domoticz.utils.round(averageTemp(domoticz,sonde),2)
		-- récupération température ext
		local temp_ext = nil
		if sonde_ext ~= '' and sonde_ext ~= nil then
			temp_ext = domoticz.utils.round(averageTemp(domoticz,sonde_ext),2)
		else
			temp_ext = domoticz.devices(thermostat).setPoint
		end
		
		-- à chaque cycle ou quand la consigne est modifiée
		if ( domoticz.time.minutes%cycle == 0 )or item.isDevice then						
			-- si l'on veut chauffer
			if ( domoticz.devices(OnOff).active ) then
				-- récupération de la consigne
				local consigne = domoticz.devices(thermostat).setPoint

				
				-- calcul de la commande en %
				local commande
				if consigne - temp >= bandeProportionnelle then
					commande = 100
				else
					commande = ((coeffC * (consigne - temp)) + (coeffT * (consigne - temp_ext)))*100
				end
				domoticz.log("Puissance de chauffe "..commande.."%", domoticz.LOG_DEBUG)
						
				-- calcul du temps de fonctionnement
				if commande >= 100 then
					-- débordement de 20s pour ne pas couper avant recalcule
					heatTime = (cycle*60)+20
				elseif commande > 0 and commande < 100 then
					-- secu mini maxi
					heatTime = domoticz.utils.round(constrain(commande*cycle*0.6,secu,(cycle*60)-secu))
				elseif commande <= 0 then
					-- coupure retardée
					heatTime = constrain(secu-domoticz.devices(radiateur).lastUpdate.secondsAgo,0,secu)
				end
				
				-- action sur l'élément chauffant
				if heatTime > 0 then
					domoticz.devices(radiateur).switchOn()
					domoticz.devices(radiateur).switchOff().afterSec(heatTime)
				else
					domoticz.devices(radiateur).switchOff()
				end			
			
				-- journalisation
			
				domoticz.log('TPI zone: '..string.upper(zone),domoticz.LOG_DEBUG)
				if temp_ext ~= nil then
					domoticz.log('temperature ext: '..temp_ext..'°C',domoticz.LOG_DEBUG)
				end
				domoticz.log('température int : '..temp..'°C pour '..consigne..'°C souhaité',domoticz.LOG_DEBUG)
				domoticz.log('Temps de chauffe : '..heatTime.."s",domoticz.LOG_DEBUG)
				domoticz.log('CoeffC : '..coeffC,domoticz.LOG_DEBUG)
				domoticz.log('CoeffT : '..coeffT,domoticz.LOG_DEBUG)
				domoticz.log('Cycle : '..cycle..'min (sécu: '..secu..'s)',domoticz.LOG_DEBUG)
				-- avertissement si secu dépasse 1/4 du cycle
				if ((100*secu)/(60*cycle)>25) then
					domoticz.log('sécu trop importante, ralonger durée de cycle..',domoticz.LOG_ERROR)
				end
			end
		end
		-- toutes les 5 minutes, si on ne veut pas chauffer
		if ( domoticz.time.minutes%5 == 0 and domoticz.devices(OnOff).state == 'Off' ) then

			-- arrêt chauffage (renvoi commande systematique par sécurité)
			domoticz.devices(radiateur).switchOff().afterSec(constrain(secu-domoticz.devices(radiateur).lastUpdate.secondsAgo,3,secu))
		end
	end
}
C'est pas forcément adapté à tout le monde, et il se peut qu'il faille jouer avec les coefficients et la durée de cycle.
Mais ça a le mérite de fonctionner chez moi ;)
Ma maison à plein d'IP ! :mrgreen:
SAV Bonjour. Vous avez vidé le cache ?

Aile
Messages : 142
Enregistré le : 27 janv. 2022, 12:18

Re: [DzVents] Gestion de Chauffage TPI

Message par Aile »

Bonjour Neutrino,

Je suis justement en train de faire des tests sur le script de Vil1driver sur deux émetteurs de chaleurs très différents : un radiateur à bain d'huile et un climatiseur air/air (split).
La mise au point des paramètres PID est effectivement assez longue, et je dois dire que je n'ai pas eu beaucoup de succès avec le mode "Compute".
J'ai rajouté ton algorithme au script PID et je teste en ce moment les deux méthodes sur le radiateur.
Si ça t'intéresse, je te tiendrai au courant de mes résultats.
NUC Celeron 1037U-SSD / Windows 10 Pro
  • EcoCompteur Legrand
  • RFLink Nodo / capteurs température Alecto / capteurs mouvement EV1527
  • Clef Sonoff Zigbee 3.0 / Sonoff SNZB-02 / Détecteurs fumée Heiman / Télécommande Heiman
  • Shelly 1

Neutrino
Messages : 2154
Enregistré le : 10 juil. 2015, 15:42
Localisation : Les Herbiers(85)

Re: [DzVents] Gestion de Chauffage TPI

Message par Neutrino »

C'est toujours bon d'avoir des retours ;)
Merci
Ma maison à plein d'IP ! :mrgreen:
SAV Bonjour. Vous avez vidé le cache ?

Aile
Messages : 142
Enregistré le : 27 janv. 2022, 12:18

Re: [DzVents] Gestion de Chauffage TPI

Message par Aile »

Les premiers tests sur le radiateur sont plutôt bluffants :
Capture.JPG
Capture.JPG (45.02 Kio) Vu 222 fois
Entre 17° et 16,9° constants pour une consigne de 17°. C'est bien plus régulier qu'avec la méthode PID, alors même que l'algorithme est simplissime...

NB :
  • La courbe verte "Humidité" correspond en fait au pourcentage de marche du radiateur
  • Mon radiateur est un bain d'huile 1000 watts piloté par un Shelly 1
  • La pièce fait 14 m², et elle est assez médiocrement isolée (4 cm polystyrène)
  • Mes coefficients sont bien supérieurs à tes préconisations : coeffC=3/coeffT=0.025/Cycle=5 mn
NUC Celeron 1037U-SSD / Windows 10 Pro
  • EcoCompteur Legrand
  • RFLink Nodo / capteurs température Alecto / capteurs mouvement EV1527
  • Clef Sonoff Zigbee 3.0 / Sonoff SNZB-02 / Détecteurs fumée Heiman / Télécommande Heiman
  • Shelly 1

Neutrino
Messages : 2154
Enregistré le : 10 juil. 2015, 15:42
Localisation : Les Herbiers(85)

Re: [DzVents] Gestion de Chauffage TPI

Message par Neutrino »

L'algorithme est simple mais très efficace de mon côté aussi.
Je n'ai plus les oscillations que j'avais avec le PID.
Pour moi, le fonctionnement est validé. :)
Ma maison à plein d'IP ! :mrgreen:
SAV Bonjour. Vous avez vidé le cache ?

Mamethis
Messages : 6
Enregistré le : 25 avr. 2017, 13:29

Re: [DzVents] Gestion de Chauffage TPI

Message par Mamethis »

Bonjour tous,

Même si j'utilise avec de bons résultats le script PID de Vil1driver depuis plusieurs années, ma curiosité est piquée par ce script ! :)
Cependant, je n'ai pas trouvé comment jouer sur les coefficients.
Y'a-t-il des pas d'incrémentation à respecter et doit-on faire des variations par tâtonnement ?

Merci beaucoup en tout cas @Neutrino pour ce script !

Aile
Messages : 142
Enregistré le : 27 janv. 2022, 12:18

Re: [DzVents] Gestion de Chauffage TPI

Message par Aile »

Bonjour Mamethis,

Je suis vraiment étonné de l'efficacité de cette méthode, parce qu'en définitive, ce n'est qu'une régulation de type proportionnel en fonction des températures intérieures et extérieures.
Il n'y a aucun mécanisme d'anticipation comme pour le PID.

En ce qui me concerne, j'ai fait les ajustements des coefficients de manière empirique, mais c'est allé beaucoup plus vite qu'avec la méthode PID...
En réduisant le cycle à 20 minutes (pour préserver le relais), j'ai un hystérésis de ±0,2°, mais avec 10 minutes, c'est 0,1°.

Je suis en train de tester le fonctionnement avec un climatiseur de type "Split" en mode chaud. C'est plus compliqué parce que je ne lui envoie que des ordres du type "consigne à 20°", "consigne à 24°", etc. et non on/off.
Sa régulation interne vient donc contrarier les calculs.

Pour mieux comparer les deux méthodes, j'ai fait un nouveau script trèèèès largement inspiré de celui de Vil1driver, mais avec les deux options PID ou TPI, et la possibilité de piloter une PAC en mode été et hiver.
Le mode été n'a pas encore été testé, vu la saison, mais si un australien nous lit, il est le bienvenu pour les essais :mrgreen:...
NUC Celeron 1037U-SSD / Windows 10 Pro
  • EcoCompteur Legrand
  • RFLink Nodo / capteurs température Alecto / capteurs mouvement EV1527
  • Clef Sonoff Zigbee 3.0 / Sonoff SNZB-02 / Détecteurs fumée Heiman / Télécommande Heiman
  • Shelly 1

Répondre