[SOLVED] Double Entries of state change in persistence DB

All,

I have always struggled with double entries in my persistence DB (mariaDB) since ever (I guess).
Today I found the root cause for it:
A weird persistence configuration:

I used to have this one:
Strategies {
everyMinute : “0 * * * * ?”
every5Minutes : “0 0/5 * * * ?”
everyHour : “0 0 * * * ?”
everyDay : “0 0 0 * * ?”
}

Items {
// which data to be stored
	* : strategy = everyChange, restoreOnStartup
	G_jdbc* : strategy = everyChange, restoreOnStartup // required for storing the groups' members state (not the groups' state)
	G_Numbers* : strategy = every5Minutes, everyChange, restoreOnStartup
	G_Lights : strategy = everyChange, restoreOnStartup // required for storing the groups' state itself (not the members' state)
	G_All_OFF : strategy = everyChange, restoreOnStartup
	G_Mobiles : strategy = every5Minutes, everyChange, restoreOnStartup
	G_Windows : strategy = everyChange, restoreOnStartup
	G_Melder : strategy = everyChange, restoreOnStartup
	G_Bypass : strategy = everyChange, restoreOnStartup
	G_Battery : strategy = everyChange, restoreOnStartup
	G_OverR : strategy = everyChange, restoreOnStartup
	G_Net : strategy = every5Minutes, everyChange, restoreOnStartup
	G_Homecoming : strategy = everyChange, restoreOnStartup
	G_Battery : strategy = everyChange, restoreOnStartup
	G_Hood : strategy = everyChange, restoreOnStartup
	G_CarWind : strategy = everyChange, restoreOnStartup
	G_CarDoors : strategy = everyChange, restoreOnStartup
	G_CarTyres : strategy = everyChange, restoreOnStartup
}

with * I wanted to make sure the store the state of the Group itself (which is not the case if storing the members (e.g. G_jdbc*).
This caused the double entry:
one by * for storing each single item’s change
and one through G_jdbc* for all members (e.g. switches).

Since I use this one, I don’t have the issue anymore:
Strategies {
everyMinute : “0 * * * * ?”
every5Minutes : “0 0/5 * * * ?”
everyHour : “0 0 * * * ?”
everyDay : “0 0 0 * * ?”
}

Items {
// which data to be stored
//	* : strategy = everyChange, restoreOnStartup	// after switching this OFF, no more Group states have been stored (G_Lights* only stores the members)
	G_Numbers* : strategy = every5Minutes, everyChange, restoreOnStartup

// store the members of the groups
	G_Numbers*, G_jdbc*, G_FuelPrices*, G_Lights*, G_All_OFF*, G_Homecoming*, G_Mobiles*, G_Windows*,
	G_Melder*, G_CarWind*, G_CarDoors*, G_CarTyres*, G_Bypass*, G_Battery*, G_Hood*, G_OverR*, G_Net* : strategy = everyChange, restoreOnStartup
// store the group stat itself
	G_Numbers, G_jdbc, G_FuelPrices, G_Lights, G_All_OFF, G_Homecoming, G_Mobiles, G_Windows,
	G_Melder, G_CarWind, G_CarDoors, G_CarTyres, G_Bypass, G_Battery, G_Hood, G_OverR, G_Net : strategy = everyChange, restoreOnStartup
}

This might be a trivial conclusion and a personal problem.
But I have seen similar issues around the community, so I hope it helps.

But what if a Group is within another group and is stored as the Groupmember and the Group itself?

I don’t know. I would expect that if the Group were a member of another Group that is persisted with *, I would expect the state of that Group to be stored but not its members. Though I could also see how the subGroup would not be persisted. Seems like it wouldn’t be too hard of an experiment to run.

I still struggle to get reliable persistence for G_Numbers (every5Minutes) and on everyChange for e.g. switch and Group-states.

I currently have this one:

Strategies {
	everyMinute	:	"0 * * * * ?"
	every5Minutes : "0 0/5 * * * ?"
   	everyHour   :	"0 0 * * * ?"
   	everyDay    :	"0 0 0 * * ?"
}

Items {
	* : strategy = everyChange, restoreOnStartup
	G_Numbers* : strategy = every5Minutes//, everyChange, restoreOnStartup

According to the documentation * should store every single item to the persistence DB.

  1. Does this include the state of the Groups in the items file as well - e.g.
    Group:Switch:OR(ON,OFF) G_Lights "Licht [%d]"
  2. Additionally to the on everyChange and restoreOnStartup G_Number members will be stored every minute, correct=

As these statements above correct?

I am not positive but I think the answer is no.

The members of G_Numbers will be saved every 5 minutes according to your .persist file above. G_Numbers itself does not get saved.

Yes, but the everyChange, restoreOnStartup still does apply for G_Numbers from * strategy above, right?

I don’t think * applies to Groups. I don’t know for sure though.

I did a test with the following persistence config:
Strategies {
everyMinute : “0 * * * * ?”
every5Minutes : “0 0/5 * * * ?”
everyHour : “0 0 * * * ?”
everyDay : “0 0 0 * * ?”
}

Items {
	* : strategy = everyChange, restoreOnStartup
	G_Numbers* : strategy = every5Minutes

}

and actually the Group-state of e.g. G_Lights containing all lights is stored.
It doesn’t matter if I trigger the group itself or one of its members.

So that means * will store everything - even the Groups’ state itself.

However, one strange thing:
If I trigger through karaf by smarthome:update G_Lights ON or OFF the pesistence DB changes once.

If i trigger using habpanel I sometimes get three entries (switching OFF leads to OFF, ON, OFF stored within less than 100 ms).

Any idea where this might come from?

Does events.log show the same rapid flipping between states?

I tried it again - so it looks like it’s flipping there as well - it’S not consistent though.

By the way, If I put it through karaf with smarthome:update G_Lights ON, I don’t get any events.log entry!?

Trigger of G_Lights by Habpanel:

ON - seems to be ok

2018-07-26 08:43:31.619 [ome.event.ItemCommandEvent] - Item 'G_Lights' received command ON
2018-07-26 08:43:31.626 [ome.event.ItemCommandEvent] - Item 'Z_WoZiLicht' received command ON
2018-07-26 08:43:31.631 [ome.event.ItemCommandEvent] - Item 'Z_Treppenlicht' received command ON
2018-07-26 08:43:31.672 [vent.ItemStateChangedEvent] - Z_WoZiLicht changed from OFF to ON
2018-07-26 08:43:31.677 [vent.ItemStateChangedEvent] - Z_Treppenlicht changed from OFF to ON

OFF - 5th line is weird. Why is G_Lights going back from OFF to ON?

2018-07-26 08:43:43.914 [ome.event.ItemCommandEvent] - Item 'G_Lights' received command OFF
2018-07-26 08:43:43.920 [ome.event.ItemCommandEvent] - Item 'Z_WoZiLicht' received command OFF
2018-07-26 08:43:43.938 [ome.event.ItemCommandEvent] - Item 'Z_Treppenlicht' received command OFF
2018-07-26 08:43:43.961 [vent.ItemStateChangedEvent] - Z_WoZiLicht changed from ON to OFF
2018-07-26 08:43:43.981 [GroupItemStateChangedEvent] - G_Lights changed from OFF to ON through Z_WoZiLicht
2018-07-26 08:43:44.002 [vent.ItemStateChangedEvent] - Z_Treppenlicht changed from ON to OFF
2018-07-26 08:43:44.015 [GroupItemStateChangedEvent] - G_Lights changed from ON to OFF through Z_Treppenlicht

I’ve noticed that events.log doesn’t show updates anymore unless the update results in a change. Perhaps if you put the events logger into DEBUG level instead of INFO it will show the updates too. I think this changed in OH 2.3. At least that is where I first noticed it.

Anyway, now we know the problem isn’t persistence which is storing the data as it arrives. Just to level set, post your G_Lights definition.

OK, I think I see what is going on.

  1. You send command OFF to G_Lights
  2. G_Lights changes state to OFF as a result of the command
  3. The two members of G_Lights receive the command OFF
  4. Z_WoZiLicht changes to OFF which causes the state of G_Lights to be recalculated. Z_Treppenlicht is still ON so the new state of G_Lights is ON. This overwrites the OFF that G_Lights was set to on step 2.
  5. X_Treppenlicht changes to OFF which causes the state of G_Lights to be recalculated. All the lights are now OFF so the new state is OFF.

This is a tricky one. The behavior is a little unexpected but it is clear to me why it is happening. I think what you would need to do is to use a proxy Item and a Rule instead of a Group to avoid this behavior. I’m not sure it can be fixed without breaking something things you can do with Groups.

Thanks for your analysis of my problem.
Your explanation makes sense.

However, I thought this is what groups are for?
To switch all lights OFF with one item.
And I have just two lights connected so far.

How about other people grouping 10 lights and more?

Unfortunately I think I already have too many proxy items and are currently more cleaning up instead of expanding my system.

So if this will not cause problems, i will keep it as is. At least it‘s consistent and I understand the reason now :slight_smile:

And that is what is happening.

All your lights were turned OFF after sending one command to the Group Item.

But your problem isn’t that Groups are not working, it’s that you are looking to persist the state of the Items and the way that the command filters through the system and the Group Item updates it momentarily (less than a few dozen milliseconds) is ON while all the members are still processing the OFF command. The Group is actually behaving as designed.

If you want to avoid having this momentary ON state before the Group settles back to OFF, you can’t use a Group. But as far as I can tell, the only place where this would even be noticeable is if you are persisting the states and charting them, which is where you noticed the behavior.

You can have 2 lights or 100 lights and it all works. When you send the command to the Group it gets forwarded to the members. And for a moment, the Group Item’s state will go back to ON until all the members of the Group go to OFF.

But be aware this is also a function of the aggregation function you are using. Because it is OR(ON,OFF), as long as any member of the Group is ON the Group’s state will calculate to ON. And the Group’s state is recalculated for every change to any one of its members. So if you have 100 Items, the Group’s state will be recalculated 100 times, once for each of the 100 lights that changed as a result of the OFF command. And it won’t be until the very last light turns OFF that the Group’s state will return to OFF.

Thanks. You are absolutely right.
And please don’t get me wrong. I did not mean that there is a problem with the Group handling.

It does what it should.
Maybe I was a little too picky when I found the flipping in my database.

So I will not change it, because it does not create any (obvious) issues except flooding my mariaDB with data.

However, I will keep this behavior in mind and will check my code if I execute something in Group changes.

Again, thanks for your help and tremendous support.

With you and the other guys around, I wouldn’t be where I am with my smart home.

I honestly don’t like it either. But understanding why it does that leads me to accept that is just the way it has to be. The only way to avoid it is to somehow avoid the command OFF from changing the Group’s state which can have all sorts of repercussions.

I’m happy to help. Stuff like this is where one really needs to get down to the next level down in how OH works to understand what is happening.