Aller au contenu

Empêcher une function de bloquer un script


Shad

Messages recommandés

Après discussion avec Andrew, il m'a donnée une fonction très intéressante pour empêcher une fonction de faire planter un script.

Celui-ci m'a été surtout donnée pour le main loop d'un virtual device, pour éviter que le main loop ne plante et ne redémarre pas.

local ok = pcall(function()
  --
  -- place here the code that can raise an error
  --
  -- wrong json string
  test = json.decode('{"a:2}')
  fibaro:debug(test.a)
end)

if (not ok) then
  fibaro:debug('decode raised an error')
end

Remplacer la partie après function() avec la partie de votre code complète qui exécutera une commande ou il peut y avoir une erreur comme Net.FHttp. Par exemple pour récupérer un json, le parser et faire ce que vous voulez avec le informations récupérés.

 

Pour info après quelque recherche, la fonction pcall retourne une valeur TRUE ou FALSE pour ceux que sa intérresse.

Lien vers le commentaire
Partager sur d’autres sites

J'avais expliqué tout cela sur mon post ici http://www.domotique-fibaro.fr/index.php/topic/109-ping-dun-%C3%A9quipement-r%C3%A9seau/ (en dessous du code) :)

 

Pour faire simple: La fonction LUA pcall permet l’exécution du code en mode "protégé" ou "encapsulé", c'est à  dire qu' il ne lèvera pas d' erreur dans le processus de votre box si jamais le code provoquait une erreur. La box est protégée, vos scènes aussi, mainloop, etc..

 

Aussi à  savoir: pcall, retourne true ou false en fonction de la réussite du code comme Shad a précisé mais peut aussi retourner un résultat issue de la fonction en utilisant la méthode interne error.

 

La fonction pcall peut-être utilisé pour faire en LUA du try..catch... pour ceux qui connaissent.

 

Des exemples ici pour comprendre: http://www.lua.org/pil/8.4.html, http://www.lua.org/pil/8.5.html

Lien vers le commentaire
Partager sur d’autres sites

Mouais seulement je viens de découvrir avec le main, quand le problème sur le quel on a parler sur le forum officielle commence, grâce a cette fonction le main loop n'est pas bloquer, mais il ne se réinitialise pas pour autant.

Sa veut dire que même lorsque le main loop recommence, le problème est toujours la.

Faudrait une solution pour réinitialiser le main loop en plus de sa.

 

Krikroff, faut que je lise mieux les poste car je m'étais arrêter sur le ping de l'équipement :D

Lien vers le commentaire
Partager sur d’autres sites

C'est normal parceque si il n'y a pas d'erreur (merci pcall) le MainLoop n'arrête pas son processus, et comme tout ce qui est créé dans le loop vie tout au Long de l'existence du loop ! Alors problème ...

Pour résoudre ton problème Shad je ferais ceci:

Déclarer mon Fhttp en global et si erreur détectée par le pcall alors libérer la variable et recréer le socket FHttp. Je procède aisini et je n'ai plus de problème :-)

Lien vers le commentaire
Partager sur d’autres sites

J'ai bien l'impression que le main loop est une sorte de fonction dans une boucle while ;-)

Pour éviter tout problème et isoler mes process j'utilise des fonctions avec tout déclaré en local dedans et par exemple mon socket déclare lui sans local àl'extérieur de mes fonctions comme cela mon socket est accessible dans toutes les fonctions.

Lien vers le commentaire
Partager sur d’autres sites

C'est ce que j'ai presque fais :D.

 

Je ne l'avais pas passé en local mais juste.

 

XBMC = Net.FHttp('192.168.5.25', 8080);

 

 

Donc j'ai relancer un films de 2h pour essayer, j'en suis a 25min sans problème.

En espérant que sa dure, car j'aimerais bien faire ma release maintenant ^^.

Lien vers le commentaire
Partager sur d’autres sites

Il va falloir que je regarde de plus près ce que vous indiquez

J'ai remplacé 2 modules virtuels et une scène pour récupérer mes infos Netatmo par un seul module virtuel dont je n'utilise que le main loop

Et après 48 heures de fonctionnement, je me suis rendu compte que je n'avais plus de mise àjour des infos remontées de Netatmo (contrairement àl'application dédiée)

J'en conclu que le main loop s'est bloqué et si j'ai bien compris sur le forum officiel, je ne suis pas le seul àconstater le problème

Lien vers le commentaire
Partager sur d’autres sites

La je suis sur mon smartphone donc dure de faire quelque chose de propre mais j'essaie dans la soirée de vous proposer un bout de code pour monitorer le cycle de vie du MainLoop , nous pourrons àplusieurs peut mettre en évidence un problème ou pas !

J'ai plusieurs VD qui tournent sans problème en main loop et pourtant il y a du monde en sockets ;-)

Lien vers le commentaire
Partager sur d’autres sites

Voila j'ai fait un script watchdog afin de surveiller le Mainloop, cela tourne depuis 2h00 du matin donc depuis plus de 10H et tout va bien ;-) je croise les doigts !

 

Refresh tous les 10 secondes.

 

mainloop watchdog

 

Je posterais le code ;) si cela intéresse quelqu'un ?

Il y aura une version local et une avec envoi vers thingspeak pour historiser tout cela...

Lien vers le commentaire
Partager sur d’autres sites

Je viens de relancer à  la main mon mainloop avec debug et cette fois-ci j'obtiens ce message :

[ERROR] 11:05:03: line 14: attempt to index field 'body' (a nil value)

Dans le code que j'avais récupéré, il manque un contrôle de code erreur

 

Le code du main loop

--[[
%% autostart
%% properties
%% globals
--]]

-- Setting up the connection data 
FHTE = Net.FHttp("www.xxxxxxxxx.com") 
-- Netatmo extérieur
response = FHTE:GET("/netatmo/netatmo.php?intext=ext") 
-- decoding json string to table 
result = json.decode(response) 
temperature_exterieure = result.body[1].value[1][1];
humidite_exterieure =result.body[1].value[1][2];
-- variable globale pour info sms
fibaro:setGlobal("tempext", "Température extérieure : "..temperature_exterieure.."°C")
-- Netatmo intérieur
response = FHTE:GET("/netatmo/netatmo.php?intext=int") 
-- decoding json string to table 
result = json.decode(response) 
temperature_interieure = result.body[1].value[1][1];
co2 =result.body[1].value[1][2];
humidite_interieure =result.body[1].value[1][3];
pression =result.body[1].value[1][4];
bruit =result.body[1].value[1][5];
-- variable globale pour info sms
fibaro:setGlobal("tempint", "Température intérieure : "..temperature_interieure.."°C")
-- affichage infos dasn module virtuel
fibaro:call(114,"setProperty","ui.temperature.value",(temperature_interieure.."°C / "..temperature_exterieure.."°C"))
fibaro:call(114,"setProperty","ui.humidite.value",(humidite_interieure.."% / "..humidite_exterieure.."%"))
fibaro:call(114,"setProperty","ui.pression.value",(pression.." mbar"))
fibaro:call(114,"setProperty","ui.co2.value",(co2.." ppm"))
fibaro:call(114,"setProperty","ui.bruit.value",(bruit.." dB"))
-- tempo de 6 minutes
fibaro:sleep(360*1000); 
Lien vers le commentaire
Partager sur d’autres sites

C'est "tout simple"...

Sans rien toucher au code, j'ai relancé plus tard le main loop et cette fois-ci sans erreur

Le problème doit venir du fait que Net.FHttp ne récupérait plus la valeur "humidité extérieure" provenant de Netatmo

Ce qui faisait planter le mainloop... et comme je ne fais aucun contrôle dans le script  :(

 

Ton watchdog sera bien utile  ;)

Lien vers le commentaire
Partager sur d’autres sites

i-magin, pour résoudre ton problème il faut ajouter cela ton ton code

if (response~= nil) then
local result = json.decode(response) ;
if (result ~= nil) then
  -- place ton code ici result.body ....
else
  fibaro:debug("le script netatmo est inaccessible!");
end
end

Au moins il n'y aura pas d'erreur...

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...