Domotique Piscine

Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
aleph0
Messages : 328
Inscription : 27 avr. 2016, 08:06
Localisation : Hérault (34)

Re: Domotique Piscine

Message par aleph0 »

Dans la fonction CalcFiltration(), il te manque les deux lignes suivantes

Code : Tout sélectionner

    HDebFilt=os.date("%H:%M", DebutFiltration*60-3600)
    print("Début de filtration : "..HDebFilt)
juste avant le

Code : Tout sélectionner

UpdateVar(var_PPStart,HDebFilt)
Gardaux
Messages : 109
Inscription : 05 oct. 2017, 13:42
Localisation : Bouches du Rhône

Re: Domotique Piscine

Message par Gardaux »

Génial merci beaucoup Aleph0 ;)
---------------------------------------------------------------------------------------------------
Domoticz + Raspberry Pi3 x2 + RFXCOM (IFTTT)
Domoticz + Synology + RFLink
multinet
Messages : 24
Inscription : 09 févr. 2016, 13:07

Re: Domotique Piscine

Message par multinet »

Bonjour

Quelqu'un pourrait il me dire ou se trouve le bug dans le scripts (ci dessous) qui fait que tous les jours à minuit j'ai le compteur d'utilisation qui est a 18 446 744 07, 709 552 000 minutes ?
Capture d’écran 2018-07-14 à 11.39.43.jpg
Capture d’écran 2018-07-14 à 11.39.43.jpg (68.01 Kio) Consulté 6854 fois

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 = true                            -- gestion ou non du mode hors gel

local dev_TAir    = "Jardin"                        -- Température extérieure (nécessaire seulement pour le mode hors gel)
local dev_TEau    = "Piscine"                       -- Température eau piscine
local dev_PpeFl   = "Filtration Piscine #3 (B+)"    -- Interrupteur de commande de la pompe
local dev_ModeFl  = "Mode filtration piscine"       -- Selecteur du mode de la pompe (Manuel/Auto HC/AutoHP)
local dev_cptFl   = "Consommation Piscine"          -- Compteur de consommation électrique piscine
local dev_DureeFl = "Compteur piscine"              -- Compteur de fonctionnement de la pompe en minutes
local dev_HP      = "EDF Heures pleines"            -- Indicateur d'heure pleine EdF

local tps_Fl      = "Temps filtration"              -- Capteur texte pour afficher le temps de filtration
local rest_Fl     = "Restant filtration"            -- Capteur texte pour afficher le temps restant de filtration
local heure_Fl    = "Debut filtration"              -- Capteur texte pour afficher l'heure de début de filtration

local var_PPStart = "HeureFiltration"               -- Variable contenant l'heure de départ de la filtration
local var_PPDuree = "DureeFiltration"               -- 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 (6)
local cst_Pisc_V   =18     -- volume du bassin, en m3 (18)
local cst_Adj      =0.250  -- Coefficient à ajuster en + ou en - pour filtrer plus ou moins longtemps (0.250)
local cst_PpeFl_W  =500    -- Puissance électrique de la pompe piscine (500)
local cst_MinFiltr =30

-- TELEGRAM settings
telegram_token = "*****HIDDEN******"
telegram_chatid = -000000

--Debug settings
local LOGGING = true
local version = 'Piscine Filtration v0.0.1 du 2018/05'

function telegram(message)
    os.execute('curl --data chat_id='..telegram_chatid..' --data-urlencode "text='..message..'"  "https://api.telegram.org/bot'..telegram_token..'/sendMessage" ')
end     


-- -------------------------------
-- Bibliothèque de fonctions
-- -------------------------------
local CmdIdx=1
local CompteurMin=0
local debug=1

function isempty(s)
  return s == nil or s == ''
end

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,HP,conso,prod,freq)
    -- Met à jour un P1 smart counter
    -- device : nom du compteur
    -- HP     : "On" si heures pleines, "Off" si heures creuses
    -- conso  : consommation instantannée
    -- prod   : production instantannée
    -- freq   : frequence d'exécution du script (en minutes) 
    
    local u1, u2, p1, p2
    local dbg=1
    
    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[HP] == 'On' 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
    local dbg=1
    
    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 
   
   -- Si la duree de filtration < cst_MinFiltr (cas de l'eau <10°C avec mes parametres) alors on force la durée mini
    if (dureeFiltration < cst_MinFiltr) then
        dureeFiltration=cst_MinFiltr
    end    
    
    
    
    print("Durée de filtration : "..dureeFiltration.." min")
    commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[tps_Fl]..'|0|'..tonumber(dureeFiltration)..' min'}
    CmdIdx=CmdIdx+1
    
    if otherdevices[dev_ModeFl] == "AutoHC" then
        -- Mode Auto Heures Creuses
        -- On filtre jusqu'à 6h30 si possible (=390 min), et on déborde si nécessaire
        DebutFiltration=math.max(10,((6*60)+30)-dureeFiltration)
    else
        -- Mode Auto Heures Pleines ou Manuel
        -- 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)
    commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[heure_Fl]..'|0|'..HDebFilt}
    CmdIdx=CmdIdx+1
    
    -- email
    today=os.date("%A %e %B %Y")
    commandArray['SendEmail']='Filtration de la piscine du '..today..'#Température moyenne de la veille : '..val_TEau..' °C\n\rDurée de filtration nécessaire : '..dureeFiltration..' minutes\n\nDébut de filtration à : '..HDebFilt..' ('..otherdevices[dev_ModeFl]..')#nicolas.rebillard@gmail.com'

    --notification TELEGRAM
    msg = version..'\n\rFiltration de la piscine du '..today..'\n\r\n\rTempérature moyenne de la veille : '..val_TEau..' °C\n\r\n\rDurée de filtration nécessaire : '..dureeFiltration..' minutes\n\nDébut de filtration à : '..HDebFilt..' ('..otherdevices[dev_ModeFl]..')'
    telegram(msg)
        
    -- Mise à jour des variables utilisateurs
    UpdateVar(var_PPStart,HDebFilt)
    UpdateVar(var_PPDuree,dureeFiltration)
end

function ChkFiltration()
    --[[Gestion de la filtration (Mode de la filtration Off / Manuel / Auto HC / Auto HP)

    Start / Stop de la pompe
    --]]

    local Min_last_stop=23*60+45       -- Heure maxi pour arrêter la filtration en minute
    local dbg=0
    local PpeRest
    
    print("Script Piscine : Gestion de la filtration")

    PpeDuree=tonumber(uservariables[var_PPDuree])
    val_ModeFl=otherdevices[dev_ModeFl]
    val_PpeFl=otherdevices[dev_PpeFl]
    if (otherdevices[dev_ModeFl] ~= "Manuel") and (otherdevices[dev_ModeFl] ~= "Off") then
        --val_TEau = tonumber(string.match(otherdevices_svalues[dev_TEau],"(%d+.%d*);.*"))
        val_TEau=tonumber(otherdevices_svalues[dev_TEau])
        
        if (val_TEau >= 12) then
            print("---Temperature de la piscine : "..tostring(val_TEau))
            -- 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
            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..'\'"')
            if (isempty(PpeFait) or (PpeFait==18446744073709552000) ) then
                PpeFait=0
            else    
                PpeFait=tonumber(PpeFait)*5/cst_PpeFl_W 
            end
            print("Déjà effectué : "..PpeFait.." minutes sur "..PpeDuree)
            
            -- Calcul du temps restant de filtration
            PpeRest=PpeDuree-PpeFait
            if (PpeRest > 0) then
                print("Temps restant de filtration : "..PpeRest.." minutes ")
                commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[rest_Fl]..'|0|'..tonumber(PpeRest)..' min'}
                CmdIdx=CmdIdx+1
            else 
                print("Filtration finie")
                commandArray[CmdIdx] = {['UpdateDevice'] = otherdevices_idx[rest_Fl]..'|0|'..'Arrêtée'}
                CmdIdx=CmdIdx+1            
            end
            
            -- Mise à jour du capteur loggant la durée de filtration, en minutes
            UpdateDev(dev_DureeFl,0,tonumber(PpeFait))
            
            if dbg == 1 then 
                print("PpeStart : "..PpeStart)
                print("PpeFait : "..PpeFait)
                print("PpeDuree : "..PpeDuree)
                print("val_PpeFl : "..val_PpeFl)            
            end
            if (MinDuJour >= PpeStart and PpeFait < PpeDuree and val_PpeFl == "Off") then
                print("Filtration piscine : Démarrage par timer")
                telegram('Demarrage de la filtration piscine par timer')
                UpdateSw(dev_PpeFl,'On')
                --UpdateDev(dev_Status,0,"Démarrage par timer")
            elseif (PpeFait >= PpeDuree or MinDuJour>=Min_last_stop) and (val_PpeFl == "On") then
                print("Filtration piscine : Arrêt par timer")
                telegram('Arrêt de la filtration piscine par timer')
                --UpdateDev(dev_Status,0,"Arrêt par timer")
                UpdateSw(dev_PpeFl,'Off')
            end
            
        else -- temp eau < 12°C et AutpHP ou AutoHC
          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
                -- Filtration On
                print("Filtration piscine : Démarrage par température")
                telegram('Demarrage de la filtration piscine par température (mode hors-gel)')
                --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
                -- Filtration Off
                print("Filtration piscine : Arrêt par température")
                telegram('Arrêt de la filtration piscine par température (mode hors-gel)')
                --UpdateDev(dev_Status,0,"Arrêt par température")
                UpdateSw(dev_PpeFl,'Off')
            end
          end -- gst_horsGel
        end -- filtration timer/temperature 
    elseif (otherdevices[dev_ModeFl] == "Manuel") then 
        if (otherdevices[dev_PpeFl] == "On") then
            -- Calcul de la durée de fonctionnement de la pompe aujourd'hui
            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
            
            -- Mise à jour du capteur loggant la durée de filtration, en minutes
            print("Filtration piscine : mode Manuel et filtration ON -> mise a jour du compteur de minutes")
            UpdateDev(dev_DureeFl,0,tonumber(PpeFait))
        else
            print("Filtration piscine : mode Manuel et filtration OFF -> pas de changement")
        end
    else -- Mode Off
        if (otherdevices[dev_PpeFl] == "On") then
            print("Filtration piscine : consigne utilisateur OFF")
            UpdateSw(dev_PpeFl,'Off')   
        else
            print("Filtration piscine : consigne OFF et deja en OFF")
        end
    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

--DEBUG CalcFiltration()

-- Marche/Arrêt de la pompe de filtration toutes les minutes
if (((time.min-1) % 1)== 0) then ChkFiltration() end

-- DEBUG ChkFiltration()

-- Mise à jour du compteur de consommation de la piscine toutes les 5min
if (((time.min-2) % 5)== 0) then 
    UpdateP1(dev_cptFl,dev_HP,ConsoDev(dev_PpeFl,cst_PpeFl_W,0),0,5)
end

return commandArray 
C'est visiblement dans la fonction CalcFiltration() ; J'ai cherché sans succes

Meric pour votre aide :)

Multinet
Invité

Re: RE: Re: Domotique Piscine

Message par Invité »

[quote="multinet"]Bonjour

Quelqu'un pourrait il me dire ou se trouve le bug dans le scripts (ci dessous) qui fait que tous les jours à minuit j'ai le compteur d'utilisation qui est a 18 446 744 07, 709 552 000 minutes ?

Multinet[/quote]

Tu n'aurais pas fait une mise à jour vers la dernière version stable par hasard ? J'ai le même problème sur un compteur d'eau depuis la mise à jour : cette valeur s'affiche jusqu'à ce que la consommation (ou utilisation dans ton cas) soit non nulle. Je pense que ça sera corrigé dans une des prochaines versions de Domoticz
MAidEN91
Messages : 132
Inscription : 01 sept. 2015, 20:50

Re: Domotique Piscine

Message par MAidEN91 »

Hello,

Je détartre le post :D

J'essaye de récupérer ce script pour l'adapter sur ma filtration mais je ne parviens pas à le faire tourner :cry:

Mes 2 variables (var_PPDuree et var_PPStart) sont bien créées.

Voici le code

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
    
1/ Les devices :
- dev_Tair et dev_Teau de type thermomètres, ras
- dev_PpeFl : le switch qui commande la pompe de filtration , de type On/Off
- dev_ModeFl : un interrupteur selecteur pour le mode de filtration. Doit contenir 4 niveaux :
* Off (Caché)
* Manu (Level 10) Dans ce mode, le script fait seulement les calculs de durée et de début, mais ne gère pas la pompe
* Auto HC (Level 20) pour filtration en heures creuses
* Auto HP (Level 30) pour filtration en journée 
- dev_HC : Un switch on/off avec planning pour indiquer les heures pleines ou creuses (On=HC, Off=HP)
- dev_cptFl : Un P1 smart counter pour comptabiliser la consommation électrique de la pompe

Le script a été conçu pour qu'on puisse à tout moment prendre la pompe en manuel (pour passer l'aspirateur, nettoyer les filtres, etc) et faire ce qu'on veut (arrêter, démarrer comme on veut) et, lorsqu'on repasse en mode automatique, il reprends la filtration là où elle avait élé laissée. Il faut donc un compteur qui stocke le temps de filtration effectué chaque jour pour pouvoir le comparer au temps calculé à minuit. La version la plus simple aurait été d'accumuler des minutes dans une variable. Mais finalement, la gestion qui consiste plutôt à accumuler des kWh dans un compteur n'est pas beaucoup plus compliquée, et elle donne l'avantage d'avoir un historique de la filtration ainsi que les rapports de coûts de celle-ci. C'est pour ça que j'ai choisi un compteur électrique plutôt qu'un compteur de minutes. En divisant les kWh par la puissance de la pompe, on retrouve la durée de filtration effectuée.

2/ Les variables :
2 variables à définir :
- var_PPStart, de type "Heure" stocke l'heure de début de filtration calculée à minuit
- var_PPDuree, de type "Entier" stocke la durée de filtration calculée, en minutes

3/ Les constantes
Elles servent à calculer la durée de filtration en fonction des caractéristiques du bassin et de la pompe :
- cst_PpeFl_Q Le débit nominal de la pompe de filtration en m3/h
- cst_Pisc_V Le volume du bassin, en m3
- cst_PpeFl_W La puissance électrique de la pompe piscine, pour pouvoir calculer la durée de filtration quotidienne ainsi que la consommation électrique correspondante
- cst_Adj Un coefficient à ajuster en + ou en - pour filtrer plus ou moins longtemps
    
    
--]]

-- Paramètres
local dbPath      = "/home/pi/domoticz/domoticz.db"
local gst_HorsGel = false                   -- gestion ou non du mode hors gel

local dev_TAir    = "Température"           --"Température Extérieure"  					idx 307 	-- Température extérieure (nécessaire seulement pour le mode hors gel)
local dev_TEau    = "T° Piscine"            --"Température piscine"     					idx 276		-- Température eau piscine
local dev_PpeFl   = "Pompe"                 --"Filtration piscine"      					idx 333		-- Interrupteur de commande de la pompe
local dev_ModeFl  = "Auto_HC/HP"            --"Mode filtration piscine"						idx 327		-- Selecteur du mode de la pompe (Manu/Auto HC/AutoHP)
local dev_cptFl   = "Conso_Piscine"         --"Consommation Piscine"    					idx 328  	-- Compteur de consommation électrique piscine
local dev_HC      = "Témoin_HC"             --"Heures creuses EDF"      					idx 22   	-- Indicateur d'heure creuses EdF
local tps_Fl      = "Temps filtration"      -- Capteur texte pour afficher le temps de filtration		idx 329
local rest_Fl     = "Restant filtration"    -- Capteur texte pour afficher le temps restant de filtration	idx 330
local heure_Fl    = "Debut filtration"      -- Capteur texte pour afficher l'heure de début de filtration	idx 331
local fin_Fl      = "Fin filtration"   	    -- Capteur texte pour afficher l'heure de fin de filtration		idx 332

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=30               -- Débit nominal de la pompe de filtration en m3/h
local cst_Pisc_V  =45               -- 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 =1500              -- 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)
    val_TEau=tonumber(otherdevices_svalues[dev_TEau])
    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


    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(match(otherdevices_svalues[dev_TEau],"(.-);.*"))
        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)
         
            -- Calcul du temps restant de filtration
            PpeRest=PpeDuree-PpeFait
            if (PpeRest > 0) then
                print("Temps restant de filtration piscine : "..PpeRest.." minutes ")
                commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[rest_Fl]..'|0|'..tonumber(PpeRest)..' min'}
            else 
                print("Filtration piscine finie")
                commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[rest_Fl]..'|0|'..'Arrêtée'}
            end
            
                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
            
            -- Calcul de l'heure de début de filtration
            HDebFilt=os.date("%H:%M", PpeStart*60-3600)
            print("Début de filtration : "..HDebFilt)
            commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[heure_Fl]..'|0|'..HDebFilt}
            
            -- Calcul de l'heure de fin de filtration
            HFinFilt=os.date("%H:%M", ((PpeStart*60-3600)+(PpeDuree*60)))
            print("Fin de la filtration a : "..HFinFilt)
            commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[fin_Fl]..'|0|'..HFinFilt}
         
        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 
Et voici l'erreur quand je le lance :

Code : Tout sélectionner

2019-06-02 19:22:00.080 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_piscine.lua: /home/pi/domoticz/scripts/lua/script_time_piscine.lua:117: bad argument #1 to 'match' (string expected, got nil)
La ligne 117 correspond à :

Code : Tout sélectionner

u1, u2, p1, p2 = string.match(otherdevices_svalues[device],"(.-);(.-);(.-);(.-);.*")
J'ai essayé en virant le "string." avant le match mais pareil :roll:

Si un dev charitable à une idée pour dépanner ça serait top! :mrgreen:
mickaelr30
Messages : 210
Inscription : 29 août 2015, 15:57

Re: Domotique Piscine

Message par mickaelr30 »

bonsoir,
as-tu installé la dépendance sqlite3 ?
Domoticz + Imperihome + Mydomoathome
1-wire : 12 DS18b20 + 3 DS2413
Z-Wave : 8 FGR221 + 3 FGS222 + 3 FGSD002
téléinfo : 2 modules ( consommation + production)
Mysensors+2 éclairages ws2812 et WLED
2 caméra IP +1 raspberry piscine + 1 nuc domoticz
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: Domotique Piscine

Message par denis_brasseur »

MAidEN91 a écrit : 02 juin 2019, 19:32 Hello,

Je détartre le post :D
....................................
Et voici l'erreur quand je le lance :

Code : Tout sélectionner

2019-06-02 19:22:00.080 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_piscine.lua: /home/pi/domoticz/scripts/lua/script_time_piscine.lua:117: bad argument #1 to 'match' (string expected, got nil)
La ligne 117 correspond à :

Code : Tout sélectionner

u1, u2, p1, p2 = string.match(otherdevices_svalues[device],"(.-);(.-);(.-);(.-);.*")
J'ai essayé en virant le "string." avant le match mais pareil :roll:

Si un dev charitable à une idée pour dépanner ça serait top! :mrgreen:
SI tu fais

Code : Tout sélectionner

print(otherdevices_svalues[device])
qu'obtiens-tu ?
Tu devrais obtenir tes 4 valeurs u1, u2, p1, p2 séparé par un point virgule.
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
MAidEN91
Messages : 132
Inscription : 01 sept. 2015, 20:50

Re: Domotique Piscine

Message par MAidEN91 »

mickaelr30 a écrit : 02 juin 2019, 21:44 bonsoir,
as-tu installé la dépendance sqlite3 ?
Oui j'ai la version SQLite version 3.8.7.1 d'installé
MAidEN91
Messages : 132
Inscription : 01 sept. 2015, 20:50

Re: Domotique Piscine

Message par MAidEN91 »

SI tu fais

Code : Tout sélectionner

print(otherdevices_svalues[device])
qu'obtiens-tu ?
Tu devrais obtenir tes 4 valeurs u1, u2, p1, p2 séparé par un point virgule.
J'ai ajouté la ligne juste au dessus dans mon script mais je n'ai rien qui s'affiche dans les logs à part mon message d'erreur, comment faire pour tester le résultat du print?
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: Domotique Piscine

Message par denis_brasseur »

la mesure est effectué par un P1 smart counter pour comptabiliser la consommation électrique de la pompe.

Son nom est défini ligne 46

Code : Tout sélectionner

local dev_cptFl   = "Conso_Piscine"
Tu dois modifié, si ce n'est pas déjà fait, le nom du device "Conso_Piscine", pour qu'il corresponde au nom de ton device.
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
Répondre