Aller au contenu

Recommended Posts

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

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

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...

Partager ce message


Lien à poster
Partager sur d’autres sites

Tu peux fournir un exemple ?

Partager ce message


Lien à poster
Partager sur d’autres sites

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.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

@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é...

Partager ce message


Lien à poster
Partager sur d’autres sites

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:

  1. Tu peux utiliser un autre setTimeout pour vérifier régulièrement ta variable (cohérent avec ta démarche asynchrone).
  2. 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.

Partager ce message


Lien à poster
Partager sur d’autres sites

@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... :2:
Modifié par OJC

Partager ce message


Lien à poster
Partager sur d’autres sites

Bah parfait alors...


Envoyé de mon iPhone en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

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é par OJC
  • Like 1

Partager ce message


Lien à poster
Partager sur d’autres sites

×