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

@jgab

I have tried your log function in QA and it doesn't work - error: line: 0 attempt to index a nil value (local 'self')

Please login or register to see this code.

in ZB it works without problems ...

 

Link to comment
Share on other sites

  • Topic Author
  • 8 minutes ago, petrkl12 said:

    @jgab

    I have tried your log function in QA and it doesn't work - error: line: 0 attempt to index a nil value (local 'self')

    Please login or register to see this code.

    in ZB it works without problems ...

     

     

    Sorry, it should be self to orgDebug instead of quickSelf

    Please login or register to see this code.

    I changed in the original post.

    Link to comment
    Share on other sites

    @jgab Do you know how to get value from slider or label in QA?

    I tried:

    local value = fibaro.getValue(devID, "mySlider") - this doesn't work

    Link to comment
    Share on other sites

  • Topic Author
  • 5 hours ago, petrkl12 said:

    @jgab Do you know how to get value from slider or label in QA?

    I tried:

    local value = fibaro.getValue(devID, "mySlider") - this doesn't work

    Yes, that's a good question. I haven't been able to find the value anywhere. Anyone else?

    The only way I found is to keep track of it as it changes with the callback (function QuickApp:mySliderClicked(value) sValue= value end)

    Link to comment
    Share on other sites

  • Topic Author
  • Here is some code that uses the fibaroapiHC3 sdk to help convert a HC2 VD to a HC3 QuickApp.

    It doesn't make a functional QD but it helps with restructuring the code. 

    • It puts the mainLoop in a setTimeout looping function.
    • It puts the code from the buttons and sliders and put them into function QuickApp:buttonClicked functions.
    • It tries to create a similar UI with buttons and sliders etc. (there are some "limitation" on the HC3...)
    • It makes some simple code transformations (fibaro:* -> fibaro.* etc)

    It takes a filename of a VD residing on the disk and writes out a version with extension ".fqa" that can be imported into the HC3.

     

    The code translation could be more extensive - one could provide a function that translates the label updates "io.name.value"  etc.

    But when converting a VD it's a start.

     

    Please login or register to see this code.

     

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

  • Topic Author
  • Here is a simple webhook QD.

    The idea is that instead of having external apps continuously polling the HC3 for events, the app makes a call to the HC3 and register it's url for callbacks.

    The HC3 will POST all events to the apps that have registered with it.

    If an app doesn't answer to the POST it's just unregistered. 

    If an app register twice it's detected and won't cause a duplicate post. Thus, a strategy for apps could be to re-register at intervals in case the HC3 QuickApp have been restarted.

    To register, the external app does a POST to http://<HC3IP>/api/devices/<QD ID>/action/registerForEvents with the payload = {args = {"<callback url>"}}

     

    Here is a simple NodeRed flow that register for call-backs and the receives events (just logs them)

    Please login or register to see this spoiler.

     

    Here is the code for the QD - by turning on/off the "Binary button" the loop is started/stopped

    Please login or register to see this code.

     

    Edited by jgab
    Link to comment
    Share on other sites

    @jgab

    Just now I have discovered that fibaro allows only one scene (Lua / Block) instance !? Any new instance will kill previous.  (Probably this is the reason that fibaro:countScenes() function deleted.) It requires now to create scene for every event of every device... and to try to avoid any loops or delays! in code?

     

    Since you're very familiar with QuickApp, is it possible to run more than one instance?

    If so, we'll need to migrate our scenes to QuickApp device. Lua scene have no use anymore for complex solutions, for simple solution just create a block scene. for everything else QuickApp is the answer (will have a lot of devices that are scenes)

    Here is Fibaro's descriptions to that:

    There are no ‘instances’ known from HC2 in current configuration.
    There are 2 options in scene configuration:

    • only allow to run one scene at the time (no possibility to kill it by running another one), starting next one is possible only if the first one ended
    • first scene instance is always killed by a next one

     

    Thanks in advance.

    Edited by cag014
    Link to comment
    Share on other sites

  • Topic Author
  • 2 hours ago, cag014 said:

    @jgab

    Since you're very familiar with QuickApp, is it possible to run more than one instance?

    Thanks in advance.

    Why you need to run more than once instance?

    You poll /refreshState and spawn a new thread (setTimeout) for each trigger you want to act on....

    e.g. another way to see it is that threads becomes your instances.

    Link to comment
    Share on other sites

  • Topic Author
  • 2 hours ago, cag014 said:

    @jgab

    • only allow to run one scene at the time (no possibility to kill it by running another one), starting next one is possible only if the first one ended

     

    So, the question is how many they allow to buffer up here (waiting for the next to end).

     

    Yes, but scenes do s*ck more now. You can see that the "conditions" stuff was done purely to translate the blocks scenes conditions.Ït's to verbose, inconsequent,  and prone to errors (all those curly brackets) to be used by humans.They could have chosen a much more elegant syntax - more readable....

    Link to comment
    Share on other sites

    18 minutes ago, jgab said:

    You poll /refreshState and spawn a new thread (setTimeout) for each trigger you want to act on....

    Have tried and looks like it "kills" all instances and threads..

    What about QuickApp?  Same situation?

    Edited by cag014
    Link to comment
    Share on other sites

  • Topic Author
  • 4 hours ago, cag014 said:

    Have tried and looks like it "kills" all instances and threads..

    What about QuickApp?  Same situation?

    No it doesn't. Just that you don't get any error message if there is a bug and the code crash.

    See my tip on how to patch setTimeout to get resonable error messages (in scenes you patch fibaro.setTimeout) . And you have to prime /refreshState as it hangs ~30s if there are no events.

    Edited by jgab
    Link to comment
    Share on other sites

  • Topic Author
  • 7 hours ago, jgab said:

    So, the question is how many they allow to buffer up here (waiting for the next to end).

    Actually, it turns out to be a real mess...

    Please login or register to see this code.

    If from another scene we increment Test from 1 to 10, and have set "Allow to restart" to "no", you would kind of expect that you would get 1 to 10 printed.

    Please login or register to see this code.

    However, it drops about half of the triggers.

    On the HC2 we knew that if we put "Max running instances" to 10 it would start 10 before dropping triggers (and we also got a notice that there were too many running instances).

    Here they seem to be  just silently dropped.

    Fibaro, you can do better than this....

    Edited by jgab
    Link to comment
    Share on other sites

    On 2/25/2020 at 8:05 AM, jgab said:

    However, it drops about half of the triggers.

     

    Here they seem to be  just silently dropped.

     

    not sure if this is not to the BUI refresh, anyway, 70ms sleep is enough to catch all

    Link to comment
    Share on other sites

  • Topic Author
  • 9 hours ago, tinman said:

     

    not sure if this is not to the BUI refresh, anyway, 70ms sleep is enough to catch all

    Nop, it's not the GUI refresh problem, of the debug window(?)  (if the actions part does something, like update another variable, it misses too)

    Nop, delays won't fix the problem.  

     

    You can introduce a delay between the triggers in my example because it's a for-loop in one scene that generates these triggers.

    In reality these triggers can come from different scenes, quick apps, devices - that just happens to generate triggers 

    at the ~same time... If you have a scene with a condition that can trigger on more than 3 different things ("any") and they by

    coincidence happen at once, you start to loose triggers...

     

    Of course this is a very rare coincidence. But that is the worst bugs when you support users:

    "Oh, this light don't turn on in the evening, but it only happens about once a month, can you help me find the problem..?."

     

    The event/status queue we have with /refreshStates gives us all the triggers in the example, so no excuse for not picking them one at a time...

     

    No, this is just a bad design choice. (among a couple of others...)

     

    Of course they need to throttle events (if my example loop would have been a "while(true) do ... ").

    However, you don't do it after 3, you do it after 300 - the HC2 did it after 10 (with max instances) and you at least got a warning when it was exceeded.

    Link to comment
    Share on other sites

  • Topic Author
  • api/settings/network seems broken...

    api.get("/settings/network") returns 501 but works when called from externally with the REST API.

     

    (I'm having a quick app that tries get the IP address of the box it's running on...)

    Link to comment
    Share on other sites

    Hi

    I need help.  Is it possible making devices via "/api/devies" with post method?

    It returns 400 Error:Bad Request. I can't find plugin type. Here's error code.

    Please login or register to see this code.

    Link to comment
    Share on other sites

  • Topic Author
  • On 2/28/2020 at 9:55 AM, rangee said:

    Hi

    I need help.  Is it possible making devices via "/api/devies" with post method?

    It returns 400 Error:Bad Request. I can't find plugin type. Here's error code.

    Please login or register to see this code.

     

    I haven't been able to do it with /api/devices either. Same error.

    Have a look at 

    and the function hc3_emulator.createQuickApp(<name>,<type>,<body>,<UI>,<quickVars>,<dry run>) provided in fibaroapiHC3.lua file.

     

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

    21 minutes ago, jgab said:

     

    I haven't been able to do it with /api/devices either. Same error.

    Have a look at 

    and the function fibaro._createQuickApp(<name>,<type>,<body>,<UI>,<quickVars>,<dry run>) provided in fibaroapiHC3.lua file.

     

     

    Oh. Thank you.

    I didnt know your apiHC3.lua support  createQuickApp feature.

    Awesome!

     

    Can you explain the difference between "createQuickApp" and "createProxy"?

    Link to comment
    Share on other sites

  • Topic Author
  • On 2/28/2020 at 11:00 AM, rangee said:

     

    Oh. Thank you.

    I didnt know your apiHC3.lua support  createQuickApp feature.

    Awesome!

     

    Can you explain the difference between "createQuickApp" and "createProxy"?

     

    Here is an example

    Please login or register to see this code.

    Creates a proxy on the HC3 named "My Test" with one button and one slider.

    Makes callback to the IDE QuickApp:b2Clicked() and QuickApp:s1Clicked(val)

    Edited by jgab
    Link to comment
    Share on other sites

    16 minutes ago, jgab said:

     

    Here is an example

    Please login or register to see this code.

    Creates a proxy on the HC3 named "My Test" with one button and one slider.

    Makes callback to the IDE QuickApp:b2Clicked() and QuickApp:s1Clicked(val)

     

     

    Thank you very much! I understand.

    Proxy QuickApp is for off-line debugging.

    Both features will be very helpful when I create more then 100 QuickApp.

    Thank you again.

    Link to comment
    Share on other sites

    • jgab changed the title to SDK for remote and offline HC3 development.

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