Code : Tout sélectionner
--[[ Script de gestion de la piscine
Fonctions :
1. Gestion de la filtration
1.1 Calculer la durée et la période optimale de filtration
1.2 Démarrer / arrêter la filtration
Si température eau > 12°C, selon planning calculé au dessus
Sinon, marche si température air <1°C, arrêt si >2°C
--]]
-- Paramètres
local dbPath = "/var/domoticz/domoticz.db"
local gst_HorsGel = true -- gestion ou non du mode hors gel
local dev_TAir = "Température Extérieure" -- Température extérieure (nécessaire seulement pour le mode hors gel)
local dev_TEau = "Température piscine" -- Température eau piscine
local dev_PpeFl = "Filtration piscine" -- Interrupteur de commande de la pompe
local dev_ModeFl = "Mode filtration piscine" -- Selecteur du mode de la pompe (Manu/Auto HC/AutoHP)
local dev_cptFl = "Consommation Piscine" -- Compteur de consommation électrique piscine
local dev_HC = "Heures creuses EDF" -- Indicateur d'heure creuses EdF
local var_PPStart = "PpePiscStart" -- Variable contenant l'heure de départ de la filtration
local var_PPDuree = "PpePiscDuree" -- Variable contenant la durée de la filtration
-- Réglages du temps de filtration
local cst_PpeFl_Qn=6 -- Débit nominal de la pompe de filtration en m3/h
local cst_Pisc_V =24 -- volume du bassin, en m3
local cst_Adj =0.175 -- Coefficient à ajuster en + ou en - pour filtrer plus ou moins longtemps
local cst_PpeFl_W =312 -- Puissance électrique de la pompe piscine
-- -------------------------------
-- Bibliothèque de fonctions
-- -------------------------------
local CmdIdx=1
local debug=1
function round(num, dec)
if num == 0 then
return 0
else
local mult = 10^(dec or 0)
return math.floor(num * mult + 0.5) / mult
end
end
function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end
function UpdateSw(device,commande)
--Update un switch Domoticz
commandArray[CmdIdx] = {[device] = commande}
CmdIdx=CmdIdx+1
end
function UpdateVar(variable,valeur)
--Update une variable Domoticz
commandArray[CmdIdx] = {['Variable:'..variable] = tostring(valeur)}
CmdIdx=CmdIdx+1
end
function UpdateDev(device,nvalue,svalues)
--Met à jour un device numérique Domotica
commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}
CmdIdx=CmdIdx+1
end
function UpdateP1(device,HC,conso,prod,freq)
-- Met à jour un P1 smart counter
-- device : nom du compteur
-- HC : "On" si heures creuses, "Off" si heures pleines
-- conso : consommation instantannée
-- prod : production instantannée
-- freq : frequence d'exécution du script (en minutes)
local u1, u2, p1, p2
local dbg=0
u1, u2, p1, p2 = string.match(otherdevices_svalues[device],"(.-);(.-);(.-);(.-);.*")
-- Utile pour les compteurs nouvellement crées
u1=u1 or 0
u2=u2 or 0
p1=p1 or 0
p2=p2 or 0
if dbg == 1 then
print("Mise à jour de "..tostring(device))
print("u1 "..tostring(u1))
print("u2 "..tostring(u2))
print("p1 "..tostring(p1))
print("p2 "..tostring(p2))
print("conso "..tostring(conso))
print("prod "..tostring(prod))
end
if otherdevices[HC] == 'Off' then
-- svalue=USAGE1;USAGE2;RETURN1;RETURN2;CONS;PROD
commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[device]..'|0|'..tostring(u1+conso*freq/60)..';'..tostring(u2)..';'..tostring(p1+prod*freq/60)..';'..tostring(p2)..';'..tostring(conso)..';'..tostring(prod)}
CmdIdx=CmdIdx+1
else
commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[device]..'|0|'..tostring(u1)..';'..tostring(u2+conso*freq/60)..';'..tostring(p1)..';'..tostring(p2+prod*freq/60)..';'..tostring(conso)..';'..tostring(prod)}
CmdIdx=CmdIdx+1
end
end
function ConsoDev(switch,ConsoMarche,ConsoVeille)
-- Retourne la consommation d'un appareil commandé
-- selon qu'il est en marche ou en veille
if otherdevices[switch] == 'On' then
return ConsoMarche
else
return ConsoVeille
end
end
function CalcFiltration()
--[[ Calcule
* La durée optimale de filtration en fonction de la Température
de l'eau, du débit de la pompe et du volume du bassin
* L'heure de début de la filtration selon qu'on veut filtrer en heure creuses ou pleines
Utilise les variables globales suivantes
dev_Teau : device du thermomètre d'eau
dev_ModeFl : le sélecteur de mode de filtration
cst_PpeFl_Qn: débit nominal de la pompe en m3/h
cst_Pisc_V : Volume du bassin en m3
cst_Adj : Coefficient d'ajustement
var_PPStart : Nom de la variable qui va stocker l'heure de départ de la filtration
var_PPDuree : Nom de la vatiable qui va stocker la durée de filtration
--]]
local val_TEau, MidiSol, DebutFiltration, dureeFiltration, HDebFilt
print("Script Piscine : Calcul de la filtration")
val_TEau=os.capture('sqlite3 '..dbPath..' "select temp_avg from temperature_calendar where devicerowid='..otherdevices_idx[dev_TEau]..' order by date desc limit 1"')
val_TEau=round(val_TEau,1)
print("Température moyenne hier : "..val_TEau.." °C")
dureeFiltration=round(60*math.max(0,cst_Adj*cst_Pisc_V/cst_PpeFl_Qn*(val_TEau-10)),0) -- Résultat en minutes
print("Durée de filtration : "..dureeFiltration.." min")
if otherdevices[dev_ModeFl] == "Auto HC" then
-- Mode Auto Heures Creuses
-- On filtre jusqu'à 7h00 si possible (=420 min), et on déborde si nécessaire
DebutFiltration=math.max(10,420-dureeFiltration)
else
-- Mode Auto Heures Pleines ou Manu
-- On filtre en journée, centré sur le midi solaire
MidiSol=round((timeofday['SunriseInMinutes']+timeofday['SunsetInMinutes'])/2,0) -- en minutes
DebutFiltration=round(MidiSol-dureeFiltration/2,0) -- en minutes
end
HDebFilt=os.date("%H:%M", DebutFiltration*60-3600)
print("Début de filtration : "..HDebFilt)
UpdateVar(var_PPStart,HDebFilt)
UpdateVar(var_PPDuree,dureeFiltration)
end
function ChkFiltration()
--[[Gestion de la filtration
Start / Stop de la pompe
Demandes de chloration automaique --]]
-- Mode de la filtration :
-- Manu / Auto HC / Auto HP
local PpeDuree, val_TEau, val_PpeFl, MinDuJour, PpeStart, today, PpeFait
print("Script Piscine : Gestion de la filtration")
PpeDuree=tonumber(uservariables[var_PPDuree])
if (otherdevices[dev_ModeFl] ~= "Manu") then
val_TEau = tonumber(string.match(otherdevices_svalues[dev_TEau],"(%d+.%d*);.*"))
val_PpeFl=otherdevices[dev_PpeFl]
if (val_TEau >= 12) then
-- La témpérature d'eau est >=12°C : on utilise la temporisation
MinDuJour=60*time.hour+time.min
PpeStart=tonumber(string.sub(uservariables[var_PPStart],1,2))*60+tonumber(string.sub(uservariables[var_PPStart],4,5))
-- Calcul de la durée de fonctionnement de la pompe aujourd'hui
-- Basé sur le compteur de puissance piscine
today = os.date("%Y-%m-%d")
PpeFait=os.capture('sqlite3 '..dbPath..' "select sum(value3) from multimeter where devicerowid='..otherdevices_idx[dev_cptFl]..' and Date(date)=\''..today..'\'"')*5/cst_PpeFl_W
print("Déjà effectué : "..PpeFait.." minutes sur "..PpeDuree)
if (MinDuJour >= PpeStart and PpeFait < PpeDuree and val_PpeFl == "Off") then
print("Filtration piscine : Démarrage par timer")
UpdateSw(dev_PpeFl,'On')
elseif (PpeFait >= PpeDuree and val_PpeFl == "On") then
print("Filtration piscine : Arrêt par timer")
UpdateSw(dev_PpeFl,'Off')
end
else
if gst_HorsGel then
--[[ La température de l'eau est <12°C : on utilise la température
Démarrage si température d'air <= 1
Arrêt si température d'air >= 1.5 et température eau >= 0.5
--]]
val_Tair = tonumber(otherdevices_svalues[dev_TAir])
if (val_Tair <= 1) and val_PpeFl == "Off" then
print("Filtration piscine : Démarrage par température")
UpdateSw(dev_PpeFl,'On')
elseif (val_Tair >= 1.5) and (val_TEau>=0.5) and val_PpeFl == "On" then
print("Filtration piscine : Arrêt par température")
UpdateSw(dev_PpeFl,'Off')
end
end
end -- filtration timer/temperature
else
print("Mode manu, pas de changement")
end -- end mode auto/manu
end
-- -------------------------------
-- Fin bibliothèque de fonctions
-- -------------------------------
commandArray = {}
time = os.date("*t")
--Calcul de la durée optimale de filtration et de l'heure de démarrage tous le jours à minuit une
if time.hour==0 and time.min ==1 then CalcFiltration() end
-- Marche/Arrêt de la pompe de filtration tous les quart d'heures
if (((time.min-1) % 15)== 0) then ChkFiltration() end
-- Mise à jour du compteur de consommation de la piscine toutes les 5min
if (((time.min-2) % 5)== 0) then
UpdateP1(dev_cptFl,dev_HC,ConsoDev(dev_PpeFl,cst_PpeFl_W,0),0,5)
end
return commandArray