JossAlf Posté(e) le 21 mai 2014 Signaler Posté(e) le 21 mai 2014 Bonjour, J'ai un problème avec l'utilisation d'une variable locale... Je pensais pouvoir affecter une valeur à cette variable comme suit : local SqueezeNom = "Cuisine" if SqueezeNom == 'Cuisine' then local player = "00:04:20:2b:81:00 " fibaro:debug(player) end if SqueezeNom == 'Salon' then local player = "00:04:20:29:bb:3e " end if SqueezeNom == 'ChambreB' then local player = "00:04:20:2c:0b:fe " end if SqueezeNom == 'ChambreH' then local player = "00:04:20:2c:35:bc " end fibaro:debug(player) if SqueezeNom == 'ChambreH' then local player = "00:04:20:2c:35:bc " end fibaro:debug(player) Le premier debug (ligne 6) me donne bien "00:04:20:2b:81:00" Mais le second (ligne 26) me retourne une erreur : [ERROR] 16:53:07: line :debug (arg 2), expected 'string const &' got 'nil' Je comprends pas... C'est comme si la variable locale "player" est tellement localisée qu'elle n'existe que dans le IF .. end ? HELP !!
JossAlf Posté(e) le 21 mai 2014 Auteur Signaler Posté(e) le 21 mai 2014 J'ai corrigé le problème en passant par une variable globale "de transition" comme ça : local SqueezeNom = "Cuisine" if SqueezeNom == 'Cuisine' then fibaro:setGlobal('Player' , "00:04:20:2b:81:00 " ) end if SqueezeNom == 'Salon' then fibaro:setGlobal('Player' , "00:04:20:29:bb:3e ") end if SqueezeNom == 'ChambreB' then fibaro:setGlobal('Player' , "00:04:20:2c:0b:fe ") end if SqueezeNom == 'ChambreH' then fibaro:setGlobal('Player' , "00:04:20:2c:35:bc ") end local player = fibaro:getGlobalValue("Player") fibaro:debug(player) Mais ça remet en question ma compréhension des variables locales que je pensaient valable dans tout le code du module virtuel ou de la scène ?! Si quelqu'un peux me dire si c'est normal ou si c'est un bug. Merci.
Tomzebest Posté(e) le 21 mai 2014 Signaler Posté(e) le 21 mai 2014 Salut l'ami! Alors d'après mes connaissances, après then il faut demander au système de faire une action. Dans ton premier cas tu veux assigner une valeur à une variable locale. En fait tu ne peux pas sans passer par une fonction fibaro, comme tu l'as fait dans le second cas. Je ne connais pas les squeezebox donc je ne sais pas si je pourrais t'aider en fonction de ce que tu veux faire. Dans ton premier cas la fonction debug te donne une bonne réponse puis une erreur parce que le système lit comme ça: local SqueezeNom = "Cuisine" -- on assigne le nom Cuisine à la variable locale SqueezeNom if SqueezeNom == 'Cuisine' then -- si la variable locale porte le nom Cuisine alors local player = "00:04:20:2b:81:00 " --[[ ici tu redéfinis personnellement une variable locale nommée player et tu lui assignes une chaîne de caractère, mais ce n'est pas ton système qui lui assigne automatiquement car après then il faut une fonction. Local te permet de définir toi même une variable... Donc après ton then le système ne fait aucune action, il continue la lecture, et ici va juste créer à ta demande une nouvelle variable locale sans rapport avec ce qui précède.--]] fibaro:debug(player) -- comme tu viens juste de créer ta variable au dessus, il va donc te sortir ta chaîne en debug end -- De la même façon ici aucune action sera réalisée car il n'y a pas de fonction après tes then if SqueezeNom == 'Salon' then local player = "00:04:20:29:bb:3e " end if SqueezeNom == 'ChambreB' then local player = "00:04:20:2c:0b:fe " end if SqueezeNom == 'ChambreH' then local player = "00:04:20:2c:35:bc " end -- jusqu'ici fibaro:debug(player) --[[ici tu as un message d'erreur car tu as 'end' entre ta création de ta dernière variable locale et ta fonction debug. Donc il va lire ta fonction debug comme si il n'y avait rien au dessus. Essaye de faire une nouvelle scène avec juste fibaro:debug(player) et tu auras le même message d'erreur. La lecture du script s'arrête la à cause de l'erreur précédente.]]-- if SqueezeNom == 'ChambreH' then local player = "00:04:20:2c:35:bc " end fibaro:debug(player) Je ne sais pas ce que tu veux faire mais si tu veux récupérer des adresses IP de modules virtuels tu peux utiliser la fonction: deviceIp = fibaro:get(126, "IPAddress")
JossAlf Posté(e) le 21 mai 2014 Auteur Signaler Posté(e) le 21 mai 2014 (modifié) Salut Tom ! Content de te revoir. Ca faisait un bail ! Je souhaitais assigner le numéro MAC de mes squeezebox en fonction du nom de la pièce passée àune variable locale. Comme c'est la première fois que j'utilise un if pour modifier la valeur d'une variable locale, je ne savais pas qu'après un then, il fallait une fonction !!! Mais ce que je ne comprends pas c'est pourquoi en dehors d'un "if then end", local player = "00:04:20:2c:35:bc " fonctionne comme je le souhaite. J'ai fait un petit MV pour me simplifier les choses et diffuser rapidement des messages. Tiens je vais le mettre en ligne. Comme ça il pourra être amélioré En tout cas merci pour ton aide. MAJ : Lien vers le module virtuel Modifié le 21 mai 2014 par JossAlf
Tomzebest Posté(e) le 21 mai 2014 Signaler Posté(e) le 21 mai 2014 Ahhh oui adresse MAC pas adresse IP! M'en lala la poussière de plâtre me fait disjoncter! Oui je suis pas trop présent sur le forum en ce moment, en plein dans les finitions de la cuisine et du salon!!! Une petite astuce au passage aussi avec les if then else. Il y a aussi elseif qui peut être utilisé aussi souvent que tu veux comme ça. if ... then ... elseif ... then ... elseif ... then ... elseif ... then ... else... end Ca signifie sinon si... Comme ça je trouve que ça fait plus propre, tu vois qu'il y a plusieurs possibilités pour une chose en particulier à faire, et tu finis une seule fois par end. Sinon je ne suis pas un expert mais je crains que tu ne puisses pas modifier la valeur, le nom ou quoi que ce soit d'une variable locale par le système, contrairement à une variable globale. en dehors du if then end, ta fonction debug va bien t'afficher l'adresse mac puisque le système va lire local player = "00:04:20:2b:81:00 " -- dans mon tuto sur le lua j'explique qu'il faut imaginer que tu ouvres un tiroir avec une étiquette marquée player, et que dedans tu as un papier avec marqué 00:04:20:2b:81:00 fibaro:debug(player) -- tu demandes au système d'ouvrir le tiroir nommé player et de t'indiquer ce qu'il y a marqué sur le papier simplement Le reste du code est faux donc le système lit mais en gros tant qu'il n'y a pas de fonctions il ne fait rien d'autre que d'ouvrir ton tiroir player et de changer le numéro inscrit sur le papier. Si il rencontre à nouveau une fonction fibaro:debug(player) juste après que tu ais crée une nouvelle variable locale player, il va te donner cette nouvelle valeur que tu as assignée. L'erreur que tu as eu c'est qu'entre le moment où tu as crée ta variable locale en 18 et ta fonction debug en 21, tu as un end qui a terminé une condition commencée en 17 (mais qui ne marchera pas car on ne peut pas changer une variable locale par le système) donc le système ne tiens plus compte de ce qu'il y a au dessus du end. Essaye dans une nouvelle scène de mettre juste if SqueezeNom == 'ChambreH' then local player = "00:04:20:2c:35:bc " end fibaro:debug(player) ou fibaro:debug(player) et il t'indiquera le même message d'erreur, car dans sa lecture du script, ça ne veut rien dire, il lui manque des éléments ou les choses ne sont pas dans le bon ordre.
JossAlf Posté(e) le 21 mai 2014 Auteur Signaler Posté(e) le 21 mai 2014 Merci Tom. Je comprends mieux la nécessité de passer par une variable globale. Mais ça reste un peu ésotérique comme fonctionnement. Je m'y pencherai plus en profondeur. Je n'aime pas rester dans le flou ... Pour les elsif, je ne les ai pas utilisés sciemment car j'avais cru lire quelque part que ça ralentissait le code ?! Mais je ne sais pas où j'ai lu ça ? À confirmer ou infirmer donc En tout cas, Mon module virtuel fonctionne parfaitement bien et me facilite la vie (pour confirmer la bonne réception des ordres) Ça me fera un super complément au GEA de Steven.
Tomzebest Posté(e) le 21 mai 2014 Signaler Posté(e) le 21 mai 2014 Ah je ne sais pas pour les elseif, mais moi j'ai lu un message de Krikroff qui dit qu'avec ses 10 milliards de lignes de codes la box avait toujours autant de patate donc moi j'hésite pas
JossAlf Posté(e) le 21 mai 2014 Auteur Signaler Posté(e) le 21 mai 2014 J'avais eu de lui la même réponse quand je m'interrogeais sur l'impacts des mains loop
JossAlf Posté(e) le 21 mai 2014 Auteur Signaler Posté(e) le 21 mai 2014 Je vais sur le tchat si tu veux échange gare sur ces variables locales...
JossAlf Posté(e) le 21 mai 2014 Auteur Signaler Posté(e) le 21 mai 2014 Bon alors j'ai trouvé ! Le problème venait du mot "local" avant le nom de la variable "player" !! Apparement ça ne plaisait pas à la HC2 ?! Donc ce code est faux et retourne une erreur sur le second fibaro:debug(player) if 0 == 0 then local player = "OK" fibaro:debug(player) end fibaro:debug(player) En revanche ce code est bon et retourne bien OK sur les 2 debug. if 0 == 0 then player = "OK" fibaro:debug(player) end fibaro:debug(player) On peut donc bien modifier la valeur d'une variable locale avec un simple IF... Je me suis donc pris la tête pour une erreur de syntaxe !!! Je suis passé par une variable globale inutile ... 1
Steven Posté(e) le 21 mai 2014 Signaler Posté(e) le 21 mai 2014 Héhé dans ton exemple si tu ne mets pas "local" tu crées une variable globale donc cela fonctionne. Créer une variable local dans une condition "If" équivaut a créer un variable dans une fonction. Cela signifie que sa visibilité est réduite à la condition même. Ce qui est logique si on prend l'exemple suivante si ( je murmure à l'oreille de JossAlf) then local mon_message = "C'est un secret" end fibaro:debug(mon_message) -- Il en sait rien puisque c'est un secret Par contre, si on déclare proprement ces variables locales, il n'y aura aucun soucis local player = nil if (true) then player = "Coucou" end fibaro:debug(player) Ainsi le script à une visibilité sur la variable local player et peut la modifier. Cette dernière reste local à l'environnement ou elle a été créée. Si je fait fonction coucou() local player = "Mon player dans ma fonction" fibaro:debug(player) -- je suis dans la fonction, je connais donc player end debug:fibaro(player) -- connait pas car player est local à ma fonction et là , je n'y suis pas. J'espère que cela peux aider. Donc ton code propre et optimisé donnera local payer = nil if SqueezeNom == 'Cuisine' then player = "00:04:20:2b:81:00 " elseif SqueezeNom == 'Salon' then local player = "00:04:20:29:bb:3e " elseif SqueezeNom == 'ChambreB' then local player = "00:04:20:2c:0b:fe " elseif SqueezeNom == 'ChambreH' then local player = "00:04:20:2c:35:bc " end -- Ou --Bien plus joli local Squeezers = { ['Cuisine'] = "00:04:20:2b:81:00 ", ['Salon'] = "00:04:20:29:bb:3e ", ['ChambreB'] = "00:04:20:2c:0b:fe ", ['ChambreH'] = "00:04:20:2c:35:bc ", } fibaro:debug(Squeezers["Cuisine"])
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 Merci Steven. Est-ce que dans ton exemple suivant on est en variable locale tout le temps ? Autrement dit : est-ce que le fait de l'avoir déclaré player en variable local par local player = nil permet d'utiliser "player" dans et en dehors de If (true) ... end ou cela ne change rien à mon problème ? Par contre, si on déclare proprement ces variables locales, il n'y aura aucun soucis local player = nil if (true) then player = "Coucou" end fibaro:debug(player)
Krikroff Posté(e) le 22 mai 2014 Signaler Posté(e) le 22 mai 2014 La variable locale est disponible dans le bloc dans lequel elle est déclarée alors que la variable globale (normalement définie a l’extérieur des blocs ou fonctions) elle est utilisable dans tous les blocs . Dans le HC2 une scène, un bouton ou même le main loop c'est un bloc ! Donc ici l'utilisation d'une variable locale n'a d’intérêt que si tu codes des fonctions Et je suis bien d'accord avec Steven pour la forme suivante: local Squeezers = { ['Cuisine'] = "00:04:20:2b:81:00 ", ['Salon'] = "00:04:20:29:bb:3e ", ['ChambreB'] = "00:04:20:2c:0b:fe ", ['ChambreH'] = "00:04:20:2c:35:bc ", }
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 Bon je pense que je commence à comprendre mais il me reste un doute... Je reprends pour être certain : local player = nil if SqueezeNom == 'Cuisine' then player = "001 " elseif SqueezeNom == 'Salon' then player = "002 " end fibaro:debug(player) Ce code signifie : Ligne 2 : Je crée une variable locale appelée "player" Ligne 4 : Si SqueezeNom vaut "Cuisine" alors Ligne 5 : ma variable (locale qui valait nil) se voit affectée maintenant "001" Ligne 6 : mais si SqueezeNom vaut "Salon" alors Ligne 7 : ma variable (locale qui valait nil) se voit affectée maintenant "002" Ligne 8 : fin Ligne 10 : Affiche en debug la valeur de ma variable locale player -> soit 001 si SqueezeNom = Cuisine ; soit 002 si SqueezeNom = Salon et Nil si squeezeNom est mal renseignée. C'est bien ça ? Si j'avais oubliée la ligne 2 "local player = nil", la HC2 aurait interprété les lignes 5 et 6 comme la création d'une variable GLOBALE appelée player. Alors que là on utilise player comme variable LOCALE. C'est bien ça ? PS : désolé mais quand je fais le boulet je fais pas semblant...
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 Bon alors dernière question : if SqueezeNom == 'Cuisine' then player = "001 " elseif SqueezeNom == 'Salon' then player = "002 " end fibaro:debug(fibaro:getGlobalValue("player")) -- variable globale fibaro:debug(player) -- pas bon -> génère une erreur parce que player en local n'existe pas ! D'après ce code (comme je n'ai pas déclaré de variable locale) je n'ai qu'une variable GLOBALE créée à la volée. Voici ma question : Je croyais qu'il fallait passer par le panneau de gestion des variables pour créer les GLOBALES (à moins que ce ne soit que pour pouvoir gérer visuellement leur valeur) ? Celle-ci n'apparaitra d'ailleurs pas sur le panneau ? Je sais je suis compliqué...
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 Maintenant que j'ai compris, je trouve ça super subtile en fait : local player = "001" fibaro:debug(player) if 0 == 0 then local player = "002 " fibaro:debug(player) end fibaro:debug(player) donne ça au debug [DEBUG] 13:20:44: 001[DEBUG] 13:20:44: 002 (création d'une nouvelle variable au sein du if qui n'est pas la même que celle créée à la ligne 2)[DEBUG] 13:20:44: 001 (on reste sur la valeur donnée lors de la création ligne 2) On voit que l'on a 2 variables locales player qui n'ont pas les mêmes valeurs ! Alors que ça : local player = "001" fibaro:debug(player) if 0 == 0 then player = "002 " fibaro:debug(player) end fibaro:debug(player) Donne ce résultat au début : [DEBUG] 13:22:55: 001[DEBUG] 13:22:55: 002[DEBUG] 13:22:55: 002 On voit que l'on a bien qu'une variable locale et enfin ça : --local player = "001" --fibaro:debug(player) if 0 == 0 then local player = "002 " fibaro:debug(player) end fibaro:debug(player) Retourne au debug : [DEBUG] 13:25:53: 002[ERROR] 13:25:53: line :debug (arg 2), expected 'string const &' got 'nil' Car on a créé à la volée un variable locale qui n'existe que entre IF et END ​Et que le dernier debug cherche une variable LOCALE qui n'a jamais été déclarée avant le IF OUF... je crois que j'ai compris ! 1
Steven Posté(e) le 22 mai 2014 Signaler Posté(e) le 22 mai 2014 Il y a variable globale en terme de programmation (ce que nous avons précédemment décrit) et les variables de la HC2 qui en réalité sont des données stockées dans une base.
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 ok ! Donc la valeur d'une variable stockée dans la base de la HC2 s'obtins par fibaro:getGlobalValue("player") Alors que la valeur d'une variable globale créée dans un code s'obtient comme une variable locale ? fibaro:debug(player) Peut donc s'employer pour afficher le contenu d'une variable locale et globale créée dans un code !
Steven Posté(e) le 22 mai 2014 Signaler Posté(e) le 22 mai 2014 Oui, ils ont appelé cela variables globales mais en réalité ce sont des données partagées.
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 En fait toute mon incompréhension vient de ce panneau de variables ! Je croyais que les variables globales ne pouvaient être créées QUE depuis ce panneau sous la HC2. Et que toutes les autres variables créées au sein du code ne pouvaient être QUE LOCALES ! Ben là j'ai fait fort moi ! Je commençais à me dire que c'était super alambiqué comme gestion des variables...
JossAlf Posté(e) le 22 mai 2014 Auteur Signaler Posté(e) le 22 mai 2014 Merci Steven , Krikroff et Tom. Me voilà rassuré. Il faut seulement que je détruise tous les schèmes* que j'avais mis en place dans mon esprit depuis hier !!! * Larousse : Ensemble de concepts permettant de se faire une image de la réalité en résumant les éléments disparates de cette réalité à l'aide d'instruments fournis par la raison.
Lazer Posté(e) le 22 mai 2014 Signaler Posté(e) le 22 mai 2014 Après avoir bien lu toutes ces explications, je me rappelle maintenant du concept de base en programmation, qui est appelée portée des variables. Je ne crois pas avoir vu Krikroff ou Steven mentionner ce concept, mais je suis certain que vous connaissez parfaitement ça. Pourtant c'est bien de ça qu'il s'agit dans le cas présent. Finalement c'est le défaut des langages trop permissifs comme le LUA, le PHP, etc, qui permettent d'utiliser des variables sans les déclarer explicitement, avec comme conséquence des résultats imprévisibles, obligeant à mettre beaucoup de debug pour comprendre l'origine du problème. Avec des langages genre le Pascal où l'on était obligé de déclarer très précisément chaque variable, il n'y avait plus d’ambiguà¯té possible. 1
Messages recommandés