pepite Posté(e) le 1 novembre 2016 Signaler Posté(e) le 1 novembre 2016 Bonsoir, Lis ca, tu vas comprendre, c'est la fonction fibaro:get qui permet de récuperer les 2 informations http://www.fibarouk.co.uk/support/lua/library/fibaroget/
lamparo Posté(e) le 1 novembre 2016 Signaler Posté(e) le 1 novembre 2016 Bonsoir, Lis ca, tu vas comprendre, c'est la fonction fibaro:get qui permet de récuperer les 2 informations http://www.fibarouk.co.uk/support/lua/library/fibaroget/ Tu es un chef merci pour le coup de pouce, je galère pour trouver les bonnes commandes. @+ JP 1
OJC Posté(e) le 12 novembre 2017 Signaler Posté(e) le 12 novembre 2017 Pour information à destination de ceux qui se poseraient la question setTimeout est incompatible avec la boucle while : si cette dernière tourne au moment du timeout, la fonction définie dans setTimeout ne s'exécute pas...
Krikroff Posté(e) le 12 novembre 2017 Signaler Posté(e) le 12 novembre 2017 Tu peux fournir un exemple ?
Lazer Posté(e) le 13 novembre 2017 Signaler Posté(e) le 13 novembre 2017 En fait, ce n'est pas spécialement une boucle "while" qui pose problème, c'est tout traitement synchrone commencé doit être terminé en entier avant que le code appelé par Settimeout commence à s'exécuter en asynchrone. Facile à mettre en évidence avec un simple sleep() de plusieurs secondes, lequel serait la dernière instruction d'une suite de commandes (sans boucle donc)... on voit clairement que le code appelé par settimout ne commence qu'après ce sleep.
OJC Posté(e) le 14 novembre 2017 Signaler Posté(e) le 14 novembre 2017 @Lazer C'est exactement ça, dit bien mieux que je ne saurais le faire. Concrètement, je suis sur Heating Manager avec le cycle de chauffage qui est relancé à intervalles réguliers via setTimeout. Pour prendre en compte les changements de consigne de manière satisfaisante et pouvoir faire passer une information entre deux instances d'une scène, j'ai essayé de passer par une variable globale qui est scannée en permanence par une boucle while. Et pendant qu'elle tourne, le cycle n'est pas relancé...
Krikroff Posté(e) le 14 novembre 2017 Signaler Posté(e) le 14 novembre 2017 D'une manière générale j’évite l'utilisation des boucles "while" dans les scripts LUA si je n'ai pas la maîtrise à 100% de son comportement. Après tu peux très bien mixer synchrone et asynchrone mais cela demande d’écrire du code pour le gérer correctement et surtout une réflexion préliminaire afin de bien penser l'architecture. Bon, a tout problème existe une solution, tu peux peut-être adapter simplement ton code, deux pistes: Tu peux utiliser un autre setTimeout pour vérifier régulièrement ta variable (cohérent avec ta démarche asynchrone). Tu peux mettre un trigger sur la variable afin de déclencher un traitement en cas de modification de cette dernière ? J'utilise cette technique ici par exemple https://www.domotique-fibaro.fr/topic/1956-notification-center/?tab=comments#comment-24645. .
OJC Posté(e) le 14 novembre 2017 Signaler Posté(e) le 14 novembre 2017 (modifié) @Krikroff Après tests, j'avais écarté le trigger sur la variable (je ne sais plus pourquoi, j'ai tellement tourné le truc dans tous les sens ) Mon problème était de recalculer la commande de chauffe à chaque modification de la consigne, plutôt que d'arrêter ou lancer le chauffage jusqu'à la fin du cycle en cours (ce que j'avais fait initialement et qui est une solution passable sur un cycle de 10' mais un peu bâtarde sur un cycle de 30' ou 45'), et ce en faisant en sorte que le setTimeout du cycle principal ne fasse pas sa life en coupant le chauffage selon la commande de chauffe précédente alors que la nouvelle imposerait de continuer à chauffer. Donc il me fallait faire passer l'info non seulement du VD à la scène, mais entre deux instances de la scène... Je me suis bien arraché les cheveux, et au final, j'ai utilisé setTimeout pour scanner en permanence non pas une variable mais le VD directement. Au final, c'est incomparablement plus simple et cela me permet, en plus, de virer tous les triggers et de n'avoir en permanence qu'une seule instance de la scène (au lieu d'une instance pour le cycle principal et d'une nouvelle instance de courte durée à chaque modification de la température de consigne). C'est le même code qui est utilisé dans les deux cas, avec juste un paramètre de plus pour éviter l'arrêt non désiré de la chauffe. Bref... J'imagine que c'est plus clair pour moi qui ai le nez dedans que pour vous... Modifié le 14 novembre 2017 par OJC
Krikroff Posté(e) le 14 novembre 2017 Signaler Posté(e) le 14 novembre 2017 Bah parfait alors...Envoyé de mon iPhone en utilisant Tapatalk
OJC Posté(e) le 14 novembre 2017 Signaler Posté(e) le 14 novembre 2017 (modifié) Voilà le code pour mieux comprendre mon propos : Révélation function HeatingManager:startCycle(item, P, hC, isOverride) if (auto_kP and params_kP.learning[tostring(item.heater)]) then HeatingManager:setCoefficients(item) end item.stopTime = os.time() + hC if (P > 0) then HeatingManager:startHeater(item, hC) if (P < 1) then params_kP.learning[tostring(item.heater)] = not (isOverride) setTimeout(function() if (os.time() >= item.stopTime) then HeatingManager:stopHeater(item) end end, hC * 1000) end else if (logInfo) then lib:log("[INFO] Heating is not required in ".. item.room .. "( " .. item.name .. ")") end HeatingManager:stopHeater(item) end end function StartHeatingManager() local P, hC = 0, 0 for _, item in ipairs(collection) do if (logInfo) then lib:log("[INFO] Checking " .. item.room .. "( " .. item.name .. ")...") end P, hC = HeatingManager:getCommand(item) HeatingManager:startCycle(item, P, hC) end setTimeout(StartHeatingManager, maxCycle * 60 * 1000) end function StartOverrideManager() local curSetpoint, P, hC = 0, 0, 0 for _, item in ipairs(collection) do curSetpoint = lib:temp2num(fibaro:getValue(getLinkedID("Panel"), "ui." .. item.panel .. ".value")) if curSetpoint ~= item.lastSetpoint then lib:log("[INFO] Setpoint has changed for " .. item.room) P, hC = HeatingManager:getCommand(item) HeatingManager:startCycle(item, P, hC, true) end end setTimeout(StartOverrideManager, 1000) end C'est la fonction StartOverrideManager() qui scanne en permanence le VD pour détecter un changement de la consigne et qui recalcule la commande de chauffe. Dans la fonction StartCycle() se trouve la fonction setTimeout qui se charge de couper le chauffage à la fin de la période de chauffe en vérifiant s'il a le droit de le faire. Modifié le 14 novembre 2017 par OJC 1
Messages recommandés