I think these are equivalent, but what might be the advantage or disadvantages of either?
Is one faster? Is one more reliable?
A third option...
If my assumption about Hubitat explicitly asking the device if the switch is already on, this seems like less load on the Z-Wave network.
These assumptions are all predicated on Hubitat talking to the device explicitly rather then consulting an internal (mirrored) database to figure out the status. If the device status is held in RAM, then we would want to use one of the first two.
From the snippets you posted, the hub would not poll your light for its status unless you explicitly direct it to with another action first.
The hub will go with the last status reported by the device and saved in the hub’s internal database.
I don’t think that means it’s necessarily “maintained in ram” but I’m not sure. But it is on the hub.
It’s unlikely any of the three versions of your actions would make much of a difference to the hub or z-wave mesh. Since turning on a single z-wave light is a very simple action.
My understand is slightly different from yours. - In case #3, there is a single ZW network operation, that writes "On" to the ZW device (regardless if it's on or off), and assuming it's a ZW+ device, the hub state gets updated when the "ACK" comes back from the device, saying the device is on (assuming the write succeeds to the destination device)
In case #1 or #2, the "test" if on, doesn't automatically trigger a ZW read of state from the device, rather it triggers a DB lookup in the device state (table/cached memory, depending on the H2 DB). The current device state is tested per the conditional and the "On" is sent if needed (so potentially no ZW IO if the device is already on - So potentially less IO than #3, where there always a write).
If you want to trigger a device read to make sure you have the current state (which should automatically be updated by ZW+ from physical device changes - without any hub triggers), then you could trigger a "refresh" for the device, to force a ZW read.
While #1 and #2 are the same, in terms of ZW IO, there definitely is a performance difference between the two, with #2 being slightly (tens of ms) faster and having less overhead. - That's because the conditional test is done all within the single "Groovy" command, versus the interpreted overhead of the separate test in RM, which has additional overhead pulling opcodes from the DB, and executing the same underlying test within RM, versus just straight Groovy code - Not a lot of overhead/runtime, mind you, (we're talking ms), compared to the slowness of the ZW IO, but "raw Groovy" logic is going to be faster than equivalent RM logic.
That's my understanding, and I'm sure folks will correct me, if I'm way off base.
The above is my understanding as well, and it's a somewhat minimal (yet material) difference in RAM versus flash speed (the "hard disk" for persistant storage in the hub is flash memory) - RAM is like <= 1 ms for access, and the flash access to the H2 database is likely several ms (so appreciably slower, yet not likely something that your going to notice on human scale).
I believe there is caching happening with the H2 DB level (or the application level can be coded with "atomic state updates to force DB update), so it's likely unclear if a application request for current device state is going to hit RAM or flash. Either is likely going to be 100's of times faster than the ZW network IO. So subtle distinction, as there really are several different access paths for current device state.
The real point, is that the DB is normally accessed for current device state - An actual network IO doesn't automatically happen, unless you specifically request it.
My understanding has always been that the 1st one (command only switches that are off), will only send a z-wave command if the status of the switch is off in the database, the second one will always send a z-wave command whether the device is on or off.
So the 1st will will generate less traffic on the z-wave network by checking if HE thinks it's already off, as the second will generate traffic all the time.
Which is better, it all depends on the strength of your z-wave mesh. Personally I only use the "command only switches that are off" option when dealing with virtual switches or the likes just to be 100% sure.
That’s a good point but if I understand things correctly (and I may not), the same thing will happen in all three screenshots if the hub has sent an on command.
Versions one and two might not send an on command (based on device’s previous status), version three always will. That’s the primary difference.
I don’t doubt that timing differences could be measured by a computer, but would be imperceptible to a human unless something else is going on with the hub that’s already causing a strain that either the hub or the mesh can barely handle as-is.
My only additional comment around options #1 versus #2 (explicit conditional tests in RM code) - Is that I always prefer the #2 approach, it's cleaner, less lines of code, less stuff to edit, etc. - It just seems simpler to me (and I think it's such a common pattern, is that's why the option of the test in #2 was added later in RM)
#3 is clearly a different thing. - It's going to ALWAYS do ZW IO, and that may or may not be important - It's also somewhat "less important" given the ZW retry command options that have been added at a device level, but that's another option all together, in terms of reliability and trusting ZW writes to succeed in a weak mesh environment.
I agree. I code my automations in Groovy, and I always check state before sending a command. I assume a simple lookup is more efficient than sending a command through the network that is not needed.
From what I am reading, there is a setting in Groups and Scenes called Enable activation optimization that does this, meaning that with this option on it will check state first, but with it off it just fires the command every time. Default behavior for Hubitat is fire and forget.
Webcore has a similar setting, as is described well in this post:
Incorrect, it checks the device state saved on the hub, does not "ask" the device.
Also incorrect, the two examples checking the device state would be less zwave traffic when the device is already in the correct state. Without checking the state you are always sending the command regardless of the current state.
Its held on the device pages which you can clearly see if you were to open any of them. Saved in an internal database, not just RAM, the saved device states along with everything else will survive a reboot.
But during the reboot the Device may change a State. Because during the reboot hub is not functional new State will be missing and therefore incorrect after reboot is completed.