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


jgab

HC3 QuickApps coding - tips and tricks

Recommended Posts

A thread to share some coding techniques for QuickApps? 

Because QD's are "long running scenes" (they don't have to be loaded and restarted for every event) - it is actually worthwhile to build up a library of "nice to have" code and include them in QDs.

 

Please login or register to see this link.

 

Please login or register to see this link.

s

Please login or register to see this link.

 

List of posts:

  • Introduction to the QuickApp anatomy - tutorial
    • Please login or register to see this link.

      Lua functions and object-oriented programming. (QuickApp is a OO class, so we need that base)
    • Please login or register to see this link.

      The basic QuickApp functions and what they do... and how.
    • Please login or register to see this link.

      . More on QuickApp event handling - interaction with the UI and fibaro.call(<quickApp>,"name",...)
    • Part 4. QuickAppChildren and how to raise them...
  • Please login or register to see this link.

  • Please login or register to see this link.

     (

    Please login or register to see this link.

    )
  • Please login or register to see this link.

    (fibaroapiHC3.lua)
  • Please login or register to see this link.

    (like fibaro.getSourceTrigger()) 
    • Please login or register to see this link.

  • Please login or register to see this link.

  • Please login or register to see this link.

  • Please login or register to see this link.

    (demonstrating the UI with buttons)
  • Please login or register to see this link.

    (demonstrates UI buttons that change labels/text to present options) It doesn't' actually schedules the profile yet. (

    Please login or register to see this link.

    )
  • Please login or register to see this link.

    - like when using net.HTTPClient() instead of FHTTP().
  • Please login or register to see this link.

    (without drifting)
  • Please login or register to see this link.

    (leveraging the "polling for triggers" code)
  • Please login or register to see this link.

     (and

    Please login or register to see this link.

    )
  • Please login or register to see this link.

    (files in a flat format)
  • Please login or register to see this link.

    (not strictly about QuickApps but related) - can speed-up time :-) 
  • Please login or register to see this link.

    (uses the QuickApp structure for asynchronous calls in a previous tip)
  • Please login or register to see this link.

    • Please login or register to see this link.

  • Please login or register to see this link.

     
  • Please login or register to see this link.

    - pushing events to external apps
  • Please login or register to see this link.

    - ex. power and battery and updating the properties (updates the little battery and power icon UI) @tinman
  • Please login or register to see this link.

    (and a few other)  ....    Ex. keyfob QA by @tinman

 

Readers note. I started to call QuickApp devices for QDs (as in QuickApp Device, thought QAs sounded like Question and Answers). So, I use the word QD here and there but I'm not religious about it...

Edited by jgab
  • Like 3
  • Thanks 2

Share this post


Link to post
Share on other sites
  • Topic Author
  • We can call functions in other QAs with fibaro.call(ID,<function name>,<args>)

    However, we can't get values back easily as fibaro.call returns nil...

    We can use callback methods but it's usually not so convenient, we would really like fibaro.call to immediately return the value, i.e. be synchronous.

    What we really want to do is to have something like (synchronous) RPC calls...

     

    So here is a way to achieve synchronous remote function calls - e.g. for a shared library of Lua code or something.

    (It's actually more than just shared code as it calls a QA that can keep a state between calls and share that state between many calling  clients, i.e RPC)

     

    The QD (with deviceID 81)  that is exporting the functions looks like:

    Please login or register to see this code.

    Please login or register to see this code.

    <table> is a list of the global functions you want to export

     

    Then we have another QuickApp that wants to use function 'test1' from QuickApp 81 and it will import the function like this (it will also import 'test2'):

    Please login or register to see this code.

    Please login or register to see this code.

    <deviceID> is the deviceID of the QuickApp exporting the functions

    <table>is the table we want to put the functions in - default is _G which will make them global

    <log> is a boolean that if true logs imported functions to the console

     

    The second QD calls the test1 function a number of times and prints the average time a call took:

    Please login or register to see this code.

    Average call takes ~70ms - not that bad.

     

    The magic is the functions that we create when we import them. Those "imported" functions need to send the name of the function and the arguments to the exporting QD, and wait for the answer to come back.

    Because it's a synchronous call we can do 

    Please login or register to see this code.

    ...which would have been more cumbersome if it was an asynchronous call.

     

    The code for import/export is

    Please login or register to see this code.

     

    Shouldn't be used for functions called 1000's per second - but for larger utility functions this works quite ok.

     

    If Fibaro would trust us programmers and allow Lua's coroutines to be used in scenes/QDs this could be much more efficiently (and elegantly) implemented.... we wouldn't need to busy wait for the return value, we wouldn't need to use a fibaro global for the return value, and we would only need to suspend the calling "thread". 

    Lua's coroutines are deemed safe for Lua sandboxes since v5.2 so please let us have them!

     

    Edited by jgab
    • Like 1

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • This post is not updated anymore as the discussion on the fibaroapiHC3.lua SDK has moved to 

     

    --------------------------------------------------------------------------------

     

    File:  

    Please login or register to see this attachment.

    (v0.65)

     

    I've started to run and test HC3 QDs offline (using ZeroBrane studio, free for Mac,Windows, and Linux) and have made a fibaroapi.lua file that can be included to emulate the fibaro calls and call out to the HC3.

     

    It's similar to the old fibaroapi for the HC2 but with more extensive support to create a better "offline experience"... 

    define

    Please login or register to see this code.

    and include 

    Please login or register to see this code.

    most of the functions are there and will be improved over time.

    • There are support for net.HTTPClient() and setTimeout/clearTimeout and api.*
    • There are support for getting triggers and events from the HC3
      • Support for auto-creating a QuickApp proxy with UI elements that sends events back to the code being debugged.
    • There are support for both QuickApps and Scenes (with conditions)

     

    Currently supported (v 0.38)

    Please login or register to see this code.

    If someone wants to try this in another IDE than Zerobrane that I use (like Visual Studio) the only thing that could be an issue is to have access to the Lua libraries

    Please login or register to see this code.

    They are pretty standard lua libraries - based on LuaSocket. If someone manage to get it running in VisualStudio I would be interested to know.

     

    Any improvements are happily received (in code) and credits will be due granted.

    Here is another post with some examples of coding QuickApps:

    ...and one for coding scenes

     

     

    v 0.7 fixed bug in offline updateProperty

    v 0.8 bug using fibaro:...

    v 0.9 fixed bug  in getValue

    v 0.10 fixed offline quickvars

    v 0.12 fixed clearTimeout bug

    v 0.14 fixed clearTimeout bug for real....

    v 0.15 rudimentary support for scenes...

    v 0.16 fix getVariable

    v 0.18 https fix, support for auto creating proxy on HC3

    v 0.20 stability fix, + more events.

    v 0.21 more scene conditions and "speed time"

    v 0.23 fix bug plugins->plugin

    v 0.24 caching values allow speed-time to run faster and create less traffic to the HC3.  global-variables triggers in conditions

    v 0.25 fibaro.warning etc. Bug fixes.

    v 0.29 fixed bug in setTimeout (again) when running at "speed time"

    v 0.30 more event types + general fixes

    v 0.35 New approach to polling for triggers as emit customevent REST API hangs ~60s on 5.021.38

    v 0.38 Fixed bug in createQuickApp's rendering of UI elements. Added fibaro.sleep....

    v 0.40 Fixes.

    v 0.44 Changed calling conventions for fibaro._createQuickApp

    v 0.45 Support for changing UI layout of existing QuickApp. fibaro.__updateViewLayout(id,UI)

    v 0.50 Refactoring, new calling convention for fibaro._start(), first attempt to simulated off-line devices...

    v 0.60 More refactoring. Fixed a bug with setTimeout and "speed time". Additional bug-fixes and additions from @petergebruers, moved emulator functions from fibaro._* to hc3_emulator.* . This means a new calling convention for starting the scene...  Because it's a major restructuring of the code new bugs could have cropped up - please let me know.

    v 0.64 Bugfixes, better offline support.

    Edited by jgab
    • Like 1
    • Thanks 4

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Another thing that can be useful to do in QD's is to receive triggers - because scenes are so "functionality challenged" in the HC3 it can be useful to use QD's as scenes and let them react on events in the systems.

    Here is the standard way of polling /refreshStates and then posting the incoming events to a user defined QuickApp:event(event)

     

    Please login or register to see this code.

    There could be support for more events and some kind of filter function.

    In general, errors in setTimeout timers never give any error messages so it's good to have a routine that is debugged and works. Also, at the moment, /refreshStates hangs if there are no events available so we emit our own "tick" event to drive the loop.

     

    (this kind of loop is what I'm using in my EventRunner port)

     

    Note. This code has evolved now and I would recommend to have a look in the fibaroapiHC3.lua file how to poll for events

    Edited by jgab
    Fix, debug
    • Like 2

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • As I said, in QDs if you call setTimeout(fun, ms) and there is a bug/error in the fun so it crashes, you will not get any error messages. This can be very annoying trying to pinpoint what's gone wrong in your code.

    Hopefully Fibaro will fix this but while we wait (can't hold my breath more than 2min)  we can patch setTimeout to print out the error

    Please login or register to see this code.

    There is still the problem with line numbers being wrong. We can fix that too

    Please login or register to see this code.

     

    Edited by jgab
    • Like 1

    Share this post


    Link to post
    Share on other sites

    Thank you, jgab, for all tips!

    Share this post


    Link to post
    Share on other sites

    First of all thanks for info sharing,.

    My questions is, why I need "ton" of code just to make HC3 more user-friendly and to have useful functionality?

    It's insane to create so many functions just to have a nice workaround and all that is just the beginning. I believe moving forward you'll find more and more "workarounds".

    13 hours ago, jgab said:

     

    The verdict is still out there... However, I'm a nerd so any hardware is a temptation for me ;-) 

    Looks like you did provide the verdict... 

    Edited by AR27690

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 23 minutes ago, AR27690 said:

    First of all thanks for info sharing,.

    My questions is, why I need "ton" of code just to make HC3 more user-friendly and to have useful functionality?

    It's insane to create so many functions just to have a nice workaround and all that is just the beginning. I believe moving forward you'll find more and more "workarounds".

    Looks like you did provide the verdict... 

     

    Well it depends on where you come from.

     

    -As a user I would like to have ready made functionality like schedulers and nice block scenes with great UI graphics. I would not like to see "a ton of code". Do you get that in the HC3? Maybe, profiles and block scenes may solve some tasks for some people.

     

    -As a developer I would like to have powerful APIs and the full expressiveness of Lua to create great code (that would be easy for other user to use without having to see my code). In principle I have nothing against a lot of code if it's useful code.

    -- So far Fibaro have been reluctant to invest in the "developer experience" which forces developers to do all kind of workarounds to get things done... (at the moment they seem to want to limit the possibilities for developers to make life easier for installer - an approach that I believe is misguided..)

     

    Another way to put it: I'm not sharing this code for people looking for easy to use functionality. I'm sharing the code for developers that would like to make easy to use functionality for themselves or others.

    Could Fibaro have provided more functionality for developers? - yes - but we can build our own "frameworks" ontop of what they provide that suits our own development style.

    Edited by jgab
    • Like 1

    Share this post


    Link to post
    Share on other sites
    39 minutes ago, jgab said:

    -As a developer I would like to have powerful APIs and the full expressiveness of Lua to create great code (that would be easy for other user to use without having to see my code). In principle I have nothing against a lot of code if it's useful code.

    Now I'm confused... you're saying that you intend to provide easy-use for other users, but honestly to copy all code and to learn how to use it is not so easy.

    I'm not a SW person, so to me just to understand how to use your code (what and when to call which function) is very hard.

    I feel that your work and code intended for users with moderate and above SW knowledge.

    Based on my programming skills, I'm probably in wrong topic.

    Any way according to users' reaction your tips are very helpful - well done

     

     

    Edited by AR27690

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 1 minute ago, AR27690 said:

    Now I'm confused... you're saying that you intend to provide easy-use for other users, but honestly to copy all code and to learn how to use it is not so easy.

    I'm not a SW person, so to me just to understand how to use your code (what and when to call which function) is very hard.

    I feel that your work and code intended for users with moderate and above SW knowledge.

    Based on my programming skills, I'm probably in wrong topic.

     

    Yes, I share the code for developers (SW persons) - not for regular users. I agree that users (non SW people) should not need to code, or feel forced to cut&paste code they don't understand to get the functionality they need. SW developers should be able to wrap new functionality in QDs that can be easily used by others.

    Share this post


    Link to post
    Share on other sites
    2 minutes ago, jgab said:

     

    Yes, I share the code for developers (SW persons) - not for regular users. I agree that users (non SW people) should not need to code, or feel forced to cut&paste code they don't understand to get the functionality they need. SW developers should be able to wrap new functionality in QDs that can be easily used by others.

    So regular users left alone by fibaro and developers...😋

    Sorry for my ignorance, what QDs means?

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • A generic template for a QuickApp Device (QD) could look like this:

    Please login or register to see this code.

    Different types of devices should support different QuickApp:* methods. This is a multilevel switch and support setValue,turnOn, and turnOff.

    It also has a UI with a slides, button and a label.

     

    One take-away here is that the functions you declare on QuickApp, ex. function QuickApp:turnOn() etc becomes the "API" of the device and is callable from other devices or even the external REST API. Therefore you should keep you business logic in "normal" Lua functions or "objects" that you define and call from QuickApp:onInit() at startup. Here we call our function main().

     

    On 2/11/2020 at 10:53 AM, AR27690 said:

    So regular users left alone by fibaro and developers...😋

    Sorry for my ignorance, what QDs means?

     

    No, we developers are trying our darnest to create value to you that you don't get directly from Fibaro.

    Edited by jgab
    • Like 1
    • Thanks 1

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Ok, back to code.

     

    The QD has support for UI buttons, labels, and sliders like the old VD (no improvements here).

    We declared handler in the QD, so if we have a button with id 'button1' it will call 

    function QuickApp:button1Clicked() .... end

    when we click on the button. 

    Disclaimer: Still some bugs on the HC3 that makes these UI's not working on mobile apps, and sometimes flaky even in the web gui... but that will hopefully be fixed.

     

    So, on to an example:

    Assume, we make a simple QD to work as a code lock - here we make the QD to be of type ''door sensor' (we chose the type when we create the QuickApp device).

    It could look like this:

    Please login or register to see this code.

    We lay out the controls like this

    Please login or register to see this image.

    /monthly_2020_02/codelock.png.b819d5f737ce3dd0c7ea24544782762a.png" />

    and name the handlers 'button0' etc.

    This device will then act as a code lock, that will get 'unsecured' when the right code is typed and auto-secure again after 4s.

    Other scenes and devices (or block scenes) could trigger on this device being unsecured and do something - like disable an alarm.

    FQA:

    Please login or register to see this attachment.

    Next post, a bit more advanced...

    Edited by jgab
    • Like 2
    • Thanks 2

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • A bit more elaborate QD example.

     

    First, we can update the names of the UI elements (e.g buttons) programmatically and it's reflected immediately in the web GUI (still issues with the mobile app it seems),

    Anyway , that means that we can change the names of buttons to reflects states.

    Here is a control to schedule activations of profiles on the HC3 (profiles are pre-sets of device states that you can give names like "Home"; "Away" etc. and easily activate from scenes or devices.

    This control is used to schedule a time when we want a particular profile to be activated.

    Please login or register to see this image.

    /monthly_2020_02/profiles.png.0b0262961596fc86949e49feddfd51cf.png" />

    The upper left button [sunset+07:20] will toggle between time, sunset+/- time or sunrise+/- time when pressed.

    The upper right, [Home] will toggle between the different available profiles when pressed.

    The 4 numbers are used to set the time (increases their digit when pressed)

    [Save] should save the scheduling data associated with the profile.

    [Enabled] toggles between enabled/disabled for the schedule for the profile in question

     

    The actual logic to schedule the activation of the profile is not there yet (another exercise)., but it demonstrates the type of GUI interaction that can be done.

    The element IDs are

    [id='time'][id='profile']

    [id='hour1'][id='hour2'][id='min1'][id='min2']

    [id='save'][id='enabled']

    ...and the code looks like

    Please login or register to see this code.

    (sometimes the web GUI doesn't update the new button texts, sometimes by restarting or opening/closing the editor makes it work)

    • Like 1

    Share this post


    Link to post
    Share on other sites
    3 hours ago, jgab said:

    A bit more elaborate QD example.

     

    Here is a control to schedule activations of profiles on the HC3 (profiles are pre-sets of device states that you can give names like "Home"; "Away" etc. and easily activate from scenes or devices.

     

     

    Hi! Seriously @jgab, did you read my mind? I was just thinking about how to schedule the profiles, and then I searched your thread and found your example! :)

     

    I will code this in, I want to use it for workdays to turn on lights, the Sonos etc. and a bunch of other things.

     

    Thank you!

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 2 minutes ago, robw said:

     

    Hi! Seriously @jgab, did you read my mind? I was just thinking about how to schedule the profiles, and then I searched your thread and found your example! :)

     

    I will code this in, I want to use it for workdays to turn on lights, the Sonos etc. and a bunch of other things.

     

    Thank you!

    Beware that the UI updates are still wonky-

    but I have seen it work with my own eyes 😁

    There is a rumor of an update on Friday. Have you heard anything? (one of the Swedish resellers that inform buyers of a new fw coming)

    Share this post


    Link to post
    Share on other sites
    4 minutes ago, jgab said:

    Beware that the UI updates are still wonky-

    but I have seen it work with my own eyes 😁

    There is a rumor of an update on Friday. Have you heard anything? (one of the Swedish resellers that inform buyers of a new fw coming)

     

    Sorry, I have not heard anything. I got my HC3 from Kjell.com, and they don't report anything. Hopefully we'll see a new firmware then! Thank's for all your tips and tricks here!

    Cheers,

    Share this post


    Link to post
    Share on other sites

     

    On 2/11/2020 at 2:49 PM, jgab said:
    On 2/11/2020 at 11:53 AM, AR27690 said:

    So regular users left alone by fibaro and developers...😋

    Sorry for my ignorance, what QDs means?

     

    No, we developers are trying our darnest to create value to you that you don't get directly from Fibaro.

    Now I'm totally confused, you said and I quote:

     

    On 2/11/2020 at 11:47 AM, jgab said:

    Yes, I share the code for developers (SW persons) - not for regular users. I agree that users (non SW people) should not need to code, or feel forced to cut&paste code they don't understand to get the functionality they need. SW developers should be able to wrap new functionality in QDs that can be easily used by others.

     

    But may be I'm wrong... for other hand have tried to use your door lock code (my friend has HC3) and we've lost on buttons and labels creation. I do believe some code in button control required, right?

    Anyhow thanks for your enthusiasm. 

    Edited by AR27690

    Share this post


    Link to post
    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...