Re: Régulation d'une chaudière Frisquet ECO radio System
Publié : 31 janv. 2016, 11:52
Tuto partie 5 : les scripts
J'ai deux scripts python qui tournent :
- régulateur.py : le PID
- PWM.py : celui qui pilote la chaudière
je vais chercher dans un fichier *.cfg les différentes constantes dont j'ai besoin
j'importe un module nommé modules_SSO qui regroupe des fonctions pour parser du JSON depuis l'API Domoticz ou pour piloter mon relais.
nota : du fait de mon installation d'origine basée sur la techno SCS myhome de Legrand/Bticino, j'utilise Domoticz plutôt comme une IHM.
Régulatuer.py
PWM.py
il faut m'excuser pour le manque de commentaires dans les scripts mais je suis entrain de les éditer dans ce sens.
J'ai deux scripts python qui tournent :
- régulateur.py : le PID
- PWM.py : celui qui pilote la chaudière
je vais chercher dans un fichier *.cfg les différentes constantes dont j'ai besoin
j'importe un module nommé modules_SSO qui regroupe des fonctions pour parser du JSON depuis l'API Domoticz ou pour piloter mon relais.
nota : du fait de mon installation d'origine basée sur la techno SCS myhome de Legrand/Bticino, j'utilise Domoticz plutôt comme une IHM.
Régulatuer.py
Code : Tout sélectionner
!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
******************* Créé le 16/01/2016 par SSO *************************
Description :
-------------
Régule la chaudière selon les conditions intérieures.
il faut également executer PWM.py
Conditions d'éxécution:
-----------------------
Crontab au boot
@reboot /home/pi/domoticz/scripts/python/Chauffage/regulateur.py
************************************************************************
'''
'''
**************************** Modifications *****************************
25/01/2016
----------
- ajustement pour faire démarrer le script depuis crontab
- PWM.py est démarrer par le crontab et non par regulateur.py
- Calcul de la dérivée sur la mesure + deltaT réel
26/01/2016
----------
- l'action dérivée est active également dans la Bm (pas P ni I)
- Ajout de la Relance soutenue: si la commande est à zéro pendant plus d'un temps DelayStandby (minutes) alors on relance (100%) pour TRelance (minutes).
************************************************************************
'''
import ConfigParser,time
from modules_SSO import *
#Initialisation des paramètres du régulateur
IdxInter='112'
IdxConsigne='111'
IdxMesure='16'
IdxCommande='113'
CfgPID=ConfigParser.ConfigParser()
Integral=0.0
Derivee=0.0
Puissance=50.0
Mesure0=float(domo_json_read(IdxMesure,'Temp'))
T0=DomoJsonReadLastUpdate(IdxMesure)
TStandby=0.0
Standby=True
Relance=False
#*********************************************
ChauffCommand=domo_json_read(IdxInter,'Status')
while True:
ChauffCommand=domo_json_read(IdxInter,'Status')
if ChauffCommand=='On':
CfgPID.read('/home/pi/domoticz/scripts/python/Chauffage/PID.cfg')
Kp=CfgPID.getfloat('CoeffPID','Kp')
Ki=CfgPID.getfloat('CoeffPID','Ki')
Kd=CfgPID.getfloat('CoeffPID','Kd')
Bm=CfgPID.getfloat('CoeffPID','Bm')
DelayRelance=CfgPID.getfloat('CoeffPID','DelayRelance')
DelayStandby=CfgPID.getfloat('CoeffPID','DelayStandby')
Periode=CfgPID.getint('CoeffPID','Periode')
Consigne=float(domo_json_read(IdxConsigne,'SetPoint'))
Mesure=float(domo_json_read(IdxMesure,'Temp'))
Erreur=Consigne-Mesure
#On ne met à jour la Puissance que si :
# |Erreur| > Bande Morte Bm
if abs(Erreur)>Bm:
if Mesure!=Mesure0:
T=DomoJsonReadLastUpdate(IdxMesure)
Derivee=Derivee+(Mesure0-Mesure)/(T-T0)
Mesure0=Mesure
T0=T
if Erreur<0 and Puissance==0:
Integral=Integral
elif Erreur>0 and Puissance==100:
Integral=Integral
else:
Integral=Integral+Erreur
Puissance=Kp*Erreur+Ki*Integral+Kd*Derivee
print Puissance
else:
if Mesure!=Mesure0:
T=DomoJsonReadLastUpdate(IdxMesure)
Derivee=Derivee+(Mesure0-Mesure)/(T-T0)
Mesure0=Mesure
T0=T
Puissance=Ki*Integral+Kd*Derivee
if Puissance>100:
Puissance=100
if Puissance<=0:
Puissance=0
if Standby==False:
TStandby=time.time()
Standby==True
if Puissance>0 and Standby==True:
if (time.time()-TStandby)>(DelayStandby*60):
Puissance=100
Relance=True
Standby=False
DomoJsonWritePercent(IdxCommande,str(Puissance))
if Relance==True:
time.sleep(DelayRelance*60)
Relance=False
else:
time.sleep(Periode)
ChauffCommand=domo_json_read(IdxInter,'Status')
else:
DomoJsonWritePercent(IdxCommande,'0')
PWM.py
Code : Tout sélectionner
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import ConfigParser,time
from modules_SSO import *
#Initialisation des paramètres du régulateur
Cfg=ConfigParser.ConfigParser()
Commande0=50.0
Puissance0=0.0
T0=DomoJsonReadLastUpdate('113')
#Initialisation des paramètres du socket
cfg=ConfigParser.ConfigParser()
cfg.read("/home/pi/domoticz/scripts/python/parametres.cfg")
buffer_size=cfg.getint('Param_F455','buffer_size')
ip_F455=cfg.get('Param_F455','ip') # IP passerelle F455
port_F455=cfg.getint('Param_F455','port') # port pour commande opennwebnet
ChauffCommand=domo_json_read('112','Status')
while ChauffCommand=='On':
#on récupère l'ensemble des données
#**********une fois le PID réglé il faudra sortir la mise à jour des Coeff ****************
Cfg.read('/home/pi/domoticz/scripts/python/Chauffage/PID.cfg')
Kc=Cfg.getfloat('CoeffPWM','Kc')
PeriodePWM=Cfg.getfloat('CoeffPWM','Periode')
PeriodePID=Cfg.getfloat('CoeffPID','Periode')
#*******************************
Puissance=float(DomoJsonReadPercent('113','Data'))
T=DomoJsonReadLastUpdate('113')
if Puissance==100:
Commande=100
elif Puissance==0:
Commande=0
else:
DeltaPuissance=Puissance-Puissance0
DeltaT=T-T0
try:
DPsurDT=DeltaPuissance/DeltaT
except ZeroDivisionError:
DPsurDT=0
Commande=int(50+(50*DPsurDT)/Kc)
if Commande>100:
Commande=100
elif Commande<0:
Commande=0
DomoJsonWritePercent('116',Commande)
T0=T
Puissance0=Puissance
#Envoie de la période de commande
TOn=Commande*PeriodePWM/100
TOff=PeriodePWM-TOn
if TOn!=0:
LightCommandOwn('11','34') #11 --> ON pendant 1 minute (chien de garde!!)
time.sleep(TOn)
if TOff!=0:
LightCommandOwn('0','34')
time.sleep(TOff)
ChauffCommand=domo_json_read('112','Status')
#Avant de quitter on met la valeur de Domoticz à zéro
DomoJsonWritePercent('116','0')
LightCommandOwn('0','34')