[LUA] Regulation chauffage PID
Re: Regul chauffage PID
Re bonjour ou plutôt bonsoir, je pense avoir un petit peu progressé comme débutant mais maintenant je suis devant un mur d'interrogation!
j'ai implanté les scripts de la régul PID et j'obtiens les erreurs suivantes:
2016-05-17 22:30:23.051 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_device_conschauf.lua: /home/pi/domoticz/scripts/lua/script_device_conschauf.lua:1: unexpected symbol near char(255)
2016-05-17 22:31:00.383 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_cmdchauffv2.lua: /home/pi/domoticz/scripts/lua/script_time_cmdchauffv2.lua:1: unexpected symbol near char(255)
Voici le script que j'ai entré script_device_conschauf.lua:
-- script_device_conschauf.lua ---------------------------------------
-- G PETREMENT -----------------------------------------------2015----
----------------------------------------------------------------------
-- Pilotage d'un Thermostat setpoint Consigne pour pilotage regul ----
-- en fonction d'une programation journaliere ------------------------
----------------------------------------------------------------------
-- Le programme est basé sur l'action de 2 switchs (virtuels ou non) -
-- Le Switch EcoConfort dispose d'une programation mais peut aussi ---
-- être actionné manuellement. ---------------------------------------
-- Le switch HorsGel est un mode vacance qui stope la programmation --
-- Les temperatures de consignes sont stockées en variable direct ----
-- dans domoticz pour être modifiées par l'interface web. ------------
----------------------------------------------------------------------
----------------------------------------------------------------------
-- VARIABLES UTILISATEUR : mettre les nom des dispositifs ici --------
----------------------------------------------------------------------
local VarConsJour = 'ConsigneJour' --Variable consigne jour
local VarConsNuit = 'ConsigneNuit' --Variable consigne nuit
local VarConsVac = 'ConsigneVacance' --Variable consigne vacances
local VarSomErr = 'SommeErreur' --Variable Somme des erreurs
local SondeCons = 'ConsigneChauffage' --Sonde de temperature
local InterEcoConfort = 'EcoConfort' --Interrupteur programmé Off:eco On:confort
local InterHorsGel = 'HorsGel' --Interrupteur On:mode hors gel>> plus de programmation, consigne vacance ou manuelle
local domoticz_url = '192.168.0.203:8080' --Adresse IP:port de Domoticz
local IDXcons = '54' --IDx de l'afficheur de consigne
----------------------------------------------------------------------
-- Fonction retourant la differrence de temps en secondes ------------
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
commandArray = {}
-- Recuperation des variables ---------------------------------------
local ConsJour = uservariables[VarConsJour]
local ConsNuit = uservariables[VarConsNuit]
local ConsVac = uservariables[VarConsVac]
local Consigne = otherdevices_temperature[SondeCons]
local t1 = os.date("%H:%M")
-- Lorsqu'un interrupteur est manipulé on modifie la temperature de consigne.
-- La variable SommeErreur utilisée pour calculer le gain intégral est aussi remise à 0 >> Gain intégral=0
if (((devicechanged[InterEcoConfort] == 'On') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort] == 'On'))) then
print("-------------- Temperature modifiée vers Confort à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsJour
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
elseif (((devicechanged[InterEcoConfort] == 'Off') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort]=='Off' ))) then
print("-------------- Temperature modifiée vers Eco à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsNuit
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
elseif (devicechanged[InterHorsGel] == 'On') then
print("-------------- Temperature modifiée vers HorsGel à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsVac
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
end
return commandArray
et le suivant script_time_cmdchauffv2.lua:
-- script_time_cmdchauffv2.lua ---------------------------------------
-- G PETREMENT -------------------------------------------------------
----------------------------------------------------------------------
-- Permet de commander relais de pilotage de chaudiere à gaz ---------
-- Le cycle fait 900s / 15min ---------------------------------------
-- La commande est un nombre de 0 à 100 ------------------------------
-- Le cycle minimum de la chaudière est de 3min pour réduire l'usure -
----------------------------------------------------------------------
local InterOnOff = 'Chauffage On/Off' --Interrupteur général de mise en route du chauffage
local VarCmdChauff = 'CmdChauff' --Variable de commande de chauffage définie par script_device_thermostat
local CycleMini = 180 --Durée de chauffe minimum en secondes (fonction de la chaudière)
local InterRelais = 'Piface RelayChaud' --Sortie vers relais chaudière
local domoticz_url = '192.168.0.203:8080' --Adresse IP:port de Domoticz
-- Fonction retourant la differrence de temps en secondes
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
commandArray = {}
-- Recuperation des variables
local CmdChauff = uservariables[VarCmdChauff]
local OnOff = otherdevices[InterOnOff]
-- Recuperation des minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))
-- Execution de cette partie du script toutes les 15 minutes
-- Contacte la chaudière et modifie la variable domoticz Cycle
if( (minutes==15) or (minutes==0) or (minutes==30) or (minutes==45) ) then
print('-- Lancement du script à '..hours..'h'..minutes)
print('-- OnOff ='..OnOff..' / CmdChauff ='..CmdChauff)
if OnOff == 'On' then --Si l'inter général est ON
local Cycle = CmdChauff * 9 --Calcul du temps de cycle en seconde
if Cycle < CycleMini then --Si le cycle est trop court on coupe
commandArray[InterRelais]='Off'
-- commandArray['Variable:'..VarCycle]= tostring('0')
print('Cycle :'..Cycle..'s >> Chaudière Off')
elseif Cycle > 870 then --Si le cycle est trop long (> 14min30) on allume sans coupure
commandArray[InterRelais]='On'
-- commandArray['Variable:'..VarCycle]= tostring(Cycle)
print('Cycle :'..Cycle..'s >> Chaudière On')
else --Enfin on lance pour X seconde
print('Cycle lancé pour : '..Cycle..'secondes')
commandArray[1]={[InterRelais]='On'}
commandArray[2]={[InterRelais]='Off AFTER '..tostring(Cycle)}
end
else
commandArray[InterRelais]='Off'
-- commandArray['Variable:'..VarCycle]= tostring('0')
print('Chaudière Off')
end
end
return commandArray
et voici une capture de ma page Domoticz:
Autres questions:
1) je ne sais pas comment entrer les valeurs des Constantes Kp Ki Kd dans ma régulation! elles sont déclarées comme des variables mais à aucun moment je n'ai vu une entrée de ces constantes.
2) Comment obtenir dans domoticz le tableau des variables:
3) Comment debuger un programme en script lua?
Merci d'avance à celui qui voudra bien me répondre.
Raspberry Pi model B+,Dongle WIFI, RFXComm,6 modules volet roulant BLYSS, sonde Oregon
j'ai implanté les scripts de la régul PID et j'obtiens les erreurs suivantes:
2016-05-17 22:30:23.051 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_device_conschauf.lua: /home/pi/domoticz/scripts/lua/script_device_conschauf.lua:1: unexpected symbol near char(255)
2016-05-17 22:31:00.383 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_cmdchauffv2.lua: /home/pi/domoticz/scripts/lua/script_time_cmdchauffv2.lua:1: unexpected symbol near char(255)
Voici le script que j'ai entré script_device_conschauf.lua:
-- script_device_conschauf.lua ---------------------------------------
-- G PETREMENT -----------------------------------------------2015----
----------------------------------------------------------------------
-- Pilotage d'un Thermostat setpoint Consigne pour pilotage regul ----
-- en fonction d'une programation journaliere ------------------------
----------------------------------------------------------------------
-- Le programme est basé sur l'action de 2 switchs (virtuels ou non) -
-- Le Switch EcoConfort dispose d'une programation mais peut aussi ---
-- être actionné manuellement. ---------------------------------------
-- Le switch HorsGel est un mode vacance qui stope la programmation --
-- Les temperatures de consignes sont stockées en variable direct ----
-- dans domoticz pour être modifiées par l'interface web. ------------
----------------------------------------------------------------------
----------------------------------------------------------------------
-- VARIABLES UTILISATEUR : mettre les nom des dispositifs ici --------
----------------------------------------------------------------------
local VarConsJour = 'ConsigneJour' --Variable consigne jour
local VarConsNuit = 'ConsigneNuit' --Variable consigne nuit
local VarConsVac = 'ConsigneVacance' --Variable consigne vacances
local VarSomErr = 'SommeErreur' --Variable Somme des erreurs
local SondeCons = 'ConsigneChauffage' --Sonde de temperature
local InterEcoConfort = 'EcoConfort' --Interrupteur programmé Off:eco On:confort
local InterHorsGel = 'HorsGel' --Interrupteur On:mode hors gel>> plus de programmation, consigne vacance ou manuelle
local domoticz_url = '192.168.0.203:8080' --Adresse IP:port de Domoticz
local IDXcons = '54' --IDx de l'afficheur de consigne
----------------------------------------------------------------------
-- Fonction retourant la differrence de temps en secondes ------------
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
commandArray = {}
-- Recuperation des variables ---------------------------------------
local ConsJour = uservariables[VarConsJour]
local ConsNuit = uservariables[VarConsNuit]
local ConsVac = uservariables[VarConsVac]
local Consigne = otherdevices_temperature[SondeCons]
local t1 = os.date("%H:%M")
-- Lorsqu'un interrupteur est manipulé on modifie la temperature de consigne.
-- La variable SommeErreur utilisée pour calculer le gain intégral est aussi remise à 0 >> Gain intégral=0
if (((devicechanged[InterEcoConfort] == 'On') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort] == 'On'))) then
print("-------------- Temperature modifiée vers Confort à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsJour
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
elseif (((devicechanged[InterEcoConfort] == 'Off') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort]=='Off' ))) then
print("-------------- Temperature modifiée vers Eco à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsNuit
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
elseif (devicechanged[InterHorsGel] == 'On') then
print("-------------- Temperature modifiée vers HorsGel à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsVac
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
end
return commandArray
et le suivant script_time_cmdchauffv2.lua:
-- script_time_cmdchauffv2.lua ---------------------------------------
-- G PETREMENT -------------------------------------------------------
----------------------------------------------------------------------
-- Permet de commander relais de pilotage de chaudiere à gaz ---------
-- Le cycle fait 900s / 15min ---------------------------------------
-- La commande est un nombre de 0 à 100 ------------------------------
-- Le cycle minimum de la chaudière est de 3min pour réduire l'usure -
----------------------------------------------------------------------
local InterOnOff = 'Chauffage On/Off' --Interrupteur général de mise en route du chauffage
local VarCmdChauff = 'CmdChauff' --Variable de commande de chauffage définie par script_device_thermostat
local CycleMini = 180 --Durée de chauffe minimum en secondes (fonction de la chaudière)
local InterRelais = 'Piface RelayChaud' --Sortie vers relais chaudière
local domoticz_url = '192.168.0.203:8080' --Adresse IP:port de Domoticz
-- Fonction retourant la differrence de temps en secondes
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
commandArray = {}
-- Recuperation des variables
local CmdChauff = uservariables[VarCmdChauff]
local OnOff = otherdevices[InterOnOff]
-- Recuperation des minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))
-- Execution de cette partie du script toutes les 15 minutes
-- Contacte la chaudière et modifie la variable domoticz Cycle
if( (minutes==15) or (minutes==0) or (minutes==30) or (minutes==45) ) then
print('-- Lancement du script à '..hours..'h'..minutes)
print('-- OnOff ='..OnOff..' / CmdChauff ='..CmdChauff)
if OnOff == 'On' then --Si l'inter général est ON
local Cycle = CmdChauff * 9 --Calcul du temps de cycle en seconde
if Cycle < CycleMini then --Si le cycle est trop court on coupe
commandArray[InterRelais]='Off'
-- commandArray['Variable:'..VarCycle]= tostring('0')
print('Cycle :'..Cycle..'s >> Chaudière Off')
elseif Cycle > 870 then --Si le cycle est trop long (> 14min30) on allume sans coupure
commandArray[InterRelais]='On'
-- commandArray['Variable:'..VarCycle]= tostring(Cycle)
print('Cycle :'..Cycle..'s >> Chaudière On')
else --Enfin on lance pour X seconde
print('Cycle lancé pour : '..Cycle..'secondes')
commandArray[1]={[InterRelais]='On'}
commandArray[2]={[InterRelais]='Off AFTER '..tostring(Cycle)}
end
else
commandArray[InterRelais]='Off'
-- commandArray['Variable:'..VarCycle]= tostring('0')
print('Chaudière Off')
end
end
return commandArray
et voici une capture de ma page Domoticz:
Autres questions:
1) je ne sais pas comment entrer les valeurs des Constantes Kp Ki Kd dans ma régulation! elles sont déclarées comme des variables mais à aucun moment je n'ai vu une entrée de ces constantes.
2) Comment obtenir dans domoticz le tableau des variables:
3) Comment debuger un programme en script lua?
Merci d'avance à celui qui voudra bien me répondre.
Raspberry Pi model B+,Dongle WIFI, RFXComm,6 modules volet roulant BLYSS, sonde Oregon
Raspberry Pi2 VPN, Pi 3, Pi4 ,RFXCom, 6 volets BLYSS, sondes Temp_humid Attiny85, zigbee, Mysensors, RFLINK , Zwave capteurs portes Prises, Alarme avec 2 sirènes maison esp8266, Thermostat NETAMO vannes thermostatiques
-
Hober Mallow
- Messages : 9
- Inscription : 02 oct. 2016, 21:54
Re: Regul chauffage PID
Super Boulot !
Je souhaite utiliser cette régulation dans différents environnement : Chauffage, congelateur etc...
PAr contre j'ai un petit soucis, je trouve cette erreur dans les logs :
2016-10-02 19:51:56.017 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_device_thermostatv3.lua: ...e/pi/domoticz/scripts/lua/script_device_thermostatv3.lua:105: attempt to perform arithmetic on local 'consigne' (a nil value)
Vous auriez une idée?
Cdt.
Hober Mallow
Je souhaite utiliser cette régulation dans différents environnement : Chauffage, congelateur etc...
PAr contre j'ai un petit soucis, je trouve cette erreur dans les logs :
2016-10-02 19:51:56.017 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_device_thermostatv3.lua: ...e/pi/domoticz/scripts/lua/script_device_thermostatv3.lua:105: attempt to perform arithmetic on local 'consigne' (a nil value)
Vous auriez une idée?
Cdt.
Hober Mallow
Re: Regul chauffage PID
Salut Hober Mallow
Depuis j'ai un peu modifié mais fichiers pour faire une simulation et voire comment la régulation répondait à un échelon ou à une rampe de variation de la température.
Je n'ai pas encore mis en application sur ma chaudière au Fuel!
Mais voici mes fichiers
et voici les captures d'écran obtenues:
Pour ton erreur vérifie le nom des variables et il faut créer le fichier dom_tmperr.txt avec des valeurs bidons au départ qui sert au calcul de la dérivée pour amorcer la régulation.
Bon courage
Depuis j'ai un peu modifié mais fichiers pour faire une simulation et voire comment la régulation répondait à un échelon ou à une rampe de variation de la température.
Je n'ai pas encore mis en application sur ma chaudière au Fuel!
Mais voici mes fichiers
Code : Tout sélectionner
-- script_device_conschauf.lua ---------------------------------------
-- G PETREMENT -----------------------------------------------2015----
----------------------------------------------------------------------
-- Pilotage d'un Thermostat setpoint Consigne pour pilotage regul ----
-- en fonction d'une programation journaliere ------------------------
----------------------------------------------------------------------
-- Le programme est basé sur l'action de 2 switchs (virtuels ou non) -
-- Le Switch EcoConfort dispose d'une programation mais peut aussi ---
-- être actionné manuellement. ---------------------------------------
-- Le switch HorsGel est un mode vacance qui stope la programmation --
-- Les temperatures de consignes sont stockées en variable direct ----
-- dans domoticz pour être modifiées par l'interface web. ------------
----------------------------------------------------------------------
----------------------------------------------------------------------
-- VARIABLES UTILISATEUR : mettre les nom des dispositifs ici --------
----------------------------------------------------------------------
local VarConsJour = 'ConsigneJour' --Variable consigne jour
local VarConsNuit = 'ConsigneNuit' --Variable consigne nuit
local VarConsVac = 'ConsigneVacance' --Variable consigne vacances
local VarSomErr = 'SommeErreur' --Variable Somme des erreurs
local SondeCons = 'Th_salon' --Consigne thermostat de temperature
local InterEcoConfort = 'EcoConfort' --Interrupteur programmé Off:eco On:confort
local InterHorsGel = 'HorsGel' --Interrupteur On:mode hors gel>> plus de programmation, consigne vacance ou manuelle
local domoticz_url = '192.168.0.23:9085' --Adresse IP:port de Domoticz
local IDXcons = '1' --IDx de l'afficheur de consigne
----------------------------------------------------------------------
-- Fonction retourant la differrence de temps en secondes ------------
--function timedifference(s)
-- year = string.sub(s, 1, 4)
-- month = string.sub(s, 6, 7)
-- day = string.sub(s, 9, 10)
-- hour = string.sub(s, 12, 13)
-- minutes = string.sub(s, 15, 16)
-- seconds = string.sub(s, 18, 19)
-- t1 = os.time()
-- t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
-- difference = os.difftime (t1, t2)
-- return difference
--end
commandArray = {}
-- Recuperation des variables ---------------------------------------
local ConsJour = uservariables[VarConsJour]
local ConsNuit = uservariables[VarConsNuit]
local ConsVac = uservariables[VarConsVac]
--local Consigne = otherdevices_temperature[SondeCons]
--local Consigne = otherdevices_svalues[SondeCons]
--print('consignes jour= '..ConsJour..'° Nuit= ' ..ConsNuit..'° Vac= '..ConsVac..'° et Consigne Thermostat= '..Consigne..'°')
local t1 = os.date("%H:%M")
-- Lorsqu'un interrupteur est manipulé on modifie la temperature de consigne.
-- La variable SommeErreur utilisée pour calculer le gain intégral est aussi remise à 0 >> Gain intégral=0
if (((devicechanged[InterEcoConfort] == 'On') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort] == 'On'))) then
print("-------------- Temperature modifiée vers Confort à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsJour
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
elseif (((devicechanged[InterEcoConfort] == 'Off') and (otherdevices[InterHorsGel] == 'Off')) or ((devicechanged[InterHorsGel] == 'Off') and (otherdevices[InterEcoConfort]=='Off' ))) then
print("-------------- Temperature modifiée vers Eco à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsNuit
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
elseif (devicechanged[InterHorsGel] == 'On') then
print("-------------- Temperature modifiée vers HorsGel à "..t1)
-- Mise a jour de l'afficheur via JSON -----------------------------
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDXcons..'&nvalue=0&svalue='..ConsVac
commandArray[1]={['OpenURL']=url }
commandArray['Variable:'..VarSomErr]='0'
end
return commandArrayCode : Tout sélectionner
-- script_device_thermostatv3.lua ------------------------------------
----------------------------------------------------------------------
-- G PETREMENT 2015 --------------------------------------------------
-- This script is a heating regulation use to maintain temperatur ----
-- at a specific value. ----------------------------------------------
----------------------------------------------------------------------
--------------------------------
--- Variables utilisateur ------
--------------------------------
local VarConsigne = 'Th_salon' --Température de consigne
local SondeSj = 'SondeSejour' --Nom de la sonde de température du séjour nom
local Varsonde = 'SondeChauff' --Variable Domoticz :Nom de la sonde simulée de température
local AffTexte = 'AffichageParams' -- Dispositif affichages des paramètres
local IDerreur = '6' --IDX de l'afficheur "TempErreur" d'erreur
local IDSomerreur = '5' --IDX de l'afficheur "TempSomErreur" Somme d'erreur
local IDDeltaErreur = '7' --IDX de l'afficheur "DiffErreur" Différence d'erreur
local IDCmdChauff = '8' --IDX de l'afficheur "Cmde_Chauff" Proportionnel Commande Chauffage
local IDAffTexte = '28' --IDX de l'afficheur des paramètres
local domoticz_url = '192.168.0.23:9085' --Adresse IP:port de Domoticz
local VarKp = "Kp" --Variable Domoticz : Gain proportinnel
local VarKi = "Ki" --Variable Domoticz : Gain intégral
local VarKd = "Kd" --Variable Domoticz : Gain dérivé
local VarTempErr = 'TemperatureErreur' --Variable domoticz pour l'erreur de temperature
local VarSomErr = 'SommeErreur' --Variable domoticz pour la somme des erreurs
local VarDeltaErr = 'DeltaErreur' --Variable domoticz pour la différences des erreurs
local VarCmdChauff = 'CmdChauff' --Variable Domoticz de commande du chauffage : permet de passer la commande à script_time_chauff.lua
local VarCmdImax = 'CmdImax' --Variable domoticz qui défini le gain intégral maximum
local fichier = '/var/tmp/dom_tmperr.txt' --Chemin d'acces du fichier sur un RAMdisque pour réduire l'usure de la carte SD
local nbr_stk = 22 --Quantité de valeurs utilisées pour le calcul de la dérivée de l'erreur (ne pas mettre 0!!)
--------------------------------------------------------------
-- Fonction pour arrondir un nombre à la décimale souhaitée --
--------------------------------------------------------------
math.round = function(number, precision)
precision = precision or 0
local decimal = string.find(tostring(number), ".", nil, true);
if ( decimal ) then
local power = 10 ^ precision;
if ( number >= 0 ) then
number = math.floor(number * power + 0.5) / power;
else
number = math.ceil(number * power - 0.5) / power;
end
-- convert number to string for formatting
number = tostring(number);
-- set cutoff
local cutoff = number:sub(decimal + 1 + precision);
-- delete everything after the cutoff
number = number:gsub(cutoff, "");
else
-- number is an integer
if ( precision > 0 ) then
number = tostring(number);
number = number .. ".";
for i = 1,precision
do
number = number .. "0";
end
end
end
return number;
end
---------------------------------------------------------
--- Fonction pour calculer la commande de chauffage ---
---------------------------------------------------------
Chauff = function(Kp,Err,Ki,SomErr, Kd, DifErr)
--print('Kp'..Kp..'Err'..Err..'Ki'..Ki..'SomErr'..SomErr..'Kd'..Kd..'DifErr'..DifErr)
local cmd = Kp*Err + Ki*SomErr + Kd*DifErr
-- La commande de chauffage est un nombre entier compris entre 0 et 100
if cmd < 0 then
cmd = 0
elseif cmd > 100 then
cmd = 100
else
cmd = math.round(cmd, 0)
end
return cmd
end
-----------------------------
---- Programme principal ----
-----------------------------
commandArray = {}
--La sonde Oregon 'Salon' emet toutes les 40 secondes. Ce sera approximativement la fréquence d'exécution de ce script.
--print('Anciennes valeurs: Consigne Temp.: '..otherdevices_svalues[VarConsigne]..'° '..'Temp. de sonde (ou simul.): '..' '..otherdevices_svalues[Varsonde]..'° ')
if ( (devicechanged[SondeSj]) or (devicechanged[VarConsigne]) or (devicechanged[Varsonde]) ) then
-- Initialisation des variables
local t = {} --Table buffer avec le fichier texte
local SomErreur = tonumber(uservariables[VarSomErr]) --Somme des erreurs
local Kp = tonumber(uservariables[VarKp])
local Ki = tonumber(uservariables[VarKi])
local Kd = tonumber(uservariables[VarKd])
local CmdImax = tonumber(uservariables[VarCmdImax]) --Limitation de l'action intégrale (debug)
local consigne = otherdevices_svalues[VarConsigne] --Température de consigne
---------------------------------
--- Calcul du proportionnel ---
---------------------------------
--Temperature relevée dans le salon
--local temperature = devicechanged[sonde..'_Temperature']
local temperature = tonumber(otherdevices_svalues[Varsonde])
temperature = tonumber(math.round(temperature,2))
print('Température sonde (ou simulation):'..temperature..'° , Consigne thermostat: '..consigne..'°')
-- Update de la sonde d'erreur
local TmpErreur = consigne - temperature
local url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDerreur..'&nvalue=0&svalue='..TmpErreur
commandArray[1]={['OpenURL']=url }
------------------------------
--- Calcul de la dérivée ---
------------------------------
--Creation si le ficher n'existe pas
local f = io.open(fichier, "a+")
f:close()
--Lecture du fichier et remplissage de la table t
f = io.open(fichier, "r")
for line in f:lines() do
if line ~= nil then
table.insert(t,line)
end
end
f:close()
-- Ajout de la nouvelle ligne a la table
table.insert(t,tostring(os.time()..";"..math.round(TmpErreur,2)))
--Suppression de l'élement le plus vieu
while #t > nbr_stk do
table.remove(t,1)
end
-- Eriture dans fichier'
f = io.open(fichier,"w")
for key,value in pairs(t) do
f:write(value.."\n")
end
f:close()
-- Calcul Difference entre deux erreurs à (22/2) x TintervalSonde = 55min d'interval + calibration) (sonde Bresser tous les 5min)
local MoyErr1 = 0
local MoyErr2 = 0
for i=1,#t/2 do
MoyErr1 = MoyErr1 + tostring(string.sub(t[i],string.find(t[i], ";")+1))
MoyErr2 = MoyErr2 + tostring(string.sub(t[#t+1-i],string.find(t[#t+1-i], ";")+1))
end
--Le delta erreur est calculé sur la moyenne de 22 erreurs ce qui permet de 'lisser' la variation
local DeltaErreur = tonumber(math.round(((MoyErr2 / (#t/2)) - (MoyErr1 / (#t/2)))*8 ,2)) --Delta en d°/heure
print('--DeltaErreur = ('..MoyErr2..'/'..(#t/2)..') - ('..MoyErr1..'/'..(#t/2)..') * 8= '..DeltaErreur)
-- Update de la sonde DeltaErreur
url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDDeltaErreur..'&nvalue=0&svalue='..DeltaErreur
commandArray[2]={['OpenURL']=url }
-------------------------------
--- Calcul de l'intégrale ---
-------------------------------
-- Calcul de la somme des erreurs + Update de la sonde Somme d'erreur
-- Si la l'erreur est supérieure à +-1° on ne somme pas pour limiter l'impact des changements de consigne
if ((TmpErreur > -1) and (TmpErreur < 1) and (Ki ~= 0)) then
SomErreur = tonumber(math.round(TmpErreur + SomErreur,2))
if (SomErreur > (CmdImax/Ki)) then
SomErreur = CmdImax/Ki
elseif (SomErreur < 0) then
SomErreur = 0
end
end
url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDSomerreur..'&nvalue=0&svalue='..SomErreur
commandArray[3]={['OpenURL']=url }
------------------------------------------
--- Calcul de la commande de chauffage ---
------------------------------------------
local CmdChauff = Chauff(Kp, TmpErreur, Ki, SomErreur, Kd, DeltaErreur)
-- Update de la mesure Commande
url = domoticz_url..'/json.htm?type=command¶m=udevice&idx='..IDCmdChauff..'&nvalue=0&svalue='..CmdChauff
commandArray[4]={['OpenURL']=url }
print('Nouveaux param.: Commande de chauffage (0>100): '..CmdChauff..'% ; = Kp*Err ='..tostring(Kp*TmpErreur)..'% + Ki*SomErr ='..tostring(Ki*SomErreur)..'% + Kd*DifErr ='..tostring(Kd*DeltaErreur)..'%')
commandArray['UpdateDevice'] = IDAffTexte .. '|0|Cmde_chauff: '..CmdChauff..'% ; = Kp*Err('..tostring(Kp*TmpErreur)..'%) + Ki*SomErr('..tostring(Ki*SomErreur)..'%) + Kd*DifErr('..tostring(Kd*DeltaErreur)..'%)'
--Passage des variables à domoticz
commandArray['Variable:'..VarTempErr]= tostring(TmpErreur)
commandArray['Variable:'..VarSomErr]= tostring(SomErreur)
commandArray['Variable:'..VarDeltaErr]= tostring(DeltaErreur)
commandArray['Variable:'..VarCmdChauff]= tostring(CmdChauff)
end
return commandArrayCode : Tout sélectionner
-- script_time_cmdchauffv2.lua ---------------------------------------
-- G PETREMENT -------------------------------------------------------
----------------------------------------------------------------------
-- Permet de commander relais de pilotage de chaudiere à gaz ---------
-- Le cycle fait 900s / 15min ---------------------------------------
-- La commande est un nombre de 0 à 100 ------------------------------
-- Le cycle minimum de la chaudière est de 3min pour réduire l'usure -
----------------------------------------------------------------------
local InterOnOff = 'Chauffage On/Off' --Interrupteur général de mise en route du chauffage
local VarCmdChauff = 'CmdChauff' --Variable de commande de chauffage définie par script_device_thermostat
local CycleMini = 30 -- 30s Durée de chauffe minimum en secondes (fonction de la chaudière période 10 minutes)
local CycleMaxi = 570 -- 570s Durée de chauffe limite en secondes si >=570s cycle = 100% (fonction de la chaudièrepériode 10 minutes)
local Tperiode = 600 -- Tperiode = 600s duree maxi du cycle
--local IpTelJacky = '192.168.0.10'
local InterRelais = 'RelayChaud' --Sortie vers relais chaudière
--------------------------------------------------------------
-- Fonction pour arrondir un nombre à la décimale souhaitée --
--------------------------------------------------------------
math.round = function(number, precision)
precision = precision or 0
local decimal = string.find(tostring(number), ".", nil, true);
if ( decimal ) then
local power = 10 ^ precision;
if ( number >= 0 ) then
number = math.floor(number * power + 0.5) / power;
else
number = math.ceil(number * power - 0.5) / power;
end
-- convert number to string for formatting
number = tostring(number);
-- set cutoff
local cutoff = number:sub(decimal + 1 + precision);
-- delete everything after the cutoff
number = number:gsub(cutoff, "");
else
-- number is an integer
if ( precision > 0 ) then
number = tostring(number);
number = number .. ".";
for i = 1,precision
do
number = number .. "0";
end
end
end
return number;
end
commandArray = {}
-- Recuperation des variables
CycleMaxi = Tperiode * 0.975
CycleMini = Tperiode * 0.025
local OnOff = otherdevices[InterOnOff]
local CmdChauff = uservariables[VarCmdChauff]
local Cycle=(CmdChauff * Tperiode/100) -- Calcul du temps de cycle = CmdChauff(0<>100)* Tpériode/100 = CmdChauff * 120/100 = CmdChauff * 1.2
Cycle=tonumber(math.round(Cycle, 0))
-- Recuperation des minutes et unités de minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))
unites=tonumber(string.sub(os.date('%M',time),2,2))
-- print('il est:'..hours..'h'..minutes..' '..' > unites = '..unites..' '..' minutes Cycle = '..Cycle..'s')
-- Execution de cette partie du script toutes les 10 minutes
-- Contacte la chaudière et modifie la variable domoticz Cycle
if( (unites%10==0) or (unites==0) ) then --or (unites==2) or (unites==4) or (unites==6) or (unites==8) ) then période toutes les 10 minutes (ou 2 minutes -- or(unites==5)
print('-- Lancement du script cycle chauffage à '..hours..'h'..minutes)
--print('-- et Lancement du ping SmartphoneJacky')
--if (otherdevices['SmartphoneJacky']=='Off' or (otherdevices['SmartphoneJacky']=='On' and timedifference(otherdevices_lastupdate['SmartphoneJacky']) > 300)) then
--ping_success_tel=os.execute('ping -c1 '..IpTelJacky)
--if ping_success_tel then -- or ping_success_tel
-- commandArray['SmartphoneJacky']='On'
-- print'succès présence SmartphoneJacky !!'
-- else
-- commandArray['SmartphoneJacky']='Off'
-- print'erreur absence SmartphoneJacky !!'
--end
if OnOff == 'On' then
if Cycle < CycleMini then --Si le cycle est trop court on coupe
commandArray[InterRelais]='Off'
print('Cycle < mini:'..Cycle..'s >> Chaudière Off à '..hours..'h'..minutes..' sur la durée du cycle maxi')
elseif Cycle >= CycleMaxi then --Si le cycle est trop long > Période-30s on allume sans coupure
commandArray[InterRelais]='On'
print('Cycle >= maxi :'..Cycle..'s >> Chaudière On sur la durée du cycle maxi')
else
--Enfin on lance pour X seconde
print('Cycle Chaudière On lancé à '..hours..'h'..minutes..'pour : '..Cycle..'s et Off ensuite sur la période restante du cycle maxi')
commandArray[1]={[InterRelais]='On'}
commandArray[2]={[InterRelais]='Off AFTER '..tostring(Cycle)}
end
else
commandArray[InterRelais]='Off'
print('Chaudière est sur Off en permanence bouton On/Off sur Off')
end
end
return commandArrayBon courage
Raspberry Pi2 VPN, Pi 3, Pi4 ,RFXCom, 6 volets BLYSS, sondes Temp_humid Attiny85, zigbee, Mysensors, RFLINK , Zwave capteurs portes Prises, Alarme avec 2 sirènes maison esp8266, Thermostat NETAMO vannes thermostatiques
-
Hober Mallow
- Messages : 9
- Inscription : 02 oct. 2016, 21:54
Re: Regul chauffage PID
Bonjour ;
Merci pour ce complément.
J'ai toujours un message d'erreur dans les logs :
2016-10-03 17:19:51.094 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_device_thermostatv3.lua: ...e/pi/domoticz/scripts/lua/script_device_thermostatv3.lua:107: attempt to concatenate local 'consigne' (a nil value)
Je ne comprend pas pourquoi
Cela est il possible que vous me transmettiez vos paramétres de Dispositifs (Menu Regles dispositifs)
Merci d'avance
Hober Mallow
Merci pour ce complément.
J'ai toujours un message d'erreur dans les logs :
2016-10-03 17:19:51.094 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_device_thermostatv3.lua: ...e/pi/domoticz/scripts/lua/script_device_thermostatv3.lua:107: attempt to concatenate local 'consigne' (a nil value)
Je ne comprend pas pourquoi
Cela est il possible que vous me transmettiez vos paramétres de Dispositifs (Menu Regles dispositifs)
Merci d'avance
Hober Mallow
Re: Regul chauffage PID
Re bonsoir
L'erreur provient du fait que mon système est en simulation, c'est à dire que j'ai créé un thermostat salon set point Th_salon pour la consigne mais aussi je simule la température du chauffage en remplaçant la sonde salon par un thermostat set point SondeChauff voir les premières lignes du fichier:local VarConsigne = 'Th_salon' --Température de consigne (thermostat set point)
local SondeSj = 'SondeSejour' --Nom de la sonde de température du séjour(pas utilisée dans la simulation et à substituer à SondeChauff)
local Varsonde = 'SondeChauff' --Variable Domoticz :Nom de la sonde simulée de température (thermostat set point)
La permutation est à faire lignes 104 et 105.
En espérant que ça t'aidera.
L'erreur provient du fait que mon système est en simulation, c'est à dire que j'ai créé un thermostat salon set point Th_salon pour la consigne mais aussi je simule la température du chauffage en remplaçant la sonde salon par un thermostat set point SondeChauff voir les premières lignes du fichier:local VarConsigne = 'Th_salon' --Température de consigne (thermostat set point)
local SondeSj = 'SondeSejour' --Nom de la sonde de température du séjour(pas utilisée dans la simulation et à substituer à SondeChauff)
local Varsonde = 'SondeChauff' --Variable Domoticz :Nom de la sonde simulée de température (thermostat set point)
La permutation est à faire lignes 104 et 105.
En espérant que ça t'aidera.
Raspberry Pi2 VPN, Pi 3, Pi4 ,RFXCom, 6 volets BLYSS, sondes Temp_humid Attiny85, zigbee, Mysensors, RFLINK , Zwave capteurs portes Prises, Alarme avec 2 sirènes maison esp8266, Thermostat NETAMO vannes thermostatiques
-
Hober Mallow
- Messages : 9
- Inscription : 02 oct. 2016, 21:54
Re: Regul chauffage PID
Re
J'ai essayé rapidement sans sucés
Je regarderai cela tranquillement ce week end
J'ai hâte de la voir tourner, tu as un meilleur recul depuis ca miseen service ? ca réagit correctement aux element externe (ouverture porte en hiver, etc..)
cdt
J'ai essayé rapidement sans sucés
Je regarderai cela tranquillement ce week end
J'ai hâte de la voir tourner, tu as un meilleur recul depuis ca miseen service ? ca réagit correctement aux element externe (ouverture porte en hiver, etc..)
cdt
Re: Regul chauffage PID
Je te rappelle quand même que le projet a été initié par Guitoo et que c'est son projet que je suis en train de réaliser!
Si tu veux des informations sur un fonctionnement en mode réel il vaut mieux que tu demandes à l'auteur.
Moi je n'ai pas encore essayé de le faire en réel parce que je suis en train de réaliser des sondes et des relais MySensors avec liaison radio 2,4GHz basé sur NRF24L01 qui me serviront à substituer l'horloge thermostat THEBEN qui pilote actuellement ma chaudière.
Si tu veux des informations sur un fonctionnement en mode réel il vaut mieux que tu demandes à l'auteur.
Moi je n'ai pas encore essayé de le faire en réel parce que je suis en train de réaliser des sondes et des relais MySensors avec liaison radio 2,4GHz basé sur NRF24L01 qui me serviront à substituer l'horloge thermostat THEBEN qui pilote actuellement ma chaudière.
Raspberry Pi2 VPN, Pi 3, Pi4 ,RFXCom, 6 volets BLYSS, sondes Temp_humid Attiny85, zigbee, Mysensors, RFLINK , Zwave capteurs portes Prises, Alarme avec 2 sirènes maison esp8266, Thermostat NETAMO vannes thermostatiques
Re: Regul chauffage PID
La conceration pour Guitoo ! Son script a en parti ete adapter pour Jeedom ! Un beau plugin a 4€.
Bravo a lui, et bravo au createur du plugin qui le cite.
Bravo a lui, et bravo au createur du plugin qui le cite.
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
http://www.domo-attitude.fr
Regul chauffage PID
C'est l'open source ... Il y a aussi une parti de code pour une régul PID prise ailleurs.
Il y a un fait similaire sur un autre plugin thermostat qui aurait été pompé depuis la VERA.
De façon général difficile de mettre sous licence une formule Mathématiques.
L'auteur a quand même :
Traduit le LUA en php
Fait une interface graphique
Et fait une belle documention hyper lisible et compréhensible de tous.
Soyez fière d'être source d'inspiration !
Pour le côté pecunier : je ne penses pas que les développeurs vivent bien de leurs plugins (le nombre de téléchargement ne reflète pas le nombre d'achat, car il compte le download des updates + achats + retelechargements).
Pour la license rien ne t'empêche de le faire.
Il y a un fait similaire sur un autre plugin thermostat qui aurait été pompé depuis la VERA.
De façon général difficile de mettre sous licence une formule Mathématiques.
L'auteur a quand même :
Traduit le LUA en php
Fait une interface graphique
Et fait une belle documention hyper lisible et compréhensible de tous.
Soyez fière d'être source d'inspiration !
Pour le côté pecunier : je ne penses pas que les développeurs vivent bien de leurs plugins (le nombre de téléchargement ne reflète pas le nombre d'achat, car il compte le download des updates + achats + retelechargements).
Pour la license rien ne t'empêche de le faire.
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
http://www.domo-attitude.fr