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

On 2/18/2020 at 11:15 PM, tinman said:

 

that's right, and yes it will be there and it does works, e.g. here with Wallmote Quad

 

Please login or register to see this spoiler.

 

hello Having a wallmote too (several actually) and migrating from HC2 to HC3, your post retains all my attention... unfortunately, it doesn't work for me

I get a (load):4: attempt to index a nil value (field 'value')

as if this 'value' data was not existing.

 

Checking sourTrigger returns, it looks like indeed, there is none... any idea?

thanks in advance, 

:)

 

 

 

Link to comment
Share on other sites

Guys i have a little problem with creating QA variables.
I have a code to check the existence of QA variables:
 

Please login or register to see this code.

So the code checks (not the most elegant way :-D ) the existence of desired variable, but i can't find an api call to create one if non existent. Anyone ideas, or some help?

Link to comment
Share on other sites

@Bodyart Dear!

 

no.

fibaro.call(plugin.mainDeviceId, "setVariable""BodyArt""rulez!")

Please login or register to see this image.

/monthly_2020_05/image.png.5b93be85db2e0c98f4b397db4f244a2e.png" />
 
image.png.3e3b890af97e7baca4f07b2aa0028525.png
  • Like 1
Link to comment
Share on other sites

Oh man, so simple and i was searching the whole swagger ?...

Thank you very much, what are you drinking?

Otchen spasibo :-D

 

Edited by Bodyart
  • Thanks 1
Link to comment
Share on other sites

On 2/14/2020 at 6:15 AM, jgab said:

function QuickApp:onInit()     setInterval(function() print("Tick!) end, 60*1000) -- call function every minute end

Hi @jgab, first off thanks for all the work you've done and sharing it with all of us!

 

I am just starting to experiment with QA's and try to build a simple timer using your setInterval.

Is there a way to align it with the exact minute? So it runs at HH:MM:00  

 

Jim

Link to comment
Share on other sites

4 minutes ago, jimicr said:

Is there a way to align it with the exact minute? So it runs at HH:MM:00  

I am not a Jan but no law against to create timer for 1 sec and check the current time and fire only on 00 mins.

IMHO

Edited by 10der
Link to comment
Share on other sites

  • Topic Author
  • Just now, 10der said:

    I am not a Jan but no law against to create timer for 1 sec and check the current time and fire only on 00 mins.

    IMHO

    Noooooooooo :-)

    Link to comment
    Share on other sites

    1 minute ago, 10der said:

    I am not a Jan but no law against to create timer for 1 sec and check the current time and fire only on 00 mins.

    IMHO

     

    1 minute ago, jgab said:

    Noooooooooo :-)

    Yep, now I'm lost ?

    Link to comment
    Share on other sites

    ok. another solution waiting at first time 00 sec and than continue.

    but not guess about drifts

    Edited by 10der
    Link to comment
    Share on other sites

    3 minutes ago, 10der said:

    ok. another solution waiting at first time 00 sec and than continue.

    but not guess aboy drifts

    Will try to figure out how to do that. Thanks for thinking with me

     

    Link to comment
    Share on other sites

  • Topic Author
  • 2 minutes ago, jimicr said:

     

    Yep, now I'm lost ?

    The short answer, you can't align setInterval to the minute.

    You can start setInterval on the minute but it will start to drift if you do any work inside setInterval (and you don't want to sleep inside the function)

    The standard way to get alignment is to use setTimeout

    Please login or register to see this code.

    you could then make your own minute aligned setInterval then

    Please login or register to see this code.

    One could generalise it to work with hours days etc...

    • Thanks 2
    Link to comment
    Share on other sites

  • Topic Author
  • One could argue that setInterval should try to compensate to make sure it runs on the exact interval given.   

    Below is a version that replaces the standard setInterval with such a version. The problem is that we want to support

    clearTimeout too. To do that we need access to the latest setTimeout reference. We solve that by stuffing the ref inside a table that becomes our new reference value.

    This should be a drop in replacement of the old setInterval, but one that tries to keep the interval given and not start to drift.

    Please login or register to see this code.

    Although, you still need to start it on the minute if you want it aligned on the minute.

    Ex.

    Please login or register to see this code.

    ...a bit complex maybe...

     

    One could also do a function nextMinute(fun) that runs a function on the next even minute

    Please login or register to see this code.

     

    Then we could do (with the last setInterval version)

    Please login or register to see this code.

     

    or loop on every minute by just doing

    Please login or register to see this code.

    For completeness, a compensating setTimeout loop:

    Please login or register to see this code.

     

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

  • Topic Author
  • In the new FW, 5.031.33 there is a new function

    Please login or register to see this code.

    It's called when the QA is loaded with the value 'true', which I guess sets the fibaro.call handler to do calls asynchronous by default.

    Please login or register to see this code.

    produces the output 

    Please login or register to see this code.

    Telling us that they make the remote call without waiting for the ack.

    If we set the handler to 'false' we get the old behaviour

    Please login or register to see this code.

    with a 5s delay.

    Ï still think you should call your own QuickApp functions using self, but why not.

    It may also not ack when calling other QuickApps, and that may speed things up. (I can't verify that but it's likely)

    However, I don't experience any speedup with my RPC calls (still around 0.08s per call round-trip)

     

    And please don't use fibaro.sleep or busy-loops. That will still prevent any UI/call interaction with your QA.

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

    @jgab I deleted by mistake my statewatcher QA.... and now i can not find the latest version.. and i know it was one greater then 4 .  I looked for 30 mins :(  can you please point me in the right direction ? 

    Link to comment
    Share on other sites

  • Topic Author
  • I believe the lates is the one linked in this post 

    (it added day and month intervals)

     

    Link to comment
    Share on other sites

    Cheers:) that one i found but i was under the impression there is a newer one ?

     

    I just love that QA ? makes my job so much easier.  Thank you again :) 

    Edited by Momos
    Link to comment
    Share on other sites

    Hello Jan,

    My IOS Locator doest work anymore getting error for myselves and my wife same error message.

    Please login or register to see this image.

    /monthly_2020_06/image.png.ba46354fe489b5be5c0c7e4d5efa4ae0.png" />

    Please advice,

    //Sjakie

    Link to comment
    Share on other sites

  • Topic Author
  • If you have played with QuickApp children you know that if you create them of different types you get different kind of "built-in" user interfaces for them.

    Ex. if you create a child of type com.fibaro.philipsHueLight you get an UI that looks like

    Please login or register to see this image.

    /monthly_2020_06/Hue.png.8725e8b891408edc9b3f36b17d9d9f10.png" />

    with a nice color slider. Other device types have other types of UI layout. These are layouts we can't create today in regular QuickApps but will hopefully come in the future....

     

    However, an issue with childrens' UI elements are they they are not easy to create action handlers for.

    Assume that we create a quickApp child for com.fibaro.sonosSpeaker

    sonos.png.ab45148c932b1dae83ae57b9f38668ac.png

    We get these buttons. If we press the 'play' button we get

    [14.06.2020] [11:25:08] [TRACE] [QUICKAPP1005]: UIEvent: {"values":[],"eventType":"onReleased","elementName":"play_Button","deviceId":1006}
    [14.06.2020] [11:25:08] [WARNING] [QUICKAPP1005]: UI callback for element: play_Button not found.

     

    It can't find the function to call. I.e. the method of the quickApp child class.

    If we have a QuickAppChild class for the player and define the handler

    Please login or register to see this code.

    it will still not find it, and we still get the error.

     

    The reason seems to be that the standard UIEvent handler for the QuickApp class doesn't propagate UIEvents to its children.

    In the QuickApp tutorial #3 I talked about a UIEvent handler that could be defined to intercept all ui events. We can use it here to make it work.

    Please login or register to see this code.

    Here we check if the deviceID in the event is the deviceId for a child, and in that case we call the child's handler (the method in the child class)

    (The code takes some precautions to be backward compatible with the existing behaviour.)

    Hopefully in the future when we get "real" UIs for children so this hack will not be needed.

     

    For the Sonos example above I include a skeleton QA that creates child media players of the com.fibaro.sonosPlayer type. ( In this case for HEOS players, but can be easily changed ).

    The example creates 2 children and forwards the button presses to the correct object instances. 

    You just have to fill in the code to actually call the media players (with http?) do make it do something...

    Please login or register to see this attachment.

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

  • Topic Author
  • If you are writing a QA dealing with QuickAppChildren, I can recommend the following add-ons to your QuickApp class.

    Please login or register to see this code.

    This means that the HEOS QA I included in the previous example simply becomes

    Please login or register to see this code.

    This QA class has a "create" and "remove" button that creates children devices of type com.fibaro.sonosSpeaker and sets the icon to the HEOS icon.

    If QuickApp:createChild is used you only need to do QuickApp:loadChildren() in the QuickApp:onInit() when you start up.

    It will remember what class the device is and create the right child objects and thus overcomes the issue with different object mapped to the sa<me type.

    It will also fix the UIEvent delegation.

    There is also a QuickApp:callChildren(fun,...) that calls all children with the function specified.

    Ex. self:callChildren(HEOSPlayer.play_Button)

    If you call self:createChild{..., data = {...}}

    and have a :setup method for your child class it will be called with the data as argument. This is good if you need to setup something in the child class after it has been constructed the first time. As an example, a child has a .parent field that points to the QuickApp object (self). However that field is not initialised when we are inside the .__init method of the child. It is set after the child is created. When our .setup method is called we can be sure that the child is fully constructed and do stuff we need , like calling common methods in the QuickApp (parent) class.

    Otherwise I would recommend to store child data during runtime in the child's quickAppVariables to persists them.

     

    Including the QA

    Please login or register to see this attachment.

     

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