dzVents - gérer la mise à jour des variables (user et data)

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 <\>.
lamaisondelou69
Messages : 24
Inscription : 16 mars 2020, 18:58

dzVents - gérer la mise à jour des variables (user et data)

Message par lamaisondelou69 »

Bonjour,

Je débute en dzVents. J'ai cru comprendre que chaque mise à jour de devices, variables, etc.. engendre le redémarrage du script. Et ça me pose un problème.
Mon cas concret :
- j'ai créé un capteur Arduino avec détecteur de mouvement (DP) et photo resistance (CP)
- dans le sketch Arduino, l'info du DP est instantanément mise à jour par interruption. La CP est mise à jour toutes les 30 secondes.
- le sketch Arduino est celui de mysensors adapté pour multi-capteurs.
- je règle la temporisation du DP dans le script dzVents dans Domoticz (90 secondes)

La valeur mesurée par la CP toutes les 30 secondes est un peu aléatoire (genre 100 - 120 - 50 - 95 - 110...) fiable quand on regarde un log sur 24 heures, mais instable. (faut pas trop en demander à un composant à quelques centimes d'euros...). Mais suffisant pour mon besoin (suivre l'évolution de la luminosité extérieure).

Je pensais régler la question de ces sautes de mesures par un lissage sur 5 à 10 valeurs. Je parviens à établir une moyenne avec le script ci-dessous.

Code : Tout sélectionner

return {
	on = {
		devices = {
		    'EXT_CP'
		    },
		timer = {},
		variables = {
		    'MOY_EXT_CP'
		    },
		scenes = {},
		groups = {},
		security = {},
		httpResponses = {},
		customEvents = {},
		system = {},
	},
	data = {
	    VAL_EXT_CP = {history = true, maxItems = 10}
	    },
	logging = {
	    level = domoticz.LOG_DEBUG,
        marker = "EXT-LUMINOSITE"
	    },
	execute = function(domoticz, devices)
        domoticz.data.VAL_EXT_CP.add(devices.lux)
	    MOYENNE = domoticz.data.VAL_EXT_CP.avg()
	    domoticz.variables('MOY_EXT_CP').set(MOYENNE)
	    
	end
}
Le problème intervient quand je veux mixer ça avec mon script pour le DP : comme la moyenne est recalculée toutes les 30 secondes, ça reset ma temporisation de 90 secondes du détecteur de mouvement (qui du coup ne s'éteint plus jamais...)
Je parviens à gérer la valeur instantanée de la CP mise à jour toutes les 30 secondes avec le code ci-dessous :

Code : Tout sélectionner

return {
	on = {
		devices = {
		    'RDC_CH1_ECL_GEN',
		    'RDC_CH1_DP'
		    },
		timer = {},
		variables = {},
		scenes = {},
		groups = {},
		security = {},
		httpResponses = {},
		customEvents = {},
		system = {},
	},
	data = {},
	logging = {
	    level = domoticz.LOG_DEBUG,
        marker = "RDC-CH1-Eclairage"
	    },
	execute = function(domoticz, devices)
        -- variables modifiables
        local LUX_LIMIT = 50       -- niveau d'éclairement
        local TEMPO = 90           -- temporisation détecteur de mouvement en secondes
        local AJOUT_LUX = 150       -- estimation de l'apport de l'éclairage artificiel
        
        -- variables programme
        local LUX_ACTUAL = domoticz.devices('RDC_CH1_CP').lux -- Récupère la valeur de la CP
        local DP = domoticz.devices('RDC_CH1_DP')               -- définit l'abréviation DP
        local LPE = domoticz.devices('RDC_CH1_ECL_GEN')         -- définit l'abréviation LPE
        
        -- programme
        if domoticz.devices('RDC_CH1_ECL_GEN').lastUpdate.secondsAgo > 30 then
            LAST_LUX = LUX_ACTUAL
        else
            LAST_LUX = LUX_ACTUAL - AJOUT_LUX
        end
        if LAST_LUX <= LUX_LIMIT then
            if DP.state == 'On'and LPE.state == 'Off' then
                -- on détecte un mouvement et la lampe est éteinte
                LPE.switchOn().checkFirst()
            elseif DP.state == 'On' and LPE.state == 'On' then
                -- on détecte un nouveau mouvement et la lampe est allumée
                LPE.switchOn().checkFirst()
            end
        end
        if DP.state == 'Off' and LPE.state == 'On' then
                -- plus de mouvement, et la lampe est allumée
                LPE.switchOff().afterSec(TEMPO).checkFirst()
                -- on éteint la lampe après la temporisation
        end
	end
}
Mais impossible d'intégrer le calcul de moyenne là-dedans.

Donc ma question est :
comment utiliser la valeur moyenne de ma CP sans qu'elle reset mon script du DP ?
- via les global_data ?
- via un script séparé ?
- via une fonction ?

Merci d'avance de votre aide !
lamaisondelou69
Messages : 24
Inscription : 16 mars 2020, 18:58

[RESOLU] dzVents - gérer la mise à jour des variables (user et data)

Message par lamaisondelou69 »

Je me réponds.
En fait mon problème venait d'une incompréhension du fonctionnement de dzvents.
En gros, seuls les éléments indiqués dans la partie On {} vont déclencher le script.
Donc, pour ma question, j'ai créé une variable dans la partie Data {}, et celle-ci ne déclenche pas le script.

Pour info, j'ai une installation avec Domoticz sur Raspberry, un composant photoresistance raccordé à un Arduino avec Shield Ethernet et programme basé sur mysensors. Les mesures de ma photoresistance sont mises à jour toutes les 30 secondes.
Mon problème venait que les valeurs renvoyées par la photoresistance avaient de fortes variations (un lissage sur 24h ou plus est représentatif de l'évolution de luminosité naturelle, mais sur une période plus courte (de l'ordre de la minute), les valeurs étaient inutilisables.
Ce problème étant inhérent au montage avec le composant (il faudrait tester un composant pré-monté type LM393 s'il est plus précis), j'ai résolu mon souci en créant une moyenne dans dzvents. Je prends les 10 dernières valeurs, et je fais la moyenne, ce qui me donne une valeur plus précise.

Ci-dessous le script qui permet d'allumer/éteindre une lampe (un relais arduino) selon la luminosité et la détection de mouvement (avec luminosité et temporisation réglables) :

Code : Tout sélectionner

return {
	on = {
		devices = {
		    'RDC_CH1_ECL_GEN',
		    'RDC_CH1_DP'
		    },
		timer = {},
		variables = {},
		scenes = {},
		groups = {},
		security = {},
		httpResponses = {},
		customEvents = {},
		system = {},
	},
	data = {
	    VAL_CP_RDC_CH1 = { history = true, maxItems = 10 },
	    VAL_CP_EXT = { history = true, maxItems = 10 }
	    },
	logging = {
	    -- level    =   domoticz.LOG_DEBUG,                -- Seulement un niveau peut être actif; commenter les autres
        -- level    =   domoticz.LOG_INFO,              -- Only one level can be active; comment others
         level    =   domoticz.LOG_ERROR,
        -- level    =   domoticz.LOG_MODULE_EXEC_INFO,
        marker = "RDC-CH1-Eclairage"
	    },
	execute = function(domoticz, devices)
        -- variables modifiables
        local LUX_LIMIT = 50       -- niveau d'éclairement intérieur
        local TEMPO = 90           -- temporisation détecteur de mouvement en secondes
        local LUX_EXT = 50         -- niveau d'éclairement extérieur
        
        -- variables programme
        local LUX_ACTUAL = domoticz.devices('RDC_CH1_CP').lux 
        local DP = domoticz.devices('RDC_CH1_DP')               -- définit l'abréviation DP
        local LPE = domoticz.devices('RDC_CH1_ECL_GEN')         -- définit l'abréviation LPE
        if LPE.state == 'Off' then
            domoticz.data.VAL_CP_RDC_CH1.add(domoticz.devices('RDC_CH1_CP').lux)    -- Récupère la valeur de la CP uniquement si la lampe est éteinte.
        end
        local MOY_CP_RDC_CH1 = domoticz.data.VAL_CP_RDC_CH1.avg()   -- calcule la moyenne des 10 dernières valeurs de la CP (permet de lisser les résultats)
        domoticz.data.VAL_CP_EXT.add(domoticz.devices('EXT_CP').lux)
        local MOY_CP_EXT = domoticz.data.VAL_CP_EXT.avg()
        
        if MOY_CP_RDC_CH1 <= LUX_LIMIT or MOY_CP_EXT < LUX_EXT then
            if DP.state == 'On'and LPE.state == 'Off' then
                -- on détecte un mouvement et la lampe est éteinte
                LPE.switchOn().checkFirst()
            elseif DP.state == 'On' and LPE.state == 'On' then
                -- on détecte un nouveau mouvement et la lampe est allumée
                LPE.switchOn().checkFirst()
            end
        end
        if DP.state == 'Off' and LPE.state == 'On' then
                -- plus de mouvement, et la lampe est allumée
                LPE.switchOff().afterSec(TEMPO).checkFirst()
                -- on éteint la lampe après la temporisation
        end
	end
}
Répondre