Aller au contenu
J3R3M

[Résolu] [LUA] Effectuer une action répétée sur un bouton ou vérifier avant afin qu'elle ne soit pas répétée?

Recommended Posts

Merci de ce script, cela peut être très utile pour optimiser la programmation de certains scripts.

Je trouve que c'est bon à savoir, même si ça semble dérisoire, mais dans le cas, on ne calcule que le temps d'accès à l'information

C'est-à-dire que l'on connaît déjà les IDs des modules, ce qui impose d'avoir au préalable un script qui liste les IDs des modules à vérifier, ce qui sera forcément plus long que si on a directement l'accès à l'info dans une VG.

 

Si tu as publié ton script avec les valeurs testées, on est donc sur 1000 tests d'accès, la différence doit donc être 10 fois plus flagrante avec 10 000 tests, bien que ça n'arrive jamais.

 

Une petite question concernant le script que j'essaie de comprendre au maximum : dans la ligne suivante :

execute("getVG         :", function() local v,m = fibaro:getGlobal(VG) end)

À quoi correspond la variable "m", s'il-te-plaît ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Le test que j'ai effectué était sur 10'000 itérations, par contre, par défaut, il y a 1'000 dans le script.

 

fibaro:getGlobal(VG) retourne la valeur et la date de dernière modification de la vg.

local v, m = fibaro:getGlobal(VG) 

 

v = valeur

m = LastModificationTime

 

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 21 minutes, Steven a dit :

Le test que j'ai effectué était sur 10'000 itérations, par contre, par défaut, il y a 1'000 dans le script.

Bon, la différence de temps d'accès est donc effectivement dérisoire, merci de cette précision!

 

il y a 21 minutes, Steven a dit :

fibaro:getGlobal(VG) retourne la valeur et la date de dernière modification de la vg.

local v, m = fibaro:getGlobal(VG) 

 

v = valeur

m = LastModificationTime 

 

Ah oui, merci! Je n'avais pas fait attention que tu avais fait appel à fibaro:getGlobal, j'utilise toujours directement les fonctions appelant la valeur et le timestamp de modification.

En tous cas, merci de ces éclaircissements et du temps accordé pour répondre à mes questions plus ou moins tordues!

Modifié par J3R3M

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 4 minutes, J3R3M a dit :

En tous cas, merci de ces éclaircissements et du temps accordé pour répondre à mes questions plus ou moins tordues!

Lol, si tes questions sont tordues ... quelles sont celles de @pepite :2:;)

Partager ce message


Lien à poster
Partager sur d’autres sites

@J3R3M a des questions sensées, les miennes sont complètement débiles ;-) mais j'assume ;-)

 

Et mon tuteur assure @Steven, quelle patience ;-)

Partager ce message


Lien à poster
Partager sur d’autres sites

En fait, j'essaie de généraliser mon cas afin qu'il puisse éventuellement servir à d'autres personnes, c'est pour cela que ça peut vite devenir sans queue ni tête :P

 

D'ailleurs, une autre question me vient en tête, même si je pense connaître la réponse.

Lorsque des données doivent être accessibles rapidement, je suppose qu'il est préférable de favoriser le stockage de celle-ci dans une VG qui lui est dédiée, plutôt que dans un gros tableau encodé en json?

 

En fait, à partir du moment où j'ai commencé à maîtriser les tableaux, j'ai reprogrammé toutes mes scènes pour qu'elles exploitent le tableau contenu dans une seule VG, ce qui donne un bon gros tableau.

Mais, finalement, pour des informations qui sont à la fois souvent modifiées, mais aussi souvent traitées, comme le dernier mouvement détecté dans une pièce à tout hasard, n'est-il pas préférable d'avoir une VG seulement pour cette information plutôt que le décodage d'un json + Accès en table pieces["NOMPIECE"].LastMove pour parler de mon cas?

 

:lol:

Modifié par J3R3M

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 11 heures, J3R3M a dit :

D'ailleurs, une autre question me vient en tête, même si je pense connaître la réponse.

Lorsque des données doivent être accessibles rapidement, je suppose qu'il est préférable de favoriser le stockage de celle-ci dans une VG qui lui est dédiée, plutôt que dans un gros tableau encodé en json?

Absolument, bien que optimisé, encoder/décoder du json c'est effectuer de la transformation de chaîne de caractères, c'est donc toujours un peu lent (on parle de micro/nanoseconds).

 

La base de données est capable d'avaler une quantité de données vraiment importante, et si les index sont bien placés, les performances sont juste remarquable, donc inutile d'hésiter àl'exploiter.

 

JSON quant à lui à des limite. Prenons un exemple simple ... la récursivité ( A appel B et B appel A)

 

Résultat :

local tableauA, tableauB = {}, {}

tableauA["A"] = "Aa"
tableauA["B"] = tableauB

tableauB["A"] = tableauA
tableauB["B"] = "Bb"

print( json.encode(tableauA) )

Krakkk boooommmmm

[DEBUG] 08:47:18: 2018-11-30 08:47:18.646926 [ fatal] Unknown exception: /usr/share/lua/5.2/json/encode.lua:130: Recursive encoding of value

 

Néanmoins, entre les performances de la HC2 et la base de données. Je dirais que chercher la performance à outrance ne sert à rien. Il vaut mieux simplifier le code pour en optimiser la maintenance. LUA n'étant pas un langage des plus simple à maintenir, je pense que l'effort doit être mis là dessus en priorité.

 

Alors, pour répondre à ta question. Stocker un tableau de JSON n'est, pour moi, pas optimiser en terme de maintenance. La HC2 ne permet pas de "voir" un tableau de JSON, l'écran des VG n'affiche rien de parlant. On est donc obligé de faire un morceau de code pour parcourir le JSON afin d'en connaitre la structure. Le créateur du code, lui, connait la structure car c'est lui qui la mise en place, mais une autre personne qui reprend le code sera un peu perdu au début.

Mettre en commentaire la structure pour aider l'utilisateur est fort utile, mais basé sur mes 27 ans de développement, je peux t'assurer que la documentation ne suit JAMAIS les évolutions du code et que seul le code fait office de documentation. C'est bien triste, mais c'est un fait.

 

Voilà, je crois que mon gros pavé te donne mon avis personnel sur la question. La version 6.x de GEA a été écrite dans ce sens. Je n'arrivais plus maintenir les versions précédentes. Je suis donc reparti de 0 pour tout récrire motivé par la sale bête de @pepite.

 

Have fun

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites
Le 16/11/2018 à 06:48, jjacques68 a dit :

punaise !!  je viens de lire le post, moi depuis toujours, pour les relais, je test son état avant d’actionner...

 

si j’avais su que c’était pas utile... 

 

c’est étrange par ce qu’il me semble que pour les relais des volets, j’entendais un clic quand meme... pour cela que je testais avant

Du style quand on veut fermer un volet qui est déjà fermé... faut que je re essaye...

Moi aussi, les modules volets claquent et le voyant s'allume à la moindre commande, même si l’état et déjà celui  demandé, c'est à dire par exemple si il est fermé, si j'envoie la Command de fermé, le module tente de fermer.

Je comprends que sur la commande ouvert cela se fasse car un volet même ouvert à fond n'est jamais a 100% pour le module.

je vérifie donc tous le temps l’état de mes volet sauf évidement pour le STOP.

 

Partager ce message


Lien à poster
Partager sur d’autres sites
Le 30/11/2018 à 09:12, Steven a dit :

Néanmoins, entre les performances de la HC2 et la base de données. Je dirais que chercher la performance à outrance ne sert à rien. Il vaut mieux simplifier le code pour en optimiser la maintenance. LUA n'étant pas un langage des plus simple à maintenir, je pense que l'effort doit être mis là dessus en priorité.

J'ai appris cela depuis peu et je suis actuellement en train de chercher à diminuer les vérifications non nécessaires dans mes scripts afin de gagner en temps d'exécution.

Le 30/11/2018 à 09:12, Steven a dit :

Alors, pour répondre à ta question. Stocker un tableau de JSON n'est, pour moi, pas optimiser en terme de maintenance. La HC2 ne permet pas de "voir" un tableau de JSON, l'écran des VG n'affiche rien de parlant. On est donc obligé de faire un morceau de code pour parcourir le JSON afin d'en connaitre la structure.

Ça, c'est indéniable. J'ai dû créé plusieurs VD simplement pour afficher et gérer certaines valeurs de mon tableau sans avoir à éditer une scène...

Le 30/11/2018 à 09:12, Steven a dit :

Le créateur du code, lui, connait la structure car c'est lui qui la mise en place, mais une autre personne qui reprend le code sera un peu perdu au début. 

Mettre en commentaire la structure pour aider l'utilisateur est fort utile, mais basé sur mes 27 ans de développement, je peux t'assurer que la documentation ne suit JAMAIS les évolutions du code et que seul le code fait office de documentation. C'est bien triste, mais c'est un fait.

Et je suis une fois de plus d'accord avec toi. J'essaie de me faire violence pour commenter au maximum les scènes, mais il est évident que quiconque le relira aura surtout besoin de manger le code pour le comprendre...

Le 30/11/2018 à 09:12, Steven a dit :

Voilà, je crois que mon gros pavé te donne mon avis personnel sur la question.

Oui et je te remercie infiniment du temps accordé pour chacune de tes réponses!

Partager ce message


Lien à poster
Partager sur d’autres sites

Oups, une dernière question me vient à l'esprit...

Dans l'utilisation d'un tableau json, sais-tu s'il met plus du temps à accéder à une valeur contenue dans une clé, qui est contenue dans une clé, qui elle-même est contenue dans une clé etc. etc., par rapport à une valeur accessible "directement" ?

 

Je préfère toujours illustrer avec un petit exemple :

t : {};
t["EXEMPLE"] = {	Etat = 1,
					Bla = {A=1,B=2,C=3,D=4},
					Suite = { k="on",l="ne",m="s'arrête",n={v="vraiment",w="plus"}}
}

Sera-t'il plus rapide d'accéder à t["EXEMPLE"].Etat plutôt qu'à t["EXEMPLE"].Suite.n.v ?

Promis, après j'arrête d'abuser! :13:

Partager ce message


Lien à poster
Partager sur d’autres sites

Le réponse me semble évidente.

 

Est-ce plus rapide de parcourir 2 tableaux ou 4 tableaux.

 

t.exemple.etat = 2 tableaux

t.exemple.Suite.n.v = 4 tableaux

 

Dis toi que chaque tableau correspond à un dictionnaire. Tu recherches dans le premier qui va te donner un référence sur le 2ème qui tu vas ouvrir et parcourir à la recherche du mot état pour enfin en lire la définition. Quand est-il lorsque tu dois rechercher dans 4 dictionnaires ?

 

Je donne comme exemple un dictionnaire car la plus part des recherches dans des tableaux sont justement basées sur des recherches "dichotomique" (https://fr.wikipedia.org/wiki/Recherche_dichotomique)

Partager ce message


Lien à poster
Partager sur d’autres sites

Une nouvelle fois merci.

Je ne pensais vraiment pas que LUA effectuait une recherche pour chaque sous-tableau.

J'étais persuadé qu'il accédait directement à la valeur dont on spécifiait la clé et qu'il affichait une erreur si la clé n'était pas correcte.

 

Qu'en est-il lorsqu'on réencode une seule clé d'un tableau?

Par exemple, admettons que le tableau ci-dessus soit encodé est stocké dans une Variable Globale. On souhaite changer la valeur d'un de ses sous-tableaux :

t = json.decode(fibaro:getGlobalValue("MA_VG"));

t["EXEMPLE"].Suite.n.v = "carrément";
fibaro:setGlobal("MA_VG", json.encode(t));

Le tableau est donc entièrement relu et est ensuite ré-encodé avec seulement le changement de cette valeur, c'est cela?

Ce qui signifierait que, si deux scènes cherchaient à mettre à jour au sein du même tableau, la valeur d'une clé différente et ce, simultanément, le résultat pourrait être aléatoire.

J'ai à peu près pigé le principe ? :unsure:

Partager ce message


Lien à poster
Partager sur d’autres sites

Je viens de voir le message, désolé.

 

Oui tu as bien compris. Il est tout à fait possible qu'une de tes scènes écrasent les données qu'une autre scène vient de mettre à jour. Pour éviter cela, il n'existe qu'une seule manière et elle n'est même pas 100% fiable. Il s'agit de faire un local v, t = getGlobal("MA_VG") pour avoir la valeur et la date de la dernière maj de la variable. 

Ensuite, avant de faire le setGlobal, il faut refaire un getGlobal et comparer les dates, si c'est les même tu peux faire ton setGlobal.

Bien évidement si 2 scènes arrivent exactement à ce point au même moment, c'est mort. Mais pour des gros traitement, cela peut s’avérer une solution.

 

Pseudo code :

 

local v, t = fibaro:getGlobal("MA_VG")

...

< traitement de v >

...

if (t == fibaro:getGlobalModificationTime("MA_VG")) then

   .. la VG ne semble pas avoir été modifiée entre temps ... on stock.

   fibaro:setGlobal("MA_VG")

else 

   .... la VG a changé entre temps ... soit tu recommences, soit tu laisse tomber

end

 

 

 

 

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a une heure, Steven a dit :

Je viens de voir le message, désolé.

Ne sois pas désolé, c'est déjà super sympa de répondre à toutes mes interrogations qui doivent paraître sans fin!

il y a une heure, Steven a dit :

Oui tu as bien compris. Il est tout à fait possible qu'une de tes scènes écrasent les données qu'une autre scène vient de mettre à jour. Pour éviter cela, il n'existe qu'une seule manière et elle n'est même pas 100% fiable. Il s'agit de faire un local v, t = getGlobal("MA_VG") pour avoir la valeur et la date de la dernière maj de la variable. 

Ensuite, avant de faire le setGlobal, il faut refaire un getGlobal et comparer les dates, si c'est les même tu peux faire ton setGlobal.

Bien évidement si 2 scènes arrivent exactement à ce point au même moment, c'est mort. Mais pour des gros traitement, cela peut s’avérer une solution.

Merci de cette confirmation, ainsi que du code.

Je pense comprendre un peu mieux le fonctionnement. Jusqu'alors, je pensais qu'on était capable de modifier uniquement une valeur spécifique.

Dans cette situation, compte-tenu des réponses fournies à mes précédentes questions, je vais plutôt voir pour diviser les actions dans différentes VG en fonction des interactions des informations.

Ça devrait d'ailleurs permettre un (minime) gain de temps de traitement si les tables sont moins complexes à parcourir :-)

 

Avec toutes ces réponses, je devrais être capable de gagner un peu de temps sur certaines scènes et également, de comprendre certaines réactions que je n'étais pas capable d'expliquer auparavant!

 

Un grand MERCI! :13:

  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

×