Is it possible to persist single commands of a Rollershutter?

For my presence simulation I need to record all manual events to the rollershutters. So I need to get persisted when someone sends the DOWN command, STOP command or a POSITION.

As far as I know the default persistence would only persist the resulting position after a change.

So maybe I need to write rules like “item received command down” and persist it on my own? I need that for all my 16 rollershutters and all 4 commands (up,down,stop,postion), so a general approach would be great…

I think you will find this a bit challenging as your UP/DOWN, STOP/START, and POSITIONs are all different data types and your database can only save one datatype per Item. The designers of OH chose to save the position to the DB so there is no way you can also save the other two types for the same Item.

Your best bet will be to use a proxy Item to save the commands. If you are using rrd4j you must use a Number type Item as rrd4j cannot save Strings. Otherwise you can use a String Item (I’ll assume a String).

For each rollershutter create a String Rollershutter1Command Item.

In your rule:

rule "Persist rollershutter1's commands"
when
    Item rollershutter1 received command
then
    Rollershutter1Command.postUpdate(receivedCommand.toString)
end

Since Rollershutter1Command is also persisted the command will be persisted as well.

NOTE: I’m not 100% positive this will work. I have a nagging memory that by the time you get to your rules any STOPMOVE or UPDOWN will have already been converted to a Percent type. If that is the case you will have to swap your proxy Item.

Instead of putting the actual Rollershutter on your sitemap, put your String Item on the sitemap. When the String Item receives a command it needs to forward that command on to the real rollershutter Item in a Rule.

I have a myql persistence running, so this might be a working solution.

Too bad that I can’t get the triggering item from a group, otherwise I could use “Item gRollershutters received command” to persist all the values in one rule…

I guess I will set up a rule to log the commands to check your NOTE.

There are lots of caveats with this, but you can with a little hack. Assuming all members of the group are persisted:

val triggeringItem = gGroup.members.sortBy[lastUpdate].last

This will return the most recently updated Item from the group.

Now for the caveats:

  • sometime it can take a couple hundred msecs before persistence catches up with the event so you may need a Thread::sleep before the above.
  • if multiple Items can be updated really close together you may lose one of the events and process the latter one twice
  • if you trigger the rule by gGroup received update your rule will be triggered multiple time per Item update. The other triggers on gGroup will not work the way you want. So you might need to trigger the rule on the individual Items but you can still use the above in the rule.

The last caveat is key so I will repeat and elaborate. If using a Group as the Item to trigger a rule in order to execute the rule when one of the Group’s Items are updated or commanded, you must use Item gGroup receive update.

When you use Item gGroup received command the rule will only trigger if you send a command to gGroup, not its members.

When you use Item gGroup changed the rule will only trigger when all of its members are the same state and one of them changes which causes a change to the gGroup’s state. For example, if all the members are Switches and they are all OFF, the rule will trigger when the first one changes to ON but it will not trigger again when the second, third, etc one changes to ON.

You should look at this thread for more examples of stuff you can do with Groups in rules.

Just tested it and stumbled across the caveats you listed. So I guess I will go with lamba functions, so I have to create all the rules for all items, but the function what happens on command will only be written once.

I’ve been successful following the middle road.

Write one rule that lists each Item as a trigger instead of the Group.

Put in a Thread:sleep(100) // experiment to find a minimum reliable values

Grab the Item using the sortBy and do the rule.

I’ve also found in most cases, the fact that the rule runs multiple times per Item update really doesn’t matter so I just trigger on the Group and let it run multiple times.

Before I found this trick I had dozens and dozens of rules and lambdas and I’ve eliminated all of them.

The problem is, I need the received command instead of update. Because I want to record and persist all manually triggered (e.g. wall switch, habdroid etc.) actions. So I need to go with single rules for every item…

rule "persist commands"
when
    Item Item1 received command or
    Item Item2 received command or
    ...
then
    Thread::sleep(100)
    val triggered = gGroup.members.sortBy[lastUpdate].last
    // persist or forward or what ever
end

Ah… good idea. But I don’t like the sleep thing.

You may not need it if your persistence is fast enough. And 100 msec may be much longer than needed.

Personally, I’d rather deal with a one line sleep and be able to consolidate my code than write pages and pages of the same thing over and over again for each Item. This isn’t a high performance real-time task we are doing here. So long as your commands are at least 100 msec apart I can say with certainty that this works.

Even with a lambda you are looking at 6 LOC per Item.

Maybe I’ll give it a try. Although I can see a lot of mysql queries to get the last updated item. Might not be a big problem, but I only have 16 rollershutters and I guess they will never change. So I’ll see which way to go.

Currently I have still the problem that the rule gets triggered twice, same like in this post from me Rule triggered twice with knx binding

I still have to play around to get what I want…