Aller au contenu

Incompréhension Dans Les Net.httpclient


jjacques68

Messages recommandés

Bonjours,

 

J'ai évoqué ce problème dans un autre post et je préfère en rouvrir un consacré que à  ce problème.

 

J'ai beaucoup de mal à  comprendre le principe de fonctionnement des commandes Net.HTTPClient ou encore Net.HTTP ou encore NET.FHTTP...

Pire encore ça marche facile dans les modules et pas dans les scènes !!

 

bref un vrai casse tête. :13:

 

Pour illustrer mon affaire voici une petite scène qui relève le compteur1 d'un ipx800 et la stocke dans une variable locale "essai" :

--[[
%% properties
%% events
%% globals
--]]

local essai=0
fibaro:debug(essai)
local http = net.HTTPClient()
http:request("http://192.168.xx.xx/api/xdevices.json?cmd=40", {
	options = {method = 'GET', headers = {['Authorization'] = "BASIC xxx="},},
	success = function(response)
    		     jsonResponse = json.decode(response.data)
        	     essai = jsonResponse.C1
      		     fibaro:debug(essai)        		
      		  end,
	error = function(response)
    		   fibaro:debug("Error: " ..response)
    		end
})  
fibaro:sleep(1000)
fibaro:debug(essai)  

LOGIQUEMENT !!!!

 

essai = 0 au début de la scène ! ET doit prendre ensuite la valeur du compteur !

 

le debug devrait donner ça !

 

0

valeur_du_compteur

valeur_du_compteur

 

Mais non !!! mon debug m'affiche :

 

0

0

valeur_du_compteur

 

On dirait que la fonction "success" est appelée à  la fin de la scène !! je n'y comprends rien !!! :15:

Les 2 fibaro:debug qui ne sont pas dans la fonction success sont executés en premier !!

 

Comment utiliser alors la valeur qu'elle récupère ??

 

Je vous remercie d'avance pour votre aide !!

Lien vers le commentaire
Partager sur d’autres sites

J'ai trouvé un début d'explication :

 

http://www.domotique-fibaro.fr/index.php/topic/311-ipx800-v3/page-11

 

Si @Gazous pouvait passer par là  et m'expliquer ceci ???

 

 

Par contre pour bien traiter ton appel, tu devras dans la,section error rappeller relancer ta scene ou ta requête après un petit sllep de 1 seconde par exemple.

Lien vers le commentaire
Partager sur d’autres sites

Alors en passant par une function qui est appelée dans le success de la requête HTTP c'est top !! - merci @Gazous !!

 

mais maintenant je souhaite faire 3 appels de cette requête espacés de 10 seconde pour relevé 3 fois le compteur.

Et là  ça plante, aucune réponse !!! voici le code :

local essai=0
local i = 1

while i <= 3 do --pour récupérer 3 fois la valeur du compteur

function affiche() -- function pour utilise le retour du compteur ->OK
  essai = jsonResponse.C1
  fibaro:debug(essai)
  i=i+1 --incrémente une variable pour sortir de la boucle 
  fibaro:sleep(10*1000) --10 secondes entre chaque récupération
end

local http = net.HTTPClient() --connexion à  IPX800
http:request("http://192.168.xx.xx/api/xdevices.json?cmd=40", {
	options = {method = 'GET', headers = {['Authorization'] = "BASIC xxx="},},
	success = function(response)
    		     jsonResponse = json.decode(response.data)
        	     affiche() --utilisation du retour       		
      		   end,
	error = function(response)
    		   fibaro:debug("Error: " ..response)
    		end
})
  
end

une idée ?

Lien vers le commentaire
Partager sur d’autres sites

Je pense que "i" étant "local" dans le corps principal du programme il n'est pas connu dans la fonction "affiche".

 

Le "sleep" serai mieux en ligne 25.

 

J'ai le sentiment que ton code génère une foultitude de "request" ce qui fait exploser le tout.

Lien vers le commentaire
Partager sur d’autres sites

attention, l'utilisation de la fonction net.HTTPClient() est asynchrone.

donc ton code ne s'exécute plus de façon linéaire, d'où les comportements étranges que tu constates.

 

Tu ne peux plus utiliser la commande sleep(), et il faut que tu utilises setTimeout() qui est également asynchrone, comme net.HTTPClient()

Regarde le code de ma scène Watchdog, il fait utilisation des 2 fonctions imbriquées.

 

Berale24 avait aussi fait un tuto sur l'utilisation du setTimeout() sur le forum, et de mémoire il en existe un autre, très complet et en anglais sur le forum officiel.

Lien vers le commentaire
Partager sur d’autres sites

Alors, voici le code qui fonctionne :

local essai=0
local i=0

function Recup()
  local http = net.HTTPClient() --connexion à  IPX800
  http:request("http://192.168.xx.xx/api/xdevices.json?cmd=40", {
  options = {method = 'GET', headers = {['Authorization'] = "BASIC xxx="},},
  success = function(response)
	      jsonResponse = json.decode(response.data)
    	      affiche() --utilisation du retour       		
 	    end,

  error = function(response)
	    fibaro:debug("Error: " ..response)
          end
  })
end
 
function affiche()
  if i == 3 then fibaro:abort() end
  essai = jsonResponse.C1
  fibaro:debug(essai)
  i=i+1 
  setTimout(Recup, 10*1000)
end

Recup()

Je me suis grandement inspiré du code de @Gazous notamment dans sont tuto : Eco-Devices Live & Day Reporter (Hp/hc)

 

Et ça confirme ce que vous disiez !

 

C'est compliqué, mais ça marche !

  • Upvote 1
Lien vers le commentaire
Partager sur d’autres sites

Je suis entrain de faire un gros travail sur la gestion de l'eau chez moi,

 

compteur gioanola (1 pulse/0.25l), ipx800 et électrovanne.

 

Là  je suis entrain de faire en sorte que dans un VD j'ai : le débit instantané, la dernière consommation d'eau utilisée, la conso du jour, semaine, mois, année et total.

J'ai une scène pour le relevé de l'index, une pour le débit instantanée et une pour le dernier volume utilisé.

 

C'est franchement pas mal, quoique pour le débit instantané, je remarque que je dépasse pas 15 l/min...

 

je sais pas si c'est normal, je me demande si y a pas une limitation dans le nombre d’impulsion à  la seconde que peux renvoyer le compteur d'eau.

Ou encore le nombre d'impulsion que peut recevoir l'ipx.

Ou encore la durée de traitement d'une scène même une scène simple.

 

Faut que je fasse des recherches...

 

J'aurais bien aimé voulu partagé tout ça avec vous, mais je sais pas comment faire ! créé un topic pour ça ?

ça va être long à  lire et écrire... :)

Lien vers le commentaire
Partager sur d’autres sites

J'ai un compteur Granola (faut de frappe volontaire..... :rolleyes: ) à  1 impulsion par litre, branché uniquement sur le circuit d'eau chaude du ballon, et je ne dépasse jamais 10 L/min

 

Donc ton 15L/min ne me semble pas aberrant en fonction de ce que tu mesures, de la pression, du débit (diamètre des tuyaux) chez toi.

Dans le doute tu peux remplir un jerrican pour mesurer le débit réel.

 

Ceci dit, il est tout à  fait possible que tu loupes des impulsions.
Perso mon compteur est branché sur un Raspberry PI, et il avait fallu que je m'applique particulièrement sur le code source du programme multithreadé en C pour être certain de ne pas louper des impulsions.

Donc si toi tu passes par un IPX, puis une scène de la HC2, c'est sà»r que tu vas en laisser passer.... car entre le temps de déclenchement du trigger de la scène, le temps d'exécution LUA, la sauvegarde de la nouvelle valeur dans la variable globale, il se passe du temps. Et tu vas devoir jongler avec les instances des scènes, sachant que la HC2 ne permet pas de poser de mutex sur les variables globales (avec les conséquences qu'on connait => 503 erreur), alors le problème devient vite insoluble.

 

Il faut que tu laisses l'IPX compteur seul de façon autonome, et la HC2 vient lire la valeur à  intervalle régulier. Dans ce sens là , tu ne perdras pas d'infos, mais tu perdras le coté instantané de la lecture.

 

A noter que Steven (je crois) avait constaté que son IPX800 v3 pouvait oublier de compter certaines impulsions, donc ce n'est pas infaillible non plus.

Lien vers le commentaire
Partager sur d’autres sites

si je mesure le débit réel (mesure du temps pour remplir 1 litre et que j'applique la règle de 3, c'est quasi bon !!)

 

Mais quand j'ouvre plusieurs robinet en même temps, c'est la que la question se pose.

 

Ensuite mon 15l/minute vient de mon script :

 

à  chaque pulse de l'ipx, je mesure le temps en utilisant os.time().

je fais un os.difftime, entre la 2eme et la 1ere, et du coup la plus petite valeur que je peux obtenir est 1 s !!!! logique !!

 

0,25l/pulse ---> 1 seconde par pulse -----> 60 pulses par minutes ------> 15l/min !!

 

d'après les caractéristiques du compteur, mais je remets plus la main dessus, (5 pulses pas seconde MAX soit 1.25 l/s soit 75l/min) on est tranquille !!! :P

d'après les caractéristiques de l'ipx800, il peut recevoir jusqu'à  5 pulses par seconde !  donc toujours tout bon.

 

Y aurait-il un moyen de travailler avec des dixièmes de secondes ???

Lien vers le commentaire
Partager sur d’autres sites

pour la précision en milli-seconde, qqun connait ça ?

require "socket"
print("Milliseconds: " .. socket.gettime()*1000)

trouvé ici : http://stackoverflow.com/questions/463101/lua-current-time-in-milliseconds

 

parce que je sais pas du tout comment s'en servir...

Lien vers le commentaire
Partager sur d’autres sites

Comme indiqué dans ton code, il faut la librairie "socket", qui n'est bien sà»r pas disponible sur la HC2.

D'ailleurs, l'instruction "require" est bloquée, donc toute tentative d'importer une librairie échoue (et il faudrait déjà  que tu puisses copier la-dite librairie sur la HC2).

 

:(

Lien vers le commentaire
Partager sur d’autres sites

J'ai déjàutilisé le mot socket... Pour les ping par exemple...

Dans ce Tuto : http://www.domotique-fibaro.fr/index.php/topic/109-ping-dun-équipement-réseau/

Mais visiblement ce serait pas la même chose... La c'est très compliqué pour moi...

Lien vers le commentaire
Partager sur d’autres sites

pour en revenir au sujet de base,

 

net.http et autres sont des fonctions asynchrone, ok.

 

Comment sait-on qu'elle s'est terminée cette fonction ?

 

C'est quand on traite le success ?

 

Mais si on traite pas le success, la fonction ne s'arrête jamais ? (sauf en cas d'erreur ?)

Lien vers le commentaire
Partager sur d’autres sites

×
×
  • Créer...