Repeated z-wave scene activation in rules engine?

I’ve got a aeotec minimote set to operate in scene mode. Pressing the first button activates scene one, holding it activates scene two. Repeat across three more buttons giving you control of up to eight scenes on the remote.

What I’m trying to do is have repeated scene activations do different things. The practical use case is simple: pressing the button will set the dimmer switch (or switches) to 1%. Pressing it again will set it to 20%, then 50%, then 100%, then 0%.

The state within the rule is simple enough, but what I’m having trouble with is the rule condition for firing. I have:

rule Lights
when
    Item zwave_device_home_node13_scene_number changed to 1
then
    if (state == 0) {
        zwave_device_home_node_5_switch_dimmer.send(new PercentType(100))
        state = 1
    } else if (state == 1) {
        zwave_device_home_node_5_switch_dimmer.send(new PercentType(0))
        state = 0
    }
end

This is a simplified version of my rule (as I have more than two states), but this should convey the premise.

Where I’m running up against problems is the when statement. As I’m keying off of the _scene_number value changing, and it isn’t actually changing when I repeatedly activate the scene, the rule doesn’t fire unless I activate a different scene first. This complicates things somewhat.

Is there a way that I can key off of the underlying event that is fired, as opposed to the _scene_number changing?

Log example of what I’m trying to fire my rule based upon:

19:00:11.659 [DEBUG] [ssage.ApplicationCommandMessageClass] - NODE 13: Incoming command class SCENE_ACTIVATION
19:00:11.673 [DEBUG] [.commandclass.ZWaveBasicCommandClass] - Received Scene Activation for Node ID = 13
19:00:11.683 [DEBUG] [.commandclass.ZWaveBasicCommandClass] - Scene Activation Set
19:00:11.697 [DEBUG] [.commandclass.ZWaveBasicCommandClass] - Scene activation node from node 13: Scene 1, Time 0

received command or received update or you can create a rule that triggers off of 'received update` from any of the minimote Items which immediately sets it back to OFF when they are turned ON so the next time you press the button there is a change.

See the following thread for both my and @TheKorn’s approaches to this.

1 Like

I don’t profess to be a master of the rules by any means, but I figured I’d document what I wound up using in case it’s of any use to anyone in the future. I’m also going to explain why things are setup this way.

I have three of these remotes, all of which had items manually created via the Paper UI (actually the API). I’m not using any of the legacy item definitions to make these remotes work.

My goal was to have repeated button pushes do different things. In specific:

  1. Increase the brightness 10% with every push, cycling from 100% back to 0%.
  2. If the button was held down, turn the light off. If the button was held down while the light was off, restore the brightness of the light to its previous state.

So, to do this:

1- Configure the remote for scene mode.

This sets the remote to send scene commands to the wider zwave network, instead of talking directly to the devices on the network.

2- Because I have three of these remotes, I created a distinct reset-remotes.rules file, containing the following rule, duplicated (+ names adjusted) for each remote:

rule "ResetMasterRemoteScene"
when
        Item master_remote_scene changed
then
        if (master_remote_scene.state != 0) {
                postUpdate("master_remote_scene", "0")
        }
end

The postUpdate() call is important. If I was using sendCommand(), that would actually emit an event onto the network, which would trigger the rule again. postUpdate() does not push a command out to the network; it seemingly just updates openhab’s internal state to make it think that it received an update to set the scene back to 0. This allows the remote to send repeated scene commands that openhab actually pays attention to.

This rule accomplishes the core of my original question. Thanks, @rlkoshak, for the pointer in the right direction!

3- The first rule to control the dimmer is the staggered 0/1/10/20/30/…/100/0 phased rule. It’s relatively straight-forward:

var Number masterLampDimmer = 0 // this will be written to here, but read in another rule

rule "MasterLamp"
when
        Item master_remote_scene changed to 1
then
        var Number s = master_lamp_a_dimmer.state // pull the current state of the item into a variable we can (and will) manipulate 

        // adjust state going 0 -> 1 -> 10 -> 20 -> ... -> 100 -> 0
        if (s == 0) {
                s = 1
        } else if (s == 1) {
                s = 10
        } else if (s + 10 <= 100) {
                s = s + 10
        } else {
                s = 0
        }

        if (s != 0) {
                masterLampDimmer = s // remember the setting for later
        }

        // actually adjust the lights
        sendCommand("master_lamp_a_dimmer", s.toString) // I found sending strings to openhab to be WAY less
        sendCommand("master_lamp_b_dimmer", s.toString) // complicated than sending any other datatype
end

The short version is that I get the current state, modify it as per my rule logic, remember it if the value is non-zero, and then actually emit the new brightness command to the network.

4- The last rule is my “toggle” rule. The aeon remotes activate scene one when the first button is pushed, and then two when the button is held. The second button sends three when pressed, and four when held, etc.

So, because we stored the state in the previous rule:

rule "MasterLampToggle"
when
        Item master_remote_scene changed to 2
then
        if (master_lamp_a_dimmer.state == 0 && masterLampDimmer > 0) {
                sendCommand("master_lamp_a_dimmer", masterLampDimmer.toString)
                sendCommand("master_lamp_b_dimmer", masterLampDimmer.toString)
        } else {
                sendCommand("master_lamp_a_dimmer", "0")
                sendCommand("master_lamp_b_dimmer", "0")
        }
end

If the light is off, and if we’ve stored a non-zero value, then set the stored value. Otherwise, just turn the lights off.

The end result is thus:

  1. If the light is off, pushing button one will turn the light on to 1%.
  2. If the light is at 1%, the next push will set it to 10%.
  3. On each subsequent push, the light will increase another 10%, all the way up to 100%, and then back down to 0%.
  4. If the light is at 50% and the button is held down, the light will turn off. A subsequent holding of the button will restore the light to its previous state.

This is the overly complicated way of saying “push button, light get brighter. Hold button, light turn off/turn on.” :slight_smile: