[LUA] Script de chauffage avec détection PIR et retour de conso
Publié : 10 mars 2015, 13:26
Bonjour,
un script parmi tant d'autres.... mais je l'aime bien et madame également :p
il colle parfaitement à nos horaires extrêmement variables et absence impromptues..

ce script permet de maintenir une température choisie et réglée sur un capteur virtuel de consigne de thermostat,
dans une plage horaire de 7h à 23h ou sur 24h grâce à un bouton marche forcée,
et cela uniquement si notre présence est détectée via un capteur de mouvement (PIR pour les intimes),
- principe copié sur un produit du commerce -
dès que nous sommes présent dans la pièce, le chauffage se met en route, et uniquement dans cette pièce.
si nous nous absentons, le script va progressivement faire baisser la consigne sur une durée de 3h pour arriver à la consigne économique (-2°C ou -3°C)
dans cette période, toute nouvelle détection de présence remontera instantanément la consigne à sa valeur initiale.
si vous souhaitez que le chauffage se mette en route avant votre réveil ou votre retour de ballade,
vous n'avez simplement qu'a programmer le changement d'état de votre capteur PIR grâce à la fonction planning de domoticz,
ou bien vous connecter à distance pour manuellement le faire changer d'état.
il m'est arrivé de ne plus recevoir d'info de mes sondes de température, alors j'ai ajouté une sécurité qui coupe le chauffage le temps du blackout radio et envoie un mail d'alerte.
cerise sur le gâteau, il est prévu de 'mesurer' la consommation électrique de vos chauffage et d'alimenter un capteur virtuel de consommation.
ce n'est pas vraiment de la mesure mais le script s'exécutant toutes les minutes et la consommation d'un radiateur étant quelque-chose de stable et connu, il était aisé de faire les calculs nécessaires.
si vous avez comme moi plusieurs pièces et donc plusieurs script de chauffages (typiquement 1 par pièce/zone), il est possible d'utiliser le même capteur de conso pour tout le monde. le code est prévu pour.
voici le script:
un script parmi tant d'autres.... mais je l'aime bien et madame également :p
il colle parfaitement à nos horaires extrêmement variables et absence impromptues..

ce script permet de maintenir une température choisie et réglée sur un capteur virtuel de consigne de thermostat,
dans une plage horaire de 7h à 23h ou sur 24h grâce à un bouton marche forcée,
et cela uniquement si notre présence est détectée via un capteur de mouvement (PIR pour les intimes),
- principe copié sur un produit du commerce -
dès que nous sommes présent dans la pièce, le chauffage se met en route, et uniquement dans cette pièce.
si nous nous absentons, le script va progressivement faire baisser la consigne sur une durée de 3h pour arriver à la consigne économique (-2°C ou -3°C)
dans cette période, toute nouvelle détection de présence remontera instantanément la consigne à sa valeur initiale.
si vous souhaitez que le chauffage se mette en route avant votre réveil ou votre retour de ballade,
vous n'avez simplement qu'a programmer le changement d'état de votre capteur PIR grâce à la fonction planning de domoticz,
ou bien vous connecter à distance pour manuellement le faire changer d'état.
il m'est arrivé de ne plus recevoir d'info de mes sondes de température, alors j'ai ajouté une sécurité qui coupe le chauffage le temps du blackout radio et envoie un mail d'alerte.
cerise sur le gâteau, il est prévu de 'mesurer' la consommation électrique de vos chauffage et d'alimenter un capteur virtuel de consommation.
ce n'est pas vraiment de la mesure mais le script s'exécutant toutes les minutes et la consommation d'un radiateur étant quelque-chose de stable et connu, il était aisé de faire les calculs nécessaires.
si vous avez comme moi plusieurs pièces et donc plusieurs script de chauffages (typiquement 1 par pièce/zone), il est possible d'utiliser le même capteur de conso pour tout le monde. le code est prévu pour.
voici le script:
Code : Tout sélectionner
--[[
Type: time
Name: chauffage
Description: Ce script permet de maintenir une température de confort,
suivant la détection de notre présence (dans une plage horaire donnée),
puis de progressivement abaisser la température en notre abscence.
Usage: un interrupteur général 'mode' permet de passer du mode auto (conf/éco) au mode hors gêle.
un second 'boost' permet de chauffer hors plage horaire (toujours sur détection de présence)
un troisième 'guess' permet de forcer notre présence
si nous faisons la fête, pour avoir du chauffage tant que la soirée à lieu
activer 'boost'
'boost' se désactivera de lui même après une heure sans détection de présence
si vous voulez chauffer(confort) même sans détection de mouvement (bébé, personne alitée)
activer 'guess'
le script permet également de renseigner un capteur virtuel de consommation électrique.
Inertie: lorsque le chauffage est allumé, on incrémente un compteur +1/min
suivant ce compteur, la consigne à atteindre est abaissée de 0.1°C toutes les 10 minutes, avec un abaissement maxi de 0.5°C
donc plus le temps passe, plus la température de la pièce augmente et plus la consigne baisse..
lorsque la température rejoint la consigne(modifiée), on arrête de chauffer.
on laisse un peu la pièce profiter de l'énergie accumulée dans les radiateurs.
et on décrémente le compteur -1/min ce qui va remonter la consigne de 0.1°C toutes les 10 minutes
donc plus le temps passe et plus la température continue de monter et plus la consigne augmente (jusqu'à relancer la chauffe)
lorsque l'on atteint et/ou dépasse la consigne initiale le compteur est remis à zéro.
au bout de 10 minutes à la consigne voulue, on remet en route le chauffe pour 2min puis on le stop 2min et on recommence.
si cela nous fait dépasser la consigne on arrête.
si on tombe sous la consigne, on aura gagné en réactivité car le radiateur sera préchauffé.
--]]
----------------------------------------------
------ Configuration ------
----------------------------------------------
-- nom de zone
local zone = 'salon' -- nom de la zone pour affichage dans les logs et alerte mail
-- consignes
local consigne_conf = 'th_salon' -- nom de thermostat virtuel de gestion de la température de confort
local consigne_abs = 10 -- Température lors d'abscence prolongée (hors gêle)
local consigne_1h = 0.5 -- valeur d'abaissement de la consigne après 1 heure d'abscence
local consigne_2h = 1.5 -- valeur d'abaissement de la consigne après 2 heure d'abscence
local consigne_3h = 2.5 -- valeur d'abaissement de la consigne après 3 heure d'abscence
-- capteurs
local sonde = 'salon' -- Nom de la sonde de température
local presence = 'mv salon' -- Nom du capteur de mouvement
local mode = 'chauffage' -- Nom de l'interrupteur virtuel général (On=auto Off=hors gêle)
local boost = 'boost' -- Nom de l'interrupteur virtuel pour déroger au couvre feu (chauffer hors plage de chauffe définie)
local guess = 'guess' -- Nom de l'interrupteur virtuel pour forcer notre présence
-- période de chauffage
-- pour une période de 24h, mettre debut = '00:00' et fin = '24:00'
-- bien respecter le format hh:mm
local debut = '07:00'
local fin = '23:00'
-- radiateur
local radiateur = 'radiateur salon' -- Nom de l'interrupteur de chauffage
local puissance = 2700 -- puissance du chauffage en watt
local conso = 'conso chauffage' -- nom du capteur virtuel de consommation électrique (type= instant + counter)
local conso_id = 107 -- idx du capteur virtuel de consommation électrique
local reset = false -- force la mise à zero de la consomation instantané (laisser à false pour un fonctionnement normal) true/false
-- inertie (beta)
local inertie = true -- radiateur à inertie true/false
local up = 1.5 -- incrément du compteur par minute (vitesse d'abaissement de la consigne)
local down = 1.9 -- décrément du compteur par minute (vitesse de remontée de la consigne)
-- email
local mail = '******@*****' -- pour réception alerte sonde muette (chauffage coupé)
-- domoticz
local url = '192.168.22.100:8080' -- user:pass@ip:port de domoticz, pour la création des variables
----------------------------------------------
-- Fin de la partie configuration --
----------------------------------------------
function timedifference(d)
s = otherdevices_lastupdate[d]
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
-- quelle heure est-il
local heure = string.sub(os.date("%X"), 1, 5)
-- on regarde depuis combien de temps on est abscent
local abscence = string.sub(os.date("!%X", timedifference(presence)), 1, 5)
-- si demandé on simule une présence constante
if (otherdevices[guess] == 'On') then
abscence = '00:00'
end
-- notre dernière apparition était elle dans la plage horaire ?
if ((60*tonumber(string.sub(heure,1,2)) + tonumber(string.sub(heure,4,5))) - (60*tonumber(string.sub(abscence,1,2)) + tonumber(string.sub(abscence,4,5))) >= 60*tonumber(string.sub(debut,1,2)) + tonumber(string.sub(debut,4,5))) then
inScope = true
else
inScope = false
end
-- on regarde de quand date la dernière relève de température
local lastSeen = string.sub(os.date("!%X", timedifference(sonde)), 1, 5)
commandArray = {}
--envoie d'une alerte mail si la sonde reste muette (pas de valeur reçue sur les 30 dernières minutes)
if (lastSeen >= '00:30' and lastSeen < '00:32') then
commandArray['SendEmail']='Domoticz Alerte#Alerte sonde '..zone..' muette#'..mail
end
-- création variable pour mémoriser la durée de chauffe,
-- servant à éviter un fort dépassement de consigne suite à une longue période de chauffe (inertie des radiateurs)
if (uservariables['chauffage_'..zone] == nil) then
commandArray['OpenURL']=url..'/json.htm?type=command¶m=saveuservariable&vname=chauffage_'..zone..'&vtype=2&vvalue=0'
print('script chauffage '..zone..' interrompu pour création variable manquante')
return commandArray
end
-- gestion de la consigne
-- récupération de la valeur du thermostat
consigne_conf = tonumber(otherdevices_svalues[consigne_conf])
-- si le thermostat général est actif
if (otherdevices[mode] == 'On') then
-- si il y a absence de moins d'une heure, la journée ou jusqu'au landemain matin si boost actif
if ((inScope or otherdevices[guess] == 'On') and abscence <= '01:00' and ((heure >= debut and heure < fin) or otherdevices[boost] == 'On')) then
consigne = consigne_conf
-- si absence de 1 à 2 heures la journée, abaissement de la consigne de 1°C
elseif (inScope and abscence > '01:00' and abscence <= '02:00' and heure >= debut and heure < fin) then
consigne = consigne_conf - consigne_1h
-- si absence de 2 à 3 heures la journée, abaissement de la consigne de 2°C
elseif (inScope and abscence > '02:00' and abscence <= '03:00' and heure >= debut and heure < fin) then
consigne = consigne_conf - consigne_2h
-- sinon, passage en consigne éco (3°C en dessous de la consigne confort)
else
consigne = consigne_conf - consigne_3h
-- annulation boost, soirée terminée
commandArray[boost] = 'Off'
end
else
consigne = consigne_abs
end
-- adaptation de la consigne pour tenir compte de l'inertie des radiateurs
-- on soustrait/ajoute 0.1°C à la consigne, par tranche de 10 du compteur
local count = tonumber(uservariables['chauffage_'..zone])
if (count > 0) then
adj = math.ceil(count / 10) / 10 - 0.1
else
adj = math.ceil(count / 10) / 10
end
if (inertie) then
consigne = consigne - adj
end
-- on récupère la température fournie par la sonde
local temperature = math.floor(10*tonumber(otherdevices_temperature[sonde]))/10
-- si la température est supérieure ou égale à la consigne,
-- ou que la sonde semble muette (10 min sans relève),
if (temperature >= consigne or lastSeen > '00:10') then
-- on stop la chauffe
commandArray[radiateur]='Off'
log = 'Radiateur -. OFF .-'
-- calcul de la conso
npower, energy = string.match(otherdevices_svalues[conso], "(%d+%.*%d*);(%d+%.*%d*)")
if (otherdevices[radiateur] == 'On') then
power = tonumber(npower - puissance)
if (power < 0) then
power = 0
end
else
power = tonumber(npower)
end
energy = tonumber(energy)
-- si on dépasse la consigne voulue on remet le compteur à zero
if (temperature > consigne + adj) then
commandArray['Variable:chauffage_'..zone] = '0'
-- on décrémente progessivement le compteur durée de chauffe (on ne passe sous zero que si on est à la consigne voulue)
elseif (otherdevices[radiateur] == 'Off' and (count > 0 or temperature == consigne + adj)) then
commandArray['Variable:chauffage_'..zone] = tostring(count - down)
end
-- si la température est inférieur à la consigne et que la sonde est OK
else
-- on chauffe
commandArray[radiateur]='On'
log = 'Radiateur -. ON .-'
-- calcul de la conso
npower, energy = string.match(otherdevices_svalues[conso], "(%d+%.*%d*);(%d+%.*%d*)")
if (otherdevices[radiateur] == 'On') then
power = tonumber(npower)
else
power = tonumber(npower + puissance)
end
energy = tonumber(energy + (puissance / 60))
-- si on tombe sous la consigne voulue et que le compteur est negatif, on le remet à zero
if (temperature < consigne + adj and tonumber(uservariables['chauffage_'..zone]) < 0) then
commandArray['Variable:chauffage_'..zone] = '0'
-- sinon on incrémente le compteur durée de chauffe (max 100)
elseif (otherdevices[radiateur] == 'On' and count + up <= 100) then
commandArray['Variable:chauffage_'..zone] = tostring(count + up)
end
end
-- envoie de la conso dans le capteur virtuel d'énergie
if (reset) then
power = 0
end
commandArray[3]={['UpdateDevice'] = conso_id .. '|0|' .. power .. ';' .. energy}
-- logs
print('*** Chauffage '..zone..' ***')
print(log)
if inertie then
print('Gestion de l\'inertie: count '..count)
end
if (otherdevices[boost] == 'On') then
print('Couvre feu désactivé')
end
if (inScope and otherdevices[guess] == 'Off')then
print('Absence '..zone..' : '..abscence)
elseif (otherdevices[guess] == 'On') then
print('Présence continue activée')
end
if (otherdevices[mode] == 'Off') then
print('Thermostat général sur Off')
elseif (lastSeen > '00:10') then
print('Sonde muette !')
else
print('il fait '..temperature..'°C pour '..consigne..'°C souhaité')
end
print('*** *** *** *** *** ***')
return commandArray