Aller au contenu

jang

Membres confirmés
  • Compteur de contenus

    36
  • Inscription

  • Dernière visite

Réputation sur la communauté

31 Excellent

1 abonné

À propos de jang

  • Rang
    Nouveau

Profile Information

  • Sexe :
    Homme
  • Ville :
    Home
  • Box
    Home Center 2

Visiteurs récents du profil

325 visualisations du profil
  1. jang

    Optimisation traitement de chaines de caractères

    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])
  2. jang

    Optimisation traitement de chaines de caractères

    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 ...
  3. jang

    Optimisation traitement de chaines de caractères

    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?
  4. jang

    HC3 - 5.040.37 - 23/07/2020

    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
  5. jang

    HC3 - 5.040.37 - 23/07/2020

    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....
  6. jang

    HC3 - 5.040.37 - 23/07/2020

    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.
  7. jang

    HC3 - 5.040.37 - 23/07/2020

    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
  8. jang

    HC3 - 5.040.37 - 23/07/2020

    Helper function? local function call(f,...) local args = {...} if type(f)=='number' then return setTimeout(function() args[1](select(2,unpack(args))) end,f) else return setTimeout(function() f(unpack(args)) end,0) end end function foo1(x) print(x) if x < 10 then call(foo1,x+1) -- 0s delay end end function foo2(x) print(x) if x < 10 then call(1000,foo2,x+1) -- 1s delay end end function QuickApp:onInit() foo1(0) foo2(0) end and function main() if ... then call(MySubFunction1,42) end if ... then call(MySubFunction2,17) end call(50,main) end function MySubFunction1(x) ... end function MySubFunction2(x) ... end
  9. jang

    Récupérer le label d'un bouton

    https://forum.fibaro.com/topic/49113-hc3-quickapps-coding-tips-and-tricks/?do=findComment&amp;comment=206686
  10. jang

    Gestion des appareils enfants

    Yes, but potentially an interesting part of the problem Here are some add on to the QuickApp class to make child management easier. https://forum.fibaro.com/topic/49113-hc3-quickapps-coding-tips-and-tricks/?do=findComment&amp;comment=209389 Reduces tasks to QuickApp:createChild{} and QuickApp:loadChildren() and fixes button interactions...
  11. jang

    Gestion des appareils enfants

    You could hijack the com.fibaro.sonosPlayer type class 'HEOSPlayer'(QuickAppChild) function HEOSPlayer:__init(dev) QuickAppChild.__init(self,dev) self.ip = dev.properties.ip self:trace("HEOS:",self.ip," initiated, deviceId:",self.id) end function HEOSPlayer:play_Button() self:trace("Play HEOS:",self.ip,", deviceId:",self.id) end function HEOSPlayer:pause_Button() self:trace("Pause HEOS:",self.ip,", deviceId:",self.id) end function HEOSPlayer:rewind_Button() self:trace("Rewind HEOS:",self.ip,", deviceId:",self.id) end function HEOSPlayer:forward_Button() self:trace("Forward HEOS:",self.ip,", deviceId:",self.id) end function HEOSPlayer:mute_on() self:trace("Mute HEOS:",self.ip,", deviceId:",self.id) end function HEOSPlayer:mute_off() self:trace("Unmute HEOS:",self.ip,", deviceId:",self.id) end function HEOSPlayer:volume_Slider(ev) self:trace("Volume HEOS:",self.ip,", deviceId:",self.id," Volume:",ev.values[1]) self:updateProperty("volume",ev.values[1]) self:updateProperty('ui.volume_Label.caption', tostring(ev.values[1])) end function HEOSPlayer:setInfo(label,title,creator) self:updateProperty('ui.position_Label.caption', "Label:"..label) self:updateProperty('ui.title_Label.caption', "Title:"..title) self:updateProperty('ui.creator_Label.caption', "Creator:"..creator) end local function getChildVariable(child,varName) for _,v in ipairs(child.properties.quickAppVariables or {}) do if v.name==varName then return v.value end end return "" end function QuickApp:UIHandler(event) local obj = self if self.id ~= event.deviceId then obj = self.childDevices[event.deviceId] end if not obj then return end local elm,etyp = event.elementName, event.eventType local cb = obj.uiCallbacks or {} if obj[elm] then return obj:callAction(elm, event) end if cb[elm] and cb[elm][etyp] then return obj:callAction(cb[elm][etyp], event) end if obj[elm.."Clicked"] then return obj:callAction(elm.."Clicked", table.unpack(event.values or {})) end self:warning("UI callback for element:", elm, " not found.") end function QuickApp:onInit() self:trace("Mother of HEOS, deviceId:",self.id) local cdevs = api.get("/devices?parentId="..self.id) or {} -- Pick up all my children function self:initChildDevices() end -- Null function, else Fibaro calls it after onInit()... if #cdevs ~= 2 then -- No children, create 2 local initChildData = { {className="HEOSPlayer", type="com.fibaro.sonosSpeaker", ip="1.2.3.4"}, {className="HEOSPlayer", type="com.fibaro.sonosSpeaker", ip="1.2.3.5"}, } for i,c in ipairs(initChildData) do local child = self:createChildDevice( {name = "HEOS "..i, type=c.type, initialProperties = { deviceIcon = 28, --icon = { path="plugins/com.fibaro.denonHeos/img/icon.png"}, ip = c.ip, }, -- Add properties if you need initialInterfaces = {}, -- Add interfaces if you need }, _G[c.className] -- Fetch class constructor from class name ) child:setVariable("className",c.className) -- Save class name so we know when we load it next time api.put("/devices/"..child.id,{properties={icon={path="plugins/com.fibaro.denonHeos/img/icon.png"}}}) end else for _,child in ipairs(cdevs) do local className = getChildVariable(child,"className") childObject = _G[className](child) self.childDevices[child.id]=childObject end end end
  12. jang

    getSourceTrigger

    { type = "date" , property = "cron" , operator = "match" , value = { "0/10" , "*" , "*" , "*" , "*" , "*" } } Toutes les 10 minutes
  13. jang

    Gestion des appareils enfants

    Almost... the parent asks the child to create himself, by calling the child's constructor. A child does not have a parent (is not aware of the parent) before being fully initialised (__init and _onInit are finished). When the child is fully initialised the parent sets the 'parent' field of the child to the parent. (in createChildDevice() and initChildDevices() )
  14. jang

    Gestion des appareils enfants

    => You must make a call to setTimeout () to execute another function which will have the rights to access all objects setTimeout is the wrong weapon. child = self:createChildDevice(....) -- create new child, do minimal work here. child:Ask_State() -- child is completely setup - update state self:initChildDevices ({ [ "com.fibaro.binarySwitch" ] = IPX , }) -- create existing childs, , do minimal work here. for _,child in pairs(self.childDevices) do child:Ask_State() end -- childs are completely setup, update states
  15. jang

    Gestion des appareils enfants

    0 fonctionne également. Vous revenez de __init(). __init appelle :onInit() Mieux vaut mettre à jour les "child states" après "initChildDevices"
×