jjacques68 Posté(e) le 23 mars 2020 Signaler Posté(e) le 23 mars 2020 Hello ! Petite question : est-il possible qu'un QA renvoie une valeur suite à son appelle ? Voici un exemple tout bête : function QuickApp:MyFunction() return "toto" end et voici son appel : MonRetour = fibaro.call(xx, "MyFunction) Mais visiblement ça marche pas Alors pour des retours de type : boolean, il suffit d'utiliser un QA de type binarySensor/Switch numérique, il faut utiliser un QA de type multilevelSensor/Switch string ????? J'ai bien tenté d'utiliser des QA de type générique, mais ils ne proposent pas la propriété "value" !
Krikroff Posté(e) le 24 mars 2020 Signaler Posté(e) le 24 mars 2020 C’est dans le backlog mais pas de retour de Fibaro sur cette demande.Je te confirme donc que cela n’est pas à ma connaissance faisable et que clairement cela manque !L’astuce pour faire sans pour le moment cette de faire le retour dans une variable globale puis de mettre un trigger sur cette variable dans la scène, comme cela la scène reçoit le retour dès mis à disposition je n’ai pas trouvé mieux pour le moment en matière de performance et efficacité.Il faut encore coder pour contourner cela peut devenir lassant... et surtout de plus en plus difficile à maintenir.Envoyé de mon iPhone en utilisant Tapatalk
jjacques68 Posté(e) le 24 mars 2020 Auteur Signaler Posté(e) le 24 mars 2020 Bon ben va pour une VG alors c'est un peu dommage... Merci !!
jang Posté(e) le 25 mars 2020 Signaler Posté(e) le 25 mars 2020 (modifié) On 3/24/2020 at 6:02 PM, jjacques68 said: Well, go for a VG then It is kind of a shame ... Thank you !! Here's a way to make synchronous calls between QA - and it's pretty quick. QA server. plugin.mainDeviceId = 240---------------------------------------------------------- -------- -------- -------- function foo (a, b) return a + b end --- fun test -- call = {callerID = <id>, callVar = <string>, fun = <string>, args = <table>} function QuickApp : RPC (call) local res = _G [call.fun] and {pcall (_G [call.fun], table.unpack (call.args))} or { false , "No such function" } fibaro.setGlobalVariable (call.var, json.encode (res)) end function QuickApp : onInit () self: debug ( "RPC server" , plugin.mainDeviceId) end QA Client: ---------------------------------------------------------- -------- -------- ------------- local function rpc (id, timeout, fun, ...) local v = "RPC" ..tostring ({}): sub ( 10 ) api.post ( "/ globalVariables" , {name = v}) fibaro.call (id, "RPC" , {id = plugin.mainDeviceId, var = v, fun = fun, args = {...}}) local t, res = os.time () + timeout, { false , "timeout" } while os.time () <= t do res = fibaro.getGlobalVariable (v) print (type (res)) if res and res ~ = "" then res = json.decode (res) break end end api.delete ( "/ globalVariables /" ..v) if res [ 1 ] then return select ( 2 , table.unpack (res)) else error (res [ 2 ]) end end local function rpcFun (id, timeout, fun) return function (...) return rpc (id, timeout, fun, ...) end end function QuickApp : onInit () self: debug ( "onInit" , plugin.mainDeviceId) local foo = rpcFun ( 240 , 5 , "foo" ) for i = 1 , 10 do print (foo ( 8 , i)) end end ---------------------------------------------------------- -------- -------- -------- ------------- Modifié le 25 mars 2020 par jang 1
jjacques68 Posté(e) le 25 mars 2020 Auteur Signaler Posté(e) le 25 mars 2020 thanks, I will study that...
jang Posté(e) le 25 mars 2020 Signaler Posté(e) le 25 mars 2020 (modifié) I'm giving up. I can't paste code in this forum I think I succeeded. Modifié le 25 mars 2020 par jang 1 1
jjacques68 Posté(e) le 26 mars 2020 Auteur Signaler Posté(e) le 26 mars 2020 (modifié) I try to use a part of your method with another code, to do something else, but it doesn't work and I don't understand the result : I open a socket to Wireless device throught 23 port and I must receive a response... here is a part of the main code : -- init of Variable QA self:setVariable("Result", "toto") -- open connection to the device self.sock:connect(self:getVariable("IP"), 23, { success = function(result) self:debug("SUCCES CONNECTION") --read response self:Read() --wait response (3 s)... Timeout = os.time() + 3 while os.time() < Timeout do res = self:getVariable("Result") self:debug("VARIABLE = "..res) if res and res ~= "toto" then break end fibaro.sleep(1000) end self:debug("END LOOP - "..res) end, here is the function Read() : in the same QA function QuickApp:Read() self:debug("START READ...") self.sock:read({ success = function(result) self:setVariable("Result", result) self:debug("END READ - "..result) end, error = function(err) self:debug("READ ERROR - "..err) end }) end and now, the result in debug console : [DEBUG] 26.03.2020 08:47:35: onInit [DEBUG] 26.03.2020 08:47:37: onUIEvent: {"eventType":"onReleased","deviceId":133,"values":[null],"elementName":"button1"} [DEBUG] 26.03.2020 08:47:37: SUCCES CONNECTION [DEBUG] 26.03.2020 08:47:37: START READ... [DEBUG] 26.03.2020 08:47:37: VARIABLE = toto [DEBUG] 26.03.2020 08:47:38: VARIABLE = toto [DEBUG] 26.03.2020 08:47:39: VARIABLE = toto [DEBUG] 26.03.2020 08:47:40: END LOOP - toto [DEBUG] 26.03.2020 08:59:08: END READ - ������!���� login: I don't understand why, "END READ - OK" is in the end !!! it should be before "END LOOP" !!!! and the result should be normally : "������!���� login:" I have the impression that, "self.sock:read" is blocked during the loop in the main. And the variable is not update. I try with to call Read() with a setTimeout(), but it's worse... I try with a Global Variable, but it's the same result... I try with a variable declared in the QA with self.xxx, but same... do you have an idea ? edit : if I delete the loop : it's ok, but maybe I don't receive the response in times... I would like to keep the timeout loop... but how ? [DEBUG] 26.03.2020 09:01:53: SUCCES CONNECTION [DEBUG] 26.03.2020 09:01:53: START READ... [DEBUG] 26.03.2020 09:01:53: END READ - ������!���� login: Modifié le 26 mars 2020 par jjacques68
jjacques68 Posté(e) le 26 mars 2020 Auteur Signaler Posté(e) le 26 mars 2020 I think, I find the solution : I had to put the whole loop in a setTimeout : -- init of Variable QA self:setVariable("Result", "toto") -- open connection to the device self.sock:connect(self:getVariable("IP"), 23, { success = function(result) self:debug("SUCCES CONNECTION") --read response self:Read() --wait response fibaro.setTimeout(10, function() --wait response (3 s)... Timeout = os.time() + 3 while os.time() < Timeout do res = self:getVariable("Result") --self:debug("VARIABLE = "..res) if res and res ~= "toto" then break end fibaro.sleep(1000) end self:debug("END LOOP - "..res) end) end, and the debug : [DEBUG] 26.03.2020 09:14:47: onUIEvent: {"elementName":"button1","eventType":"onReleased","deviceId":133,"values":[null]} [DEBUG] 26.03.2020 09:14:47: SUCCES CONNECTION [DEBUG] 26.03.2020 09:14:47: START READ... [DEBUG] 26.03.2020 09:14:47: END LOOP - ������!���� login:
jang Posté(e) le 26 mars 2020 Signaler Posté(e) le 26 mars 2020 (modifié) 2 hours ago, jjacques68 said: I think, I find the solution : I had to put the whole loop in a setTimeout : Unfortunately, you were just lucky that the answer came during the 10ms of your setTimeout. When you enter the while-loop nothing else will run in the same QA. In fact, nothing happens in parallel in a QA, not call-backs, not calls to QuickApp: function etc. You need to constantly give time to other parts of your code with setTimeout. My example works because it's between two different QAs. If you use it within the same QA you need to use callbacks and setTimeout loop - not as elegant / simple. Ex. (Server same) Customer: local function rpc(callback,id,timeout,fun,...) local v,args = "RPC"..tostring({}):sub(10),{...} api.post("/globalVariables",{name=v}) setTimeout(function() fibaro.call(id,"RPC",{id=plugin.mainDeviceId,var=v,fun=fun,args=args}) end,0) local t,res=os.time()+timeout local function loop() if os.time()<=t then local res = fibaro.getGlobalVariable(v) if res and res~= "" then api.delete("/globalVariables/"..v) res = json.decode(res) if res[1] then callback(select(2,table.unpack(res))) else print("RPC error:"..res[2]) end else setTimeout(loop,10) end else api.delete("/globalVariables/"..v) print("RPC Timeout:"..fun) end end loop() end local function rpcFun(id,timeout,fun) return function(cb,...) return rpc(cb,id,timeout,fun,...) end end function QuickApp:onInit() self:debug("onInit ",plugin.mainDeviceId) local foo = rpcFun(240,5,"foo") for i=1,10 do foo(print,8,i) end end Modifié le 26 mars 2020 par jang
Messages recommandés