-
Compteur de contenus
208 -
Inscription
-
Dernière visite
-
Jours gagnés
41
Tout ce qui a été posté par jang
-
Besoin d'aide pour rétro-ingénierie d'une porte automatique (poulailler)
jang a répondu à un(e) sujet de fel-x dans Le bistrot
We can't disable or change font/color of button (except for unicode characters) I understand that you would like to disable one option but still show the user that the option exists. "There is Open Door, but it's not available right now" An alternative, that may be understandable for the user, is to have a single button that serves both functions and changes text between "Open Door" and "Close Door". Another alternative is to change the text of the inactive button to be strike-through letters (unicode), "O̶p̶e̶n̶ ̶D̶o̶o̶r̶" https://www.contentharmony.com/tools/strikethrough-text-generator/ -
Quick App - Gestionnaire d'Événements Automatique - GEA pour HC3
jang a répondu à un(e) sujet de Lazer dans Quick App Developpeur
Well, it's a bit tricky. If you use setProperty, it will not call the QAs updateProperty method. Some QAs may have written code to override the logic for QuickApp:updateProperty and then it's not called. The other problem is that the Device:updateProperty that QuickApp:updateProperty inherits from, do update the QuickApp's objects self.properties[prop]=value If we only call setProperty, self.properties.value will differ from fibaro.getValue(self.id,"value") which could cause issues for some QAs... One could check if the device is a QA and call updateProperty, and if not call setProperty... local isQACache = {} local function isQA (id) if isQACache [id]~= nil then return isQACache[id] end local d = __fibaro_get_device (id) if d then for _,i in ipairs(d.interfaces) do if i == 'quickApp' then isQACache[id] = true return true end end end isQACache [ id ]= false end takes on average 10ms per QA for my 200 QAs. And the result is cached so checking same id is then fast... -
This only works if the device is a QA. QuickApp's have 'updateProperty' defined as an API. I would recommend api.post("/plugins/updateProperty", { deviceId = 20, propertyName = 'userDescription', value = 'FWPP1' })
-
No there is no reason. Except maybe a wish to bring all functionality in under fibaro.* - but they can't remove setTimeout due to old QAs/Scenes. function fibaro.setTimeout(time,fun) return setTimeout(fun,time) end Like the rebranding of fibaro.* to hub.* - but also here, to be backward compatible with QAs/Scenes they can never remove fibaro.*... Another mystery is that Fibaro maintains 2 implementations for the fibaro.* functions. One for Scenes and one for QAs - and they are not always in sync... My thinking has been that it is 2 different consultant companies that do the Scene engine vs the QA framework... :-)
-
Have you tried it? Did it work for you?
-
What kind of animal is Conso Live (Enphase_MeterTotalConsumptionPower_Updated) that is expect to send an event/signal. Another QA? another zwave device? something else?
- 16 réponses
-
- déclencheur
- event
-
(et 1 en plus)
Étiqueté avec :
-
Problems: 1. You set 'value' but test 'state' 2. If you click 'off' -> 'on' quickly you may end up with 2 running loops... I think @laser meant something like this (but here we use the property instead of a local var) local function loop() if (hub.getValue(plugin.mainDeviceId,"value") == true) then print("Run Loop action") end -- loop setTimeout(loop,1000*loop_value_sec) -- secondes end loop() function QuickApp:turnOn() self:debug("binary switch turned on") self:updateProperty("value", true) end function QuickApp:turnOff() self:debug("binary switch turned off") self:updateProperty("value", false) end
-
Unfortunately not. I have QAs that don't work on the HC3L because I use os.time() a lot. os.time(), these days, returns a value dangerously close to what fits in 32 bits and when doing arithmetics with the value, calculating time, it sometimes overflow and create bad results on the HC3L... So, I recommend the HC3L only for block scenes... For dev platform I use https://forum.fibaro.com/topic/66394-visual-studio-code-vscode-for-quickapp-development/ Life is too short for trying to develop directly on the HC3/HC3L...
-
Are you running it on a HC3 Lite? Fibaro, in their wisdom to save space, compiled the Lua environment for the HC3L as 32bits... ...which cause all kinds of issues like these...
-
-
api.put("/rooms/239",{icon='User1002'})
-
local commands = { Opened = "https://airsend.cloud/device/xxxxx/command/4/?session=???", Closed = "https://airsend.cloud/device/xxxxx/command/5/?session=???", Stopped = "https://airsend.cloud/device/xxxxx/command/3/?session=???", } function QuickApp:command(cmd,state) assert(commands[cmd],"Bad command") local http = net.HTTPClient() http:request(commands[cmd], { success = function(response) if response.status == 200 then print('OK, réponse : '.. response.data) self:debug("base shutter "..cmd:lower()) self:updateProperty("state", state or cmd) else self:error("Erreur : status=" .. tostring(response.status)) end end, error = function(err) self:error("Erreur : " .. err) end, options = { method = 'GET' } }) end function QuickApp:open() sendCommand('Opened') end function QuickApp:close() sendCommand('Closed') end function QuickApp:stop() sendCommand('Stopped',"Unknown") end
-
The only problem is that hub.call can't return any value - to do this you need to add additional sorcery...
-
vider une propriété de type tableau dans l'API
jang a répondu à un(e) sujet de jjacques68 dans Support
Well, you have the tools, the rest is just some list manipulations... ;-) local days = { monday=0, tuesday=1, wednesday=2, thursday=3, friday=4, saturday=5, sunday=6 } local function map(list) local r ={} for _,e in ipairs(list) do assert(days[e],"Bad day:"..tostring(e)) r[e]=true end return r end local function flatten(list) local r ={} for e,_ in pairs(list) do assert(days[e],"Bad day:"..tostring(e)) r[#r+1]=e end table.sort(r,function(a,b) return days[a] <= days[b] end) return r end -- self:setSprinklerDays(4,{"monday",wednesday"}) -- will set scheduled days to monday and wednesday for sprinkler schedule 4 function QuickApp:setSprinklerDays(sprinkerId,list) return api.put("/panels/sprinklers/4" ,{ days = json.util.InitArray(flatten(map(list)))}) end -- self:addSprinklerDays(4,{"monday",wednesday"}) -- will add monday and wednesday to currently scheduled days for sprinkler schedule 4 function QuickApp:addSprinklerDays(sprinklerId,list) local days = map(api.get("/panels/sprinklers/"..sprinklerId).days or {}) for _,d in ipairs(list) do days[d]=true end return api.put("/panels/sprinklers/4" ,{ days = json.util.InitArray(flatten(days))}) end -- self:removeSprinklerDays(4,{"monday",wednesday"}) -- will remove monday and wednesday from currently scheduled days for sprinkler schedule 4 function QuickApp:removeSprinklerDays(sprinklerId,list) local days = map(api.get("/panels/sprinklers/"..sprinklerId).days or {}) for _,d in ipairs(list) do days[d]=nil end return api.put("/panels/sprinklers/4" ,{ days = json.util.InitArray(flatten(days))}) end function QuickApp : onInit () print(self:setSprinklerDays(4,{"monday","friday"})) print(self:addSprinklerDays(4,{"saturday"})) print(self:removeSprinklerDays(4,{"monday"})) end -
vider une propriété de type tableau dans l'API
jang a répondu à un(e) sujet de jjacques68 dans Support
Btw, this is the json encoder/decoder used in QAs https://github.com/harningt/luajson/ (Scenes use another implementation) -
vider une propriété de type tableau dans l'API
jang a répondu à un(e) sujet de jjacques68 dans Support
You could try local ListDay = json.util.InitArray({}) --<----- empty array MyPanel = api.get("/panels/sprinklers/11" ) res = api.put("/panels/sprinklers/11" , { days = ListDay }) The reason is that the json.encoder don't know if the Lua table {} should be encoded as an empty json key-value table "{}" or an empty json array "[]" The json.util.InitArray() function creates an object that the json.encoder always encodes as an array. Of course, the suggestion above only works if api.put uses the QAs built-in json.encode... -
Yes, it's really buggy. Try to add function QuickApp : OnReleased ( event ) self : updateView ( "slider" , "value" , "75" ) -- Any other value than 25... self : updateView ( "slider" , "value" , "25" ) end
- 12 réponses
-
- 1
-
-
os.time gives seconds in absolute time since 1973... os.clock returns cpu timed used so far by the process (QA or Scene). When the QA starts the os.clock will return 0, and then start to count cpu time used. cpu time used is usually smaller then absolute time (over any measured time interval)
-
...it's kind of an mqtt mechanism between QAs... but with a much simpler api...
-
Oh, finally someone discovered that function :-) Yes, it's really cool and quite efficient as the publisher only sends to subscribers actually subscribing on the event (source filtering). Also it works well with the fibaroExtra event mechanism that makes it easy to work with HC3 device and internal events.
-
I wouldn't call it a mega optimization... If it would run million of times / sec I would agree... but not for 4 times per second... Of course it's not the monthly energy savings that are of importance here but to make sure we can complete the 4 calls per seconds and still do all other stuff... ...then 0.26 microseconds is more like a micro optimization... local n,t0=100000 a = { b = function() end } c = function() end local d = function() end print("----------") t0 = os.clock() for i=1,n do a.b() end local v0 = (os.clock()-t0)*1000 print(string.format("Time '%s' = %0.6f",'a',v0/n)) t0 = os.clock() for i=1,n do c() end local v1 = (os.clock()-t0)*1000 print(string.format("Time '%s' = %0.6f",'c',v1/n)) t0 = os.clock() for i=1,n do d() end local v2 = (os.clock()-t0)*1000 print(string.format("Time '%s' = %0.6f",'d',v2/n)) local save = (v0-v2)/n printf("Saving %0.6f milliseconds per call, using local fun vs global table fun",save) printf("Saving %0.3f seconds per month, using 4 calls / second",30*24*3600*4*save/1000) ...and the answer is [19.04.2023] [07:27:56] [DEBUG] [QUICKAPP1090]: Saving 0.000264 milliseconds per call, using local fun vs global table fun [19.04.2023] [07:27:56] [DEBUG] [QUICKAPP1090]: Saving 2.734 seconds per month, using 4 calls / second
-
Excessive typing can affect your health
-
print(os.date("%FT%T%z"):sub(1,-3)..":00") print(os.date("%FT%T%z",os.time()+24*3600):sub(1,-3)..":00") Assuming timezone offset always even hours.
-
You shouldn't encode response.data. It's already encoded. Just use decode. The '\n' is no problem. print("My_Json:" , response.data) local My_Json = json.decode ( response.data ) access_token = My_Json.access_token token_type = My_Json.token_type expires_in = My_Json.expires_in print ( "access_token:" , access_token ) print ( "token_type:" , token_type ) print ( "expires in:" , expires_in )
-
It's just to cater for a variable number of arguments in the provided table. Now it's just a table with an single url so it is kind of an overkill (and then we tuck on the success and error handlers at the end). By allowing join to take a function with unknown number of arguments we keep it generic and let the sendRequest deal with the number of args. Yes you need the count the number of calls and use that later to count down... because register is a key/value table you can't just use #register... I'm not sure how your 'registerscan' is implemented but I assume that the callback is called at success. Then I would add another callback for errors and implement it something like this local function scallAll(register) local n,finish=0 for _, register in pairs(register) do n=n+1 local cb = register.callback registerscan(registerNumber, function(res) cb(res) isFinished() end, -- success callback function(err) print("Err:",err) isFinished() end -- error callback ) end function isFinished() n=n-1 if n==0 then self:debug("Scan completed") end end end Yes, it's just a reuse of the name 'err'. The second err in "function(err) ..." shadows the previous definition. What's bother me now is that the code is buggy as the call to the builtin error function can't take two string error messages. The correct code would have been error(url..err)