Aller au contenu

LUA : Variable Table contenant elle-même une table ?


Messages recommandés

Posté(e) (modifié)

Bonsoir à tous,

 

Je me tourne une fois de plus vers vous pour quémander votre grande sagesse et surtout quelques bribes de vos grandes connaissances.

 

Je cherche à simplifier/optimiser mes scènes de pièce.

Depuis mes premiers posts, j'ai considérablement évolué dans l'apprentissage du LUA, mais là, je suis au point mort...

 

À l'origine, à chaque début de ces scènes, j'avais déclaré plusieurs variables de table que j'exploitais ensuite.

 

local liste_pieces = {"ENTREE","WC","SDB","SEJOUR","CUISINE","CHAMBRE"};

local ID_REGLAGES = { ["ENTREE"] = 168,
["WC"] = 202,
["SDB"] = 206,
["SEJOUR"] = 205,
["CUISINE"] = 203,
["CHAMBRE"] = 204 };


local PIECE_ACTIVE = { ["ENTREE"] = 1,
["WC"] = 2,
["SDB"] = 3,
["SEJOUR"] = 4,
["CUISINE"] = 5,
["CHAMBRE"] = 6 };

local ID_DETECTEUR = { ["ENTREE"] = nil,
["WC"] = 184,
["SDB"] = 220,
["SEJOUR"] = nil,
["CUISINE"] = 5,
["CHAMBRE"] = 37 };

 

Et je cherche maintenant à tout regrouper dans une seule et même variable (afin de la stocker ensuite dans une Variable Globale).

J'ai bien vu que c'était possible et après plusieurs heures d'essais et de lecture de la documentation officielle LUA + d'autres sites, je suis contraint d'admettre mon échec.

 

J'ai essayé de créer ma nouvelle variable de cette manière :

 

local pieces = {};
table.insert(pieces, ["ENTREE"] = {	id=1,	nom="ENTREE",reglages=168,detect=nil,sonos=136});
table.insert(pieces, ["WC"] = {		id=2,	nom="WC",reglages=202,detect=184,sonos=nil});
table.insert(pieces, ["SDB"] = 	{	id=3,	nom="SDB",reglages=206,detect=220,sonos=137});
table.insert(pieces, ["SEJOUR"] = {	id=4,	nom="SEJOUR",reglages=205,detect=nil,sonos=134});
table.insert(pieces, ["CUISINE"] = {id=5,	nom="CUISINE",reglages=203,detect=5,sonos=135});
table.insert(pieces, ["CHAMBRE"] = {id=6,	nom="CHAMBRE",reglages=204,detect=37,sonos=138});

 

Mais j'ai une erreur dès la déclaration de celle-ci. La déclaration fonctionne correctement si je supprimer mes indexs.

Cependant, dans ce cas, les indexs auto-incrémentés ne m'arrangent pas...

 

Comment puis-je espérer atteindre mon but, s'il-vous-plaît ?

Petite cerise sur le gâteau, comment exploiter cette nouvelle table ?

J'ai bien découvert les boucles for k,v in pairs(Table) do, mais un petit exemple d'application me ferait le plus grand bien :P

 

Merci d'avance :60:

Modifié par J3R3M
Posté(e) (modifié)

Si cela peut être intéressant, voici ce que stockent chaque variable :

  • liste_pieces / nom - Là, promis, y'a aucun piège
  • ID_REGLAGES / reglages - ID d'un VD dans lequel sont stockées des infos/du code en rapport avec la pièce
  • PIECE_ACTIVE / id - ID d'un VD m'affichant la valeur de la variable globale "PIECE_ACTIVE". Un bouton par pièce sur ce VD.
  • ID_DETECTEUR / detect - Là non plus, aucun piège. ID du principal détecteur de mouvement de la pièce
  • sonos - ID du VD Sonos correspondant à la pièce
Modifié par J3R3M
Posté(e)

Bonsoir,

 

exemple du Watchdog de @Lazer, comme ceci ta déclaration :

 

local watchdog = {
        {type = "Scene", id = 7, match = {text="GEA fonctionne depuis", interval=11*60}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email"}}, -- GEA
        {type = "Scene", id = 18, match = {text="checking scene", interval=0}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email"}}, -- CheckAll_Ids
        {type = "Scene", id = 14, match = {text="", interval=0}, no_match = {text=""}, count=1, restart=true, notification = {"push", "email"}}, -- Waze
        {type = "VD", id = 33, match = {text="", interval=40}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, -- YAMS WU
        {type = "VD", id = 17, match = {text="", interval=30}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, -- Sonos Player (Tk.isTraceEnabled = true)
        {type = "VD", id = 4, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, -- Clock Sync
        {type = "VD", id = 50, match = {text="", interval=0},  no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, -- My Batteries
        {type = "VD", id = 14, match = {text="", interval=0},  no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, -- Evénements
          {type = "VD", id = 35, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, -- Network Monitor
          {type = "VD", id = 32, match = {text="", interval=0}, no_match = {text="", type="ERROR"}, restart=true, notification = {"push", "email"}}, --Jour Chome
}

et regarde ceci

 

http://wxlua.free.fr/Tutoriel_Lua/Tuto/Iterators/pairs.php

  • Like 1
Posté(e)

Merci de ta réponse !

J'étais bien tombé sur cette page de tuto, mais je n'arrivais pas y voir plus clair.

 

Cela signifie donc qu'à chaque fois qu'un tableau est réinséré dans une variable, ça oblige l'utilisation d'une nouvelle couche de boucle for k,v in pairs ensuite ?

 

Si j'ai bien compris, dans mon cas, il faudrait que tout le code qui nécessite les variables d'une pièce soit à l'intérieur d'une double boucle ?

Si tel est le cas, je trouve l'optimisation complexe tout en alourdissant les scènes de ces boucles :(

Posté(e)

Bonjour,

 

Oui tu es obligé de boucler, mais pas forcément avec (pairs) ou (ipairs) tu peux fair eune boucle for i = 1, #toto...

 

Enfin je crois. Que souhaites tu faire exactement ?

  • Upvote 1
Posté(e) (modifié)

À chaque début de scène de pièce, je déclare une variable PIECE.

Ainsi, avec cette seule variable déclarée, le script se débrouille pour retrouver toutes les autres variables nécessaires, présentes à ce jour dans les autres tables.

 

Voici donc la structure de mes scènes en très simplifiée et tapée rapidement avec quelques explications pour aider à la compréhension :

PIECE = "CUISINE";
lum_mini = 5;

local liste_pieces = {"ENTREE","WC","SDB","SEJOUR","CUISINE","CHAMBRE"};

local ID_REGLAGES = { ["ENTREE"] = 168,
["WC"] = 202,
["SDB"] = 206,
["SEJOUR"] = 205,
["CUISINE"] = 203,
["CHAMBRE"] = 204 };


local PIECE_ACTIVE = { ["ENTREE"] = 1,
["WC"] = 2,
["SDB"] = 3,
["SEJOUR"] = 4,
["CUISINE"] = 5,
["CHAMBRE"] = 6 };

local ID_DETECTEUR = { ["ENTREE"] = nil,
["WC"] = 184,
["SDB"] = 220,
["SEJOUR"] = nil,
["CUISINE"] = 5,
["CHAMBRE"] = 37 };

local ID_SONOS = { ["ENTREE"] = nil,
["WC"] = 184,
["SDB"] = 220,
["SEJOUR"] = nil,
["CUISINE"] = 5,
["CHAMBRE"] = 37 };

-- Si je veux démarrer l'enceinte de la pièce
-- Dans les faits, j'ai aussi une table avec les valeurs possibles de volume, mini et maxi en fonction du moment de la journée
fibaro:call(ID_SONOS[PIECE], "pressButton", "Play');

-- Je mets à jour la variable globale PIECE_ACTIVE et la variable PIECE_PRECEDENTE
-- Celle-ci est gérée par les boutons d'un VD / 1 par pièce
-- Cette VG me sert, entre autres, à déterminer si l'acheminement d'une pièce à une autre est correct
-- Ex : Si tout le monde est couché et qu'il y a un mouvement dans la cuisine, il y a une intrusion
-- Car nous sommes encore incapables de nous  téléporter
setGlobal(PIECE_PRECEDENTE, PIECE);
fibaro:call(ID_VD, "pressButton", PIECE_ACTIVE[PIECE]);

-- On allume la lumière ?
if tonumber(fibaro:getValue(ID_DETECTEUR[PIECE] + 2, "value")) > lum_mini
  then fibaro:abort(); end

-- Besoin de lumière, on allume
-- J'ai un VD par pièce qui centralise quoi allumer dans la pièce en fonction des modules
-- Qu'ils soient HUE ou DIM. Donc par exemple, 1 = ON, 2 = OFF, 3 = FADE OUT
-- Bon j'ai aussi une gestion du moment de la journée, mais on fait au plus simple
fibaro:call(ID_REGLAGES[PIECE], "pressButton", 1);
  
-- Fonction que j'ai eue envie de développer
-- Je l'ai appelée TRACKING
-- S'il n'y a qu'une personne au domicile, lorsqu'on rentre dans une pièce, ça éteint les autres pièces
if fibaro:getValue("HOME_TRACKING") == "1" then
  for i = 1, #liste_pieces do
    if liste_pieces[i] ~= PIECE then fibaro:call(ID_REGLAGES[liste_pieces[i]] , "pressButton", "2"); end
  end
end

 

Je voulais donc pouvoir stocker dans une seule table toutes les informations des pièces, à la manière de mon premier post :

 

local pieces = {};
table.insert(pieces, ["ENTREE"] = {	id=1,	nom="ENTREE",reglages=168,detect=nil,sonos=136});
table.insert(pieces, ["WC"] = {		id=2,	nom="WC",reglages=202,detect=184,sonos=nil});
table.insert(pieces, ["SDB"] = 	{	id=3,	nom="SDB",reglages=206,detect=220,sonos=137});
table.insert(pieces, ["SEJOUR"] = {	id=4,	nom="SEJOUR",reglages=205,detect=nil,sonos=134});
table.insert(pieces, ["CUISINE"] = {id=5,	nom="CUISINE",reglages=203,detect=5,sonos=135});
table.insert(pieces, ["CHAMBRE"] = {id=6,	nom="CHAMBRE",reglages=204,detect=37,sonos=138});

 

Mais si je dois tout boucler à plusieurs reprises, ça ne serait pas aider la charge CPU je pense ?

Pour le moment, je me suis contenté de stocker toutes mes tables dans des Variables Globales.

Ainsi, en cas de changement dans une de celles-ci, je le fais via une scène prête à l'emploi, plutôt que de devoir éditer chaque scène.

Mais ça m'a fait créé un paquet de Variables Globales pour le coup !

Modifié par J3R3M
Posté(e)

Salut,

 

Naturellement, j'aurais fait quelquechose comme ceci, mais j'appelle des amis ::60:

@Lazer

@Steven

et tous les experts dev qui passeraient par là.

PIECE = "CUISINE";

local pieces = {
  {nom="ENTREE", id=1, reglages=168, detect=nil, sonos=136},
  {nom="WC", id=2, reglages=202, detect=184, sonos=nil},
  {nom="SDB", id=3, reglages=206, detect=220, sonos=137},
  {nom="SEJOUR", id=4, reglages=205, detect=nil, sonos=134},
  {nom="CUISINE", id=5, reglages=203, detect=5, sonos=135},
  {nom="CHAMBRE", id=6, reglages=204, detect=37, sonos=138}
}

local elements = #pieces

for i=1, elements do
    if pieces[i].nom == PIECE then
        if pieces[i].id ~= nil then id = pieces[i].id end
        if pieces[i].reglages ~= nil then reglages = pieces[i].reglages end
        if pieces[i].detect ~= nil then detect = pieces[i].detect end
        if pieces[i].sonos ~= nil then sonos = pieces[i].sonos end
    end
end

fibaro:call(sonos, "pressButton", "Play");
fibaro:call(reglages, "pressButton", 1);

 

  • Upvote 1
Posté(e)

 
Il y a 8 heures, J3R3M a dit :

À chaque début de scène de pièce, je déclare une variable PIECE.

Voici donc la structure de mes scènes en très simplifiée et tapée rapidement avec quelques explications pour aider à la compréhension :


PIECE = "CUISINE";

 

Je voulais donc pouvoir stocker dans une seule table toutes les informations des pièces, à la manière de mon premier post :

 


local pieces = {};
table.insert(pieces, ["ENTREE"] = {	id=1,	nom="ENTREE",reglages=168,detect=nil,sonos=136});
table.insert(pieces, ["WC"] = {		id=2,	nom="WC",reglages=202,detect=184,sonos=nil});
table.insert(pieces, ["SDB"] = 	{	id=3,	nom="SDB",reglages=206,detect=220,sonos=137});
table.insert(pieces, ["SEJOUR"] = {	id=4,	nom="SEJOUR",reglages=205,detect=nil,sonos=134});
table.insert(pieces, ["CUISINE"] = {id=5,	nom="CUISINE",reglages=203,detect=5,sonos=135});
table.insert(pieces, ["CHAMBRE"] = {id=6,	nom="CHAMBRE",reglages=204,detect=37,sonos=138});

 

Mais si je dois tout boucler à plusieurs reprises, ça ne serait pas aider la charge CPU je pense ?

Pour le moment, je me suis contenté de stocker toutes mes tables dans des Variables Globales.

Ainsi, en cas de changement dans une de celles-ci, je le fais via une scène prête à l'emploi, plutôt que de devoir éditer chaque scène.

Mais ça m'a fait créé un paquet de Variables Globales pour le coup !

-- Pas besoin de boucler un simple appel ainsi fait l'affaire.

fibaro:call(pieces[PIECE].reglages, "pressButton", 1);

 

  • Thanks 1
Posté(e)

@Steven ah oui, ok, mais donc ma proposition ne fonctionne pas ? mon type de tableau sans insert est faux ;-) ?

 

bon ben désolé @J3R3M, tu vois j'ai bien fait d'appeler des amis. :-)

  • Haha 1
Posté(e)

Oui il fonctionne mais ainsi afin d'avoir besoin de boucler sur le "nom":

 

local pieces = {
  {"ENTREE"id=1, reglages=168, detect=nil, sonos=136},
  {"WC" id=2, reglages=202, detect=184, sonos=nil},
  {"SDB" id=3, reglages=206, detect=220, sonos=137},
  {"SEJOUR"id=4, reglages=205, detect=nil, sonos=134},
  {"CUISINE" id=5, reglages=203, detect=5, sonos=135},
  {"CHAMBRE"id=6, reglages=204, detect=37, sonos=138}
}
  • Like 1
Posté(e)

Merci beaucoup des réponses et de vos intérêts pour ma demande :13:

 

Je vais essayer de mettre en pratique cela et reviens très vite demander quelque chose d'un peu plus poussé, si je n'arrive pas à m'en dépatouiller :2:

Posté(e) (modifié)

Alors, avec ce code d'insertion :

table.insert(pieces, "ENTREE", {...});

J'obtiens l'erreur [DEBUG] 20:06:32: line 21: bad argument #2 to 'insert' (number expected, got string)

 

 

Avec ceux-ci :

table.insert(pieces, ["ENTREE"], {...}});
table.insert(pieces, ["ENTREE"] = {...}});

J'obtiens [DEBUG] 20:10:55: line 21: unexpected symbol near '['

 

 

Et avec celui-ci :

table.insert(pieces, "ENTREE" = {});

J'obtiens [DEBUG] 20:14:46: line 21: ')' expected near '='

 

La première mise en forme semble la plus correcte. Mais visiblement LUA n'accepte pas d'avoir autre chose qu'un chiffre comme clé ? :(

Modifié par J3R3M
Posté(e)

En supprimant la clé, il n'y a pas de bug, mais ça m'oblige à détourner le problème via un code comme celui-ci :

 

local liste_pieces = {"ENTREE","WC","SDB","SEJOUR","CUISINE","CHAMBRE"};

PIECE = "ENTREE";

function piece_actu(piece)
 for i=1, #liste_pieces do
  if liste_pieces[i] == piece then return i end
 end
end

local key = piece_actu(PIECE);

local detect = pieces[key].detect;
local reglages = pieces[key].reglages;
et...

 

Ou il y a encore un moyen simple de détourner la chose ?

Posté(e)
Bonsoir Moicphil votre code pour la température est ce que je cherchais dans divers forums ...
(prémisse mon ignorance avec le code lua) comment puis-je envoyer la valeur de la température au lieu du debag au téléphone? 
J'ai essayé avec ce code "76" est l'identifiant de mon appareil, mais je pense que j'ai fait quelque chose de mal ... 
pouvez-vous m'aider? Je vous remercie beaucop.

VOTRE CODE

--[[
%% properties
66 value
%% globals
--]]
local Temperature = fibaro:getValue(11, "value")
fibaro:debug('Température actuelle : '..Temperature..' °C' )
if
tonumber(fibaro:getValue(11, "value")) < 20
then
fibaro:call(76, "sendDefinedPushNotification", "9");
end

 

 

MON CODE

fibaro:call(76, "sendPush",('Temperatura Attuale : '..Temperature..' °C' ))

 

 

×
×
  • Créer...