Plugin thermostat et gestion PAC air / air

Bonjour,
Ayant fait l’acquisition d’une clim réversible Toshiba il y a qlq semaines, j’ai rapidement vu la mauvaise régulation des splits, avec 2 voire 3 degrés degrés d’écart entre la demande et le réel.
Pour essayer de corriger cela, j’ai d’abord acheté un capteur de température + télécommande IR Smart Life, mais cela ne répondait pas à mon problème (beaucoup trop limité).
Puis je me suis tourné vers Jeedom. J’ai mis cela sur une Raspberry, la connexion SSH/SSL, et tout le reste ! Je ne pensais pas y arriver, mais ca fonctionne !! Je dois dire que je suis assez impressionné par le système et ses capacités.
En plus de cela, j’ai de la chance : j’ai une chaudière Saunier Duval avec thermostat connecté Migo qui dispose d’un plugin Jeedom et pareil pour la clim réversible Toshiba.
Du coup, le thermostat de la chaudière me sert de sonde d’ambiance (résolution de 0,1°C), et je pilote le split (pour l’instant salon seulement). J’ai regardé un peu la solution de [nico73], mais ca ne fonctionnait pas chez moi, la sonde du split est trop « aléatoire »…
Du coup, sur la même idée, j’ai fait un scénario qui tourne toutes les 10min, et qui fait office de régulateur PID. Je vous mets la séquence ici.

Le scénario tourne toutes les 10min, car ma sonde Migo est mise à jour toutes les 10min seulement. Donc on ne peut pas faire mieux…
Voici les étapes :

  • Attendre qlq secondes (car la mise à jour de la sonde intervient après qlq secondes passé les 10min (d’après les logs), donc histoire de coller au plus près à la mesure), sauf si il y a un saut de consigne,
  • Enregistrement de la consigne actuelle, pour savoir si il y a un saut au prochain cycle,
  • Calculer l’erreur,
  • Calculer la commande proportionnelle (gain en vert)
  • Calculer la commande intégrale (gain en rouge)
  • Arrondir l’intégral à qlq décimales (j’ai lu sur d’autres post que les décimales pouvaient générer des erreurs, mais il ne me semble pas que ce soit le cas ici…)
  • Saturation de l’intégrale en + et - (en orange), sinon on aura des dépassements très importants, le temps que l’intégrale « se vide »…
  • Calcul de la commande dérivée (gain en bleu)
  • Enregistrement de l’erreur sur le cycle en cours (pour le calcul de la dérivé du cycle suivant)
  • Calcul de la correction totale
  • Saturation de la correction totale (pas forcement nécessaire)
  • Calcul de la commande de clim, qui vaut : consigne de température + correction, avec arrondi à l’entier pour pouvoir envoyer un ordre acceptable par la clim (tous les 1°C pour moi, peut être que d’autres marques font mieux).
  • Saturation des consignes pour la clim
  • Enfin, ma clim gère les températures faibles via le mode « hors-gel », donc je fais cela si on est en dessous de 16.5°C.
    Certaines formules commencent par « 1*… » car j’ai l’impression que si je ne le mettais pas, c’était parfois interprété en chaine de caractère (vu dans le suivi des variables).
    Et du coup, ca fonctionne plutôt bien chez moi, je vous mets quelques vues.

Voila, j’ai trouvé un jeu de paramètre (Ki, Kp, Kd) qui fonctionne plutôt bien, même si il y a qlq dépassements. On peut faire mieux en saturant encore plus bas l’intégrale, mais du coup, le système sera moins performant si l’erreur « naturelle » de la clim est élevée (il est sensé accepter ~3°C d’écart avec ces paramètres).
Donc je trouve cela satisfaisant, pour un système piloté par pas de 1°C toutes les 10min…
Je laisse donc les curieux essayer, et me faire un retour si vous trouver un jeu de paramètre qui fonctionne mieux, ou toute autre amélioration.

J’ai 2 autres splits à réguler : un bureau et l’espace chambres (couloir). J’attends 2 sondes DS18B20 (commandées) que je vais mettre sur la Raspberry pour faire le pilotage. J’espère que ca fonctionnera bien aussi.

3 « J'aime »

Salut,

Merci pour ton partage :smiley:

Cela fait un bon moment que j’avais fais un scénario pour ajuster la température de mon salon en fonction de la différence entre la consigne et la température réelle. Je procédais par augmentation de la consigne de la PAC puis relançait le scénario au bout d’un certain temps dépendant de la différence de température. Je n’ajustais jamais pour descendre la consigne de la PAC en revanche et je la laissais gérer. J’ai quand même l’impression que c’est mieux pour le compresseur … mais bon j’ai voulu tout de même essayer pour voir ce que ça donnait.

Je me suis un peu cassé les yeux sur la capture :nerd_face: mais ça tourne :wink:

J’en ai profité pour passer la presque intégralité dans un bloc code histoire :

  • de ne pas avoir des variables qui trainent pour rien et qui sollicite la base de données à chaque fois car il n’y a réellement que 2 variables nécessaires (ou 3 par rapport à ton wait que je n’ai pas repris chez moi)
  • permettre une mise en place plus facile si d’autres veulent essayer

Du coup ça donne ça coté scénario :

Déclencheur sur changement de la consigne et sur variation de la température relevé par le capteur :

Le code :

$Consigne_Salon = cmd::byString('#[Maison][Gestion des PAC][ConsigneConfortSalon]#')->execCmd();
$Temperature_Salon = cmd::byString('#[Salon][Sensor Salon (MQTT)][Température]#')->execCmd();
$borne_min_integr = -2.6;
$borne_max_integr = 2.6;
$borne_min_total = -5;
$borne_max_total = 5;
$borne_min_pac = 15;
$borne_max_pac = 24;

 $scenario->setLog('|----------------------------------------------------------');
 $scenario->setLog('|  Consigne Salon : ' . $Consigne_Salon . ' °C / ' . 'Temperature Salon : ' . $Temperature_Salon . ' °C');
 $scenario->setLog('|----------------------------------------------------------');

$Correct_integr = $scenario->getData('Correct_integr',0);
 $scenario->setLog('| .Correct_integr (valeur précédente) : ' . $Correct_integr);
$Correct_erreur_previous = $scenario->getData('Correct_erreur_previous',0);
 $scenario->setLog('| .Correct_erreur_previous (valeur précédente) : ' . $Correct_erreur_previous);

$Correct_erreur = $Consigne_Salon - $Temperature_Salon;
 $scenario->setLog('| .Correct_erreur : ' . $Correct_erreur . ' -> mémorisation de la valeur');

$Correct_prop = 2 * $Correct_erreur;
 $scenario->setLog('| .Correct_prop : ' . $Correct_prop);

$Correct_integr = $Correct_integr + $Correct_erreur;
$Correct_integr = round($Correct_integr * 1000) / 1000;
 $scenario->setLog('| .Correct_integr : ' . $Correct_integr);
$Correct_integr = max(min($Correct_integr, $borne_max_integr), $borne_min_integr);
 $scenario->setLog('| .Correct_integr borné ['.$borne_min_integr.' / '.$borne_max_integr.'] : ' . $Correct_integr . ' -> mémorisation de la valeur');

$Correct_deriv = 1.5 * ($Correct_erreur - $Correct_erreur_previous);
 $scenario->setLog('| .Correct_deriv : ' . $Correct_deriv);

$Correct_total = $Correct_prop + $Correct_integr + $Correct_deriv;
 $scenario->setLog('| .Correct_total : ' . $Correct_total);
$Correct_total = max(min($Correct_total, $borne_max_total), $borne_min_total);
 $scenario->setLog('| .Correct_total borné ['.$borne_min_total.' / '.$borne_max_total.'] : ' . $Correct_total);

$Temp_consign_clim = round($Consigne_Salon + $Correct_total);
 $scenario->setLog('| .Temp_consign_clim : ' . $Temp_consign_clim);
$Temp_consign_clim = max(min($Temp_consign_clim, $borne_max_pac), $borne_min_pac);
 $scenario->setLog('| .Temp_consign_clim borné ['.$borne_min_pac.' / '.$borne_max_pac.'] : ' . $Temp_consign_clim);
 $scenario->setLog('|----------------------------------------------------------');

$scenario->setData('Correct_integr', $Correct_integr);
$scenario->setData('Correct_erreur_previous', $Correct_erreur);

$tags['#set_consign_clim#'] = $Temp_consign_clim;
$scenario->setTags($tags);

J’en ai profité pour modifier le comportement de mon module relevant la température pour qu’il :

  • Transmette toutes les 5mn
  • Transmette si changement de 0,1°C
  • Modifié le paramètre de répétition des valeurs à Oui

Et au final, bien sûr ça donne une température bien plus constante dans la pièce :grinning:

Voilà le graphique pour comparer. Nous n’avons pas changé la consigne mais comme je ne l’avais pas historisée avant, je n’avais pas la courbe rouge avant les modifications.

Variation autour du 0 :

Note : j’ai 2 capteurs positionnés à 2 endroits différents et l’ajustement est réalisé sur celui qui est en bleu.

1 « J'aime »

Merci pour le partage. :pray:
J’avais idée aussi de tester en mode code.
Mais j’ai pas eu le temps de tester.

Salut,
Je ne maitrise pas le code, donc je l’ai fait à ma manière… :sweat_smile:
Pour le nombre de variables, je ne sais pas ce que cela implique en terme de ressources. Je n’ai que cela qui tourne sur ma RPI, donc ca doit passer. :thinking:
Pour ta solution qui a l’air de bien fonctionner, qlq questions et remarques :

  • les termes intégrale et dérivé ont une dimension temporelle, vu qu’ils sont calculés par rapport à l’état antérieur. Donc si tu fais cela toutes les 5min (au lieu de 10min chez moi) tu dois diviser les termes Ki et Kd par 2 environ (à ajuster).
  • Si en plus des 5 minutes, tu déclenches le calcul à chaque changement de mesures, il faut (idéalement) le prendre en compte dans les calculs. Donc pour être le plus propre possible, il faudrait enregistrer le temps écoulé entre 2 calculs, et le prendre en compte. Bref, je suggère de rester sur un pas de temps fixe (5 ou 10min), et éventuellement recalcul pour chaque changement de consigne (ce qui arrive plus rarement a priori) pour conserver la réactivité.
  • Que donne ta commande envoyée au split ? Si elle fait des sauts limités à 1°C, ca doit être acceptable pour le compresseur, car il continue de fonctionner en modulant sa puissance. Si les sauts sont de ~3°C, il fera du on/off et c’est moins bon.
1 « J'aime »

Salut,

C’est une bonne habitude à prendre, bien sûr que ça ne va pas écrouler ton système mais prends l’habitude de n’utiliser les variables que quand il faut stocker pour une réutilisation ultérieur. A l’intérieur du scénario, à la place, utilise des « tag » (sauf donc pour les variables qui sont réutiliser à l’appel suivant. les tag ne sont pas enregistrés en base de données et ne sollicitent donc pas le disque.

Ah, ok ! Du coup :

  • Ki je présume que c’est pour l’intégrale mais il faut diviser quoi par 2 ? Le 2 de Correct_prop (vu qu’il influ que l’integrale) ?
  • Kd je présume que c’est pour dérivé donc là il faudrait que je tente plutôt avec 0.75 plutôt que 1.5 pour Correct_deriv

Ok, je vais donc repasser en déclencheur toutes les 5mn pour voir ce que ça donne.

Oui on peut envoyer des commandes par pas de 1°c

Salut,
Le gain intégrale est ici :

Donc oui, si tu le mets toutes les 5min, il faudrait mettre 0,5 (pour avoir le même paramétrage que moi), après peut-être qu’avec 1 ca fonctionne bien chez toi.

Oui, c’est ca.

Est-ce que tu peux superposer la commande envoyé au split sur tes courbes de températures ? Pour voir si la commande ne fait pas trop le yoyo avec des valeurs trop espacées… C’est comme ca qu’on verra que la regul et propre et pas trop sollicitante pour le compresseur.

A 14h j’ai remis une programmation toutes les 5mn en retirant le déclencheur.
C’est clairement moins fin :

Je viens de changer les paramètres : La moitié de l’intégrale et de la dérivé à partir de 21h35. A suivre.

$Correct_integr = 0.5 * ($Correct_integr + $Correct_erreur);
$Correct_deriv = 0.7 * ($Correct_erreur - $Correct_erreur_previous);

Ah oui, effectivement, le comportement est étrange…

Le 0.5 (Ki) est à mettre ici :
$Correct_integr = $Correct_integr + 0.5 * $Correct_erreur ;

OK j’ai modifié mais je doute que ça change vraiment la donne :slight_smile:
En attente sur la journée de demain et peut-être du retour de @Arnaud_69

Bonjour,
J’ai laissé le scénario initial et un déclencheur de 10 minutes.
Et comme je n’ai pas compris le fonctionnement du PID, je n’ai pas osé bricoler plus.
Ça a tourné hier et ce matin encore, j’en suis satisfait.

J’ai laissé la climatisation en soufflerie auto, et c’est la température de consigne qui fluctue.
Et de votre côté, vous laissez en auto aussi ?

Je vais surveiller surtout aujourd’hui :

Que donne ta commande envoyée au split ? Si elle fait des sauts limités à 1°C, ca doit être acceptable pour le compresseur, car il continue de fonctionner en modulant sa puissance. Si les sauts sont de ~3°C, il fera du on/off et c’est moins bon.

Oui, tout est en Auto coté clim chez moi.
J’ai repassé la saturation de l’intégrale à +1,9 / -1,9°C (pas besoin de plus chez moi, en tout cas dans cette pièce).
Ca tourne bien :

J’ai reçu mes sonde ds18b20 (pour les autres splits), mais je les ai renvoyées, car le câblage dans la maison aurait été trop lourd. J’ai commandé à la place :

  • des sondes bluetooth Xiaomi Mijia
  • des sondes SONOFF SNZB-02D Zigbee + Dongle USB ZBDONGLE-E
    → je ferai la comparaison (intégration Jeedom, réception signal, précision, fréquence rafraichissement, …) pour voir lesquelles je conserve.

Hello,

image

La température est à 17,7°C depuis 10h20 (il est 10h45) pour une consigne de 18°C.
Je trouve que la consigne donné à la PAC (17 à 10h45) remonte trop doucement, non ?

Tu es sûr qu’il fallait diviser par 2 ? :blush:

Bonjour,
Je ne sais pas si c’est normal, mais ca ne me choque pas d’avoir 0,3°C d’écart le temps que le système rejoigne la consigne…
Rien de t’empêche d’augmenter le Ki, il faut juste vérifier que la commande envoyée à la clim ne fasse pas trop le yoyo (exemple 23 puis 19 puis 23 toutes les 5min…).
Je vais l’augmenter un peu de mon coté, pour voir si ca gagne un peu en dynamique.

Pour ce qui est de la théorie :
Si tu as 0,3°C d’écart et que tu intègres toutes les 10min, au bout de 30min (si l’erreur reste à 0,3), l’intégrateur vaudra 0,3 x 3 = 0,9.
Si tu fais cela toutes les 5min, il vaudra 0,3 x 6 = 1,8, donc oui il faut le diviser par 2, si tu veux les mêmes réglages que moi.
Ces réglages sont à adapter en fonction de la pièce (volume, isolation, …) et du split. Le jeu que j’ai fourni est une base de travail, à chacun d’adapter. :wink:

Merci pour tes infos.
Tu as un site qui explique tout cela ? je n’ai pas trop trouvé :frowning:

Qlq liens :

http://www.ferdinandpiette.com/blog/2011/08/implementer-un-pid-sans-faire-de-calculs/
http://linuxcnc.org/docs/2.5/html/motion/pid_theory_fr.html

Merci. Les 1er liens piquent un peu :rofl:
Je continuerai à lire toutefois.
Edit : le lien ferdinandpiette est le plus clair et le plus simple d’approche.

Oui, pour la compréhension, il est top.
Il manque la partie anti-saturation de l’actionneur.

Dans la litérature, j’ai l’impression qu’on ne trouve que de la théorie enseignée à l’école et peu d’exemples de code de PID à implémenter.

Oui, je n’ai pas trouvé d’algorithme.
Et le lien qui est bien, je l’ai implémenté pour voir. Et bon, pas satisfait de la valeur de commande…
J’aurais bien aimé un plugin qui gère ma climatisation. Je pensais m’y pencher, mais je n’y comprends pas énormément au final…

J’aurais bien aimé un plugin qui gère mon chauffage. Je pensais m’y pencher, mais je ne sais pas faire de plugin. :wink:

Ici le code de ma fonction Regulation PID sous Node-RED

Ok, je vois le code de Node.
C’est du javascript, je le mettrai en PHP pour le mettre dans un scénario PHP.
Mon but sera d’y comprendre un peu plus.
Un petit challenge en soi. :slight_smile:

En attendant, le code de Pierrot69/Bisons tourne bien chez moi depuis 2 jours.
Et le soleil est revenu pour chauffer la maison en prime, la climatisation va se retrouver de plus en plus éteinte.

Edit : ah, c’est pour une vanne thermostatique.
Je regarde toutefois le code concernant les calculs
Y’a vraiment un besoin en tout cas pour la clim et pour les vannes…