jojo Posté(e) le 27 juillet 2022 Signaler Posté(e) le 27 juillet 2022 Bonjour, Je bloque sur ce bout de code. Et il me semble que c'est ok, mais apparemment non ... http:request(url, { success = function(response) if response.status == 200 then self:trace("OK, réponse : ".. response.data) local resp = json.decode(response.data) self:trace("resp = "..tostring(resp)) local id = resp.nukiId self:trace("nukiId = ".. tostring(id)) else je cherche à extraire le nukiId de la response. et voici le log : [27.07.2022] [18:47:57] [DEBUG] [QUICKAPP258]: onInit [27.07.2022] [18:47:57] [DEBUG] [QUICKAPP258]: State [27.07.2022] [18:47:57] [TRACE] [QUICKAPP258]: url = http://192.168.1.xxx:8080/list?token=zzzzzz [27.07.2022] [18:47:58] [TRACE] [QUICKAPP258]: OK, réponse : [{"deviceType": 0, "nukiId": 184981569, "name": "Entrée", "firmwareVersion": "1.14.1", "lastKnownState": {"mode": 2, "state": 3, "stateName": "unlocked", "batteryCritical": false, "batteryCharging": false, "batteryChargeState": 32, "keypadBatteryCritical": false, "timestamp": "2022-07-27T09:31:33+00:00"}}] [27.07.2022] [18:47:58] [TRACE] [QUICKAPP258]: resp = table: 0x3f1e6a30 [27.07.2022] [18:47:58] [TRACE] [QUICKAPP258]: nukiId = nil où est mon erreur ? Merci pour vos yeux et votre cerveau.
jojo Posté(e) le 28 juillet 2022 Auteur Signaler Posté(e) le 28 juillet 2022 il y a un truc vraiment étrange : Dans ma fonction il n'rxécute pas les instructions après le http:request(url, { success = function(response) ... } ) voici mon code "complet" : je souhaite traiter resp ensuite. http:request(url, { success = function(response) if response.status == 200 then self:trace("OK, réponse : ".. response.data) resp = json.decode(response.data) else self:error("Erreur : réponse avec statut = " .. tostring(response.status)) end end, error = function(err) self:error("Erreur : " .. err) end, options = { method = 'GET' } } ) local id = resp[1].nukiId self:trace("nukiId = ".. tostring(id)) Merci
Lazer Posté(e) le 28 juillet 2022 Signaler Posté(e) le 28 juillet 2022 "Asynchronisme".... en fait tes 2 instructions sont exécutées avant l'appel de success() ou error() Voir : 2
jojo Posté(e) le 29 juillet 2022 Auteur Signaler Posté(e) le 29 juillet 2022 Merci, je confirme que dans le debug, je vois l'instruction qui est après mon call http avant le résultat. Il doit surement y avoir une bonne raison à cela, mais je ne la vois pas. Pourquoi exécuter des actions alors que la précédente n'est pas finie ??? Je vais regarder ton lien, il y aura sûrement une réponse à mon questionnement, mais d'ici là, je considère cela comme TRES stupide et profondément illogique.
Lazer Posté(e) le 29 juillet 2022 Signaler Posté(e) le 29 juillet 2022 Non ce n'est pas très stupide, au contraire c'est bien plus logique ainsi, et surtout très puissant. Mais pas évident à assimiler au début. Commence par lire le lien, tout est expliqué.
mprinfo Posté(e) le 29 juillet 2022 Signaler Posté(e) le 29 juillet 2022 Comme le dit lazer il faut changer ça méthode pour écrire le codeEt surtout ne pas utiliser le sleepPour que la commande s'exécute apparaît il faut la mettre dans une fonction timeout() Envoyé de mon BLA-L29 en utilisant Tapatalk
jojo Posté(e) le 29 juillet 2022 Auteur Signaler Posté(e) le 29 juillet 2022 j'avais bien l'intention de lire le lien, mais c'est vrai, JE suis stupide, pourquoi faire simple, quand on peut faire compliqué ? 1
mprinfo Posté(e) le 29 juillet 2022 Signaler Posté(e) le 29 juillet 2022 Ce n'est pas une question de stupiditéC'est juste que le code s'exécute differament. Donc ça change les vieilles habitudes Envoyé de mon BLA-L29 en utilisant Tapatalk
jojo Posté(e) le 29 juillet 2022 Auteur Signaler Posté(e) le 29 juillet 2022 Il y a 4 heures, Lazer a dit : Non ce n'est pas très stupide, au contraire c'est bien plus logique ainsi, et surtout très puissant. Mais pas évident à assimiler au début. Commence par lire le lien, tout est expliqué. j'ai lu ton topic, très instructif en effet. en résumé : "fait comme on te dit de faire, sans discuter, ni essayer de comprendre pourquoi" => oui chef, de toute façon c'est comme ça. Je n'ai toujours pas compris l'avantage , si ce n'est de m'obliger à changer mes habitudes de vieux.
Cardane Posté(e) le 29 juillet 2022 Signaler Posté(e) le 29 juillet 2022 @jojo ca peut être perturbant, mais c'est très puissant... bon, après, c'est de la pure gestion asynchrone... ca va te permettre par exemple lorsque tu fais appel à une fonction qui demande un certain temps de réponse (appel extérieur vers un device externe par exemple) de continuer une partie de ton code qui n'est pas dépendante de ton code... ce qui dépend de la réponse reçue lors de ton appel sera traité lorsque la réponse arrivera... très logique en fait, etttt le reste peut être exécuté directement... il y a plein de cas ou c'es très utile, et aujourd'hui dans "l'informatique" moderne on traite bienj souvent de cette manière plutôt qu'en simple séquentiel... le top c'est le bus événementiel où ton code fait des choses, et parfois reçoit un évènement que tu traites ... (bon, ok, je simplifie très fort )... mais comme cela a été dit, il faut juste oublier de penser comme avant et puis ca roule... 1 1
jang Posté(e) le 30 juillet 2022 Signaler Posté(e) le 30 juillet 2022 If net.HTTPClient() was synchronous (returning the result immediately) it would have looked like local success,res = net.HTTPClient():request("http://myurl",options) if success then print(res) end a little like in the old HC2 VDs. If the function takes other functions for success/error or callback it's a hint that the function is asynchronous. E.g. will return immediately and later call your functions when it is ready. This is usually much more efficient if you have something else to do while you wait for the work to be completed. ...IF you have something else to do while you wait. Most code in the forums don't and a lot of beginners stumble on this. Fibaro could have let us both have the cake and eat it, however Fibaro is not very "developer friendly". With a few lines of code in the QA we could have had synchronous net.HTTPClient() and asynchronous setTimeout calls. If we wanted "parallel" net.HTTPClient() calls we would just call them in separate setTimeout functions. Just look at the section "Your QA code" in the code below QuickApp = {} ------------- Your QA code ------------ function QuickApp:ping() -- setTimeout loop logging "ping" every second self:debug("ping") setTimeout(function() self:ping() end,1000) end function QuickApp:onInit() self:debug("MyQA") setTimeout(function() self:ping() end,0) -- Start ping loop local success,res = net.HTTPClient():request("http://myurl") -- Run http request and wait for result if success==true then -- If success print result self:debug("Success:",res) end end ------------- End ---------------------- local http = {} net = { HTTPClient = function() return http end } function http:request(url) -- Synchronous http call that respect other timers print("net.HTTPClient: Calling ",url,"-will take 5 seconds") local co = coroutine.running() setTimeout(function() print("net.HTTPClient: ready") coroutine.resume(co,true,"This is the result") -- We always succeed end,5000) return coroutine.yield() end local timers = {} function setTimeout(f,t) table.insert(timers,{coroutine.wrap(f),t/1000+os.time()}) table.sort(timers,function(a,b) return a[2] <= b[2] end) end if QuickApp.onInit then function QuickApp:debug(...) print(os.date("%c"),...) end setTimeout(function() QuickApp:onInit() end,0) end while true do local t = table.remove(timers,1) while t[2] > os.time() do end t[1]() end It will run the "ping" loop while the net.HTTPClient() call waits for its result. We can write much more "natural" code and everyone would be more happy, and we would see less buggy code... However, it doesn't work on the HC3 as Fibaro in its infinite wisdom has decided to disable coroutines that is one of the biggest features of Lua. (You can try to run the example in any other "full" Lua environment to see it in action...) 'coroutines', in short, allow us to suspend execution of the code in the middle of your function (yield) and then later "wake up" the function so that it continues to run from where it was suspended (resume). In our code we let setTimeout wrap the function in a coroutine so that the function can be suspended and resumed. In the case above we suspend the net.HTTPClient() call, and then when it's ready (5s later) we wake it up so the function can return the result to the waiting caller. local success,res = net.HTTPClient():request("http://myurl") So, Lua is a very powerful language but we are unfortunately only allowed to use a small part of it... 2 1
jojo Posté(e) le 30 juillet 2022 Auteur Signaler Posté(e) le 30 juillet 2022 Thank you @jang for this detailed info. As I'm not a developper, I'll to re-read your post 10 times to start understanding it , but one day I will understand ...
jang Posté(e) le 31 juillet 2022 Signaler Posté(e) le 31 juillet 2022 (modifié) Don't lose any sleep over the post. The simple take-away was that Fibaro could have let us have both synchronous net.HTTPClient calls and asynchronous setTimeout, that would have made it easier for developers - and that with just a few lines of code. (then to prove it I gave an implementation, but that may be a bit advanced to follow, and put you to sleep ) Modifié le 31 juillet 2022 par jang 1
jojo Posté(e) le 3 août 2022 Auteur Signaler Posté(e) le 3 août 2022 thank you for this resume/summary : that is the language I understand
Messages recommandés