-
Compteur de contenus
206 -
Inscription
-
Dernière visite
-
Jours gagnés
41
Tout ce qui a été posté par jang
-
It should work. Be careful if chidId doesn't exist (just removed). HC3 logs a warning if ID doesn't exists. What are you doing with 'removeChildDevice' ?
-
télécharger QA depuis une application tierce
jang a répondu à un(e) sujet de jjacques68 dans Support
Yes, I can. ...but I have a Mac -
télécharger QA depuis une application tierce
jang a répondu à un(e) sujet de jjacques68 dans Support
... and then we want a restore functionality It should be possible to define a github hook to push production branches directly to the HC3. -
télécharger QA depuis une application tierce
jang a répondu à un(e) sujet de jjacques68 dans Support
I use ZeroBrane studio for all my HC3 development with an emulator that simulates the HC3 environment -much easier and productive to code that way... Depends on programming language - you need to create a file and write the content to that file. Lua: local fqa = api.get ("/ quickApp / export /" .. deviceID) local f = io.open (fileName, "w +") assert (f, "Can't open file" ..fileName) f: write (fqa) f: close () -
télécharger QA depuis une application tierce
jang a répondu à un(e) sujet de jjacques68 dans Support
It returns the QA encoded as a .fqa - json forma (including all subfiles) From the HC3/emulator I do api.get("/quickApp/export/"..deviceID) to download QAs... -
Everything I (currently) know about QuickAppChildren ... https://forum.fibaro.com/topic/49113-hc3-quickapps-coding-tips-and-tricks/?do=findComment&comment=223530
-
function QuickApp:test(x) self.x = x; self:debug("self.x is set to ",x) end is identical to function QuickApp.test(self,x) self.x = x; self:debug("self.x is set to ",x) end 'self' is inserted as the first variable of the function, before x when declared with ':' calling self:test(7) is identical to calling self.test(self,7) ...so when you call Object:test(7) it is the same as Object.test(Object,7) so 'self' will be bound to Object When you call Child:Func1() 'self' will be bound to Child, because the call is identical to Child.Func1(Child) It means that inside Func1 we have access to 'self', the object that called Func1 It's syntactic sugar for Lua...
-
Shared code/modules are an interesting topic. It would be nice if the community could agree about a "module" format that made it easy to use each other's modules without polluting the Lua global namespace too much... https://forum.fibaro.com/topic/49113-hc3-quickapps-coding-tips-and-tricks/?do=findComment&comment=223070
-
function QuickApp:getHC3IPaddress(name) if self.IPaddress then return self.IPaddress else name = name or ".*" local networkdata = api.get("/proxy?url=http://localhost:11112/api/settings/network") for n,d in pairs(networkdata.networkConfig or {}) do if n:match(name) and d.enabled then self.IPaddress = d.ipConfig.ip; return self.IPaddress end end end end
-
Quick App - Gestionnaire d'Événements Automatique - GEA pour HC3
jang a répondu à un(e) sujet de Lazer dans Quick App Developpeur
Running GEA 7.01 offline - easier to debug -
plugin.restart()
-
sceneActivationEvent ? https://forum.fibaro.com/topic/49410-hc3-lua-sceneactivation/?do=findComment&comment=216519
-
Isn't that a sceneActivation device? - not a centralSceneEvent device...
-
variable type table API - Erreur - mise à jour propriété de type table
jang a répondu à un(e) sujet de jjacques68 dans Support
...but from another QA you have a table... It's the marshalling of arguments that is broken - try this function QuickApp:test(arg) self:debug("Argument ",tostring(arg)," is a ",type(arg)) end function QuickApp:onInit() fibaro.call(self.id,"test","0042") fibaro.call(self.id,"test","true") fibaro.call(self.id,"test",'{"a":9}') end I complained in February about it... -
self:deleteInterfaces({"light"}) or myQuickApp:deleteInterfaces({"light"})
-
self:createChildDevice always add "quickAppChild" for you. Some types of device will also add their specific interfaces.
-
self:createChildDevice({ name = <name>, type=<type>, initialProperties = .... initialInterfaces = ... }, <Class> )
-
variable type table API - Erreur - mise à jour propriété de type table
jang a répondu à un(e) sujet de jjacques68 dans Support
I suspect a "bug" json.encode({42}) -> "[42]", an array with one item. json.encode({}) -> "{}", an empty key-value json table api.put /panels/sprinklers/ID expect days:<array>, an empty json array "[]" Somehow, a Lua array where you remove all items is still seen as an array by the "C" code that encode the Lua table. However, an empty table is default encoded as a key-value. The API type checks the argument against pre-defined schemas, and the 'days' value is found to be of the wrong type (not an array). -
performance Optimisation traitement de chaines de caractères
jang a répondu à un(e) sujet de jjacques68 dans Support
Yes, {<multiple value expression>} is a way to capture multiple return values in an array. string.byte returns 32 values in the example above. function foo() return 3,5,7 end local a = {foo()} print(a[2]) -
performance Optimisation traitement de chaines de caractères
jang a répondu à un(e) sujet de jjacques68 dans Support
No, string.byte is not that efficient (compared to .sub) The difference I get is when I explode the string (with a single .byte call) and loop over the resulting byte array local s = {value: byte (1, n)} for i = 1, n do if s [i] == 49 then ... -
performance Optimisation traitement de chaines de caractères
jang a répondu à un(e) sujet de jjacques68 dans Support
Difficult. local function test2() for i=1,#value do if string.sub(value,i,i) == "1" then else end end end local function test5() local n = value:len() local s = {value:byte(1,n)} for i=1,n do if s[i] == 49 then else end end end test5 is 50% faster for me - but you have to deal with byte values. Is the data string you read always different? If not, cache seen data strings? -
No problem. success() will be called immediately when the sensor event is available. It's just the the HTTP request is hanging until there are events available. If you have many event types a table like this can make sense - if you only have 2 it is not worth it. Events={ DevicePropertyUpdatedEvent = function(e) if e.data.property == 'quickAppVariables' then return end for _,id in ipairs({...}) do fibaro.call(id,"Function",e) end end, NotificationCreatedEvent = function(e) for _,id in ipairs({...}) do fibaro.call(id,"Function",e) end end, } if Events[e.type] then Events[e.type](e) end
-
Should be - setTimeout (Main, 50) - not setTimeout (Main(), 50) Anyway, it looks ok. My point was that sometimes the success() will not be called until there are events available. e.g. > 50ms. You could think about how to do the filtering effective with some kind of dispatch table....
-
api.get("/refreshState returns when there are events available - or times out after ~30s with empty events. So you will not always poll every 50ms. I always do http:request("http://127.0.0.1:11111/api/refreshStates?last=" .. lastRefresh... these days so I will not block other timers. (Ex. QA_Toolbox) You could have a master QA that push events to your other QAs. Pseudo code: QA.id=42 { subscribers = {43,44} while(true) events = get refreshState if events then for _,id in ipairs(subscribers) do fibaro.call(id,"NEW_EVENTS",events) end end end } QA.id=43 { function QuickApp:NEW_EVENTS(events) ... end } QA.is=44 { function QuickApp:NEW_EVENTS(events) ... end } You could add additional filtering to only send relevant events to each QA.
-
Performance worries... function foo3(x,y) return (x or 5)+(y or 6) end function QuickApp:onInit() local function printf(...) self:debug(string.format(...)) end local n = 1000 local t0 = os.clock() for i=1,n do setTimeout(foo3,0) end local t1 = os.clock()-t0 printf("SetTimeout:%.3fms",1000*t1/n) t0 = os.clock() for i=1,n do call(foo3) end local t2 = os.clock()-t0 printf("Call:%.3fms",1000*t2/n) printf("Factor:%.2f",t2/t1) end [02.08.2020] [11:02:26] [DEBUG] [QUICKAPP1449]: SetTimeout:0.015ms [02.08.2020] [11:02:26] [DEBUG] [QUICKAPP1449]: Call:0.019ms [02.08.2020] [11:02:26] [DEBUG] [QUICKAPP1449]: Factor:1.28