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


  • 0

[Help needed] Virtual device with actual system readouts


Question

Posted

Hi,

I want to create a virtual device with some actual system readouts.

First step is to monitor scenes counts:

A virtual device created with one label and one button with code:

Please login or register to see this code.

Somehow I always get zero counts, even when a scene is activated.

what am I doing wrong?

Help is highly appreciated...

14 answers to this question

Recommended Posts

  • 0
Posted

Just quick thought: why do you declare saCount again in every loop? change "local saCount = saCount + scene" to "saCount = saCount + scene". If you keep declaring this variable, the variable will be local to "for" function. If it does not help i will take a closer look at that code. By the way, what is the output in debug window?

  • 0
Posted

Just tested the code in a scene on my HC2 and it returns the scene count just fine. But as mentioned above, you need to remove "local" before saCount, otherwise it will reset itself for each rerun of the For loop.

"local" is used to declare a variable. So each time local is used, the variable will be declared as a new value and any old instances purged from the memory. Actually, there really isn't any good reason to declare it in the first place using local as there is no such thing as declaring a global on the HC2. So any variable will by default be a local variable. Some might call this junk programming, some might call it lazy, but fact of the matter is that it works just as fine as declaring the variable "local".

  • 0
Posted

Dalle1985, there is a difference, ift variable is set as local, e.g. in main loop of virtual device, it will only "live" for one run of a loop, when you make it global it will be available also in future runs.

  • 0
  • Inquirer
  • Posted
    Just tested the code in a scene on my HC2 and it returns the scene count just fine.

    Thanks for reporting! Can you test it also in a virtual device?

    Dalle1985, there is a difference, ift variable is set as local, e.g. in main loop of virtual device, it will only "live" for one run of a loop, when you make it global it will be available also in future runs.

    So this means when using it in a virtual device it doesn't matter if you add the command local to a variable?

    • 0
    Posted
    Just tested the code in a scene on my HC2 and it returns the scene count just fine.

    Thanks for reporting! Can you test it also in a virtual device?

    Well... Does seem that you are right! The virtual device does always return 0 when trying to count scenes. just tested with a scene and a VD. The scene reports 5 scenes, the VD returns 0 each time...

    [ Added: 2014-07-25, 11:29 ]

    Dalle1985, there is a difference, ift variable is set as local, e.g. in main loop of virtual device, it will only "live" for one run of a loop, when you make it global it will be available also in future runs.

    Is this only the case for main loop? Because I can't reuse the same variable in different instances of the same scene, unless I declare it as a global using a predefined variable in the var panel. Declaring a global variable in a scene should create a variable which lives until that instance of the scene is killed. I.e.:

    scene A runs, declares Global Var Z

    scene B starts, calls Var Z

    scene A is killed, Var Z is purged from memory

    scene B calls Var Z again but returns nil as variable has been purged.

    That is a global variable, in my mind.

    • 0
  • Inquirer
  • Posted

    Hmmm

    Please login or register to see this image.

    /emoticons/default_icon_eek.gif" alt=":shock:" />

    I thought I was getting crazy

    Please login or register to see this image.

    /emoticons/default_icon_mrgreen.gif" alt=":mrgreen:" />

    Thanks for testing Dalle1985, its highly appreciated.

    So a virtual device is not use usable for what I'm trying to do. To bad... I will try to use a workaround.

    My next step is to create Dead node reporting. This is what I have so far and it looks like it is working:

    Please login or register to see this code.

    Upcoming:

    Wake up reported dead nodes

    Wake up and reconfigure Zwave all reported dead nodes.

    • 0
    Posted

    Dalle1985, it can be a little confusing, because you have global variables in FIBARO system (lets call them global1) and global variables in understanding of LUA (global2). Use of global1 is quite clear, you can access them from any place in interface. Global2: when you declare variable in LUA, and add "local" before it, it lives only in current block, e.g. when you declare it inside instruction "for" it will live only inside it. But you can also just declare variable with its name and value and this is when it becomes global and you can access it from everywhere inside the same program, look for example i gave in my last post here.

    So this means when using it in a virtual device it doesn't matter if you add the command local to a variable?
    as i said, there is a difference.
    • 0
    Posted

    I have a scene for doing that:

    Please login or register to see this code.

    So what this does is that every 6 minutes (can be changed) it checks all my nodes to see if any are dead. If it finds any dead nodes, it will attempt to wake it up. After three failed attempts, it can be configured to send a push notification (as it assumes that something is wrong with that node). When it registers that the device has successfully, it will then rebuild the routing table for that device. As you can see, there are some long sleeps in the system. It will first time out for the sleep interval for the node. This is in order to ensure that the device reports back, that it has been awoken and not just that the fibaro has changed the "dead" property to 1. The second sleep period for 21 minutes after rebuilding the mesh, is something I did after advice from Andrew, because this is the timeout for the requestneighbornodeupdate and if it runs several instances at once, the HC2 might become unresponsive.

    Finally, if it has registered dead nodes, then after checking all nodes, it will do a complete routing rebuild. This might be a bit redundant to do though as the individual nodes have already been rebuilt.

    I hope this can serve as a bit of inspiration.

    • 0
  • Inquirer
  • Posted
    I hope this can serve as a bit of inspiration.

    It already did Dalle1985, it already did....

    Please login or register to see this image.

    /emoticons/default_icon_mrgreen.gif" alt=":mrgreen:" />

    That's the beauty of Open Source, but we are discussing that in an

    Please login or register to see this link.

    ...

    Please login or register to see this image.

    /emoticons/default_icon_wink.gif" alt=";-)" />

    • 0
    Posted
    Dalle1985, it can be a little confusing, because you have global variables in FIBARO system (lets call them global1) and global variables in understanding of LUA (global2). Use of global1 is quite clear, you can access them from any place in interface. Global2: when you declare variable in LUA, and add "local" before it, it lives only in current block, e.g. when you declare it inside instruction "for" it will live only inside it. But you can also just declare variable with its name and value and this is when it becomes global and you can access it from everywhere inside the same program, look for example i gave in my last post here.
    So this means when using it in a virtual device it doesn't matter if you add the command local to a variable?
    as i said, there is a difference.

    Yeah okay, so you mean global to that one instance of the Lua VM. But I guess you are actually spawning a new instance of Lua VM for every scene? That is why our thought of "Global" is different. Yes it is global inside that one piece of code, but it doesn't transcend into other codes where it could be beneficial. But I guess you have your reasons for implementing it that way (simultaneous execution of code I gather).

    • 0
    Posted

    Dalle1985, that is what i meant, there is no way of setting variable global for all instances of a scene but i only wanted to make a point, that declaring variable as local or not does matter.

    • 0
  • Inquirer
  • Posted
    I have a scene for doing that:

    ....

    repeat

    fibaro:call(1, "wakeUpDeadDevice", i);

    rebuild = 1

    fibaro:sleep(waitinterval*1000)

    if tonumber(fibaro:getValue(i, "dead")) == 0 then

    fibaro:debug(type.." "..dev.." has been woken up succesfully")

    fibaro:call(1,'requestNodeNeighborUpdate',i)

    fibaro:sleep(21*60*1000)

    fibaro:debug("Routing updated for "..type.." "..dev)

    break

    .....

    if rebuild == 1 then

    fibaro:call(1,'requestNodeNeighborUpdate',1)

    rebuild = 0

    fibaro:sleep(21*60*1000)

    end

    fibaro:sleep(wait_time*60*1000)

    until a==1000

    Just a question. Why is this done twice?

    • 0
    Posted
    I have a scene for doing that:

    ....

    repeat

    fibaro:call(1, "wakeUpDeadDevice", i);

    rebuild = 1

    fibaro:sleep(waitinterval*1000)

    if tonumber(fibaro:getValue(i, "dead")) == 0 then

    fibaro:debug(type.." "..dev.." has been woken up succesfully")

    fibaro:call(1,'requestNodeNeighborUpdate',i)

    fibaro:sleep(21*60*1000)

    fibaro:debug("Routing updated for "..type.." "..dev)

    break

    .....

    if rebuild == 1 then

    fibaro:call(1,'requestNodeNeighborUpdate',1)

    rebuild = 0

    fibaro:sleep(21*60*1000)

    end

    fibaro:sleep(wait_time*60*1000)

    until a==1000

    Just a question. Why is this done twice?

    As I wrote, this might be a bit redundant, but first it updates the routing for the node which had died, the second instance updates the entire routing table. For some reason I seem to have fewer dead nodes when I do it this way. But you probably could do without the first update.

    • 0
  • Inquirer
  • Posted

    Clear. Thanx!

    [ Added: 2014-07-26, 12:11 ]

    Question: Is there a way to detect the ID of the current scene, like the fibaro:getSelfId() which can be used by Virtual Devices?

    [ Added: 2014-07-26, 15:38 ]

    Added a new topic for my beta creation:

    Please login or register to see this link.

    Join the conversation

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

    Guest
    Answer this question...

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