Page 1 sur 1

[Résolu] Comment faire une "double" boucle dans une collection de capteurs ?

Publié : 16 mai 2021, 13:12
par Greg.O
Bonjour à tous,

je sollicite aujourd'hui l'expertise des codeurs en Dzvents car je suis bloqué sur un problème. En effet, j'ai un script déjà développé en Dzvents qui me permet de calculer l'humidité absolue dans mes 3 salles de bain. Ces scripts récupèrent les données de chaque capteur de temp/hum placé dans chaque pièce. Ensuite, rien de bien compliqué : je mets à jour un custom sensor pour afficher cette humidité absolue :

Code : Tout sélectionner

local temperature1 = domoticz.devices(device_temp1).temperature
local humidity1 = domoticz.devices(device_hum1).humidity
local absHumidity1 = HumAbs(temperature1, humidity1) 

domoticz.devices(device_hum_abs1).updateCustomSensor(absHumidity1)
Aujourd'hui, je répète ce bout de code 3 fois, en changeant le nom de mon device à chaque fois et ça fait le job.

Pour développer mes compétences en Dzvents j'aimerais réaliser la même chose, mais en utilisant la possibilité de boucler dans une collection (loop through the collections : je le précise, car je ne suis pas sûr de ma traduction : https://www.domoticz.com/wiki/DzVents:_ ... _iterators), J'aimerais donc pouvoir faire :

Pour chaque (custom sensor HumAbs_i) -> récupérer temp_i et hum_i -> calculer HumAbs_i -> mettre à jour le custom sensor.

Voici ma première idée :

Code : Tout sélectionner

local capteur = {
        'capteur1',  -- capteur physique placé dans une sdb
        'capteur2',
        'capteur3',
    }
local custom = {
	'custom1',  -- custom sensor pour affichage
	'custom2',
	'custom3',
	}
Et j'aimerais chainer en m'inspirant de cet exemple du wiki :

Code : Tout sélectionner

domoticz.devices().filter(function(device)
        return (device.lastUpdate.minutesAgo > 60)
    end).forEach(function(zombie)
        -- do something with the zombie
    end)
Mais : je n'arrive pas à transcrire en code ma pensée.
Est-ce que qqn aurait une idée ?

Re: COmment faire une "double" boucle dans une collection de capteurs

Publié : 16 mai 2021, 13:42
par Keros
J'ai fait quelque chose de similaire :

Code : Tout sélectionner

        local capteur = {}
        capteur[1] = {'capteur 1', 'custom 1'}
        capteur[2] = {'capteur 2', 'custom 2'}
        capteur[3] = {'capteur 3', 'custom 3'}
    
        for variable,sonde in pairs(capteur) do 
            temp = domoticz.devices(sonde[1]).temperature
            domoticz.devices(sonde[2]).updateCustomSensor(temp)
        end
Pour expliquer, je remplis chaque case du tableau capteur avec un tableau comportant le nom du capteur et son virtuel associé. Je boucle sur le tableau capteur pour récupérer les deux valeurs associées.
Ne me demande pas à quoi correspond variable, je n'ai pas compris. J'aurais pu écrire toto ...

Re: COmment faire une "double" boucle dans une collection de capteurs

Publié : 16 mai 2021, 14:56
par boum
La boucle for key,value in pairs(aTable) va itérer pour chacune des paires (key, value). Dans la table de l'exemple de Keros, elle sera répétée 3 fois. Une fois avec 1 pour key et {'capteur 1', 'custom 1'} pour value.

:!: L'ordre d'itération ne sera peut-être pas celui de déclaration. Pour garantir l'ordre dans ce cas, il faut for key,value in ipairs(aTable). ipairs déroulera uniquement les éléments ayant un index numérique et dans l'ordre 1, 2, 3…

Quand on ne sert pas de l'index, on peut utiliser n'importe quel nom. L'usage est d'utiliser _.

Deux variations sur le même thème :

Code : Tout sélectionner

    -- Variante 1, table avec sonde comme clef
    local capteurs = {
      ['capteur 1'] = 'custom 1',
      ['capteur 2'] = 'custom 2',
      ['capteur 3'] = 'custom 3',
     }

    for sonde,custom in pairs(capteurs) do 
        local temp = domoticz.devices(sonde).temperature
        domoticz.devices(custom).updateCustomSensor(temp)
    end
        
    -- Variante 2, table  avec clef numérique et champs nommés
    local capteurs2 = {
       { temp = 'capteur 1', custom = 'custom 1' },
       { temp = 'capteur 2', custom = 'custom 2' },
       { temp = 'capteur 3', custom = 'custom 3' },
    }

    for _,sonde in ipairs(capteurs2) do 
        local temp = domoticz.devices(sonde.temp).temperature
        domoticz.devices(sonde.custom).updateCustomSensor(temp)
    end
Dans ce cas, utiliser devices().filter() et forEach() serait moins efficace car le script testera tous les dispositifs pour savoir si le nom est un de ceux qui nous intéresse. Ces fonctions sont plutôt à utiliser quand on ne connait pas le nom des dispositifs ou que l'on veut passer en revue tous les dispositifs.

Re: COmment faire une "double" boucle dans une collection de capteurs

Publié : 16 mai 2021, 15:19
par Keros
Je n'étais pas arrivé à comprendre l'utilité de Key. J'ai compris avec tes explications. Merci ;)

Re: COmment faire une "double" boucle dans une collection de capteurs

Publié : 16 mai 2021, 20:41
par Greg.O
Merci pour vos contributions !

J'ai donc trouvé comment arriver à mes fins :

Code : Tout sélectionner

local capteurs = {
       { temp = 'Temp_SDB_1', hum = 'Humidite_SDB_1', custom = 'Custom_Test' },
       { temp = 'Temperature_SDB_2', hum = 'Humidite_SDB_2', custom = 'Custom_Test_2' },
       { temp = 'Temperature_SDB_3', hum = 'Humidite_SDB_3', custom = 'Custom_Test_3' },
    }
		
function HumAbs(t,hr)
       ha = dz.utils.round((6.112 * math.exp((17.67 * t)/(t+243.5)) * hr * 2.1674)/ (273.15 + t),1)
       return ha
end

for _,sonde in ipairs(capteurs) do 
	local temp = dz.devices(sonde.temp).temperature
	local hum = dz.devices(sonde.hum).humidity
	local huma = HumAbs(temp,hum)
		
	dz.devices(sonde.custom).updateCustomSensor(huma)
		
end
Je ne m'en serais jamais sorti seul !!

Re: COmment faire une "double" boucle dans une collection de capteurs

Publié : 16 mai 2021, 20:45
par Keros
Une troisième façon de l'écrire :mrgreen:

Je l'aime bien, elle se rapproche de la syntaxe DzVents.