Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


HC3 QuickApps coding - tips and tricks


jgab

Recommended Posts

Hello,

 

Please tell me, what am I doing wrong. I'd like to get value from one QA and use it in another one. I'm total noob in lua, and i'm trying to integrate my Shellys with HC3 so I am asking for your understanding.

 

on source QA i get variable from json:

 

self.httpClient:request(url,  
    {
        options={
            method = "GET"
        },
        success = function (response)
            if (response.status >= 200 and response.status < 300then
                self:debug("OK: " .. response.data)
                jS = json.decode(response.data)
               energy = (jS.meters[1].power)
               if (jS.relays[1].ison) == false then
                    stat = "Stan przełącznika: wyłączony" 
                    self:updateProperty("value"false)
                elseif (jS.relays[1].ison) == true then
                    stat = "Stan przełącznika: włączony"
                    self:updateProperty("value"true)
                end 
 
                self:setVariable("energy", energy)
 
 
on destnation QA:
 
function QuickApp:onInit()
    self:debug("onInit")
    self:debug(fibaro.getValue(110, energy))
end 
Debug:
[ERROR] 12.03.2020 19:57:01: [LUA Code] line: 18 Wrong parameter type, string required. Provided param 'nil' is type of nil
Link to comment
Share on other sites

You are setting QA variable? self:setVariable("energy", energy)

It is a local variable for specific QA and cannot be accessed by other QA.

And then you're trying to fibaro.getValue()  !? this is not a command to get variable in any case.....

May I suggest set in energy QA (I hope you've created QA as energy meter type)

self:updateProperty("value", energy) 

self:updateProperty("energy", energy)

now from destination QA

 self:debug(fibaro.getValue(110, "value")) or

 self:debug(fibaro.getValue(110, "energy"))

 

 

 

 

Edited by cag014
Link to comment
Share on other sites

7 minut temu, cag014 napisał:

first of all energy is a string type.

self:debug(fibaro.getValue(110, "energy"))

 

now i've got

 

[DEBUG] 12.03.2020 21:27:26: nil

Link to comment
Share on other sites

1 minute ago, michal85pl said:

now i've got

 

[DEBUG] 12.03.2020 21:27:26: nil

No, my bad...

please look again on my answer.... have edit it

Edited by cag014
Link to comment
Share on other sites

7 minut temu, cag014 napisał:

No, my bad...

please look again on my answer.... have edit it

still the same, "nil"

but my source QA is binary switch (not energy meter), from which i decode energy consumption from json

Link to comment
Share on other sites

1 minute ago, michal85pl said:

still the same, "nil"

but my source QA is binary switch (not energy meter), from which i decode energy consumption from json

No, you need to define it as energy meter. binary switch has boolean values only (true or false)

Please create a new QA and copy your code.

Link to comment
Share on other sites

7 minut temu, cag014 napisał:

No, you need to define it as energy meter. binary switch has boolean values only (true or false)

Please create a new QA and copy your code.

But my source QA is binary switch because i need to control its relay(s)

 

My idea is to read energy consumption in source QA and then use it in destination QA,  to avoid creating further queries in  destination QA (defined as energy meter). So question is, is it possible?

Link to comment
Share on other sites

Yes it possible... two options

1. Use global variable to store and retrieve energy consumption.

store -> fibaro.setGlobalVariable("energy",energy)

retrieve -> fibaro.getGlobalVariable("energy")

2. You can call function in destination QA from source QA to save energy value or to do what ever you need.

destination QA: (assumprion id = 100)

function QuickApp:getEnergy( energy)

your code

end

source QA

fibaro.call(100,"getEnergy",energy)

 

 

 

Edited by cag014
Link to comment
Share on other sites

11 godzin temu, cag014 napisał:

Yes it possible... two options

1. Use global variable to store and retrieve energy consumption.

store -> fibaro.setGlobalVariable("energy",energy")

retrieve -> fibaro.getGlobalVariable("energy")

2. You can call function in destination QA from source QA to save energy value or to do what ever you need.

destination QA: (assumprion id = 100)

function QuickApp:getEnergy( energy)

your code

end

source QA

fibaro.call(100,"getEnergy",energy)

 

 

 

the first option still returns "nil", second works great.

Thank You very much for help

Link to comment
Share on other sites

2 hours ago, michal85pl said:

the first option still returns "nil", second works great.

Thank You very much for help

Just out of curiosity, in first option: what type of global variable you have defined?

You should use standard type.

Please login or register to see this spoiler.

 

Link to comment
Share on other sites

W dniu 13.03.2020 o 12:11, cag014 napisał:

Just out of curiosity, in first option: what type of global variable you have defined?

You should use standard type.

Please login or register to see this spoiler.

 recreating global variable solved problem with "nil", now it works in both options

Link to comment
Share on other sites

Great.... glad you have sort it out.

Edited by cag014
Link to comment
Share on other sites

W dniu 1.03.2020 o 12:26, tinman napisał:

it looks that one can add extra interface to QuickApp device, however for some reason the QA behaves strange if i called self:addInterfaces({"power"}) in onInit without any check, but with small check seems to work. Now my binary switch have power property:

 

Please login or register to see this code.

Please login or register to see this link.

 

Please login or register to see this link.

 

 

 

@A.Socha anything against (from Fibaro/design point of view) calling self:addInterfaces({"power"}) in QA to add extra interface?

 

Great option...it works without problems

Link to comment
Share on other sites

  • Topic Author
  • In would be useful if conditions in scenes allowed for specifying a condition that would be true if the condition had been true for a specific time.

    In addition to "any" and "all" there could be a "trueFor", with a property "time" set to a time ex."00:05"...

    Ex. if a motion sensor has been safe for 5min, or if a set of motion sensors have been safe for 5min etc.

     

    Anyway, this is a thread about QAs, so let's do the second best thing...

     

    We compile expressions of type #<eventName>/<time to be true>/<interval for checks>/<expression>

    Please login or register to see this code.

    We actually put the rule in the QA'a quickappVariables

    name:#test

    value:00:05/2/100:safe & 101:safe & sunset..sunrise

     

    Anyway, we compile the expression into a Lua function that looks like

    Please login or register to see this code.

    numToBool converts a number to true or false if its >0, sunset and sunrise are variables bound to resp. time. (we have 'midnight' and 'now' also)

    We run it at every interval (2s in this case) and when it has been true for 5min we emit a CustomEvent with name 'test'

    We choose the interval depending on how quickly we need to be notified that an expression has been true.

     

    This allows us to use most of the power of Lua to craft our rules, we can do

    Please login or register to see this code.

    etc.

    The total code when we don't have to write a parser from scratch and interpret the result becomes quite compact (that's why load/loadstring would be appreciated)

    This code works as is but would probably need some more error checks etc before being "production ready"

    (Sorry for the long listing, but there are some techniques in the code that code be worth stealing...). QA attached at the end.

     

    Updated with same fixes and 'repeat' options.

    value=R00:05/2/88:on

    The starting 'R' indicates that the rule should continue to fire events every 5min the expression is true.

    Good to have if you want to have notification and reminders if a door/window is left open.

     

    New version. May 4, 2020

    Please login or register to see this attachment.

    supports day and month in .. test.

    Ex.

    mon..fri

    may..jun

     

    Edited by jgab
    • Like 2
    Link to comment
    Share on other sites

    Anyone able to help with simple HC3 Lua? Im trying to control my Lightwave RF and need to create new VD's. Ive tried all sorts but nothing working!

     

    Examples of my HC2 Lua codes (which work) are:

    socket = Net.FUdpSocket()
    socket:setBroadcast(true)
    socket:write("111,!F*p|<FIBARO>", "255.255.255.255", 9760)

     

    socket = Net.FUdpSocket()
    socket:setBroadcast(true)
    socket:write("111,!R2Fa|<cr>", "255.255.255.255", 9760)

     

    so all im trying to do is send a command to a local IP and port?

     

    Should be simple but im struggling!

    Link to comment
    Share on other sites

    9 minutes ago, northyorks82 said:

    Anyone able to help with simple HC3 Lua? Im trying to control my Lightwave RF and need to create new VD's. Ive tried all sorts but nothing working!

     

    Examples of my HC2 Lua codes (which work) are:

    socket = Net.FUdpSocket()
    socket:setBroadcast(true)
    socket:write("111,!F*p|<FIBARO>", "255.255.255.255", 9760)

     

    socket = Net.FUdpSocket()
    socket:setBroadcast(true)
    socket:write("111,!R2Fa|<cr>", "255.255.255.255", 9760)

     

    so all im trying to do is send a command to a local IP and port?

     

    Should be simple but im struggling!

     

    Hi, please see the TCP example quickapp at the bottom of this page: 

    Please login or register to see this link.

    I use it as a base to send IR commands through TCP to a port.

     

    If you at a later stage need to call QuickApp buttons from a scene, be sure to set up the button functions in the main code like this: 

     

    Edited by robw
    Link to comment
    Share on other sites

    10 minutes ago, robw said:

     

    Hi, please see the TCP example quickapp at the bottom of this page: 

    Please login or register to see this link.

    I use it as a base to send IR commands through TCP to a port.

     

    If you at a later stage need to call QuickApp buttons from a scene, be sure to set up the button functions in the main code like this: 

     

    Yes

     

    I tried this, so input the port and ip in variables. Touched nothing else (main code untouched) and in the button code I put:

     

    self:send("111,!F*p|<FIBARO>")

     

    But the device is not getting the command. Not sure what I'm missing...

    Link to comment
    Share on other sites

    59 minutes ago, robw said:

    socket = Net.FUdpSocket()
    socket:setBroadcast(true)
    socket:write("111,!R2Fa|<cr>", "255.255.255.255", 9760)

     

    UDP not supported Yet !

    Link to comment
    Share on other sites

  • Topic Author
  • I made a long post on how I thought QAs worked (internally) and why it is a cooperative multitasking environment and why we need to use setTimeout to give time to other tasks , like clicking buttons, calling QuickApp:functions etc.

    One thing that we see is that when we do a fibaro.sleep() every other task stops - no calls to QuickApp:functions and setTimeouts will not be called (they queue up and will be called when the sleep is over).

    So here is an implementation of the concept. A minimalistic QA environment simulator. If you run this code in a Standard 5.3 Lua environment that don't have setTimeout etc.  (real computer, not the HC3 :-) ) you will see the loop in 'my code'  running every 2s, and the QuickApp:turnOn command in 'my code' that is scheduled 5s after start will execute when its time comes.  (no extra libs needed, this is plain Lua)

    Please login or register to see this code.

    (note this example timer has a resolution of seconds. It's easy to change to use os.clock() and get milliseconds)

     

    However, we are doing it a little bit better, our fibaro.sleep() gives time to other tasks to execute - like the "incoming" 'turnOn' after 5s.

    This improvement would be easy to do for fibaro, and it would be easier for users to write code, and not be surprised why everything "stops". (In fact, every fibaro.* call could yield to give time to other tasks to run if wanted)

    I also added implementations of setTimeout and setInterval too, just to show how it fits into this model (in reality a bit more involved, but this works to demonstrate)

     

    So I repeat it again, Fibaro should enable Lua's standard coroutines. People that knows how to use it would produce much better code and we would not need to break our necks to achieve things we need to do today. If you need to do a more elaborate communication protocol over sockets requiring various timings etc - doing it in a coroutine with sleeps is just very natural - juggling timers/setTimouts are not. Why not make the HC3 an easy environment to create great code and functionality?

    Once back in the time coroutines had some sandbox/security issues but now with 5.3 it's classified on the same level as the Math library. With coroutines we could easily wrap HTTPClient() into a synchronous FHttp() function, without stopping other cooperative tasks - once again making life easier for coders.

     

    Edited by jgab
    Link to comment
    Share on other sites

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Create New...