Voici donc mon script en DzVents (langage spécifique à Domoticz basé sur Lua). Ce langage permet une grande simplification des calculs statistiques sur une base de données (telles que les moyennes, utiliser les x dernières valeures, la valeur il y a x hh:mm:ss …).
Le principe :
- se déclenche toutes les minutes
- fait 3 calculs pour les 3 sdb
- détection d’une douche <=> augmentation de l’humidité absolue de 20% en 10 minutes
- cible à atteindre pour éteindre la ventilation = l’humidité absolue repasse sous la moyenne de la valeur d’humidité absolue des 2 dernières heures.
- Script met à jour une variable indiquant le besoin de ventilation ou pas. Un autre script met la VMC en vitesse 2 ou 1.
--[[
-- Script de calcul de l'humidité absolue d'une pièce.
--
-- Calcul de la moyenne sur 6 heures de l'humidité absolue de chaque pièce
-- Ventilation s'arrête aussi si l'humidité absolue devient inférieure à la moyenne de l'humidité absolue sur les
-- 30 dernières minutes. En effet, il arrivait que, malgré la ventilation, l'humidité abs ne repassait jamais
-- sous la cible dans le cas ou la douche était prise alors que l'humidité était en train de monter par execute
--
----------------------------------------------------------------------------------------------------------------------------------
-- V1.0 : la valeur à laquelle on compare l'humidité absolue pour savoir s'il faut ventiler est faite sur les 6 dernières heures
-- V1.1 : la ventilation ne s'arrêtait pas lorsque la douche était prise alors que l'humidité absolue était en phase d'augmentation.
-- Changement de la durée de la moyenne. On passe à des valeurs plus courtes (30 min)
--
------------------------------------------------------------------------------------------------------------------------------------
--
-- Variables à éditer
--
--------------------------------------------
]]--
local scriptName = 'Calcul_Hum_Abs_SDB'
local scriptVersion = '1.1'
local device_temp1 = 'Temp_SDB_Etage' -- nom (entre ' ') ou idx de la sonde de température sdb étage
local device_hum1 = 'Humidite_SDB_Etage' -- idx de la sonde d'humidité sdb étage
local device_hum_abs1 = 'Humidite_Abs_SDB_Etage' -- nom (entre ' ') ou idx de l'éventuel dummy humidité absolue sdb etage
local device_temp2 = 'Temperature_SDB_Ewen' -- nom (entre ' ') ou idx de la sonde de température sdb Ewen
local device_hum2 = 'Humidite_SDB_Ewen' -- idx de la sonde d'humidité sdb Ewen
local device_hum_abs2 = 'Humidite_Abs_SDB_Ewen' -- nom (entre ' ') ou idx de l'éventuel dummy humidité absolue sdb Ewen
local device_temp3 = 'Temperature_SDB_Laurie' -- nom (entre ' ') ou idx de la sonde de température sdb Laurie
local device_hum3 = 'Humidite_SDB_Laurie' -- idx de la sonde d'humidité sdb étage
local device_hum_abs3 = 'Humidite_Abs_SDB_Laurie' -- nom (entre ' ') ou idx de l'éventuel dummy humidité absolue sdb Laurie
local Seuil_Declenchement_VMC = 1.5 -- valeur au dessus de la moyenne à 6 heures au dessus de laquelle il faut déclencher la VMC
local Plancher_Humidite_Cible = 1.5 -- valeur au dessus de la moyenne à 6 heures à laquelle on coupe la VMC
--------------------------------------------------------------------------------------------------------------------------------------------
-- PROGRAMME
--------------------------------------------------------------------------------------------------------------------------------------------
return {
active = true,
-- custom logging level for this script
logging = {
--level = domoticz.LOG_DEBUG,
level = domoticz.LOG_INFO, -- Seulement un niveau peut être actif; commenter les autres
--level = domoticz.LOG_ERROR, -- Only one level can be active; comment others
-- level = domoticz.LOG_MODULE_EXEC_INFO,
marker = scriptName..' v'..scriptVersion
},
on = {
timer = {
'every 1 minutes' -- pour avoir assez de valeurs d'humidité abs, je lance le script toutes les 1 minute
}
},
data = {
Duree_VentilationMin_1 = { initial = 0 },
Duree_VentilationMin_2 = { initial = 0 },
Duree_VentilationMin_3 = { initial = 0 },
},
execute = function(dz, timer)
function HumAbs(t,hr)
-- https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
-- Formule pour calculer l'humidité absolue
-- Dans la formule ci-dessous, la température (T) est exprimée en degrés Celsius, l'humidité relative (hr) est exprimée en %, et e est la base des logarithmes naturels 2.71828 [élevée à la puissance du contenu des crochets]:
-- Humidité absolue (grammes / m3 ) = (6,122 * e^[(17,67 * T) / (T + 243,5)] * rh * 2,1674))/(273,15 + T)
-- Cette formule est précise à 0,1% près, dans la gamme de température de -30 ° C à + 35 ° C
ha = dz.utils.round((6.112 * math.exp((17.67 * t)/(t+243.5)) * hr * 2.1674)/ (273.15 + t),1)
return ha
end
local capteurs = {
{ humabs = 'HumAbs1', besoin_ventil = 'Besoin_Ventilation_SDB_1', duree_ventil = 'Duree_VentilationMin_1' },
{ humabs = 'HumAbs2', besoin_ventil = 'Besoin_Ventilation_SDB_2', duree_ventil = 'Duree_VentilationMin_2' },
{ humabs = 'HumAbs3', besoin_ventil = 'Besoin_Ventilation_SDB_3', duree_ventil = 'Duree_VentilationMin_3' },
}
for _,sonde in ipairs(capteurs) do
local humabs_Tampon = sonde.humabs
local X
local Y
local test = dz.globalData[humabs_Tampon].size
dz.log('==== ' .. test .. ' ====', dz.LOG_DEBUG)
if dz.globalData[humabs_Tampon].size <= 11 then --** test sur la taille de la bdd me permet de gérer le cas
dz.log('==== HELLO 1 ====', dz.LOG_DEBUG) --** ou le pi démarre et que la bdd est vide (sinon ça génère
X = 50 --** une erreur
Y = 50
else
dz.log('==== HELLO 2 ====', dz.LOG_DEBUG)
X = dz.globalData[humabs_Tampon].getAtTime('00:10:00').data
Y = dz.globalData[humabs_Tampon].getLatest().data
end
--[[local Y = dz.globalData[humabs_Tampon].getLatest().data
if Y == nil then précédente version : bug si il n'y a pas de data stockées
Y = 50
end]]--
local Douche_On = 100 * (( Y - X ) / X ) -- Taux d'augmentation de l'humidité absolue dans une SDB
dz.log('==== ' .. sonde.besoin_ventil, dz.LOG_DEBUG)
dz.log(' = ' .. tostring(dz.variables(sonde.besoin_ventil).value), dz.LOG_DEBUG)
if (Douche_On >= 20) then
if dz.variables(sonde.besoin_ventil).value == 'false' then
dz.variables(sonde.besoin_ventil).set('true')
dz.log(' = ' .. tostring(dz.variables(sonde.besoin_ventil).value), dz.LOG_DEBUG)
dz.data[sonde.duree_ventil] = 0
end
end
end
--********************************************************************
-- calculs pour la salle de bain à l'étage
--********************************************************************
local temperature1 = dz.devices(device_temp1).temperature
local humidity1 = dz.devices(device_hum1).humidity
local absHumidity1 = HumAbs(temperature1, humidity1)
--absHumidity1 = 11.4 -- pour tester
dz.devices(device_hum_abs1).updateCustomSensor(absHumidity1) -- mis à jour du capteur virtuel de Domoticz
dz.globalData.HumAbs1.add(absHumidity1) -- fonctions statistiques sur l'humidité absolue de ma sdb
--local Avg_AbsHumidity1_6H = dz.globalData.HumAbs1.avgSince('06:00:00') -- calcul de la moyenne sur les 6 dernières heures de l'humidité relative
local Cible1 = dz.globalData.HumAbs1.avgSince('02:00:00') -- Cible1 est la valeur à laquelle on coupe la VMC
--Avg_AbsHumidity1 = 11
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log('Humidité absolue sdb étage =' .. absHumidity1, dz.LOG_DEBUG)
dz.log('Cible humidité absolue sdb étage =' .. Cible1, dz.LOG_DEBUG)
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log("dz.variables('Besoin_Ventilation_SDB_1') =" .. tostring(dz.variables('Besoin_Ventilation_SDB_1').value), dz.LOG_DEBUG)
----------------------------------------------------------------------------------------
-- S'il y a demande de ventilation
----------------------------------------------------------------------------------------
if (dz.variables('Besoin_Ventilation_SDB_1').value == 'true') then
----------------------------------------------------------------------------
-- si l'humidité absolue est en dessous du seuil souhaité mais que la ventilation
-- est toujours en marche alors on passe la ventilation à OFF et on affecte 0
-- à la valeur cible d'humidité
-----------------------------------------------------------------------------
dz.data.Duree_VentilationMin_1 = dz.data.Duree_VentilationMin_1 + 1
if (absHumidity1 <= Cible1 + 0.1) then
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log('Durée de ventilation (min) =' .. dz.data.Duree_VentilationMin_1, dz.LOG_DEBUG)
dz.log('Humidité absolue =' .. absHumidity1, dz.LOG_DEBUG)
dz.log("Valeur cible d'humidité absolue =" .. Cible1, dz.LOG_DEBUG)
dz.log("Valeur cible d'humidité atteinte, on coupe la VMC ", dz.LOG_DEBUG)
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.notify("Domoticz", "Fin du Besoin de ventilation SDB du haut : l'humidité absolue (" .. tostring(absHumidity1) ..
" g/m3) a atteint la valeur cible (" .. Cible1 .. " g/m3)", dz.PRIORITY_LOW, "" , NSS_TELEGRAM)
dz.notify("Domoticz","La ventilation a duré : ".. dz.data.Duree_VentilationMin_1 .. " minutes.", dz.PRIORITY_LOW, "" , NSS_TELEGRAM)
dz.variables('Besoin_Ventilation_SDB_1').set('false')
end
end
-- **************************************************************************************************************************
-- calculs pour la salle de bain Ewen
-- **************************************************************************************************************************
local temperature2 = dz.devices(device_temp2).temperature
local humidity2 = dz.devices(device_hum2).humidity
local absHumidity2 = HumAbs(temperature2, humidity2)
--absHumidity1 = 11.4 -- pour tester
dz.devices(device_hum_abs2).updateCustomSensor(absHumidity2) -- mis à jour du capteur virtuel de Domoticz
dz.globalData.HumAbs2.add(absHumidity2) -- fonctions statistiques sur l'humidité absolue de ma sdb
--local Avg_AbsHumidity2_6H = dz.globalData.HumAbs2.avgSince('06:00:00') -- calcul de la moyenne sur les 6 dernières heures de l'humidité relative
local Cible2 = dz.globalData.HumAbs2.avgSince('02:00:00')
--Avg_AbsHumidity1 = 11
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log('Humidité absolue sdb Ewen =' .. absHumidity2, dz.LOG_DEBUG)
dz.log('Cible humidité absolue sdb Ewen =' .. Cible2, dz.LOG_DEBUG)
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log("dz.variables('Besoin_Ventilation_SDB_2') =" .. tostring(dz.variables('Besoin_Ventilation_SDB_2').value), dz.LOG_DEBUG)
----------------------------------------------------------------------------------------
-- S'il y a demande de ventilation
----------------------------------------------------------------------------------------
if (dz.variables('Besoin_Ventilation_SDB_2').value == 'true') then
----------------------------------------------------------------------------
-- si l'humidité absolue est en dessous du seuil souhaité mais que la ventilation
-- est toujours en marche alors on passe la ventilation à OFF et on affecte 0
-- à la valeur cible d'humidité
-----------------------------------------------------------------------------
dz.data.Duree_VentilationMin_2 = dz.data.Duree_VentilationMin_2 + 1
if (absHumidity2 <= Cible2 + 0.1) then
dz.log('------------------------------------\n SDB EWEN\n', dz.LOG_DEBUG)
dz.log('Durée de ventilation (min) =' .. dz.data.Duree_VentilationMin_2, dz.LOG_DEBUG)
dz.log('Humidité absolue =' .. absHumidity2, dz.LOG_DEBUG)
dz.log("Valeur cible =" .. Cible2, dz.LOG_DEBUG)
dz.log("Valeur cible d'humidité atteinte, on coupe la VMC ", dz.LOG_DEBUG)
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.notify("Domoticz", "Fin du Besoin de ventilation SDB Ewen : l'humidité absolue (" .. tostring(absHumidity2) ..
" g/m3) a atteint la valeur cible (" .. Cible2 .. " g/m3)", dz.PRIORITY_LOW, "" , NSS_TELEGRAM)
dz.notify("Domoticz","SDB Ewen, la ventilation a duré : ".. dz.data.Duree_VentilationMin_2 .. " minutes.", dz.PRIORITY_LOW, "" , NSS_TELEGRAM)
dz.variables('Besoin_Ventilation_SDB_2').set('false')
end
end
-- ************************************************************************
-- calculs pour la salle de bain Laurie
-- ************************************************************************
local temperature3 = dz.devices(device_temp3).temperature
local humidity3 = dz.devices(device_hum3).humidity
local absHumidity3 = HumAbs(temperature3, humidity3)
--absHumidity1 = 11.4 -- pour tester
dz.devices(device_hum_abs3).updateCustomSensor(absHumidity3) -- mis à jour du capteur virtuel de Domoticz
dz.globalData.HumAbs3.add(absHumidity3) -- fonctions statistiques sur l'humidité absolue de ma sdb
--local Avg_AbsHumidity3_6H = dz.globalData.HumAbs3.avgSince('06:00:00') -- calcul de la moyenne sur les 6 dernières heures de l'humidité relative
local Cible3 = dz.globalData.HumAbs3.avgSince('02:00:00')
--Avg_AbsHumidity1 = 11
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log('Humidité absolue sdb Laurie =' .. absHumidity3, dz.LOG_DEBUG)
dz.log('Cible humidité absolue sdb Laurie =' .. Cible3, dz.LOG_DEBUG)
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.log("dz.variables('Besoin_Ventilation_SDB_3') =" .. tostring(dz.variables('Besoin_Ventilation_SDB_3').value), dz.LOG_DEBUG)
----------------------------------------------------------------------------------------
-- S'il y a demande de ventilation
----------------------------------------------------------------------------------------
if (dz.variables('Besoin_Ventilation_SDB_3').value == 'true') then
----------------------------------------------------------------------------
-- si l'humidité absolue est en dessous du seuil souhaité mais que la ventilation
-- est toujours en marche alors on passe la ventilation à OFF et on affecte 0
-- à la valeur cible d'humidité
-----------------------------------------------------------------------------
dz.data.Duree_VentilationMin_3 = dz.data.Duree_VentilationMin_3 + 1
if (absHumidity3 <= Cible3 + 0.1) then
dz.log('------------------------------------\n SDB LAURIE\n', dz.LOG_DEBUG)
dz.log('Durée de ventilation (min) =' .. dz.data.Duree_VentilationMin_3, dz.LOG_DEBUG)
dz.log('Humidité absolue =' .. absHumidity3, dz.LOG_DEBUG)
dz.log("Valeur cible d'humidité absolue =" .. Cible3, dz.LOG_DEBUG)
dz.log("Valeur cible d'humidité atteinte, on coupe la VMC ", dz.LOG_DEBUG)
dz.log('------------------------------------', dz.LOG_DEBUG)
dz.notify("Domoticz", "Fin du Besoin de ventilation SDB Laurie : \nl'humidité absolue (" .. tostring(absHumidity3) ..
" g/m3) a atteint la valeur cible (" .. Cible3 .. " g/m3)", dz.PRIORITY_LOW, "" , NSS_TELEGRAM)
dz.notify("Domoticz","SDB Laurie, la ventilation a duré : ".. dz.data.Duree_VentilationMin_3 .. " minutes.", dz.PRIORITY_LOW, "" , NSS_TELEGRAM)
dz.variables('Besoin_Ventilation_SDB_3').set('false')
end
end
end
}
J’imagine que c’est assez confu car c’est l’oeuvre d’un amateur (moi). En le reprenant aujourd’hui, j’ai mis un peu de temps à retrouver la signification de toutes les parties de mon code !