LUA requete http et réponse au format json

Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
Guillaume369
Messages : 15
Inscription : 10 févr. 2019, 17:45

LUA requete http et réponse au format json

Message par Guillaume369 »

Bonjour à tous,

J'ai réalisé un montage arduino + carte Ethernet. Cette carte compte des impulsions et gère un petit serveur Web.
J'ai un raspberry sur lequel tourne Domoticz.

Depuis mon navigateur Web, lorsque j'interroge l'arduino :

Code : Tout sélectionner

http://192.168.0.240/Get12
Il me répond au format json. Voici la réponse

Code : Tout sélectionner

{"value":"22076"}


Avec un script LUA, j'aimerais envoyer cette requête http et copier la valeur renvoyée dans une variable.
J'ai vu qu'on pouvais envoyer cette requête avec curl :

Code : Tout sélectionner

os.execute('curl "http://192.168.0.240/Get12"')
Mais comment puis-je récupérer la réponse pour la copier dans une variable ?

Cette question doit vous paraitre basique mais je découvre LUA ... :oops:

Auriez-vous un exemple à me donner pour réaliser cela ?

D'avance merci !
domcars0
Messages : 238
Inscription : 18 févr. 2017, 20:23

Re: LUA requete http et réponse au format json

Message par domcars0 »

Salut,

Peut-être ce bout de code va t'aider:

Code : Tout sélectionner

-- charge les fonctions json
json = (loadfile "/usr/local/domoticz/scripts/lua/JSON.lua")() 
....
....
-- Le status de la vanne (Off = ouverte, On = fermée )
state = 'Unknown'
-- recupere sur l'ESPeasy atelier
local handler = assert(io.popen('/usr/bin/curl -m5 "http://atelier/control?cmd=Status,GPIO,14"'))
local result_json = handler:read('*all')
handler:close()
if result_json == '' then
        print ("---- Script_Time_Vanne : Pas de reponse de l'ESP atelier! ----")
else
        local value = json:decode(result_json)
        if value.state == 1 then
                status = "On"
        else
                status = "Off"
        end
end
La liberté a un prix... celui de l'effort.
Guillaume369
Messages : 15
Inscription : 10 févr. 2019, 17:45

Re: LUA requete http et réponse au format json

Message par Guillaume369 »

Bonjour domcars0,

Je te remercie pour le morceau de code que tu m'as transmis.

Cependant, la ligne de code :

Code : Tout sélectionner

io.popen('/usr/bin/curl "http://192.168.0.240/Get12"')
Provoque le message d'erreur suivant

Code : Tout sélectionner

attemp to call a nil value
C'est déjà le message d'erreur que j'obtenais lors de mes précédentes tentatives.
Mais je vais creuser un peu plus ...
domcars0
Messages : 238
Inscription : 18 févr. 2017, 20:23

Re: LUA requete http et réponse au format json

Message par domcars0 »

T'as essayé en tapant le code dans l'interpréteur lua ?

% lua
Lua 5.2.3 Copyright (C) 1994-2013 Lua.org, PUC-Rio
> local handler = assert(io.popen('/usr/bin/curl -m5 "http://192.168.0.240/Get12"'))
> local result = handler:read('*all')
> handler:close()
> print ('Resultat = '..result)
> <Ctrl-D>
%

C'est pareil ?
La liberté a un prix... celui de l'effort.
Guillaume369
Messages : 15
Inscription : 10 févr. 2019, 17:45

Re: LUA requete http et réponse au format json

Message par Guillaume369 »

Je viens d'installer l'interpréteur Lua, voici la réponse suite à l’exécution du code :

Code : Tout sélectionner

Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
>  local handler = assert(io.popen('/usr/bin/curl -m5 "http://192.168.0.240/Get12"'))
>  local result = handler:read('*all')
stdin:1: attempt to index a nil value (global 'handler')
stack traceback:
	stdin:1: in main chunk
	[C]: in ?
>  handler:close()
stdin:1: attempt to index a nil value (global 'handler')
stack traceback:
	stdin:1: in main chunk
	[C]: in ?
>  print ('Resultat = '..result)  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    19    0    19    0     0   2877      0 --:--:-- --:--:-- --:--:--  3800
>  print ('Resultat = '..result)
Mais le message d'erreur est toujours là :cry:
domcars0
Messages : 238
Inscription : 18 févr. 2017, 20:23

Re: LUA requete http et réponse au format json

Message par domcars0 »

Et en virant les 'local' ?
C.à.d :
> handler = assert(io.popen('/usr/bin/curl -m5 "http://192.168.0.240/Get12"'))
> result = handler:read('*all')
> print (result)
Ca donne quoi ?
La liberté a un prix... celui de l'effort.
Guillaume369
Messages : 15
Inscription : 10 févr. 2019, 17:45

Re: LUA requete http et réponse au format json

Message par Guillaume369 »

domcars0,

Bien vu, ça fonctionne !
Du coup, j'ai modifié le code dans le script Lua :

Code : Tout sélectionner

json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()  -- For Linux
handler = assert(io.popen('/usr/bin/curl -m5 "http://192.168.0.240/Get12"'))
reponse_json = handler:read('*all')
handler:close()
print ('Resultat = '..reponse_json)
rep_decode = json:decode(reponse_json)
print ('Valeur = ' .. rep_decode.value)
Et je récupère bien ma valeur dans Domoticz:

2020-02-08 19:19:00.517 Status: LUA: Resultat = {"value":"25021"}
2020-02-08 19:19:00.517
2020-02-08 19:19:00.517 Status: LUA: Valeur = 25021
2020-02-08 19:19:00.517 Status: LUA: ****************

Merci beaucoup !!
Bon week-end
Guillaume369
Messages : 15
Inscription : 10 févr. 2019, 17:45

Re: LUA requete http et réponse au format json

Message par Guillaume369 »

Pour conclure, je post le morceau de code LUA qui permet d'envoyer une requête HTTP, récupérer la réponse pour ensuite mettre à jour un device coté Domoticz avec cette réponse (si cela peut servir à qqun) :

Code : Tout sélectionner

json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()  -- For Linux

-- Cette fonction encode du texte pour le passer dans une url
function url_encode(str)
  if (str) then
    str = string.gsub (str, "\n", "\r\n")
    str = string.gsub (str, "([^%w %-%_%.%~])",
        function (c) return string.format ("%%%02X", string.byte(c)) end)
    str = string.gsub (str, " ", "+")
  end
  return str
end

local time = os.date("*t")
if (time.min % 10)==0 then -- minutes modulo 10, cad toutes les fois où minutes = 10
	--Interroge EcoPV pour obtenir la valeur de l'index du cpt d'impulsions 
	handler = assert(io.popen('/usr/bin/curl -m5 "http://192.168.0.240/Get12"'))
	reponse_json = handler:read('*all')
	handler:close()
	rep_decode = json:decode(reponse_json)
	print ('Valeur = ' .. rep_decode.value)

	--domoticz_ip="192.168.0.118"
	--domoticz_port="8080"
	--#~~~~~~~~~~ IDX de Domoticz ~~~~~~~~~~~~~~~~~~~~~~~~~~~  
	--dummy_idx={'puissance':29}  
	
	--Met à jour le device 29 dans Domoticz (Prod en Wh = nb d'impulsions x 2)
	os.execute('/usr/bin/curl -m 15 "http://192.168.0.118:8080/json.htm?type=command&param=udevice&idx=29&svalue=' .. url_encode(rep_decode.value * 2) ..'" ') 
end
Guillaume
Répondre