Dimmer value in rule seems to be divided by 10


(Paul) #1

I’ll start out with the actual problem I’m trying to solve, in case anybody has a better approach to do this. Essentially, I have a bunch of z-wave dimmers. When you turn the dimmer on from the physical location, they remember their last brightness level, and return to that level. However when I use my Amazon Echos to “turn kitchen lights on”, an “ON” command gets sent, which sends the dimmer to 100% brightness.

My idea to combat this, was to create a “LastValue” item for each of my dimmers, and a rule that sends the previous state of the dimmer to this item on ever change. The overall logic of this seems to work fine, but what I can’t figure out is why the LastValue item seems to always be divided by 10 when it gets stored.

For example:

The kitchen dimmer item is currently 50, and gets a change to 0 (I turned the light off). My logging shows the state changed from 50 to 0. This means the LastValue item SHOULD be getting a value of 50, since that was the previous state of the dimmer item. Instead, my logs show the LastValue item getting a new value of 5 (rounded to an int).

I feel like I’m missing something simple, but I can’t seem to figure it out. My rule is below:

rule "All Lights Change"
	when
		Item g_Lights_All changed
	then
		try {
			Thread::sleep(100) // give persistence time to catch up

			val lightItem = g_Lights_All.allMembers.filter[s|s.lastUpdate("mapdb") !== null].sortBy[lastUpdate("mapdb")].last as DimmerItem
			logInfo(logName, "{} - {} changed from {} to {}.", fileName, lightItem.name, previousState,lightItem.state.toString)

			val lastUpdatedItem = g_Lights_LastUpdated.allMembers.filter[dt | dt.name == lightItem.name + "_LastUpdated"].head as DateTimeItem
			val lastUpdatedOldValue = lastUpdatedItem.state
			val lastUpdatedNewValue = new DateTimeType
			lastUpdatedItem.postUpdate(lastUpdatedNewValue)
			logInfo(logName, "{} - {} changed from {} to {}.", fileName, lastUpdatedItem.name, lastUpdatedOldValue, lastUpdatedNewValue)

			val lastValueItem = g_Lights_Scenes.allMembers.filter[lv | lv.name == lightItem.name + "_LastValue"].head as NumberItem
			lastValueItem.postUpdate(previousState)
			logInfo(logName, "{} - {} changed from {} to {}.", fileName, lastValueItem.name, lastValueItem.state, previousState)

		} catch (Throwable e) {
			logError(logName, "{} - Exception in 'All Lights Change' rule {}", fileName, e.toString())
		}
	end

And here are a couple of log entries. In this example, I went from 0 to about 45, then to 0, then up to 43.

2018-03-19 11:49:34.840 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant_LastValue changed from 0.00000000 to 4.50000000.
2018-03-19 11:49:37.171 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant changed from 0.00000000 to 43.
2018-03-19 11:49:37.173 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant_LastUpdated changed from 2018-03-19T11:49:34.837-0400 to 2018-03-19T11:49:37.172-0400.
2018-03-19 11:49:37.175 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant_LastValue changed from 4.50000000 to 0.00000000.
2018-03-19 11:49:38.940 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant changed from 4.30000000 to 0.
2018-03-19 11:49:38.942 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant_LastUpdated changed from 2018-03-19T11:49:37.172-0400 to 2018-03-19T11:49:38.942-0400.
2018-03-19 11:49:38.944 [INFO ] [eclipse.smarthome.model.script.rules] - group_proxies.rules - Light_Kitchen_Pendant_LastValue changed from 0.00000000 to 4.30000000.

Edit: Changed rule and log examples to remove various casting I was doing to try to figure out the problem. I don’t want any red herrings here.


(hr2) #2

please post how do you build and store previousState


(Vincent Regaud) #3

Hi there,
same question as @hr_2

		lastValueItem.postUpdate(previousState)

Where does previousState come from?


(Paul) #4

My understanding is that “previousState” is implicitly available per https://docs.openhab.org/configuration/rules-dsl.html#implicit-variables

Am I misunderstanding this?


(hr2) #5

You are right


(Vincent Regaud) #6

In this case in will the previousState of g_Lights_All (The triggering Item)
If you have 10 Lights and all the others are at 0 then the average will be divided by 10
Did you by anychance define g_Lights_All as an AVERAGE group? And do you have 10 Lights in the group?


(Vincent Regaud) #7

The line needs to be:

lastValueItem.postUpdate(lastUpdatedItem.previousState)


(Paul) #8

@vzorglub, this is exactly how I have it defined… I was actually looking into this after reading your and @hr_2’s reply, because as soon as I stopped and thought about the context of what previousState would be in this scenario, I went “oh… the group.” So, I’m pretty sure that’s the issue and I just have to figure out the syntax to get the last state of the item I want to deal with.

Thanks for pointing me in the right direction, guys!


(Paul) #9

Well, I may have jumped the gun with my “success” a bit. Firstly, it seems the exact syntax to get the previous state in this context is

lightItem.previousState().state

Secondly, and more importantly… it appears that when the rule is triggered from a group item as I have, previousState seems to be the same as the “new” state. In other words, I get a log entry saying the light has been changed from 50 to 50.

If I change the trigger to be on the light item itself, instead of the group, and use the implicit “previousState” variable, then everything works exactly as I’d expect.

I’m only using mapdb here, so I don’t have historical states to go back and find the most recent, and different, state. I’m not sure switching the persistence method is worth it versus changing the trigger to be based on actual items. I was hoping to avoid a long list of triggers, but I’m not aware of another way to accomplish this. If anybody has any thoughts I’d love to hear them.

Edit:

My assumption for why this is, is the group item receives a change following the actual item receiving the change, so by then the previous state of that item is no longer in the scope, and it already equals the current state of the item.


(Vincent Regaud) #10

The previousState method will work with another persistence.
It’s up to you, but setting a “proper” persistence service like influxdb or mysql is worth the effort. It’s very low maintenance once set-up and very useful for graphs, queries…
And you will keep your rules triggers simple.

See:

for setting up influxdb. You don’t have to set-up grafana if you don’t want to.

I recommend it

Keep mapdb to do the restoreAtStartUp for all items with an everyChange strategy
Use influxdb as the default database with and ‘everyChange’ strategy at least

Good luck