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')