Aller au contenu

Messages recommandés

Posté(e)

Ahah tu ne peux pas parler à Alexa alors hop un petit tuto

Merci c est top :-)

Envoyé de mon BND-L21 en utilisant Tapatalk

Posté(e)

merci pour le tuto,

 

Petite question , si je récupère une donné avec un GET : 

 

                local etatAlyssa = jsonTable.zones[1].state

 

pour la modifier dois je utiliser la meme structure que le GET ?

 

local myJson = { jsonTable.zones[1].state = "1" }

 

 

merci

 

 

Posté(e) (modifié)

désolé, pour etre plus clair, je souhaite comprendre le fonctionnent,

 

j'utilise pour récupérer des info  un GET et un element de la table :

local etatAlyssa = jsonTable.zones[1].state

 

Si je souhaite modifier la valeur de l'élément et lui attribuer la valeur 1 ou 0   =>  state = 1  

j'utilise donc la seconde parti de ton code avec POST et la valeur dans le myJson  EX :

 

local myJson = {
	"couleurs": {
		[1] = "bleu",
		[2] = "blanc",
		[3] = "rouge"
	},
	"fruits": {
		[1] = "pomme",
		[2] = "banane"
	},
}

 

donc pour mon cas je dois utiliser la même structure qu'avec GET ? ou il faut adapter comme dans ton ex avec les accolades :

 jsonTable.zones[1].state

 

jsonTable.zones[1].state

 

modif :

{"zones":[{"state":"0"}]}

 

 

 

ou peut etre qu'il n' a aucun rapport entre un GET et POST...

Modifié par Bloug
Posté(e)

Euh... mais en fait tu récupère un JSON via une requête GET, tu veux modifier une valeur, et le réinjecter dans une requête POST, c'est ça ?

Posté(e)

OK
Donc il faut que tu imbriques les 2 fonctions l'une dans l'autre (en vertu de ce qui a été dit... le code DOIT continuer dans la fonction success()

 

Quand tu décodes le tableau dans la première fonction success() :

				local jsonTable = json.decode(response.data)

Juste après tu modifies la valeur :

				jsonTable.zones[1].state = "1"

Puis tu donnes l'ensemble (avec json.encode()) dans les options de ton second appel http :

	options = {
		method = 'POST',
		data = json.encode(jsonTable)
	}
})

 

Posté(e)

Bon après beaucoup de tests avec GET puis POST  puis qu'avec POST et une erreur 401 j'ai ajouter des éléments dans le  headers pour bloqué sur du 400 ...

Comme le souligne le grand philosophe espagnol : Mas banda ! 

j'arrêter de polluer le topic ....

 

 

  • 8 mois après...
Posté(e) (modifié)

Bonsoir,

un grand merci pour ce post qui pour moi est d'une grande utilité car je ne pars de 0 sur le code...

 

J'ai passé bcp d'heures a tester de nombreuses possibilités mais j'ai toujours un message d'erreur.

 

Je cherche a envoyer une simple requête HTTP pour contourner un problème de compatibilité avec mon synology (maj DSM7)

L'idée c'est de pouvoir déclencher une action préconfigurée dans  surveillance station depuis une HC3 via une requête HTTPS

 

En clair la HC3 remonte un mouvement PIR et pousse la requête HTTPS qui déclenche l'action préconfigurée dans surveillance station.

 

le requête est la suivante :

https://ADRESSEipSYNOLOGY/webapi/entry.cgi?api=SYNO.SurveillanceStation.ExternalEvent&method="Trigger"&version=1&eventId=1&eventName="This is external event1"&account="{account}"&password="{password}"

 

la requête fonctionne dans Firefox, j'ai le bon retour "success" et l'action préconfigurée fonctionne mais via ma scene lua j'ai trs une erreur.

la dernière en date ;

[01.03.2021] [22:32:59] [ERROR] [SCENE96]: (load):2: ')' expected near 'Trigger'

 

ma scene lua ;

 

en déclaration j'ai ;

{
  conditions = { {
      id = 216,
      isTrigger = true,
      operator = "==",
      property = "value",
      type = "device",
      value = true
    } },
  operator = "all"
}

 

en action j'ai ;

local http = net.HTTPClient()
http:request("https://ADRESSEipSYNOLOGY/webapi/entry.cgi?api=SYNO.SurveillanceStation.ExternalEvent&method="Trigger"&version=1&eventId=1&eventName="This is external event1"&account="MONLOGIN"&password="MONPASSWORD"", {
	success = function(response)
		if response.status == 200 then
			fibaro:debug('OK, réponse : '.. response.data)
		else
			fibaro:debug("Erreur : status=" .. tostring(response.status))
		end
	end,
	error = function(err)
		fibaro:debug("Erreur : " .. err)
	end,
	options = {
		method = 'GET'
	}
})

 

si quelqu'un pouvais m'aider ca serai vraiment cool car je ne m'en sort pas.

J'imagine bien que ca doit paraitre hyper simple mais je ne suis vraiment pas doué.

 

Merci à vous !

 

 

Modifié par jucom
modif post lua
Posté(e)

Pour coller ton code dans le forum, il faut utiliser les balises </> dans la barre au dessus de la zone d'édition :

 

image.png.7fbb126ee5b1b3ceb3c0efe06853c57b.png

 

Puis choisir LUA dans la liste pour obtenir la coloration du code :

 

image.png.2aaa82f59fd7b5e0c9e0fa9002c3ff25.png

 

 

Car en l'état, c'est illisible, et il manque les numéros de ligne pour se repérer par rapport aux erreurs qui te sont remontées.

 

 

Par ailleurs, sans même tenter de lire ton code, il y a un caractère étrange qui me saute aux yeux.

Pas sûr que ça soit normal, et en tout cas l'interpréteur LUA n'en voudra pas si tu l'as collé tel quel sur la box :

 

image.png.24e9a033aca32fe69ec614ed9aeae9e8.png

 

Posté(e)

je commence a comprendre que le problème c'est la requête HTTPS en elle même car elle contient des " un peu partout.

Elle n'est pas prise en compte dans son intégralité et du coup le reste de la requête génère des erreurs.

je continu a chercher mais je ne suis pas certain d’être capable de faire en sorte que net.HTTPClient() puisse répondre à mon besoin si tenté que ça soit possible.

je vais créer un post à part à part pour ne pas polluer ici.

Posté(e)

Soit un QA contenant x fonctions avec des appel HTTP différents
Ces fonctions étant appelées (aléatoire) par d'autres QA

Qu'elle est la bonne écriture le type 1 ou le type 2  ( ou aucune des 2 )

Je n'ai pas trouvé le net.HTTPClient() dans NetWork Monitor !!

 

QA Ecriture type 1
-------------------
http = net.HTTPClient()
QuickApp:fonction1 ()
	http:request(
	  code...
	)
end
QuickApp:fonction2 ()
	http:request(
	  code... 
	)
end
QuickApp:fonction2 ()
	http:request(
	  code... 
	)
end
QA Ecriture type 2
---------------------
QuickApp:fonction1 ()
	http = net.HTTPClient()
	http:request(
	  code ...
	)
end
QuickApp:fonction2 ()
	http = net.HTTPClient()
	http:request(
	  code... 
	)
end
QuickApp:fonction2 ()
	http = net.HTTPClient()
	http:request(
	  code...
	)
end

 

Posté(e)

Pas sûr de moi, mais à priori utiliser une seule variable HTTPClient pour l'ensemble du QuickApp est valable, donc l'option n°1.

Cela dit l'option 2 est valable aussi, mais tu vas redéfinir un nouvel objet à chaque fois, donc ça prend du temps à initialiser, ça consomme plus de RAM, etc. De mémoire il me semble que c'est cette dernières option que j'utilise dans Network Monitor (mais c'est le seul, tous mes autres QuickApps ont un seul objet HTTPClient global)

 

Cependant, attention il y a une (grosse) erreur dans ton code dans l'option 2
Tu définis ta variable ainsi au sein de chaque fonction :

http = net.HTTPClient()

Donc... http est global !

Si bien qu'à chaque appel de l'une des autres fonctions, tu redéfinies... la même variable ! Bref, du travail inutile.

 

Autre chose, de façon générale, il faut éviter les variables globales :

- on ne maitrise pas leur portée, elle peuvent entrer en conflit avec d'autres variables du même nom mais dont la portée serait locale... soit dans une fonction, une boucle imbriquée, ou bien carrément dans un autre fichier (puisque les QA peuvent maintenant accueillir plusieurs fichiers LUA)

- cela consomme plus de RAM, car une variable globale n'est jamais libérée par le Garbage Collector (par définition, elle doit rester tout le temps accessible par tout le monde au sein du programme.... sauf si on la détruit explicitement avec http = nil, ce que personne ne pense à faire)

- et enfin, l'accès aux variables globales est plus lent (les variables globales sont stockées dans un super tableau _G que LUA doit parcourir pour trouver la bonne entrée)

Donc la bonne syntaxe dans chaque fonction pour l'option 2 serait :

local http = net.HTTPClient()

 

De façon similaire, dans la première option, tu as aussi défini une variable globale.

Il vaudrait mieux la stocker dans le QuickApp, lors de son initialisation :

QuickApp:onInit()
	self.http = net.HTTPClient()
end

Et on appelle ensuite self.http à chaque fois que l'on veut s'en servir.

 

Posté(e)

Le code c'était un squelete un peu simpliste 

OUI l'idée c'est de le mettre comme tu le montre et d'utiliser self.http dans les fonctions

QuickApp:onInit()
	self.http = net.HTTPClient()
end

mais j'avais un doute avec des appels concurrents et aléatoires sur les fonctions du QA 

Le = nil a l'époque des pertes de memoire en HC2 j'en avait mis de partout mais si on declare dans le init cela ne me semble plus utile dans un QA

Ce qui m'a fait poser la question c'est la lecture de l'exemple de la doc fibaro QA ou il disent : 

 

-- An example of a GET inquiry
-- self.http must have been previously created by net.HTTP
function QuickApp:getQuote()

 

Le net.HTTP est bien en dehors de la fonction alors que moi je le m'étais dans chaque fonction

 

 

 

 

Posté(e) (modifié)

mais que ce passerait-il si 2 méthodes de ce QA sont appelées "simultanément" avec la variable http déclarée dans le onInit() ?

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

Je me pose la même question sur des appels simultanés 

 

Sur la HC2, j'avais une scene avec  http=net.HTTPClient dans chacune des fonctions et http=nill en fin de fonction

La scène est activée à chaque appel et pour des appels simultanés il y avait donc plusieurs occurrences

Cela fonctionne depuis plusieurs années ( sans soucis de mémoire )

 

Mais avec un QA ?? Je fais faire des essais

Modifié par henri-allauch
Posté(e) (modifié)

L'avis de @Lazer  est le bon

J'ai fait un QA-1 avec net.HTTPClient dans le Init  et trois fonctions d'appel HTTP ( le serveur php immédiatement le renvoi le texte émis )

un bouton de test lance 5 fois les 3 fonctions - > OK

J'ai fait un deuxième QA-2 avec un bouton de TEST

il appelle 10 fois les trois fonctions du QA-1 - > OK

Rien perdu pas d'erreur 

Meme essais avec une réponse décalée de 4s ( pour simuler un delais de traitement du serveur ) 

Rien de perdu pas d'erreur

 

Je pense que c'est bon

j'ai mis les QA le php et les résultats en fichier zip joint

Test.zip

Modifié par henri-allauch
Posté(e)

Merci pour ton test qui confirme que l'option n°1, c'est à dire la variable self.http unique dans tout le QuickApp est la meilleure.

 

On ne maitrise pas ce qui se passe à l'intérieur de la librairie net.HTTPClient, codée en C, et visiblement elle gère parfaitement les requêtes simultanées :60:

 

C'était un peu le doute que j'avais eu en portant Network Monitor sur HC3, et par précaution j'ai choisi de créer une variable http pour chaque serveur à monitorer.

Visiblement c'est inutile, et je pourrais utiliser une variable self.http unique.

Bon après c'est pas pour le peu de mémoire que consomme ce QuickApp que ça va changer grand chose...

 

Il y a 17 heures, henri-allauch a dit :

Le = nil a l'époque des pertes de memoire en HC2 j'en avait mis de partout mais si on declare dans le init cela ne me semble plus utile dans un QA 

Disons que c'est toujours utile car ça permet de libérer la mémoire... mais les QuickApps étant stables par nature, ce xx = nil n'est pas indispensable comme il l'était pour les VD sur HC2 (cela dit on n'a jamais trop su pourquoi ils plantaient, jusqu'à ce que Fibaro corrige le bug)

 

Plus en détail :

  • Pour une variable locale, il est inutile de forcer sa libération avec xxx = nil à la fin du bloc de code dans laquelle elle a été déclarée, car le Garbage collector se chargera de faire la ménage tout seul
  • Pour une variable du QuickApp self.xxx, la question ne se pose pas, car si on crée une variable dans le QA, c'est qu'on veut la garder pendant toute la durée de vie du QA, donc aucune raison de la supprimer (sinon on aurait choisit une variable locale)
  • Pour une variable globale, dans ce cas, je vois 2 cas de figure :
    • soit on a sciemment choisi qu'elle soit globale pour être accessible par tout le monde (le QuickApp et les autres objets dans d'éventuels autres fichiers LUA.... mais c'est une mauvaise pratique
    • soit on a involontairement défini la variable en local pour un usage ponctuel, et dans ce cas il faut manuellement penser à la supprimer avec xxx = nil, sinon elle restera allouée en mémoire jusqu'à la fin de l'exécution du programme (dans le cas d'un QuickApp => jamais (ou bien redémarrage du QA, reboot de la box)) et le garbage collector ne pourra jamais la supprimer

Enfin, pensez que quand on veut passer une variable entre 2 fonctions, la meilleure solution est souvent le passage par paramètre.

A ce sujet, quand on passe une string ou un number en paramètre, c'est une copie.

Alors que quand on passe une table, c'est une référence... si bien que la fonction peut modifier la table originale en ne pensant modifier que sa propre table... méfiance, parfois le comportement est voulu, parfois pas !

 

Il y a 17 heures, jjacques68 a dit :

mais que ce passerait-il si 2 méthodes de ce QA sont appelées "simultanément" avec la variable http déclarée dans le onInit() ?

Impossible, comme dit hier sur un autre topic, les QA sont mono-threadés, le code ne peut jamais s'exécuter simultanément.

Il y a une file d'attente, et à chaque fois qu'on appelle un QA (un bouton, une fonction, une action, un événement, un settimout dans le cas d'une boucle, etc), tout cela est mis en file d'attente, et exécuté en série.... cf la discussion sur l'asynchronisme

 

Et franchement, je trouve ça mieux ainsi.

Pour avoir déjà programmé en multi-thread, c'est vraiment chaud, le contenu d'une variable peut être modifié entre 2 lignes consécutives de code, si un autre thread se déroule au même moment. Il faut gérer des mutex, etc, une gymnastique pas évidente.

 

Il y a 7 heures, henri-allauch a dit :

Sur la HC2, j'avais une scene avec  http=net.HTTPClient dans chacune des fonctions et http=nill en fin de fonction

La scène est activée à chaque appel et pour des appels simultanés il y avait donc plusieurs occurrences

En fait c'est différent, sur HC2 chaque instance de scène s'exécutait dans un processus (au sens Linux du terme) différent, c'est à dire un programme totalement séparé, avec son propre espace mémoire, avec sa propre copie du code, des variables, de la pile, etc.

Du coup on avait une étanchéité totale entre les instances de scènes, il était impossible pour elles de partager les mêmes variables (sauf à passer par des variables globales)

 

Sur HC3, chaque QuickApp est un processus (mono-threadé donc), et chaque scène est un processus aussi (toujours mono-threadé)

Et Fibaro, au moins jusqu'au firrmware actuel, interdit le démarrage de plusieurs "instances", c'est à dire plusieurs processus Linux.

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