We have moved at community.getvera.com

Author Topic: Watched Variables  (Read 10202 times)

Offline akbooer

  • Moderator
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +292/-70
  • "Less is more"
Re: Watched Variables
« Reply #45 on: February 03, 2016, 03:26:49 am »
I think the clue is here

Code: [Select]
237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: Status was: 0 now: 1
237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: sl_LockButton was: 1 now: 1

...whilst Status changes value from 0 to 1, sl_LockButton remains at 1, so no change of state, so no trigger.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline cybrmage

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1104
  • Karma: +113/-43
Re: Watched Variables
« Reply #46 on: February 03, 2016, 05:39:46 am »
I think the clue is here

Code: [Select]
237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: Status was: 0 now: 1
237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: sl_LockButton was: 1 now: 1

...whilst Status changes value from 0 to 1, sl_LockButton remains at 1, so no change of state, so no trigger.

On a real Vera device... When a device variable is used as a trigger or in a variable watch, the trigger is evaluated whenever the variable is updated, independent of a change in value.

This is why many plugins are coded to prevent calling luup.variable_set to update a variable unless the value of the variable has changed...

A real world example is the EVL3 plugin with a scene being triggered when a motion/door sensor is faulted... Originally, it would set the "Tripped" variable on a motion/door sensor when the alarm panel reported that the sensor had been faulted... But the EVL3 reports the fault as both a sensor fault in a keypad update (which causes the variable to be set to 1) and a zone fault in a zone update (which sets the variable to 1)... This would cause the scene to be run twice, once for each time the variable is set... The plugin now calls a helper function each time it sets a variable, and this helper function prevents calling luup.variable_set unless the value has changed.

This behavior (evaluating trigger conditions) are also used in Vera Scene Controllers... The "Sl_SceneActivated" and "Sl_SceneDeactivated" variables are used as a trigger, and is set the scene number being activated. If the trigger was not evaluated when the value does not change, you could only trigger a scene once and would need to trigger a different scene before being able to trigger the scene a second time.


« Last Edit: February 03, 2016, 05:43:59 am by cybrmage »

Offline martynwendon

  • Full Member
  • ***
  • Posts: 120
  • Karma: +15/-1
Re: Watched Variables
« Reply #47 on: February 03, 2016, 06:47:49 am »

On a real Vera device... When a device variable is used as a trigger or in a variable watch, the trigger is evaluated whenever the variable is updated, independent of a change in value.

This doesn't seem to match the behaviour that I see!

If I set a watch on a real Vera on say:

service: urn:upnp-org:serviceId:TemperatureSensor1 variable: CurrentTemperature

Unless CurrentTemperature *changes*, the watch doesn't fire, because the variable doesn't change.

If I set a watch on an entire service:

service: urn:upnp-org:serviceId:SwitchPower1

then any time ANY variable is changed within that service, the watch will fire, but if nothing changes in any variable, then the watch doesn't fire.

At least that's my experience ever since early UI5 versions up until current and seems consistent with the docs at http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#function:_variable_watch

Quote
Whenever the UPnP variable is changed for the specified device, which if a string is interpreted as a UDN and if a number as a device ID, function_name will be called. See Luup Declarations#watch_callback for the values that will be passed to function_name. If variable is nil, function_name will be called whenever any variable in the service is changed.

Scene Controllers are slightly different because there's a lot of lower level shenanigans occuring to handle the various Scene Controller command classes.  The Scene Controller variables don't directly correspond to the underlying command classes being used, Vera generates these at some lower level and forces them to be evaluated every time they are updated.
« Last Edit: February 03, 2016, 07:10:24 am by martynwendon »

Offline CudaNet

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1401
  • Karma: +42/-11
  • Chimichanga !
Re: Watched Variables
« Reply #48 on: February 03, 2016, 09:14:11 am »
So yes, we have a problem....

[1] UserA enters and leaves, UserA returns. The events are the same and therefor the watch never fires the scene.
[2] The lock button being pressed always results in a variable of '1', same problem as item 1.

So how would we know which devices exhibit this behavior (aside from locks and scene controllers) ? Trial and error. Ugh ! I've been trying to overcome this issue for some time now.  Should I let amg0 know what's being observed so we can possibly approach a solution ?

Here is a log whereby I used (new~=nil) for a sl_UserCode.

Code: [Select]
2016-02-03 08:01:34.744   luup_log:3: ALTUI: debug: -----> evaluateExpression() {"(new ~= nil)":[{"SceneID":12}]}
2016-02-03 08:01:34.744   luup_log:3: ALTUI: debug: evaluateExpression(0-10237,urn:micasaverde-com:serviceId:DoorLock1,sl_UserCode,(new ~= nil),UserID="3" UserName="UserC",UserID="4" UserName="UserD",1454508094,1,12)
2016-02-03 08:01:34.744   luup_log:3: ALTUI: debug: _evaluateUserExpression(0-10237,urn:micasaverde-com:serviceId:DoorLock1,sl_UserCode,UserID="3" UserName="UserC",UserID="4" UserName="UserD",1454508094,(new ~= nil))
2016-02-03 08:01:34.745   luup_log:3: ALTUI: debug: Evaluation of user watch expression returned: [true]
2016-02-03 08:01:34.745   luup_log:3: ALTUI: debug: run_scene(12)

However, enter a second time with the same user code and this happens...

Code: [Select]
2016-02-03 08:04:42.881   openLuup.server:: /data_request?id=lu_status2&output_format=json&DataVersion=506764955&Timeout=60&MinimumDelay=1500&_=1454506622711 tcp{client}: 0x2b84478
2016-02-03 08:04:52.307   luup.variable_set:43: 10237.urn:micasaverde-com:serviceId:DoorLock1.Status was: 1 now: 0 #hooks:0
2016-02-03 08:04:52.307   luup.variable_set:43: 10366.urn:micasaverde-com:serviceId:GenericSensor1.CurrentLevel was: 2255 now: 2267 #hooks:0
2016-02-03 08:04:52.308   luup.variable_set:43: 10506.urn:micasaverde-com:serviceId:GenericSensor1.CurrentLevel was: 2255 now: 2267 #hooks:0
2016-02-03 08:04:52.822   openLuup.server:: request completed (21453 bytes, 2 chunks, 9941 ms) tcp{client}: 0x2b84478
2016-02-03 08:04:52.926   openLuup.server:: /data_request?id=lu_status2&output_format=json&DataVersion=506764958&Timeout=60&MinimumDelay=1500&_=1454506622712 tcp{client}: 0x2b84478
2016-02-03 08:04:56.943   openLuup.server:: new client connection: tcp{client}: 0x2c78c98
openLuup, AltUI, Zway and HomeWave, enough said...

Offline akbooer

  • Moderator
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +292/-70
  • "Less is more"
Re: Watched Variables
« Reply #49 on: February 03, 2016, 10:00:05 am »
What's wrong with triggering from the Status variable which seems to change?
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline CudaNet

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1401
  • Karma: +42/-11
  • Chimichanga !
Re: Watched Variables
« Reply #50 on: February 03, 2016, 10:03:15 am »
The status variable doesn't allow me to discern between the lock button being pressed from the outside and the lock being turned on the inside. I have scenes the need to know if the lock was secured from outside the house.

What's wrong with triggering from the Status variable which seems to change?
openLuup, AltUI, Zway and HomeWave, enough said...

Offline martynwendon

  • Full Member
  • ***
  • Posts: 120
  • Karma: +15/-1
Re: Watched Variables
« Reply #51 on: February 03, 2016, 10:05:22 am »
akbooer beat me to it :-)

The trick I usually use is to find something else in the service that *does* change:

http://wiki.micasaverde.com/index.php/Luup_UPnP_Variables_and_Actions#DoorLock1

Then set your event to trigger off that and use variable_get to retrieve the current value for the other data (sl_UserCode in your case).

For Scene Controllers I normally watch "LastSceneTime" because that's a time stamp in seconds since epoch that always changes.

Offline CudaNet

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1401
  • Karma: +42/-11
  • Chimichanga !
Re: Watched Variables
« Reply #52 on: February 03, 2016, 11:54:56 am »
Yes, I'm all for a workaround if it presents itself. In this case, status won't get me there...

akbooer beat me to it :-)

The trick I usually use is to find something else in the service that *does* change:

http://wiki.micasaverde.com/index.php/Luup_UPnP_Variables_and_Actions#DoorLock1

Then set your event to trigger off that and use variable_get to retrieve the current value for the other data (sl_UserCode in your case).

For Scene Controllers I normally watch "LastSceneTime" because that's a time stamp in seconds since epoch that always changes.
openLuup, AltUI, Zway and HomeWave, enough said...

Offline martynwendon

  • Full Member
  • ***
  • Posts: 120
  • Karma: +15/-1
Re: Watched Variables
« Reply #53 on: February 03, 2016, 01:51:20 pm »
Yes, I'm all for a workaround if it presents itself. In this case, status won't get me there...

Maybe I'm missing what you're trying to do, status always changes when the lock is locked / unlocked?

And you want the value of sl_UserCode and sl_LockButton to do something with them?

So why can't you watch Status and do a variable_get on those 2 variables to get the values?

Or have I missed something?


Offline CudaNet

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1401
  • Karma: +42/-11
  • Chimichanga !
Re: Watched Variables
« Reply #54 on: February 03, 2016, 02:59:20 pm »
DoorLock1.sl_LockButton allows us to differentiate between someone leaving the property and a momentary process (fetching the mail). Evaluating status tells us nothing other than the state changed from 0 to 1 and vice versa. Great if you want to secure the door in a scene but poor in identifying if someone is actually leaving. 

DoorLock1.sl_UserCode identifies that someone is coming home and who exactly that someone is. Again, evaluating the Status and fetching the UserID may only return the last UserID that entered the house. For example, if UserA entered then left (forgot something at the store) and UserB is still home and decides to walk out and check the mail, well - triggering off status and fetching the UserID would yield UserA when all you wanted to do was check the mail.

These variables exist because Status alone doesn't help isolate exactly what happened other than the obvious (door locked/unlocked). I can only hope that Amg0 has a possible solution as I honestly have no idea how many 'devices' do exactly this. If a conditional can be applied then this would overcome the issue all together. Then again, I never try to reduce this to a simple fix as I have no doubt this is complex code.

Yes, I'm all for a workaround if it presents itself. In this case, status won't get me there...

Maybe I'm missing what you're trying to do, status always changes when the lock is locked / unlocked?

And you want the value of sl_UserCode and sl_LockButton to do something with them?

So why can't you watch Status and do a variable_get on those 2 variables to get the values?

Or have I missed something?
openLuup, AltUI, Zway and HomeWave, enough said...

Offline martynwendon

  • Full Member
  • ***
  • Posts: 120
  • Karma: +15/-1
Re: Watched Variables
« Reply #55 on: February 04, 2016, 04:38:39 am »
I must be having a slow week because I'm still not following :-)

If the status changes every time *something* happens, then I still don't see why you can't trigger off of that event but then retrieve the values of the other variables and use them to determine your logic flow?

Or are you saying that sl_LockButton is only a momentary event and flips from 0 to 1 and then back to 0?  So the *current* value is irrelevant?

If that's the case then I guess the question becomes is this possible on a *real* Vera. 

Vera may show the event in the logs, but can you set a trigger for a scene on it and can you set a variable watch that will fire when the event occurs?

Here's an example from a real Vera:

Code: [Select]
Device_Variable::m_szValue_set device: 464 service: urn:upnp-org:serviceId:TemperatureSensor1 variable: CurrentTemperature was: 20 now: 20 #hooks: 1 upnp: 0 v:0x11fb368/NONE duplicate:1 <0x2bd87680>
That "event" shows in the logs, but the variable watch does not fire because the data hasn't changed.

If you're saying that you can set a trigger or variable watch on sl_UserCode and sl_LockButton and they fire even though the data hasn't changed, then this is indeed another special case where Vera always forces the trigger or variable watch to fire whether the data has changed or not.

And that will be a problem for akbooer and amg0 unfortunately :-)

Offline akbooer

  • Moderator
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +292/-70
  • "Less is more"
Re: Watched Variables
« Reply #56 on: February 04, 2016, 05:35:13 am »
I must be having a slow week because I'm still not following :-)

I am having exactly the same difficulties in understanding why there's an issue here.

Quote
If you're saying that you can set a trigger or variable watch on sl_UserCode and sl_LockButton and they fire even though the data hasn't changed, then this is indeed another special case where Vera always forces the trigger or variable watch to fire whether the data has changed or not.

In order to try and push my understanding forward a bit, I took a look at the service file S_DoorLock1.xml  In the serviceStateTable section it contains, amongst others, these entries:

Code: [Select]
    <stateVariable sendEvents="yes" allowRepeats="yes">
      <name>sl_UserCode</name>
      <dataType>string</dataType>
      <logCode>DL_USERCODE</logCode>
      <logSeverity>3</logSeverity>
    </stateVariable>

   <stateVariable sendEvents="yes" allowRepeats="yes">
      <name>sl_LockButton</name>
      <dataType>boolean</dataType>
      <logCode>DL_LOCK_BUTTON</logCode>
      <logSeverity>3</logSeverity>
    </stateVariable>

So I'm really at a loss if you're telling me that they don't BOTH report repeated events on a real Vera.

Code: [Select]
And that will be a problem for akbooer and amg0 unfortunately :-)

I feel sure the problem will be all mine.

3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline amg0

  • Beta Testers
  • Master Member
  • *****
  • Posts: 3174
  • Karma: +210/-8
Re: Watched Variables
« Reply #57 on: February 04, 2016, 07:28:52 am »
I also have still not understood what ( in wording terms ) you are trying to do.

But some additional info regarding watches in ALTUI.

The watch expression can contain predefined variables new & old so you can use new / old and compare them in your expression.  also the function trueSince(expr,sec) can test if an expr is true and remains true for x sec.
so a valid expression could be for instance:
Code: [Select]
trueSince((new == '1' and new ~= old), 10)
To properly debug watch , you need to run ALTUI in DEBUG mode and get back the logs

Offline CudaNet

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1401
  • Karma: +42/-11
  • Chimichanga !
Re: Watched Variables
« Reply #58 on: February 04, 2016, 09:26:30 am »
@amg0 and Akbooer. I'm going to run a quick battery of tests (with debug enabled) and send them to both of you this morning. For the record, this is what an actual Vera log looks like...

Expressions currently used in openLuup/AltUI scenes:
Code: [Select]
Scene 16 (front door locked)
Schlage [237] urn:micasaverde-com:serviceId:DoorLock1 sl_LockButton (new=='1' and old == '1')

Scene 12(Front door unlocked)
Schlage [237] urn:micasaverde-com:serviceId:DoorLock1 sl_UserCode (new ~= nil and old ~=nil)

UserA presses the lock button on the outside of the door, this variable (sl_LockButton) will always appear as '1' (never 0 - 1 or 1 - 0):
Code: [Select]
VERA LOG:
06      02/04/16 8:00:54.376    Device_Variable::m_szValue_set device: 237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: Status was: 0 now: 1 #hooks: 0 upnp: 0 skip: 0 v:0xb7c810/NONE duplicate:0 <0x2b
06      02/04/16 8:00:54.377    Device_Variable::m_szValue_set device: 237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: sl_LockButton was: 1 now: 1 #hooks: 0 upnp: 0 skip: 0 v:0xd925a8/DL_LOCK_BUTTON duplicate:0

UserA enters, leaves and returns where UserB has not returned home yet.
Code: [Select]
VERA LOG:
06      02/04/16 8:03:01.536    Device_Variable::m_szValue_set device: 237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: Status was: 1 now: 0 #hooks: 0 upnp: 0 skip: 0 v:0xb7c810/NONE duplicate:0 <0x2b83a6
06      02/04/16 8:03:01.538    Device_Variable::m_szValue_set device: 237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: sl_UserCode was: UserID="4" UserName="User A" now: UserID="4" UserName="User A" #hooks: 0 upnp: 0 skip: 0 v:0xd91c28/DL_USERCODE duplicate:0 <0x2b83a680>

UserB enters just after UserA.
Code: [Select]
VERA LOG:
06      02/04/16 8:04:06.376    Device_Variable::m_szValue_set device: 237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: Status was: 1 now: 0 #hooks: 0 upnp: 0 skip: 0 v:0xb7c810/NONE duplicate:0 <0x2b83a680>
06      02/04/16 8:04:06.378    Device_Variable::m_szValue_set device: 237 service: urn:micasaverde-com:serviceId:DoorLock1 variable: sl_UserCode was: UserID="4" UserName="User A" now: UserID="3" UserName="UserB" #hooks: 0 upnp: 0 skip: 0 v:0xd91c28/DL_USERCODE duplicate:0

When the above happens (UserB enters after UserA), my openLuup/AltUI scene triggers... openLuup/AltUI log.
Code: [Select]
OPENLUUP/ALTUI LOG:
2016-02-04 08:16:55.418   luup_log:3: ALTUI: debug: evaluateExpression(0-10237,urn:micasaverde-com:serviceId:DoorLock1,sl_UserCode,(new ~= nil and old ~=nil),UserID="3" UserName="User B",UserID="4" UserName="User A",1454595415,1,12)
2016-02-04 08:16:55.418   luup_log:3: ALTUI: debug: _evaluateUserExpression(0-10237,urn:micasaverde-com:serviceId:DoorLock1,sl_UserCode,UserID="3" UserName="User B",UserID="4" UserName="User A",1454595415,(new ~= nil and old ~=nil))
2016-02-04 08:16:55.419   luup_log:3: ALTUI: debug: Evaluation of user watch expression returned: [true]
2016-02-04 08:16:55.419   luup_log:3: ALTUI: debug: run_scene(12)

Edit: Added clarity to my logs....

I also have still not understood what ( in wording terms ) you are trying to do.

But some additional info regarding watches in ALTUI.

The watch expression can contain predefined variables new & old so you can use new / old and compare them in your expression.  also the function trueSince(expr,sec) can test if an expr is true and remains true for x sec.
so a valid expression could be for instance:
Code: [Select]
trueSince((new == '1' and new ~= old), 10)
To properly debug watch , you need to run ALTUI in DEBUG mode and get back the logs
« Last Edit: February 04, 2016, 11:39:10 am by CudaNet »
openLuup, AltUI, Zway and HomeWave, enough said...

Offline oTi@

  • Community Beta
  • Master Member
  • ******
  • Posts: 4041
  • Karma: +32/-6
  • UI what ?!
Re: Watched Variables
« Reply #59 on: February 04, 2016, 10:57:35 am »
AFAIK it was previously established that a "Door Lock Button" event (driven by sl_LockButton?) is not functional, at least for Schlage.

I have scenes the need to know if the lock was secured from outside the house.
Don't know if this at all applies to your case, but where I'm at storm doors are very common. I detect directionality by having a sensor on both the front door and the storm door, based on timing. Perhaps combining that with a lock event in the same window is a reasonable indicator from which side of the door the event was triggered? (If that is truly what you are after.)
« Last Edit: February 04, 2016, 11:27:25 am by oTi@ »
Dezwaved at the moment...