Repeat rule while a trigger matches a given state UI

Hi

I’m running a snapshot version of OpenHab2, with the development version of the Velbus binding.

In a room I have an RGB light effect running on 3 Velbus dimmer channels from a VMB4DC.

What I would like to is use a presence trigger to run a pre-defined colour chase.

The presence is known due to a water temperature sensor within a pipe to a shower head.

When the flow temperature is above a threshold and the VMB7IN channel returns “PRESSED” or “LONG_PRESSED”, I would like the chase to move forward a step every X seconds. (20 seconds would do, I’m happy to adjust this to get the best cross-fade effects)

What I’m trying to achieve is very similar to the Chaser thing in the DMX binding.

(If I’d found OpenHab2 before fitting out my house, I would have used DMX for all the architectural lighting effects. The DMX fixtures around my house (that I did install) are now much easier to operate.

The following rule works really well, other than the automation of the steps. (Meaning if I put a slider in my UI linked to Bathroom_Sequence_Step I can move the steps on manually.)

(FYI, I have tried various things that I’ve found in this forum, but I don’t think I totally understand the finer detail of creating rules in OpenHab2)

Any assistance would be greatly appreciated.

The steps work perfectly, I just can’t get the channel of the VMB7IN to trigger the next step every 60 seconds (I don’t care how often, I can tweak that later)

 var Number Steps = 0
 var Timer testTimer = null



// This is the rule that I'm having issues with

rule "Cron job every minute"
when 
    Time cron "0 0/1 * * * ?"   // every minute
then
if ('velbus:vmb7in:c5053467:0B:CH1' == "PRESSED")
			{	
				Steps = Steps + 1
				Bathroom_Sequence_Step.sendCommand(Steps)
			}


    if ('velbus:vmb7in:c5053467:0B:CH1' == "LONG_PRESSED")
			{	
				Steps = Steps + 1
				Bathroom_Sequence_Step.sendCommand(Steps)
			}
end



rule "Chase Stop"
when
	Channel 'velbus:vmb7in:c5053467:0B:CH1' triggered RELEASED
then
  
  Bathroom_Sequence_Step.sendCommand("0")
	Bath_Red.sendCommand(OFF)
	Bath_Green.sendCommand(OFF)
	Bath_Blue.sendCommand(OFF)
end



rule "Chase Sequence"
when

	Item Bathroom_Sequence_Step received command
	
then

	var Steps = Bathroom_Sequence_Step.state

if (Steps == 0 )
{
    bathroomcolour.sendCommand(OFF)
	Bath_Blue.sendCommand(OFF)
	Bath_Green.sendCommand(OFF)
	Bath_Red.sendCommand(OFF)
}

if (Steps == 1 )
{
    Bath_Blue.sendCommand(OFF)
	Bath_Green.sendCommand(OFF)
	Bath_Red.sendCommand(100)
}

if (Steps == 2 )
{
   	Bath_Red.sendCommand(OFF)
	Bath_Green.sendCommand(100)
	Bath_Blue.sendCommand(OFF)

}

if (Steps == 3 )
{
   	Bath_Red.sendCommand(OFF)
	Bath_Green.sendCommand(OFF)
	Bath_Blue.sendCommand(100)

}
if (Steps == 4 )
{
   	Bath_Red.sendCommand(30)
	Bath_Green.sendCommand(50)
	Bath_Blue.sendCommand(0)

}

if (Steps == 5 )
{
   	Bath_Red.sendCommand(60)
	Bath_Green.sendCommand(OFF)
	Bath_Blue.sendCommand(80)

}

if (Steps == 6 )
{
   	Bath_Red.sendCommand(OFF)
	Bath_Green.sendCommand(60)
	Bath_Blue.sendCommand(30)

}

if (Steps == 7 )
{
   	Bath_Red.sendCommand(60)
	Bath_Green.sendCommand(30)
	Bath_Blue.sendCommand(10)

}

if (Steps == 8 )
{
   	Bath_Red.sendCommand(100)
	Bath_Green.sendCommand(OFF)
	Bath_Blue.sendCommand(100)

}

if (Steps == 9 )
{
   	Bath_Red.sendCommand(OFF)
	Bath_Green.sendCommand(50)
	Bath_Blue.sendCommand(50)

}

if (Steps == 10 )
{
   	Bathroom_Sequence_Step.sendCommand("1")

}
	
end
var Steps = Bathroom_Sequence_Step.state as Number

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

Thanks Harry.

I’ll make that adjustment for clarity.

It’s automating of the step increase that is the issue.

Cheers,

Stuart

I don’t think you can do:

if ('velbus:vmb7in:c5053467:0B:CH1' == "PRESSED")

This is basicaly comparing a string with another string
You will need to create an item for the channel
Also what are the allowed values for the steps, because every second it will increase by one to infinity… (Not quite) So it needs to loop.

String velbusStatus { channel="velbus:vmb7in:c5053467:0B:CH1" }

Then change you rule to:

var Number Steps = 0
var Timer testTimer = null
val Number maxSteps = 100

rule "Cron job every minute"
when 
    Time cron "0 0/1 * * * ?"   // every minute
then
    if (Steps >= maxSteps) Steps = 0
    if (velbusState.state.toString == "PRESSED") {	
        Steps = Steps + 1
        Bathroom_Sequence_Step.sendCommand(Steps)
    }
    if (velbusState.state.toString == "LONG_PRESSED") {	
       Steps = Steps + 1
        Bathroom_Sequence_Step.sendCommand(Steps)
    }
end

Another thing is maybe consider to use switch case…

rule "Chase Sequence"
when
    Item Bathroom_Sequence_Step received command
then
    switch (Bathroom_Sequence_Step.state as Number) {
        case 0: {
            bathroomcolour.sendCommand(OFF)
            Bath_Blue.sendCommand(OFF)
            Bath_Green.sendCommand(OFF)
            Bath_Red.sendCommand(OFF)
        }
        case 1: {
            Bath_Blue.sendCommand(OFF)
            Bath_Green.sendCommand(OFF)
            Bath_Red.sendCommand(100)
        }
        case 2: {
            Bath_Red.sendCommand(OFF)
            Bath_Green.sendCommand(100)
            Bath_Blue.sendCommand(OFF)
        }
        case 3: {
            Bath_Red.sendCommand(OFF)
            Bath_Green.sendCommand(OFF)
            Bath_Blue.sendCommand(100)
        }
        case 4: {
            Bath_Red.sendCommand(30)
            Bath_Green.sendCommand(50)
            Bath_Blue.sendCommand(0)
        }
        case 5: {
            Bath_Red.sendCommand(60)
            Bath_Green.sendCommand(OFF)
            Bath_Blue.sendCommand(80)
        }
        case 6: {
            Bath_Red.sendCommand(OFF)
            Bath_Green.sendCommand(60)
            Bath_Blue.sendCommand(30)
        }
        case 7: {
            Bath_Red.sendCommand(60)
            Bath_Green.sendCommand(30)
            Bath_Blue.sendCommand(10)
        }
        case 8: {
            Bath_Red.sendCommand(100)
            Bath_Green.sendCommand(OFF)
            Bath_Blue.sendCommand(100)
        }
        case 9: {
            Bath_Red.sendCommand(OFF)
            Bath_Green.sendCommand(50)
            Bath_Blue.sendCommand(50)
        }
        default: {                                 // all other values
            Bathroom_Sequence_Step.sendCommand(1)
        }
    }
end

Bathroom_Sequence_Step has to be of type Number.
You don’t need the var Steps. Simply use

Bathroom_Sequence_Step.sendCommand((Bathroom_Sequence_Step.state as Number) + 1)

Hello

Thanks for that.

The steps wasn’t the issue, the problem I had was getting the rule to automatically move through the sequence.

@cedricboon created this, which works perfectly :smile:

var int interval = 10
var int steps = 0
var Timer testTimer = null




rule "Step sequence"

when
    Channel 'velbus:vmb7in:c5053467:0B:input#CH1' triggered PRESSED
then
    testTimer = createTimer(now.plusSeconds(interval))
        [|
			if(steps == 0){
				bathroomcolour.sendCommand(OFF)
				Bath_Blue.sendCommand(OFF)
				Bath_Green.sendCommand(75)
				Bath_Red.sendCommand(25)

				steps = 1
			}else if(steps == 1){
				Bath_Blue.sendCommand(OFF)
				Bath_Green.sendCommand(OFF)
				Bath_Red.sendCommand(100)

				steps = 2
			}else if(steps == 2){
				Bath_Red.sendCommand(OFF)
				Bath_Green.sendCommand(100)
				Bath_Blue.sendCommand(OFF)

				steps = 3
			}else if(steps == 3){
				Bath_Red.sendCommand(OFF)
				Bath_Green.sendCommand(OFF)
				Bath_Blue.sendCommand(100)

				steps = 4
			}else if(steps == 4){
				Bath_Red.sendCommand(30)
				Bath_Green.sendCommand(50)
				Bath_Blue.sendCommand(0)

				steps = 5
			}else if(steps == 5){
				Bath_Red.sendCommand(60)
				Bath_Green.sendCommand(OFF)
				Bath_Blue.sendCommand(80)

				steps = 6
			}else if(steps == 6){
				Bath_Red.sendCommand(OFF)
				Bath_Green.sendCommand(60)
				Bath_Blue.sendCommand(30)

				steps = 7
			}else if(steps == 7){
				Bath_Red.sendCommand(60)
				Bath_Green.sendCommand(30)
				Bath_Blue.sendCommand(10)

				steps = 8
			}else if(steps == 8){
				Bath_Red.sendCommand(100)
				Bath_Green.sendCommand(OFF)
				Bath_Blue.sendCommand(100)

				steps = 9
			}else {
				Bath_Red.sendCommand(OFF)
				Bath_Green.sendCommand(50)
				Bath_Blue.sendCommand(50)

				steps = 0
			}
			testTimer.reschedule(now.plusSeconds(interval))
        ]

end




rule "Timer Stop" when
    Channel 'velbus:vmb7in:c5053467:0B:input#CH1' triggered RELEASED 
then
	if(testTimer !== null){
		testTimer.cancel()
		testTimer = null
	}
	
	Bath_Red.sendCommand(OFF)
	Bath_Green.sendCommand(OFF)
	Bath_Blue.sendCommand(OFF)


end