Page 2 sur 4

Re: nouvelle Gestion piscine

Publié : 07 mars 2020, 10:17
par samourai47
Hello a tous .
Meg plus pour aleph0 et @mickaelr30
Depuis des semaines j'essaye de faire fonctionner le script de manière fiable et je n'y arrive pas
J'ai pris dans unpremier temps la version de aleph0, puis celle de @mickaelr30.
On peut pas dire que ca ne fonctionne pas. des 3 fonctions tournenet correctement
Par contre la fonction chkfiltration fonctionne quand elle veut. PArfois pendant quelques jours. Puis ca s'arrete et ca repart.
Bref impossible a installer de manière perenne...
Avez vous aussi ces soucis? comment les avez vous resolu?
Moi je n'y arrive pas.
Je vous mets le code que j'essaye en ce moment issu de la version @mickalr30

Merci d'avance
le script

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      = "/home/pi/domoticz/domoticz.db"
local gst_HorsGel = false                      -- gestion ou non du mode hors gel

local dev_TAir    = "T° Terrasse"  -- Température extérieure (nécessaire seulement pour le mode hors gel)
local dev_TEau    = "T° Bassin"     -- Température eau piscine
local dev_Status = "Status Piscine"      		 -- Capteur texte de log des évènements
local dev_Status_Filtration = "Status filtration"      		 -- Capteur texte de log des évènements

local dev_DureeFl    = "Temps de filtration"           -- Capteur pour logger la durée de filtration calculée
local dev_PpeFl   = "Pompe"      -- Interrupteur de commande de la pompe
local dev_ModeFl  = "Auto_HC/HP" -- Selecteur du mode de la pompe (Manu/Auto HC/AutoHP)
local dev_cptFl   = "Conso_Piscine"    -- Compteur de consommation électrique piscine
local dev_HC      = "Témoin_HC"      -- Indicateur d'heure creuses EdF


local tp_moye    = "T° Moyenne Piscine"  -- Capteur texte pour afficher la température moyenne de la piscine
local tp_moyen    = "T° Piscine moyenne"

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=12      -- Débit nominal de la pompe de filtration en m3/h
local cst_Pisc_V  =48     -- 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 =800    -- Puissance électrique de la pompe piscine

-- -------------------------------
-- Bibliothèque de fonctions
-- -------------------------------
local debug=1

dofile('/home/pi/domoticz/scripts/lua/bibliotheque.lua')


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, HFinFiltr
    
    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")
--UpdateDev('T° moyenne Piscine', 0, val_TEau)
UpdateDev('T° Piscine moyenne', 0, val_TEau)

    dureeFiltration=round(60*math.max(2,cst_Adj*cst_Pisc_V/cst_PpeFl_Qn*((val_TEau))-10),0) -- Résultat en minutes min 2h / jour
   
    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)
	HFinFiltr=os.date("%H:%M", (DebutFiltration+dureeFiltration)*60-3600)
    print("Filtration de "..HDebFilt.." à "..HFinFiltr.." soit "..dureeFiltration.." min")
	print("Début de filtration : "..HDebFilt)
    dureeFiltrationH=os.date("%H:%M", dureeFiltration*60-3600)
    UpdateVar(var_PPStart,HDebFilt)
    UpdateVar(var_PPDuree,dureeFiltration)
	--UpdateDev(dev_Status,0,"------ Nouvelle journée ------")
    UpdateDev(dev_Status,0,"Filtration de "..HDebFilt.." à "..HFinFiltr.." pour "..dureeFiltrationH.." heures")
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 Min_last_stop=23*60+45, HDebFilt, HFinFiltr    -- Heure maxi pour arrêter la filtration en minute
    
    print("Script Piscine : Gestion de la filtration")

    PpeDuree=tonumber(uservariables[var_PPDuree])
    val_ModeFl=otherdevices[dev_ModeFl]
	val_PpeFl=otherdevices[dev_PpeFl]
	if (val_ModeFl ~= "Manu") then
        print("Température de la piscine : "..otherdevices_svalues[dev_TEau].." °C")
        --val_TEau = tonumber(string.match(otherdevices_svalues[dev_TEau],"(%d+.%d*);.*"))
        --val_TEau = tonumber(string.match(otherdevices_svalues[dev_TEau],"(.-);.*"))
    val_TEau=tonumber(otherdevices_svalues[dev_TEau])
	
        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("Effectué : "..PpeFait.." minutes sur "..PpeDuree)
            PpeRest=PpeDuree-PpeFait
            UpdateDev(dev_Status_Filtration,0,"Effectué : "..PpeFait.." minutes sur "..PpeDuree.."\n Reste : "..PpeRest.." minutes.")
            

		    if (MinDuJour >= PpeStart and PpeFait < PpeDuree and val_PpeFl == "Off") then
                print("Filtration piscine : Démarrage par timer")
                UpdateSw(dev_PpeFl,'On')
               -- HFinFiltr=os.date("%H:%M", (DebutFiltration+dureeFiltration)*60-3600)
                Hfin= PpeStart+PpeDuree
                HfinH=os.date("%H:%M", Hfin*60-3600)
			    UpdateDev(dev_Status,0,"Démarrage par timer :"..PpeDuree.." mn de filtration \n A partir de "..PPeStart.."Jusqu'à : "..HfinH )
				
            
			elseif val_PpeFl == "On" and (PpeFait >= PpeDuree or MinDuJour>=Min_last_stop) then
                print("Filtration piscine : Arrêt par timer.")
                UpdateSw(dev_PpeFl,'Off')
				UpdateDev(dev_Status,0,"Arrêt par timer: \n Filtrée pendant "..PpeDuree.." minutes.")
			
            end
    elseif 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
                -- Conversion température piscine depuis la variable en nombre
Temp_piscine_H = tonumber(uservariables['temppiscine'])
-- Conversion températeure piscine temps réel en nombre
Temp_piscine = tonumber(Temp_piscine) 
                --]]               

                val_TAir = tonumber(otherdevices_svalues[dev_TAir])

              
                if (val_TAir <= 1) and val_PpeFl == "Off" then
                    print("Filtration piscine : Démarrage par température")
					UpdateDev(dev_Status,0,"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")
					UpdateDev(dev_Status,0,"Arrêt par température")
                    UpdateSw(dev_PpeFl,'Off')
                                
            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) % 10)== 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

if time.min==5 then
--RefreshDev(dev_Status_Filtration)
RefreshDev(tp_moyen)

end
return commandArray 
la bibliotheque

Code : Tout sélectionner

--Bibliothèque de fonctions lua pour scripts domoticz 

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 lastupdate(obj,isvar)
    -- retourne le nombre de secondes écoulées depuis la dernière mise à jour d'un capteur ou variable
    -- isvar : true si obj est une variable ; false ou optionel sinon
    isvar=isvar or false
    if isvar then
        s=uservariables_lastupdate[obj]
    else
        s=otherdevices_lastupdate[obj]
    end

    s_year = string.sub(s, 1, 4)
    s_month = string.sub(s, 6, 7)
    s_day = string.sub(s, 9, 10)
    s_hour = string.sub(s, 12, 13)
    s_minutes = string.sub(s, 15, 16)
    s_seconds = string.sub(s, 18, 19)

    t2 = os.time{year=s_year, month=s_month, day=s_day, hour=s_hour, min=s_minutes, sec=s_seconds}
    return os.difftime (os.time(), t2)
end

function Notification(texte)
    -- Envoi "texte" en notification
    print(texte)
    commandArray[#commandArray+1] = {['SendNotification']="Domoticz#"..texte..'#0'}
end

function RefreshDev(device)
    -- Recopie la valeur actuelle dans un capteur pour qu'il ne passe pas en rouge
    commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|0|'..tostring(otherdevices_svalues[device])}
end

function RefreshSP(device)
    -- Recopie la valeur actuelle dans un setpoint pour qu'il ne passe pas en rouge
    commandArray[#commandArray+1] = {['SetSetPoint:'..otherdevices_idx[device]] = tostring(otherdevices_svalues[device])}
end

function UpdateSw(device,commande)
    --Update un switch Domoticz
    commandArray[#commandArray+1] = {[device] = commande}
end

function UpdateVar(variable,valeur)
    --Update une variable Domoticz
    commandArray[#commandArray+1] = {['Variable:'..variable] = tostring(valeur)}
end

function UpdateDev(device,nvalue,svalues)
    --Met à jour un device numérique Domoticz
    commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|'..tostring(nvalue)..'|'..tostring(svalues)}
end

function UpdateCpt(device,incr)
    -- Met à jour un counter
    -- device : nom du compteur
    -- incr   : Quantité à ajouter au compteur
    
    local Cpt
    
    Cpt = otherdevices_svalues[device]
    Cpt=Cpt or 0 -- Utile pour les compteurs nouvellement crées
    
    commandArray[#commandArray+1] = {['UpdateDevice'] = tostring(otherdevices_idx[device]).."|0|"..tostring(Cpt+incr)}
end

function UpdateP1(device,HC,conso,prod,freq)
    -- Met à jour le 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[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|0|'..tostring(u1+conso*freq/60)..';'..tostring(u2)..';'..tostring(p1+prod*freq/60)..';'..tostring(p2)..';'..tostring(conso)..';'..tostring(prod)}
    else
        commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[device]..'|0|'..tostring(u1)..';'..tostring(u2+conso*freq/60)..';'..tostring(p1)..';'..tostring(p2+prod*freq/60)..';'..tostring(conso)..';'..tostring(prod)}
    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 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 IsAlive(IP)
    if os.capture("ping -qnc 1 -w1 "..IP.." >/dev/null && echo On || echo Off")=="On" then
	return true
    else
        return false
    end
end

Re: nouvelle Gestion piscine

Publié : 07 mars 2020, 20:37
par aleph0
Peux tu nous décrire ce qu'il se passe quand ça ne fonctionne pas ? Quels sont les symptômes ?

Envoyé de mon moto g(6) en utilisant Tapatalk


Re: nouvelle Gestion piscine

Publié : 07 mars 2020, 22:20
par samourai47
Hello
En fait les fonctions calcfiltration et la mise a jour du compteur de consommation. No soucis. Tous les jours à 00h01 et toutes les 5 minutes pour le second 24/24, meme si la filtration est termine et que donc il affiche 0. le capteur est valide toutes les 5 mn

Pour la fonction chkfiltration elle va fonctionner pendant un certain temps (calcul et mises a jour des devices) puis ces mises a jour ne vont plus se faire. Ca peut intervenir n'importe quand et je me suis retrouve avec des filtrations de 2 h qui en ont duré 24..; et puis ca repart tout seul. ET ceci depuis mes premiers essais avec ton script aleph0 et maintenant celui de mickael. Meme probleme mais sans symptome...
Par exemple aujourd hui il s'est arrete de mettre a jour à 19h41 et depuis plus de calcul
par contre le script est bien lance
22:01:00.448 Status: LUA: Script Piscine : Gestion de la filtration

C'est un vrai mystère et à priori un autre a essaye ton script et rencontre le meme probleme
Mois je persiste depuis des mois mais je n'ai aucune piste....

Re: nouvelle Gestion piscine

Publié : 08 mars 2020, 06:59
par denis_brasseur
Quelques print bien placé devrait permettre d'y voir plus clair, avant les conditions de préférence :

Code : Tout sélectionner

print('(MinDuJour) '..MinDuJour..' >= (PpeStart) '..PpeStart ..' and (PpeFait) '..PpeFait..' < (PpeDuree) '..PpeDuree..' and (val_PpeFl) '..val_PpeFl..' == Off')
if (MinDuJour >= PpeStart and PpeFait < PpeDuree and val_PpeFl == "Off") then

Re: nouvelle Gestion piscine

Publié : 08 mars 2020, 09:01
par samourai47
Pour ce matin
Dernière mise a jour du device "Status de filtration"hier à 19h41...
ceux de 00h01 et celui du compteur d'ernergie tournent sans soucis

Depuis le début le script etait de type Time. Je l'ai passé en mode "All" comme précisé par mickael30; Rien changé

Comme le script est en phase "je fonctionne quand je veux"..... Le print demandé n'est pas executé

Code : Tout sélectionner

 2020-03-08 08:54:00.367 Status: LUA: Script Piscine : Gestion de la filtration
2020-03-08 08:54:00.367 Status: LUA: Température de la piscine : 6.7 °C
2020-03-08 08:54:02.152 Status: LUA: Script Piscine : Gestion de la filtration
2020-03-08 08:54:02.153 Status: LUA: Température de la piscine : 6.7 °C 
J'ai rajouté un print juste au dessus à val Teau
Ca s'affiche bien. C'est après que pour le moment plus rien ne s'affiche, mais a un moment ca risque de repartir sans rien changer
J'ai mis une filtration minimum de 2h /24 dans cette ligne

Code : Tout sélectionner

dureeFiltration=round(60*math.max(2,cst_Adj*cst_Pisc_V/cst_PpeFl_Qn*((val_TEau))-10),0)
Donc mes varibles du jour ont
Début 12h17
Duree 120 mn

Ca me prends le tete depuis des semaines, mais j'aimerai bien trouver la solution, avec de l'aide car seul je ne comprends pas cette panne aleatoire

Re: nouvelle Gestion piscine

Publié : 08 mars 2020, 11:15
par mickaelr30
bonjour,
curieux, chez moi dans l'ensemble ça fonctionne bien.

Re: nouvelle Gestion piscine

Publié : 08 mars 2020, 12:35
par samourai47
aujourd'hui il a bien démaré a l'heure dite et pour l'instant les calculs de temps de fliltration se font bien. J'ai mis toute les minutes

Code : Tout sélectionner

 2020-03-08 12:26:52.250 Status: EventSystem: Script event triggered: Nouvelle Filtration 2
2020-03-08 12:26:53.061 Status: LUA: Script Piscine : Gestion de la filtration
2020-03-08 12:26:53.061 Status: LUA: Température de la piscine : 14.0 °C
2020-03-08 12:26:53.061 Status: LUA: val_TEau 14
2020-03-08 12:26:53.102 Status: LUA: Effectué : 10 minutes sur 120
2020-03-08 12:26:53.102 Status: LUA: Reste : 110
2020-03-08 12:26:53.103 Status: LUA: (MinDuJour) 746 >= (PpeStart) 737 and (PpeFait) 10 < (PpeDuree) 120 and (val_PpeFl) On == Off 
Mais je confirme a mickael30 que c'est très bizarre
Sous buster, mais c'etait pareil avant sous strech et la derniere release de domoticz

Re: nouvelle Gestion piscine

Publié : 08 mars 2020, 15:20
par denis_brasseur
samourai47 a écrit : 08 mars 2020, 09:01

Code : Tout sélectionner

 2020-03-08 08:54:00.367 Status: LUA: Script Piscine : Gestion de la filtration
2020-03-08 08:54:00.367 Status: LUA: Température de la piscine : 6.7 °C
2020-03-08 08:54:02.152 Status: LUA: Script Piscine : Gestion de la filtration
2020-03-08 08:54:02.153 Status: LUA: Température de la piscine : 6.7 °C 
J'ai rajouté un print juste au dessus à val Teau
Ca s'affiche bien. C'est après que pour le moment plus rien ne s'affiche, mais a un moment ca risque de repartir sans rien changer
Ta température est de 6,7 °, la condition ci dessous n'est donc pas respecté :

Code : Tout sélectionner

if (val_TEau >= 12) then
Ca fonctionnait ci dessous, la température étant > à 12 ° (2020-03-08 12:26:53.061 Status: LUA: Température de la piscine : 14.0 °C)
samourai47 a écrit : 08 mars 2020, 12:35 aujourd'hui il a bien démaré a l'heure dite et pour l'instant les calculs de temps de fliltration se font bien. J'ai mis toute les minutes

Code : Tout sélectionner

 2020-03-08 12:26:52.250 Status: EventSystem: Script event triggered: Nouvelle Filtration 2
2020-03-08 12:26:53.061 Status: LUA: Script Piscine : Gestion de la filtration
2020-03-08 12:26:53.061 Status: LUA: Température de la piscine : 14.0 °C
2020-03-08 12:26:53.061 Status: LUA: val_TEau 14

[/quote]


C'est donc ceci qui va être pris en compte, mais seulement si la condition est respectée :
[code]elseif gst_HorsGel then
Tu as défini

Code : Tout sélectionner

local gst_HorsGel = false-- gestion ou non du mode hors gel
Il faut donc regarder dans cette boucle ce qui se passe, si il se passe quelque chose

Code : Tout sélectionner

elseif gst_HorsGel then
	print('test si on est dans la boucle '..gst_HorsGel)
gst_HorsGel étant égal à false, je ne suis pas sur qu'il se passe quelque chose !!

Re: nouvelle Gestion piscine

Publié : 08 mars 2020, 18:18
par samourai47
gst_HorsGel étant égal à false, je ne suis pas sur qu'il se passe quelque chose !!

Je vais vérifier, mais je ne pense pas que ce soit le soucis.
La fonction "Chkfiltration" fonctionne parfois, démarre a l'heure ou pas, termine ou pas le cycle de filtration
De plus j'ai défini une durée de 2h de filtration minimum dans la ligne

Code : Tout sélectionner

dureeFiltration=round(60*math.max(2,cst_Adj*cst_Pisc_V/cst_PpeFl_Qn*((val_TEau))-10),0)
Donc quelle que soit la temperature il doit demarer un cycle de 2h, enfin il me semble?

Re: nouvelle Gestion piscine

Publié : 09 mars 2020, 05:24
par denis_brasseur
samourai47 a écrit : 08 mars 2020, 18:18
Donc quelle que soit la temperature il doit demarer un cycle de 2h, enfin il me semble?

Code : Tout sélectionner

if (val_TEau >= 12) then
            -- La témpérature d'eau est >=12°C : on utilise la temporisation