Plugin régulateur correcteur *PID* (proportionnel, intégral, dérivé)

Ce serait trop beau ! Dans le virtuel, on a le choix d’importer le template Lumière ou Interrupteur.
Il faudrait que je réussisse à créer le template de mon Virtuel…

J’ai essayé l’import d’un autre équipement Virtuel
image

Oui c’était un mauvais avis de ma part :wink:

Correction du code pour résoudre les soucis de calculs non effectués lorsque les nombres sont écrits sous la forme scientifique (avec un exposant).

Mise à jour du code

@afawaz et @raqpub Comment ça régule chez vous ?

@Domatizer, partant de ce que tu as fait et trouvant que les scenarios c’est vraiment lourd pour écrire du code, j’ai écrit ton scenario avec du php ! et j’ai ajoute le support « multiroom » :wink:
c’est tout récent mais vu que tu as pose la question j’en suis la !
Je viens tout juste d’acquérir une station meteo netatmo avec 3 modules intérieurs !
la régulation est en cours de test, dans les chambres ca marche plutôt bien.
Je déposerai des courbes d’ici une semaine.
Mon scenario marche avec le même principe que ton régulateur virtuel. J’ai juste simplifié et garder le PI.
voici le code:

########################
#  Regulator PI
########################

$regulatorList = array(
	#        Room            Virtual Th        equipement
	array("Chambre Adam"   , "Regulateur Adam"   , "Thermostat Adam"   )
,	array("Chambre Eva"    , "Regulateur Eva"    , "Thermostat Eva"    )
,	array("Chambre Parent" , "Regulateur Parent" , "Thermostat Parent" )
);

function debug($message) {
  	global $scenario;
  	$scenario->setLog($message);
}

class Inputs {
	public $kp, $ki, $mesure, $consigne, $position;
}

class State {
	public $ki, $erreur, $erreurIntegration, $erreurSaturation, $vanne;
}

class Pi {
	private $piece, $regulateur, $thermostat;
	private $te=5/60;

	public function __construct($piece, $regulateur, $thermostat) {
		$this->piece      = $piece;
		$this->regulateur = $regulateur;
		$this->thermostat = $thermostat;
		$this->inputs     = new Inputs();
		$this->preState   = new State();
		$this->curState   = new State();
      	debug("start declaring classes");
	}
	public function getVar($var) {
		global $scenario;
		$v="PID" . str_replace("Chambre ","",$this->piece) . "_" . $var;
		$ret = $scenario->getData($v);
		$ret = $ret == "" ? 0 : $ret;
		debug("get $v = $ret");
		return $ret;
	}

	public function setVar($var, $val) {
		global $scenario;
		$v="PID" . str_replace("Chambre ","",$this->piece) . "_" . $var;
		debug("set $v = $val");
		$ret = $scenario->setData($v, $val);
	}

	function pidInfo($var) {
      	$ret = cmd::byString("#[$this->piece][$this->regulateur][$var]#")->execCmd();
      	debug("get info $var=$ret");
		return $ret;
	}

	function readInputs() {
		$in=$this->inputs;
		$in->kp       = $this->pidInfo("Kp");
		$in->ki       = $this->pidInfo("Ki");
		$in->mesure   = $this->pidInfo("T Mesuree");
		$in->position = $this->pidInfo("Position");
		$in->consigne = $this->pidInfo("T Consigne");
	}

	function restore() {
		$pre=$this->preState;
		$pre->ki                = $this->getVar ("Ki");
		$pre->erreur            = $this->getVar ("Erreur");
		$pre->erreurIntegration = $this->getVar ("ErreurIntegration");
		$pre->erreurSaturation  = $this->getVar ("ErreurSaturation");
		$pre->vanne             = $this->getVar ("Vanne");
	}

  
	function compute() {
		$in  = $this->inputs;
		$pre = $this->preState;
		$cur = $this->curState;

		$ti  = $in->kp/$in->ki;
		$ts  = $ti;

      	$cur->ki                   = $in->ki;
		$cur->erreur               = $in->consigne - $in->mesure;
		$erreurIntegrationCorrigee = $pre->ki * $pre->erreurIntegration/$in->ki;
		$cur->erreurIntegration    = $erreurIntegrationCorrigee + $this->te * ($cur->erreur + $pre->erreur)/2;

		$termeP = $in->kp * $cur->erreur;
		$termeI = $in->ki * $cur->erreurIntegration;

		$vanneIdeale = $termeP + $termeI;
		$cur->vanne = ( $vanneIdeale < 0 ) ? 0 : ( ($vanneIdeale > 99) ? 99 : $vanneIdeale );

		debug("termeP=$termeP, termeI=$termeI, vanne=$cur->vanne");

		$cur->erreurSaturation  = ($vanneIdeale - $cur->vanne)/$in->kp;
		$cur->erreurIntegration = (
			$cur->erreurIntegration
		-	$ti/$ts * $this->te*($cur->erreurSaturation+$pre->erreurSaturation)/2
		);

		debug("erreur=$cur->erreur, preErrInt= $pre->erreurIntegration,  erreurIntegration=$cur->erreurIntegration");
	}

  	function save() {
		$cur = $this->curState;
      	$in  = $this->inputs;
		
		$roundedVanne = floor($cur->vanne);

		$this->setVar ("Ki"               , floor($cur->ki                * 1000000)/1000000);
		$this->setVar ("Erreur"           , floor($cur->erreur            * 1000000)/1000000);
		$this->setVar ("ErreurIntegration", floor($cur->erreurIntegration * 1000000)/1000000);
		$this->setVar ("ErreurSaturation" , floor($cur->erreurSaturation  * 1000000)/1000000);
		$this->setVar ("Vanne"            , $roundedVanne);

		$this->ouvertureVanne = min(99, max($roundedVanne,0) );

		debug("position=$in->position, ouvertureVanne=$this->ouvertureVanne");
	}

	function setNewPosition() {
		if ($this->inputs->position != $this->ouvertureVanne) {
			$options['slider']=$this->ouvertureVanne;
			cmd::byString("#[$this->piece][$this->thermostat][Position valve]#")->execCmd($options);
			cmd::byString("#[$this->piece][$this->regulateur][Position Consigne]#")->execCmd($options);
		}
	}

  	public function go() {
      	$this->readInputs();
      	$this->restore();
      	$this->compute();
		$this->save();
		$this->setNewPosition();
    }
}

foreach ($regulatorList as $i => $regSettings) {
  	$piece      = $regSettings[0];
  	$regulateur = $regSettings[1];
	$thermostat = $regSettings[2];
  	$scenario->setLog("~~~~~~~~~~~~~~~~~ $piece, $regulateur, $thermostat ~~~~~~~~~~~~~~~~~~~~~");
    $t=new Pi($piece, $regulateur, $thermostat);
	$t->go();
}

Pas bcp de commentaire désolé, c’est tout frais, mais mon objectif est de créer un plugins si j’y arrive et puis je suis pas trop spécialise ni php ni jeedom :slight_smile: !

voici mon plugin virtuel : ( il reprend exactement celui de @Domatizer ) a l’exception des modes que j’ai ajouté il me semble.

et ca donne ca:

bon je partagerai tout ca proprement une fois termine c’est pour vous donner un aperçu !

Les netatmos ont l’air d’être réactifs avec 0.3 degre de precision, j’ai une mesure toutes les 10 minutes avec un cron de 5 minutes. ( l’upload se fait toutes les 10 minutes au serveur netatmo )

A+

2 « J'aime »

Qlq courbes ! la temperature ne baisse pas bcp la nuit …
Donc pour l’instant je ne peux pas trops conclure ! …je ne sais pas quoi en penser.
Dans l’attente que le froid revienne ! :slight_smile:

piece 10m2

piece 12m2: avec ouverture de la fenetre vers 10h

piece 20m2:

@afawaz t’as bien travaillé pour tes scénarios, bon boulot !

Je trouve plus intéressant de regarder la courbe de l’ouverture des vannes (ça me permet de voir si la régulation tourne bien). Elles doivent s’ouvrir/fermer fortement lors du changement de consigne. Et lorsque la température de consigne est atteinte, elle doivent se stabiliser autour d’un certain pourcentage.

Autre point, si la température de l’eau qui circule dans les radiateurs est modulée par chaudière en fonction de la température extérieure, alors la puissance de chauffe vise déjà une valeur minimale pour économiser de l’énergie. Donc, les remontées en température après un abaissement seront plus long. (C’est un peu comme vouloir doubler un véhicule qui roule à 128 km/h en gardant son régulateur à 130km/h, ça prend du temps). Je ne fais pas d’abaissement pour 2h de temps. Minimum une demi-journée.

Exemple, dans mon séjour, les radiateurs sont sous dimensionnés, il me faut en moyenne au moins 7h (de 5h du mat’ à midi) de chauffe pour atteindre la consigne. Lorsqu’il fait bien froid, je n’arrive même pas a atteindre la consigne le soir à 20h.

En semaine, c’était presque du 100% ouvert toute la journée et la température de consigne n’était pas atteinte le soir. Pendant les 2 jours du WE, on a regardé des films en journée avec le vidéoprojecteur. C’est lui qui a chauffé la pièce et la consigne a été dépassée. Résultat, la vanne était à 0% avant la fin de journée. Il faudrait que j’augmente encore un peu la pente de courbe pour gagner du temps mais ça consommera plus et ce n’est pas nécessaire pour les radiateurs à l’étage qui seront davantage fermés.

Euh… tu chauffes à combien chez toi?
Pour maintenir une température mes vannes s’ouvrent entre 5% et 20% pendant 15min à 20min généralement puis se referme à 0% pendant 30min à 60min (ca dépend des pièces et de la température mais c’est juste pour l’ordre de grandeur); et la température de l’eau est modulée par la PAC (sonde externer etc)
du coup ca m’étonne que tu doives chauffer à 100% pendant une journée complète…
Ou alors les radiateurs sont très largement sous-dimensionnés effectivement et p-e un manque d’isolation quelque part?

20°C dans le séjour. Pour remonter au dessus de 19°C, c’est galère quand il fait froid dehors.
Alors que dans le bureau à l’étage, en 2h c’est OK.
La température de l’eau est la même pour tous les radiateurs.

Le logement à 30 ans. L’isolation n’est pas forcément extra. Lorsqu’il fait froid, la température baisse assez vite. J’avais fait des calculs. Je perds environ les 2/3 de la différence de température intérieure-extérieure en 15h (la fameuse constante de temps). Exemple :

  • Lorsqu’il fait 20°C à l’intérieur et 10°C à l’extérieur de façon constante, si je coupe le chauffage, il fera 14°C à l’intérieur 15h plus tard. (courbe en bleu)
  • Lorsqu’il fait 20°C à l’intérieur et 0°C à l’extérieur de façon constante, si je coupe le chauffage, il fera 8°C à l’intérieur 15h plus tard. (courbe en orange)

image
Si on fait un zoom les premières heures, ça descend très rapidement au début.
image

Je coupe le chauffage à 22h (consigne Eco), il se remet en route 2 à 3 heures plus tard lorsqu’il fait bien froid dehors. À l’inverse, s’il fait très doux dehors, le chauffage ne se rallume qu’à 5h du mat’ lorsque les consignes repassent en mode Confort.

Ces courbes font mal, mais c’est la réalité ! L’amélioration de l’isolation est prévue…

Pour MAINTENIR la pièce à température, oui, c’est ce qui se passe.
Pour remonter la température de 3°C, c’est autre chose, c’est bien plus long.

Non, pas vraiment si la loi d’eau est réglée au plus juste, c’est-à-dire si la chaudière chauffe au minimum pour maintenir le logement à température.

Bonjour
J’aimerais bien comprendre ce mode de fonctionnement, il y a des choses qui m’échappent.
Vous agissez bien sûr %d’ouverture des vannes ?
Si part d’un exemple concret
Température et consige à 16.
La consigne passe à 18
Comment ça se déroule ?

Oui, en % toutes les X minutes (5 minutes, c’est un bon compromis)

Dans ce cas, il n’y a pas d’erreur consigne-mesure. La composante proportionnelle est nulle.
Si c’était un régulateur Proportionnel uniquement, la vanne serait fermée et ça ne chaufferait pas, voir les explications ici

C’est pour ça qu’il y a un terme constant (lorsqu’il n’y a pas d’intégrateur dans le régulateur) de façon à ce que la vannes soit ouverte un minimum (à 30% ou 50% par exemple) pour que ça chauffe un minimum lorsque la pièce est à température (pas d’erreur consigne-mesure).

Dans le cas d’un régulateur PI (Proportionnel et Intégrateur), l’intégrateur va cumuler l’erreur consigne-mesure au cours du temps. Il vaudra une certaine valeur (qui remplacera le terme constant) lorsque le terme proportionnel est nul.

Lorsque la pièce est à température, l’erreur proportionnelle est nulle et le pourcentage d’ouverture vaut directement Ki multiplié par l’erreur cumulée.

Exemple, avec un Ki=10%/(°C.h) et une erreur consigne-mesure cumulée de 3°C.h, la vanne restera ouverte à 30%. Si c’est la bonne valeur d’ouverture pour maintenir la pièce à température, alors la l’erreur proportionnelle est toujours nulle et le cumul de l’erreur reste constant (puisque l’erreur à ajouter est nulle). Si la bonne valeur est 35%, alors la pièce se refroidira, il y aura de nouveau une erreur à ajouter. Ainsi, l’erreur cumulée augmentera jusqu’à atteindre 3.5°C.h pour donner finalement une ouverture de 10%/(°C.h) x 3.5°C.h = 35%. Quelque soit la valeur de Ki, l’erreur cumulé va augmenter ou diminuer jusqu’à ce que la vanne obtienne la bonne valeur d’ouverture. Un régulateur avec juste un intégrateur pourrait suffire dans le cas d’une consigne constante, sinon le système serait trop lent après un changement de consigne.

Supposons que la pièce soit maintenue à une température de 16°C avec une vanne ouverte à 30%. L’erreur consigne-mesure est nulle.

D’un coup, on augmente la consigne de 2°C. L’erreur consigne-mesure augmente de 2°C. Comme elle était nulle, elle vaut maintenant 2°C.
Avec un coefficient proportionnel Kp=25%/°C, la correction proportionnelle appliquée sur la vanne sera de 25%/°C x 2°C = 50%. Ainsi, l’ouverture de vanne passe de 30% à 80%. Si la vanne était à 35%, elle serait passée à 85%.

Je voulais que ça s’ouvre un peu plus rapidement le matin, alors j’ai augmenté le Kp à 50%/°C. Comme je perds souvent plus de 2°C dans la nuit, la vanne s’ouvre à fond à 5h30 du mat’ lorsque la consigne passe de 17.5°C à 20.5°C


Dans le bureau de 8m², le radiateur chauffe vite.

Un peu comme notre pied sur la pédale d’accélération, mais en automatique sur la vanne comme le régulateur de vitesse. :slightly_smiling_face:

Merci @Domatizer pour ces explications et bravo pour ce travail.

Ce qui me « chagrine » c’est que pour moi en début de chauffe, on devrait toujours être à 100% en particulier lorsque le deltaTC est important. le calcul ne s’appliquerait que en fin de chauf ou (deltaTC par exemple 0.3).
en fin je m’interroge surtout sur d’éventuelles conséquences pour la chaudière et la conso;

  • des vannes ouvertes à 50% c’est une chaudière qui va tourner plus longtemps

  • des cycles flamme plus court, toutes les chaudières ne savent pas moduler et lorsque c’est possible la plage de modulations est limité. risque de déperditions sur le réseau départ/retour (dans mon cas ça passe par les combles)

  • si on utilise déjà un thermostat intelligent, ce genre de manœuvres risque de perturber l’apprentissage du thermostat (superposition de deux PID

Attention je ne suis ni thermicien ni chauffagiste, se sont des interrogations et suppositions

1 « J'aime »

Ton raisonnement est le bon.

Bon retour …

1 « J'aime »

Oui, en début de chauffe, c’est principalement le coef proportionnel Kp qui fixe l’ouverture en fonction de l’écart consigne-mesure. En fin de chauffe, la pièce est à température, il n’y a plus d’erreur, l’ouverture doit correspondre juste à ce qu’il faut pour maintenir la pièce est à température.

En pratique, pour des raisons de stabilité (éviter des oscillations importantes), le constructeur de vanne ne peut pas se permettre de mettre un trop grand Kp. J’avais observé sur les têtes Spirit qu’un changement de consigne de 2.5°C entraînent un mouvement de 50% de la vanne, soit un Kp=20%/°C. Elle s’ouvrira de +100% si la température mesurée est inférieure de 5°C par rapport à la consigne.

Ou elle devrait chauffer l’eau un peu plus chaude.

En fait, pour consommer moins, la vanne devrait être ouverte à 100% et la chaudière devrait chauffer au minimum selon la loi d’eau de façon à maintenir le logement tout juste à température. Il y a quelques décennies, il n’y avait pas de thermostatique !

Ensuite, lorsqu’il y a des apports gratuits tel que le soleil ou la présence de personnes (1 personne, c’est 100W de chauffe :smiley:), les thermostatiques viennent agir sur le radiateur comme des limiteurs.

Lorsque la modulation est possible, la chaudière est capable de chauffer de l’eau proportionnellement à l’écart de température intérieure - extérieure. C’est ce qu’il y a de mieux.

Le PID de la vanne thermostatique vit tranquillement sa vie. Sans modulation avec la loi d’eau, c’est juste dommage d’envoyer de l’eau par intermittence à 75°C dans les radiateurs si par la suite, la tête thermostatique doit quasiment fermer la vanne pour ne pas avoir trop chaud dans la pièce.

Donc, non, ce n’est pas le PID des vannes qui pose problème pour le TA connecté. D’ailleurs le thermostat est normalement installé dans la pièce où il n’y a pas de têtes thermostatiques. C’est plutôt la modulation de la chaudière qui peut poser souci. Mais, c’est un autre sujet.

@limad44 il me semble que tu utilises le thermostat Migo. Ce thermostat constructeur doit bien gérer l’apprentissage en plus de la modulation native de la chaudière car il a accès à tous les paramètres de la chaudière.

Sinon pour les autres thermostats « non propriétaires », oui, c’est possible d’avoir un problème d’apprentissage car ils modulent la puissance selon le rapport cyclique, il est supposé que la puissance de la chaudière soit constante à fond. En effet, si la puissance de chauffe varie à la source et n’est pas connue par le thermostat, je pense qu’il vaut mieux éviter d’utiliser les fonctions automatiques où le thermostat anticipe l’heure de mise en route pour que la température voulue soit obtenue à l’heure souhaitée, etc…

Bref, on a vite fait de se mélanger les pinceaux parmi tous ces PID !

Pour revenir au point de départ, le PID que j’ai présenté sur cette page module l’ouverture de vanne entre 0 et 100% sans faire de tout-ou-rien.

Pareil, j’ai juste énormément lu sur le sujet et relu certains cours de Sciences Industrielles.

Ah, j’écris toujours trop de lignes pour répondre. Le problème, c’est la passion !

@Domatizer
Voici qlq courbes de température avec l’ouverture et la consigne
(pour l’affichage l’ouverture est divisée par 5 avec un offset de 20)
Piece 10m2

Piece 12m2

Piece 20m2

tripple piece entre ouverte !
93m2 ( 4 radiateurs ) ( je n’atteint jamais les 23 degrés quand il fait froid ! )


voila voila

Super @afawaz

T’as mis quoi comme coefficients Kp, Ki, Ti finalement ?
Tu exécutes le scénario tous les combien de minutes ?

Juste une remarque dans l’interprétation des courbes :
Tu as souvent un pic d’ouverture de vanne avant chaque changement de consigne Eco → Confort
image
La chaudière semble être coupée la nuit. En fin de nuit (je ne vois pas bien les horaires), les vannes commencent à s’ouvrir pour vouloir chauffer, mais il n’y a pas d’eau (assez) chaude dans les radiateurs, la température ne monte pas alors les vannes continuent de s’ouvrir. (Ce comportement est normal, le régulateur fait son boulot comme s’il y avait toujours de l’eau chaude qui circule dans les radiateurs). Puis la chaudière se met en route et il y a le changement de consigne un peu même temps. Comme les vannes sont bien ouvertes, l’arrivée de l’eau bien chaude fait chauffer le radiateur très rapidement. Par conséquent, elles se referment rapidement pour se re-ouvrir normalement un peu plus tard. Pour limiter ce pic, il faudrait que ta chaudière démarre un peu plus tôt et/ou diminuer le Kp pour les petites pièces.

Est-ce que mon raisonnement te parait correct ? Elle tourne comment ta chaudière la nuit ?

Je te rassure, j’ai le même comportement car je coupe complètement la chaudière la nuit.
image
À 2h50, la température passe en dessous de la consigne Eco de 17.5°C, la chaudière se rallume et tourne en Éco. Pas besoin d’ouvrir beaucoup la vanne pour conserver les 17.5°C. Puis changement de consigne à 20.5°C à 5h30.


Bonjour
en orange c’est l’ouverture de vanne ?

Alors Alors,
Kp=50, Ki=~12 (Période d’intégration 240mn), période du scenario
n 5mn.
Mon programme 23h00 → 6h30 en Eco (18 degré) et 23 en confort.
Je suis en chauffage collectif, donc la chaudière marche en permanence je pense.
Mais j’avoue ne pas comprendre son fonctionnement, parce que parfois, a 100% d’ouverture, je sens que les radiateurs sont tièdes et parfois très chaud !
Du coup le pic avant le changement de consigne est très curieux, je ne l’explique pas, surtout que la température descend rarement sous la consigne la nuit.

J’ai remarqué récemment que la date de la machine virtuelle avait 1h de décalage. Mauvais fuseau horaire que j’ai corrigé. Les courbes du coup peuvent être décaler.
Je n’explique pas du tout ce pique autrement, je vais regarder ca de près.

Dans ton cas c’est logique vu que la température descend sous la consigne. Du coup ton explication est logique dans ton cas.

Je pense de toute façon comme tu le suggères diminuer kp dans les petites pièces pour éviter les oscillations.

Merci pour ton retour.

en orange c’est l’ouverture de vanne ?

Yes … a une heure près peut être ( le premier pique est curieux … )

Sur cette histoire de décalage en fait c’est jeedom qui décale les courbes !
la courbe d’ouverture réelle (« Ouverture ») n’est pas décalé !
Ouverture/5+20 l’est ! je ne sais pas pourquoi ! bug ?