[LUA] Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

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.
ogulf
Messages : 445
Inscription : 15 juin 2017, 14:41

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par ogulf »

@greg : excellent script, que je pense implémenter bientôt !

J'adore les explications sur les différents paramètres intermédiaires à valoriser pour calculer nos fameuses variables P=fPIDKp, I=fPIDKi et D=fPIDKd : du très concret qu'on peut réaliser pour régler très finement notre PID !!

Seulement je ne comprends pas comment on peut calculer I car, d'après les explications, I=Kc/Ti
Or si tu as bien introduit le calcul de P=Kc, qui dépend des valeurs mesurées propres à chaque installation (maison, pièce, radiateur etc.), je ne vois pas à quoi correspond le Ti qui n'est jamais évoqué à part dans ce calcul.

Un complément d'information ?
Domoticz Stable sur RPi3 + RFPlayer + ZWave+ + RFLink R48 :
- 11 x RF660P
- 1 x FGSD-002
- 10 x F007TH
- 5 x Emcoluxr EV1527 + 4 x NAS-DS01Z
- 4 x NAS-PD02Z
- 1 x Shelly 1PM
greg
Messages : 6
Inscription : 17 déc. 2016, 22:37

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par greg »

Merci pour vos commentaires, je vais bientôt ( 8-) ) mettre le code sur github avec quelques commentaires et corrections.

Pour le Ti, on a en fait Ti=Tp.

Greg
lmet
Messages : 252
Inscription : 30 juin 2017, 18:16
Localisation : Val d'Oise
Contact :

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par lmet »

Merci, on compte sur toi d'autant qu'il ne va pas tarder à peler :(
Au passage :

Code : Tout sélectionner

2017-10-02 23:50:00.448 Error: EventSystem: in Chauffage_RDC: [string "--[[..."]:245: attempt to compare number with nil
Pourtant j'ai bien une variable de déclarée : " iResetDeviceMeterTime" en Integer.
Domoticz : V4.10717
Zigate : V4.11230 plugin:4.5.4 firmware:031a
Mon petit blog domotique
ogulf
Messages : 445
Inscription : 15 juin 2017, 14:41

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par ogulf »

Retour d'expérience :

Pour l'instant j'utilise ce script en mode "simulation" car que je n'ai pas encore de quoi piloter réellement les radiateurs.
J'ai deux sondes de température : une 433MHz et une autre en Z-Wave, sur pile toutes les deux.
Si la fréquence de communication est de 50 secondes pour la première (quelle que soit la valeur retournée, donc même si elle est identique à celle envoyer 50 secondes avant), c'est différent avec l'autre car, pour préserver la pile, le capteur ne communique que si un écart de 0.1°C est mesuré. Et comme le script à pour vocation à stabiliser rapidement la température...
Du coup difficile de s'appuyer sur ce capteur Z-Wave (le script s'assure que la mesure ne date pas de plus de 10 minutes).

Alors bien sûr ce délai est modifiable, mais plus on l'augmente et moins cet algorithme devient efficace je pense.
Autre solution : alimenter le module sur secteur et communication toutes les 2 minutes :D
Domoticz Stable sur RPi3 + RFPlayer + ZWave+ + RFLink R48 :
- 11 x RF660P
- 1 x FGSD-002
- 10 x F007TH
- 5 x Emcoluxr EV1527 + 4 x NAS-DS01Z
- 4 x NAS-PD02Z
- 1 x Shelly 1PM
greg
Messages : 6
Inscription : 17 déc. 2016, 22:37

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par greg »

Hello Ogulf,

Merci beaucoup pour ton retour. Tu dois pouvoir contourner le probleme en enlevant les lignes

Code : Tout sélectionner

if (sTempSensorLastSeen >= '00:10') then
                  prDebug('Temp sensor missing')
          addCommand('SendEmail',sZoneName..' Heating Alert#Temperature sensor '..sTempSensorDeviceName..' has not updated for more than 10m.#'..sEmailContact)
        else -- Sensor has been seen, we use it
C'est en effet quelque chose à mettre éventuellement en option

Greg
ogulf
Messages : 445
Inscription : 15 juin 2017, 14:41

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par ogulf »

Pour ma part, j'utilise ce script depuis 15 jours, adapté à mon équipement X2D (obligé de passer par un Selector Switch car passe par le plugin RFPlayer), dans une chambre en bas.
Quelques difficultés pour le mettre en place, mais particularité du X2D...

En parallèle, j'utilise un autre script pour une autre zone (cuisine, en haut) : chauffage PID.

La comparaison en termes de performances risque d'être difficile malheureusement, car la cuisine est souvent au dessus de sa température de consigne, alors que la chambre elle est naturellement sous sa consigne...
Faudrait que j'ai une autre zone en haut, ce n'est pas encore possible pour le moment.

Par contre, question installation... j'dirai rien mais y'en a un qui est autrement plus facile à installer que l'autre... :mrgreen:
Ce script propose cependant plus de fonctionnalités.

En bref, je vais organiser un speed dating entre ces deux scripts, et j'en garderai l'enfant illégitime ! :lol:

Merci pour ce travail ;)
Domoticz Stable sur RPi3 + RFPlayer + ZWave+ + RFLink R48 :
- 11 x RF660P
- 1 x FGSD-002
- 10 x F007TH
- 5 x Emcoluxr EV1527 + 4 x NAS-DS01Z
- 4 x NAS-PD02Z
- 1 x Shelly 1PM
ogulf
Messages : 445
Inscription : 15 juin 2017, 14:41

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par ogulf »

@greg : j'ai fait deux petites modifications dans ton script.


1- Il me semble qu'il y a une petite erreur dans le calcul de l'utilisation des radiateurs

Dans la fonction commandHeating(sCommand,iTime)

Avant modif :

Code : Tout sélectionner

        if( sCommand == sHeatingOnForCommand ) then
          fIntervalEnergy = fIntervalEnergy + (tonumber(fInstantPower) / 60 ) * iHeatingCycleDuration 
        else
           fIntervalEnergy = fIntervalEnergy + tonumber(fInstantPower) / 60 
        end
Après modif :

Code : Tout sélectionner

        if( sCommand == sHeatingOnForCommand ) then
          fIntervalEnergy = fIntervalEnergy + (tonumber(fInstantPower) / 60 ) * iTime 
        elseif (sCommand ~= sHeatingOffCommand ) then
           fIntervalEnergy = fIntervalEnergy + tonumber(fInstantPower) / 60 * iHeatingCycleDuration
        end
En effet, lorsque le radiateur reçoit une commande "ON FOR", il va chauffer pendant iTime minutes, pas pendant iHeatingCycleDuration minutes.
Et si on envoie la commande "ON" et pas "ON FOR", alors le radiateur va chauffer pendant iHeatingCycleDuration minutes.

Pourquoi j'enverrai "ON" et pas "ON FOR" me diras-tu ? Dans quel cas ?

2- Eviter deux ordres successifs

Lorsque le temps de chauffe est calculé à la même valeur que iHeatingCycleDuration, cela pose un pb à mes récepteurs X2D.

Je m'explique avec iHeatingCycleDuration = 10 minutes (par exemple) :
- Disons que le calcul donne 6 minutes de chauffe : j'utilise l'ordre ON FOR 6 ==> au bout de 6 minutes le récepteur X2D reçoit l'ordre OFF et attend 4 minutes avant la prochaine instruction.
- Si par contre le calcul donne 10 minutes de chauffe, j'appelle "ON" car l'ordre "ON FOR 10" va envoyer un ordre OFF au bout de 10 minutes suivi quelques millièmes de secondes plus tard par un autre ordre (ON, ON FOR ou OFF) : ce second ordre n'est pas forcément pris en compte par mon récepteur.

Peut-être qu'un module DIO accepte deux ordre séparés de quelques millièmes, et les traite bien tous les deux ? Mais pas mes RF660FP.

Du coup, voici mon autre modif (spécifique au protocole X2D, mais peut être généralisée dans le script) :

Script d'origine :

Code : Tout sélectionner

                                  -- Heating cycle duration calculation
                                 if( fPIDOutput > 0 ) then -- heat
                                    fCycleDuration = round(fPIDOutput * iHeatingCycleDuration / 255,0)
                                    if( fCycleDuration == 0 ) then fCycleDuration = 1 end -- Heating is needed, let's go for at least 1 minute
                                    prDebug('Going to heat for : ' ..fCycleDuration..' minutes during the next '..round(iHeatingCycleDuration*60)..' seconds ('..iHeatingCycleDuration..' minutes) period.' )
                                    commandHeating(sHeatingOnForCommand,fCycleDuration)
                                  else -- Output null or negative, stop the heating
                                    bDebug = true
                                    prDebug(sZoneName..' : Temp='..fCurrentTemp..', Consigne='..fSetPointTemp..', Pas de chauffage dans les '..iHeatingCycleDuration..' prochaines minutes')
                                    bDebug = false
                                    commandHeating(sHeatingOffCommand)
                                 end
Petite évolution qui évite deux ordres successifs :

Code : Tout sélectionner

                                  -- Heating cycle duration calculation
                                 if( fPIDOutput > 0 ) then -- heat
                                    fCycleDuration = round(fPIDOutput * iHeatingCycleDuration / 255,0)
                                    if( fCycleDuration == 0 ) then fCycleDuration = 1 end -- Heating is needed, let's go for at least 1 minute
                                    prDebug('Going to heat for : ' ..fCycleDuration..' minutes during the next '..round(iHeatingCycleDuration*60)..' seconds ('..iHeatingCycleDuration..' minutes) period.' )
                                    if (fCycleDuration == iHeatingCycleDuration)
                                    then commandHeating(sHeatingComfortCommand)
                                    else
                                        commandHeating(sHeatingOnForCommand,fCycleDuration)
                                    end
                                  else -- Output null or negative, stop the heating
                                    bDebug = true
                                    prDebug(sZoneName..' : Temp='..fCurrentTemp..', Consigne='..fSetPointTemp..', Pas de chauffage dans les '..iHeatingCycleDuration..' prochaines minutes')
                                    bDebug = false
                                    commandHeating(sHeatingOffCommand)
                                 end
Domoticz Stable sur RPi3 + RFPlayer + ZWave+ + RFLink R48 :
- 11 x RF660P
- 1 x FGSD-002
- 10 x F007TH
- 5 x Emcoluxr EV1527 + 4 x NAS-DS01Z
- 4 x NAS-PD02Z
- 1 x Shelly 1PM
vil1driver
Messages : 5661
Inscription : 30 janv. 2015, 11:07
Localisation : Rennes (35)

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par vil1driver »

Salut,

Je ne sais pas si c'est toujours le cas mais FOR est subtile car veut dire repasser à l'état précédent et non pas à l'état opposé.

Si ton module est sur On et que tu fais un On FOR, il ne va pas passer à Off au bout du délai..

Perso je préfère utiliser AFTER.

Je n'utilise plus jamais FOR et ne sais donc pas si ce que j'énonce est toujours vrai mais je préfère vous mettre en garde.
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
ogulf
Messages : 445
Inscription : 15 juin 2017, 14:41

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par ogulf »

Merci pour ton alerte.

Cependant, voici un extrait de ma log de ce jour :

2017-10-22 20:15:00.141 LUA: Salle de Bain Bas : Temp=19, Consigne=20, Chauffage pendant 5 minutes
2017-10-22 20:20:00.182 LUA: Salle de Bain Bas : Temp=19.3, Consigne=20, Chauffage pendant 3 minutes
2017-10-22 20:23:00.252 LUA: Salle de Bain Bas : Off automatique après la période de chauffe
2017-10-22 20:25:00.518 LUA: Salle de Bain Bas : Temp=19.4, Consigne=20, Chauffage pendant 3 minutes
2017-10-22 20:28:00.331 LUA: Salle de Bain Bas : Off automatique après la période de chauffe


Analyse toutes les 5 minutes
20:15 : Reçoit "ON" (cf ma remarque précédente)
20:20 : Reçoit "ON FOR 3"
20:23 : Passage à OFF
20:25 : etc.

Donc, à priori, c'est bien corrigé. Sauf que je n'ai pas vérifié si à 20:23 l'ordre "OFF" avait bien été envoyé... Là c'est juste un message...

Je vais tâcher de surveiller et confirmer/infirmer l'utilisation du ON FOR.
Domoticz Stable sur RPi3 + RFPlayer + ZWave+ + RFLink R48 :
- 11 x RF660P
- 1 x FGSD-002
- 10 x F007TH
- 5 x Emcoluxr EV1527 + 4 x NAS-DS01Z
- 4 x NAS-PD02Z
- 1 x Shelly 1PM
Hawk49
Messages : 17
Inscription : 05 mars 2018, 10:35

Re: Script chauffage Hysteresis et PID, multi radiateurs et thermomètres

Message par Hawk49 »

Bonjour à tous, c'est une rencontre au sommet et je suis ravi de pouvoir m'adresser à vous tous en même temps ! (j'en profite pour vous remercier !)
J'ai eu beaucoup de lecture commune avec ce qui est cité dans le 1er post et entre ce qu'ont mis à disposition Greg et Vil1driver je vais gagner un temps fou (plutôt que d'imaginer moi même l'implémentation complète à partir de http://controlguru.com !!).
Il me reste un problème non résolu (dont parle lmet), c'est de prendre en compte les conditions extérieures pour anticiper le temps de chauffe. En effet (pour l'instant en simple hysterisis), mon salon ne met évidemment pas le même temps pour atteindre la consigne lorsqu'il fait 3°C ou 15°C dehors.

Voilà où j'en suis dans mes vœux:
- je souhaite gérer la température de consigne pièce par pièce avec un dispositif de type Thermostat dont la valeur change par son planning (typiquement, une consigne pour la nuit et une pour le jour)
- je voudrais utiliser un algorithme PID (pour la stabilité et parce que c'est la classe ! (j'ai fait un peu de math et de prog alors c'est une merveilleuse façon que ça me serve à quelque chose))
- je voudrais que le chauffage se mette en route AVANT le changement de consigne pour qu'elle soit atteinte à l'heure dite (avec mon algo basique, je me contente aujourd'hui d'anticiper le planning en demandant 19°C à 5h pour que la consigne soit atteinte à 6h30 par exemple). C'est cela qui me gêne, je chauffe trop tôt s'il fait 15°C dehors et trop tard s'il fait 3°C ! Du coup c'est pas WAF du tout s'il ne fait pas bon quand Madame se lève...
Je pensais prendre en compte la température extérieure ressentie (pour ne pas compliquer les choses moi-même avec le vent et l'humidité) et prendre en compte l'écart (températurePièce - températureExtRessentie) dans la partie Proportionnelle (ou plutôt Dérivée ?) de l'algo PID.

Je rajoute au passage (en avouant ne pas avoir encore cherché...): comment anticiper le changement de consigne (aller chercher dans le planning du thermostat) ?

Avez vous réfléchi à ce genre de chose et si oui où en sont vos réflexions ?
Merci pour votre partage !
Répondre