UPnP Notifications and State changes (true -> true, false -> false)

Hi,
I’m wondering what the intended behaviour is for a SecuritySensor1 having it’s [tt]Tripped[/tt] value set to the value it’s already got.

In my Alarm module, I inspect the “current state” of the Alarm when Vera initially runs my [tt][/tt] code, and then [tt]luup.variable_set[/tt] the value against each of the [tt]SecuritySensor1[/tt] objects I have going (one per Zone (48 total), three per Area (3x4 total)

This is done to keep Vera’s initial state consistent with the Alarm system, just after boot, since we never know what events we missed during any downtime.

Each time I call [tt]variable_set[/tt], I can see the logic firing in the server-side Vera logs indicating it’s setting the value the same as the existing value (expected), but I’m also seeing it Evaluating the attached Event definition (not expected).

I wasn’t expecting to see it “fire” an Event if there was no change in the “value” of the Sensor [tt]Tripped[/tt] attribute

Is this the expected behaviour? If so, is there a way to have it conditional-set the value, where it will only trigger the event if the data changes?

eg. [tt]luup.variable_set(…, false)[/tt] - where the last (optional) field represents whether it should trigger events for value-not-changed situations

Here’s a snippet of my logs, with Vera and my Events mingled… In this log there are 3x SecuritySensor1 child-devices (representing Armed, Stay-Armed, and Breached for each “Area” in my Alarm System, where I only have one “Area” in my house).

Basically I wasn’t expecting to see these event evaluations in the case of “no-change”:
[tt] Event::Evaluate 2 SMS on Alarm is false
[/tt]

01 07/25/09 17:04:16.639 lu_log:9: About to request RA001 <0x402> 51 07/25/09 17:04:16.640 0x52 0x41 0x30 0x30 0x31 0xd (RA001\r) <0x402> 52 07/25/09 17:04:16.652 intercept 0x7f7ff8f0: 0x52 0x41 0x30 0x30 0x31 0x44 0x4f 0x4f 0x4f 0x4f 0x4f 0x4f (RA001DOOOOOO) <0x1807> 06 07/25/09 17:04:16.656 Device_Variable::m_szValue_set device: 110 service: urn:micasaverde-com:serviceId:SecuritySensor1 variable: Tripped was: 0 now: 0 [/b]#hooks: 1 upnp: 1 v:0x6d8450/NONE <0x402> 07 07/25/09 17:04:16.657 [b]Event::Evaluate 1 SMS on Arming is false <0x402> 06 07/25/09 17:04:16.662 Device_Variable::[b]m_szValue_set device: 111[/b] service: urn:micasaverde-com:serviceId:SecuritySensor1 variable: [b]Tripped was: 0 now: 0 [/b]#hooks: 0 upnp: 1 v:0x6d8450/NONE <0x402> 06 07/25/09 17:04:16.666 Device_Variable::[b]m_szValue_set device: 112[/b] service: urn:micasaverde-com:serviceId:SecuritySensor1 variable: Tripped was: 0 now: 0 #hooks: 1 upnp: 1 v:0x6d8450/NONE <0x402> 07 07/25/09 17:04:16.667 Event::Evaluate 2 SMS on Alarm is false <0x402>

There are a few cases where the events should be fired again even if the value is the same. For example, with the door locks, there’s an event when someone enters his user code at the door. So the variable is, basically: “LastUserCode”. The homeowner wants to be notified everytime anybody enters his pin code at the door. So when ‘John’ enters his code, the homeowner gets a notification, and the ‘LastUserCode’ is set to “John”. If the next day John comes back and nobody else has come in since, ‘LastUserCode’ will again get set to the same value ‘John’. But this should fire an event regardless because the homeowner wants the notification. The same is true with the ‘PinFailed’ variable which is set to 1 everytime someone enters a bad code at the door lock.

However, admittedly, this isn’t the normal situation. Usually you only want the event when it changes. So I changed the code now so, by default, it ignores duplicates, but that in the UPNP S_ service file you can add a tag allowRepeats to make it fire events when the variable repeats the same value. The UPNP service now reads:

<stateVariable sendEvents="yes" allowRepeats="yes">
  <name>sl_PinFailed</name>
  <dataType>boolean</dataType>
  <logCode>DL_PINFAILED</logCode>
</stateVariable>

Great!

Since some of the services that we’re required to use here (like SecuritySensor1 etc) are “a standard”, how do we handle this if someone needs it to “default” to notify-every-time, and someone else needs to have it “notify-on-change”.

With the change you’ve put in, I dont need to worry, but I can forsee a time when someone wants it the other way around.

Of course, we can always do:

[tt] if (newValue ~= luup.variable_get(…)) then
luup.variable_set(…, newValue, …)
end
[/tt]
but that’s not guaranteed to work if the container is threaded in any way.

Thoughts?

I could add another parameter to variable_set that is a boolean ‘AlwaysFire’ which can be true, false or not specified (use the default behavior)