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

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 <\>.
Greg.O
Messages : 148
Inscription : 07 oct. 2017, 18:04

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

Message 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 ?
Dernière modification par Greg.O le 10 juil. 2021, 10:22, modifié 2 fois.
Domoticz v2021.1 sur Raspberry Pi 3B+
Raspbian Buster
Capteurs T/Hum Xiaomi / ConBee II
Zwave
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

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

Message 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 ...
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
boum
Messages : 233
Inscription : 18 janv. 2019, 11:34
Localisation : France

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

Message 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.
Dernière modification par boum le 17 mai 2021, 09:08, modifié 1 fois.
Domoticz v2022.2 sur linux-mint / Z-Wave-JS / RFXCom / Zigbee2MQTT
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

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

Message par Keros »

Je n'étais pas arrivé à comprendre l'utilité de Key. J'ai compris avec tes explications. Merci ;)
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
Greg.O
Messages : 148
Inscription : 07 oct. 2017, 18:04

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

Message 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 !!
Domoticz v2021.1 sur Raspberry Pi 3B+
Raspbian Buster
Capteurs T/Hum Xiaomi / ConBee II
Zwave
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

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

Message par Keros »

Une troisième façon de l'écrire :mrgreen:

Je l'aime bien, elle se rapproche de la syntaxe DzVents.
Comment bien utiliser le forum : Poser une question, Mettre un script, un fichier, une image ou des logs
Mes petits guides : Débuter en programmation, Le débogage, Le choix de matériel, Les sauvegardes
Ma présentation - Mes Tutos
Répondre