Aller au contenu

Messages recommandés

Posté(e)

Voilà :
GEA.add({"Or",{"Value","Fenêtre Nolan",true},{"Value","Fenêtre Ethan", true}},-1,"chambres : #name# a été ouverte !)

Envoyé de mon RMX1993 en utilisant Tapatalk

Posté(e)

OK merci, je vois... en effet, la condition Or ne peut pas être utilisée comme un trigger.

Je vais voir si je peux l'ajouter, mais sans garantie

Posté(e)

Hello,

 

J'ai une question à laquelle je ne trouve pas de réponse (ou j'ai mal cherché...)

Quelle est la syntaxe qui remplace Group qui fonctionnait sur HC2 ?

Je m'explique, j'ai des conditions du style

Variable = ON (depuis 10 mn) et Consommation < 10 (depuis 5mn) pour déclencher des actions...

Merci d'avance...

 

        -- Lave vaisselle
    GEA.add({"Sensor+", id["LAVE_VAISSELLE"], 60}, 1*60, "",{{"Global", "GEA_LaveVaisselle", "ON"}})
    
    GEA.add({"Global", "GEA_LaveVaisselle", "ON"}, 10*60, "", {{"Group", 3}})
    GEA.add({"Sensor-", id["LAVE_VAISSELLE"], 10}, 5*60, "", {{"Group", 3}})
    GEA.add({"Group", 3}, 5*60, "Le lave-vaisselle a fini de tourner",{{"Global", "GEA_LaveVaisselle", "OFF"},{"Global", "TexteAlexa", "Le+Lave+vaisselle+a+fini+de+tourner"},{"QuickApp", id["VD_ALEXA"],"Parler"}}) 
 
Posté(e)

Je ne connais pas "Group", je ne trouve rien dans le code source, tu as un lien vers la doc ?

Tu es certain que ce n'est pas une règle utilisateur que tu avais ajouté à ta propre config ?

Posté(e) (modifié)

@Lazer J'ai une question sur l'option "VariableQuickApp"... Peut-on tester si la valeur de la variable est supérieure ou inférieure à une valeur depuis un certain temps ? Ou juste si la variable vaut une valeur précise ??

 

Pour la gestion des groupes d'option de GEA sur HC2. Je me débrouille différemment. Et pour le moment, cela semble fonctionner correctement.

 

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

Oui, comme pour beaucoup d'autres options, tu peux faire des comparaisons avec + et -

GEA.add({"VariableQuickApp+", 123, "variable", 5}, 10*60, "la variable est supérieure à 5 depuis 10 minutes")

Même syntaxe que "Global" par exemple.

 

Je vais modifier la doc de syntaxe pour faire apparaitre ce cas de figure.

 

EDIT : c'est déjà le cas, tu n'as pas lu la doc, c'est pas bien :P

 

Modifié par Lazer
Posté(e)

Mise en ligne de GEA version 7.30 :

 

  • Améliorations :
    • Amélioration des performances
    • Affichage des informations détaillées sur les déclencheurs instantanés (triggers) dans la console de logs
    • Amélioration de l'option "Picture" : ID ou nom de l'utilisateur
    • Amélioration et correctif de l'option "Ask" : après réponse de l'utilisateur, permet d'exécuter une scène, une méthode d'un QuickApp, ou une action GEA
  • Correctifs :
    • Correctif de l'option "Weather" : prise en compte de la météo globale définie dans la box et non pas uniquement du module n°3 YR-Weather
    • Correctif de l'option "SonosMP3" : utilisable avec le QuickApp de Krikroff pour HC3
  • Ajouts :
    • Ajout de l'option "isEvenDay" : Teste si le numéro du jour en cours est pair
  • Suppressions :
    • Suppression de l'option "Popup" : non compatible HC3
  • Correctifs et améliorations diverses

 

Copier/coller le contenu des fichiers LUA téléchargés par dessus les fichiers main et tools dans le QuickApp (ou bien télécharger le QuickApp complet disponible en 1ère page) 

 

 

GEA v7.30.lua

Library - tools v2.12.lua

  • Like 2
Posté(e) (modifié)

Une remarque sur les performances.

Sur une grosse config (pas loin de 200 règles), la consommation CPU est divisée d'un facteur d'environ 10.

C'est énorme.

Ce qui signifie aussi que tous les traitements sont accélérés, aussi bien la boucle infinie avec rafraichissement de 30 secondes, que les événements instantanés.

 

J'ai constaté que tous les appels à l'API Fibaro (via les fonctions fibaro.* et api.*), sont extrêmement lents. On ne s'en rend pas compte dans un usage normal, mais dans le cas de GEA, qui effectue plusieurs centaines d'appels par minute, le temps cumulé est énorme.

L'amélioration des performances a donc principalement consisté à mettre en place un système de cache local.

Exemple concret, supposons plusieurs règles qui testent la valeur d'un profil, d'une variable globale, de la valeur de température d'un module, etc.... ça faisait autant de lecture de la même info plusieurs dizaines de fois pour rien. La première fois, la valeur est lue, puis conservée en cache (de simples tables LUA), pour être réutilisée quasiment instantanément lors du passage sur la règle suivante.

Évidemment, à chaque déclenchement de GEA (c'est à dire à chaque boucle de 30s ou à chaque déclenchement instantané), le cache est vidé afin de forcer une nouvelle lecture des données.

Autre cas où le cache est vidé : lorsqu'une règle déclenche une action de modification. Exemple : on modifie une variable globale, il faut vider le cache afin que la règle suivante, si elle lit la même variable, reprennent bien la nouvelle valeur.

 

Ce cache est donc l'axe d'amélioration principal des performances.

Plus quelques optimisations par ci par là sur le code.

Il serait encore possible de gagner en performance, mais ça oblige à modifier profondément GEA, je ne suis pas encore prêt (c'est que GEA est sacrément complexe....)

C'est déjà très bien comme ça.

 

Sur ma box de prod, je ne dépasse quasiment plus les 0.5% de CPU utilisé, alors qu'avant ces optimisations, je dépassais facilement 5%, voire 10% de CPU. Ce qui se ressentait sur les scénarios, lumières qui s’allument en retard, etc.

 

La consommation CPU du QuickApp est maintenant affichée à coté de la RAM :

 

image.thumb.png.a7fd3b81dfda1610a6a7a1afcc278e9a.png

 

Sur la capture d'écran ci-dessus, on voit également l'amélioration de l'affichage des déclencheurs/triggers, puisqu'on voit le nom, la pièce, la propriété. Ce sont des infos qui étaient visibles dans les toutes premières version de GEA sur HC2 v3, mais que @Steven avait dû retirer lors du passage en v4, avec justement la même gestion de la DB que sur HC3, et les lenteurs d'accès aux fonctions fibaro() et api(). Maintenant grâce à la mise en place du cache, ce problème est résolu. C'est aussi l'avantage du QuickApp, l'espace mémoire est partagé entre toutes les fonctions, là où les scènes sur HC2, avec leurs instances différentes, avaient leur propre espace mémoire, donc impossible de partager des données.

 

Modifié par Lazer
  • Like 2
Posté(e)

Sorry, long text in english but I don't trust Google translate :-)

 

A cache is a really good idea, but can be tricky also.

In my emulator I cache fibaro calls as it can run faster than realtime and calling the HC3 then becomes a bottle-neck. But I only cache when running faster than realtime.

It's not just a read cache as I update it when setting properties or calling actions too.

The reason is that

fibaro.call(x,'turnOn'); 

if fibaro.getValue(x,'value') then ... end

wouldn't work as getValue would retrieve the cached value unless I update the property when doing the turnOn.

This is not a fool-proof method as I can't guess how all actions will affect properties.

If someone does 

fibaro.call(MY_QA,"test")

if fibaro.getValue(x,"value") then ... end

and MY_QA test function updates device x's value property I miss it. That's why I only use it when speeding...

 

In my EventRunner rule engine, I don't cache values at all due to the issue above. I probably could but it requires quite a lot of code to be fool-proof, because rules can have code similar to the above.

 

I was thinking if this is also a problem for GEA? I guess you could say that all rules in GEA run in "parallel" and should see the same state. Then it works to keep a cache for an invocation and clear it before the next.

In my system the rules are run sequentially, top to bottom, and some combinations of rules depend on that. E.g. if two rules are triggered, the first rule could change a value that the second rule could use.

Then I don't know if you can change a value in a single rule and expect to use that changed value later in the rules action part?

 

What I have done instead is that I focus on keeping down the number of rules being called by triggers.

If I have a rule that looks like:

"IF ID1:isOn and ID2:power < 5 THEN ...END"

My "rule compiler" look at the test part between IF and THEN and see that 2 device properties are involved in the test.

...and thus only 2 events can be a reason to trigger that rule

{type='device', id=ID1, property='value'}

{type='device', id=ID2, property='power'}

 

With an "intricate" hash schema I associate the rule with these 2 events so if they come into the system I can quickly lookup what rule(s) to run.

This allows the system's cpu usage to not be directly dependent on the number of rules as only relevant rules are triggered by incoming events and I don't have to run all of them.

 

 

 

Posté(e)

Bonjour Lazer.

 

J'ai fait la MAJ en 7.30, et j'ai maintenant une règle qui est exclue :

[04.07.2021] [10:41:28] [ERROR] [QA_GEA_1129]: Ajout auto #26 : ["VariableCache",["OFFPalier","Fin10mn"]] => ["Ask",[[641,1088],"QUESTION : ","Voulez-vous allumer le palier ?",249]] ["VariableCache",["OFFPalier","NotUse"]] Règle exclue :

J'ai controlé par rapport à la syntaxe en 7.30, mais je ne vois pas le problème.

Voici la règle dans Gea :

GEA.add({"VariableCache","OFFPalier","Fin10mn"}, 30, "", {{"Ask", {id["ID_IPHONE_MANU"],id["ID_IPHONE_ANNO"]},"QUESTION : ","Voulez-vous allumer le palier ?",249},{"VariableCache", "OFFPalier", "NotUse" } } )	-- Ask lance la scene 249 (Palier ON-OFF)

Merci.

Posté(e)

@manuxenon

Y'a même pas de message d'erreur..... comme d'habitude, tu peux activer self.debug=true et self.lldebug=true

(et isole ta règle fautive)

 

@jang

Je répond en français, je pense que Google Translate saura traduire à peu près correctement vers l'anglais.

 

Tu as raison, l'appelle d'une méthode d'un QA peut modifier des propriétés.

J'y ai pensé, et mon système de cache est censé le gérer.

Il y a plusieurs caches.

Une table LUA pour les propriétés des devices

Une table LUA pour les variables globales

Une table LUA pour les profiles

etc.

 

Prenons un exemple, la table des propriétés des devices. Elle a une structure comme telle, qui est remplie au fur et à mesure de la lecture des propriétés :

self.cachedDeviceProperties = {
	3 = {
		Temperature = 20
	},
	10 = {
		value = true,
		power = 100
	}
}

Dans cet exemple, le premier index est l'ID des devices, et le second index représente les propriétés de chaque device.

Ce tableau est créé et rempli dans la fonction GEA:getDeviceProperty(id, property)

 

Maintenant, quand une action est effectuée sur un device, le plus simple est de supprimer du cache toutes les propriétés de ce device :

self.cachedDeviceProperties[id_num] = {}

Cela répond au problème de l'appel d'une méthode qui est susceptible de modifier plusieurs propriétés d'un device.

 

Dans d'autres situations, par exemple les actions "Dead", "Polling", "ApiGet", "ApiPost", etc... et aussi à chaque démarrage d'une nouvelle boucle de GEA, on force la suppression complète de la table avec self.refreshDeviceProperties = true (qui sera traité dans la fonction cachedDeviceProperties()).

Ainsi, normalement on ne devrait jamais avoir de cas où une propriété n'est pas à jour.

 

Le principe est similaire pour tous les autres objets stockés en cache : labels et sliders des QA, zone de climat, partition d'alarme, variables globales, variables de Quickapp, propriétés de scènes, météo, profile actif, paramètres systèmes

 

J'ai essayé de faire court, j'espère que c'est clair.

Posté(e) (modifié)

Merci Lazer :  j'ai mis le debug sur true, mais la règle 26 est toujours exlue :

[04.07.2021] [12:49:15] [ERROR] [QA_GEA_1129]: Ajout auto #26 : ["VariableCache",["OFFPalier","Fin10mn"]] => ["Ask",[[641,1088],"QUESTION : ","Voulez-vous allumer le palier ?",249]] ["VariableCache",["OFFPalier","NotUse"]] Règle exclue :
[04.07.2021] [12:49:15] [DEBUG] [QA_GEA_1129]: GEA:addEntry([331,139], -1, "", [["RestartTask",25],["VariableCache","OFFPalier","NotUse"]], "Detection de mouvement Palier. Relance du compteur, le #date# à #time#.")
[04.07.2021] [12:49:15] [DEBUG] [QA_GEA_1129]: GEA:addEntry(333, 120, " - Extinction de l’#name# après #duration#, le #date# à #time#.", [["turnOff"],["Global","Karotz","L’escalier est éteind. Il était allumé depuis #durationfull#"]])

 

Si la règle 25 se déclenche, j'ai ce message :

[04.07.2021] [12:51:47] [DEBUG] [QA_GEA_1129]: @150s [Validation*] #25 : [331] => ["TurnOff"] ["VariableCache",["OFFPalier","Fin10mn"]]
[04.07.2021] [12:51:47] [DEBUG] [QA_GEA_1129]: GEA:check() difftime(60.0) >= 60
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]:    [Démarrage] #25 : [331] => ["TurnOff"] ["VariableCache",["OFFPalier","Fin10mn"]]
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]:         [action] ["TurnOff"]
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]:         [action] ["VariableCache",["OFFPalier","Fin10mn"]]
[04.07.2021] [12:51:48] [ERROR] [QA_GEA_1129]: ./include/main.lua:3336: bad argument #3 to 'gsub' (number expected, got boolean)
[04.07.2021] [12:51:48] [ERROR] [QA_GEA_1129]: ./include/main.lua:3336: bad argument #3 to 'gsub' (number expected, got boolean)
[04.07.2021] [12:51:48] [ERROR] [QA_GEA_1129]: ./include/main.lua:3336: bad argument #3 to 'gsub' (number expected, got boolean)
[04.07.2021] [12:51:48] [ERROR] [QA_GEA_1129]: ./include/main.lua:3336: bad argument #3 to 'gsub' (number expected, got boolean)
[04.07.2021] [12:51:48] [ERROR] [QA_GEA_1129]: ./include/main.lua:3336: bad argument #3 to 'gsub' (number expected, got boolean)
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]: GEA:encapsule() copy.check() copy.name=333 id=333 property=333 value=333 value2=333 value3=333 value4=333
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]: GEA:encapsule() copy.getValue() 2 return copy.lastvalue, copy.lastDisplayValue : false, false
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]: GEA:encapsule() copy.check() result = false
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]: GEA:check() result = false, false
[04.07.2021] [12:51:48] [DEBUG] [QA_GEA_1129]: GEA:check() ready = false

Le code de la ligne 3336 :

-- --------------------------------------------------------------------------------
-- Cherche un mot dans le tableau source et retourne sa valeur dans du tableau destination
-- --------------------------------------------------------------------------------
function GEA:translate(word, tableSource, tableDest)
	for k, v in pairs(tableSource) do if tostring(v):lower() == tostring(word):lower() then return tableDest[k] end end
end

 

Pour info, c'est la régle 25 qui doit lancer la 26 :

local myTask3 = GEA.add(id["LUMIERE_PALIER"],1*60, " - Extinction de la lumière du #name# après #duration#, le #date# à #time#.", { {"turnOff"},{"VariableCache", "OFFPalier", "Fin10mn"} } )
GEA.add({id["LUMIERE_PALIER"],id["MOUV_PALIER"]},-1, "", { {"RestartTask",myTask3},{"VariableCache", "OFFPalier", "NotUse"} }, "Detection de mouvement Palier. Relance du compteur, le #date# à #time#.")

Pour rappel, règle 26 :

GEA.add({"VariableCache","OFFPalier","Fin10mn"}, 30, "", {{"Ask", {id["ID_IPHONE_MANU"],id["ID_IPHONE_ANNO"]},"QUESTION : ","Voulez-vous allumer le palier ?",249},{"VariableCache", "OFFPalier", "NotUse" } } )	-- Ask lance la scene 249 (Palier ON-OFF)

 

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

Tiens, tu peux essayer cette version 7.31

 

J'ai effectivement corrigé une erreur dans "Ask", un caractère s'était malencontreusement introduit...

J'en ai profité pour améliorer cette option, on peut maintenant identifier la Scène ou le QuickApp à appeler par son nom.

 

GEA v7.31.lua

 

Modifié par Lazer
Posté(e) (modifié)
19 hours ago Lazer said:

In this example, the first index is the device ID, and the second index represents the properties of each device.

This array is created and filled in the GEA function: getDeviceProperty (id, property)

 

Now, when an action is performed on a device, the easiest way is to delete all the properties of that device from the cache :


  

This addresses the problem of calling a method that is likely to modify several properties of a device.

 

In other situations, for example the actions "Dead", "Polling", "ApiGet", "ApiPost", etc ... and also at each start of a new loop of GEA, one forces the complete deletion of the table with self .refreshDeviceProperties = true (which will be processed in the cachedDeviceProperties () function).

So normally there should never be a case where a property is not up to date.

 

The principle is similar for all the other objects stored in cache: QA labels and sliders, climate zone, alarm partition, global variables, Quickapp variables, scene properties, weather forecast, active profile, system parameters

 

I tried to keep it short, hope this is clear.

Ok, you seems to have it covered. Fingers crossed :) 

Btw, you could add some counters for cache hits and misses - nice stats to see.

Modifié par jang
  • Like 1
Posté(e)

"There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.

Posté(e)

J'ai des lignes qui font planter mon GEA. J'ai mis un peu de temps à les isoler, voici le debug :

[06.07.2021] [09:30:42] [DEBUG] [QA_GEA_26]: @30s [Validation*] #66 : ["Value!",["Jardin",0]] ["Global",["Jour_Nuit","Jour"]] => ["TurnOff",["Jardin"]]

[06.07.2021] [09:30:42] [DEBUG] [QA_GEA_26]:    [Démarrage] #66 : ["Value!",["Jardin",0]] ["Global",["Jour_Nuit","Jour"]] => ["TurnOff",["Jardin"]]

[06.07.2021] [09:30:43] [DEBUG] [QA_GEA_26]:         [action] ["TurnOff",["Jardin"]]

[06.07.2021] [09:30:43] [ERROR] [QA_GEA_26]: ./include/main.lua:3340: bad argument #3 to 'gsub' (number expected, got boolean)

 

La ligne correspondante dans le code, est la suivante (elle semble ne pas réussir à récupérer le nom du module, et plante l'appel au "name"):

-- --------------------------------------------------------------------------------

-- Remplace les éléments du message

-- --------------------------------------------------------------------------------

function GEA:getMessage(message, forAnalyse, forLog)

    if not forAnalyse then

        if not message then message = self.currentEntry.message end

        message = tostring(message)

        message:gsub("(#.-#)", function(c)

            local position = tonumber(c:match("%[(%d+)%]") or 1)

            c = c:gsub("%[","%%%1"):gsub("%]","%%%1")

            if c:find("value") then message = message:gsub(c, tostring(self.options.result.getValue(position))) end

            if c:find("name") then message = message:gsub(c, self.options.name.getValue(position)) end

            if c:find("room") then message = message:gsub(c, self.options.room.getValue(position)) end

        end)

    end

Posté(e)

Je pense qu'il faut même que je te donne plus d'éléments sur ce bug.

 

Suite à la mise à jour sur la dernière version, mon GEA s'arrêtait sur l'exécution de cette ligne au cycle "30s" :

GEA.add({{"Value!","Spot",0},{"Global","Jour_Nuit","Jour"}},30,"GEA HC3 : Lampe #name# allumée en journée",{"turnOff"})

 

Pas de message d'erreur dans le debug, juste que GEA n'allait pas plus loin. Je sais que ce module est un peu bizarre, car cette ligne s'exécute à chaque redémarrage de GEA, même si la lampe est éteinte.

 

Je ne sais pas trop comment j'ai pensé à la suite, mais j'ai désactivé cette ligne :

GEA.output = function(message) fibaro.setGlobalVariable("Pushover", message) end

 

Et là, miracle, j'ai commencé à voir le message que j'ai cité plus haut, faisant toujours référence à ma ligne qui plantait (et les suivantes aussi), à savoir :

    GEA.add({{"Value!","Spot",0},{"Global","Jour_Nuit","Jour"}},30,"GEA HC3 : Lampe #name# allumée en journée",{"turnOff"})

    GEA.add({{"Value!","Lampes",0},{"Global","Jour_Nuit","Jour"}},30,"GEA HC3 : Lampes #name# allumée en journée",{"turnOff"})

   GEA.add({{"Value!","Escalier",0},{"Global","Jour_Nuit","Jour"}},30,"GEA HC3 : Lampe #name# allumée en journée",{"turnOff"})

   GEA.add({{"Value!","Jardin",0},{"Global","Jour_Nuit","Jour"}},30,"GEA HC3 : Lampe #name# allumée en journée",{"turnOff"})

 

Du coup, j'ai supprimé toutes les occurences #name# de ma config GEA, et cela tourne sans soucis (j'ai même pu réactiver le GEA.output)

A noter que les #duration# ne posent aucun problème.

 

 

Posté(e) (modifié)

Effectivement, merci de m'avoir aiguillé, c'était bien un bug introduit depuis la version 7.30.

 

Voici donc la version 7.32 :

  • Corrige le #name#
  • Corrige l'option "Parameter"

 

GEA v7.32.lua

 

Modifié par Lazer
  • Like 1
Posté(e) (modifié)

Bonsoir,

 

la commande suivante ne fonctionne plus chez moi depuis quelques temps (j'ai installé la 7.31 et fait l'updates des tools, mais le pb subsiste)

GEA.add(164,-1,"test",{{"RoomLights","Cuisine","turnOn"}})


le log donne ça : 
[09.07.2021] [22:10:01] [DEBUG] [QA_GEA_240]:    [Démarrage] #106 : [164] => ["RoomLights",["Cuisine","turnOn"]]

[09.07.2021] [22:10:01] [DEBUG] [QA_GEA_240]:         [action] ["RoomLights",["Cuisine","turnOn"]]

[09.07.2021] [22:10:01] [ERROR] [QA_GEA_240]: Erreur, vérifier : ["RoomLights",["Cuisine","turnOn"]]

 
 
Je ne sais pas trop quoi faire car je n'ai rien touché à ma config, la commande "RoomLights" fonctionnait bien. J'ai bien checké les majuscules de la commande "turnOn", normalement c'est bon.
Je vois dans le log un rajout de crochet dans l'action mais ne j'ai pas ça dans ma commande.
 
Merci pour le coup de main. J'utilise "RoomLights" pour eteindre automatiquement les lumières après un certain délai, du coup chez moi c'est Versailles.... :)
 
 
------
Idem en 7.32 
 
Modifié par ggpublic
test en 7.32
Posté(e)

Effectivement, désolé pour ce bug, je pense avoir trouvé ce qui pose problème.

PS : la prochaine fois pense à activer GEA.debug = true

 

Voici la version 7.33 :

  • Corrige le bug de "RoomLights"

GEA v7.33.lua

 

  • Like 1
×
×
  • Créer...