How to exit switch statement before end?

At the moment I have a if statement which should run every time but not if SwitchItem01 or SwitchItem02 has state ON. Problem is, that I cannot use return, because at the end of the rule there is some code which should run for every state.

This is working, but will be complex if I have more then 2 Items like SwitchItem01 exist and should block the if from running.

rule "Test something"
 when
  Item gSwitchItem changed
 then
  if(SwitchItem01.state.toString != "ON")
  {
   if(SwitchItem02.state.toString != "ON")
   {
     do something ...
   }
  }

  Do stuff for every Item in the group ...
end

Not working

rule "Test something"
 when
  Item gSwitchItem changed
 then
  if(SwitchItem01.state.toString == "ON")
   return;
  if(SwitchItem02.state.toString == "ON")
   return;
 
   do something ...

   // this stuff will not executed because of the return on SwitchItem01 and SwitchItem02 above
   Do stuff for every Item in the group ...
end

Next try:


rule "Test something"
 when
  Item gSwitchItem changed
 then
  switch(triggeringItem.state) 
  {
   case ON:
   {
    // this is my best choice, but this is not working, because break; is out of syntax
    if(SwitchItem01.state.toString == "ON")
     break;
    if(SwitchItem02.state.toString == "ON")
     break;

    do something ...
    }
    case OFF:
    {
     do something ...
    }
   }

   Do stuff for every Item in the group ...
end

You don’t need the break; statement:

http://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#switch-expression

Good luck

Thanks for your answer.
I know this. But without the break, the below will be executed. I need that if SwitchItem01 or SwitchItem02 is ON not to run “do something …”. It should go out of the switch statement and do the rest of the rule “Do stuff for every Item in the group …”

Did you think about a proxy item, that is switched ON by SwitchItem01 and SwitchItem02 and so on? Then you have only to check, if the proxy item is on.
Or put all SwitchitemXX in a Group and check the Group state.

I thought about this, but this will make it more complex as I thought it should. Maybe no other way to solve it.

No XOR in OH available.

@Syn
Yes that’s the other way I was thinking of

There is no break to exit the switch statement in Xtend unfortunately

Do it the other way around:

switch(triggeringItem.name.toString) {
    case "SwitchItem01": {
        If (triggeringItem.state == ON) {
            # DO STUFF
        } else {
            # DO OTHER STUFF
        }
....

I think the triggering Item must not necessary be SwitchItem01 or SwitchItem02

How about just splitting up the rule into two? Then you can use return in the first rule and the second rule will executed every time.

@Syn
Good idea, but I want to prevent to much double coding

@vzorglub
Good idea. I filter out the not wanted Items with the first switch statement und use default to pass through all other items. But if state is OFF for these two items I want to run the same code as all the other items at state ON and OFF. I want to prevent double coding

Maybe it is not solvable with an easy code. This was my idea to ask here.

Put that bit outside the switch case

but then it will executed every time even if state is ON for these two items.

Maybe I rename the two items and check if item name contains something instead of checking every single item. But this will cause all my z-wave items to reload, because item file is changed. Or use the proxy Item or group item tho consolidate this.

thanks for the discussion and your help. I see, no easy way :wink:

Not if you do an if == OFF check

Stupid question: I don’t know, what you are trying to do, but couldn’t you rearrange the code just to this:

rule "Test something"
 when
  Item gSwitchItem changed
 then
   Do stuff for every Item in the group ...

  if(SwitchItem01.state.toString == "ON")
   return;
  if(SwitchItem02.state.toString == "ON")
   return;
 
   do something ...

end
1 Like

@Syn
Yes, I had this, my rule is more complex.

I use return above in my code to skip out if no more needed. Then I come to a place just to exclude some itmes from some part of what is similar to all items which are left here at the code.

But I will rethink my code at all, maybe I can move some similar code to a place above the decission.

I’ve had mixed results trying to use break; When I’ve tried to use it in the past (granted this was a long time ago in the 1.8 days) break would exit the whole rule. Its cool if that has been fixed.

It isn’t super clear exactly what you are trying to do but I recommend the following:

  • put the code you want to execute all the time at the top of the rule like Syn suggested.

  • put your SwitchItem01 and SwitchItem02 in a Group:Switch:OR(ON,OFF) then you only need to check the state of the Group.

  • Your original isn’t so bad really. You can combine the two if statements into one if(SwitchItem01.state != ON && SwitchItem02.state != ON) and save an indent. Or use the Group like I mentioned above and use if(MyGroup.state !=ON)

So applying the above the Rule would become:

rule "Test something"
when
    Item gSwitchItem changed
then
    // Do stuff every time

    if(MyGroup.state == ON) return;

    // do something
end

This is not fixed, “break;” is no longer supported in rule syntax :wink: Throughs an error message.

About my initial problem.

I have a alarm notification chain. The rule goes step by step and checks whom to alarm in case of specific status of other things (is someone at home, is TV on, …).

At a special point in the rule I want to exclude (sort them out) two Items from alarm notification sending. If one of these item are the triggering one and are ON nothing should be done at this point of the rule. (on status OFF nothing to do at all).

Your rule example will not work, because if OFF is will do an alarm and I must check this too.

I can check item name here, yes, I can do group, yes. But I post this here for an easier and readable way. my idea was to use the break like in c++. But it is not working here.

I will let it as it is, at the moment only two items needed these special handling on a specifice part of the rule

At first, sorry for digging out this old thread, but I ´m dealing the same problem.
I want to set a variable for a timer using the outside temperature:

switch TempOut {
	case TempOut < 5	:{
		winopentime = 5
		break;
		}
	case TempOut < 15	:{
		winopentime = 15
		break;
		}
	case TempOut < 21	:{
		winopentime = 30
		break;
		}
	default				:	winopentime = 0
}

The bad thing is, “break” doesnt work, I´ve got an error message. What could I use instead?

You should realize that switch statements in the Rules DSL do not fall through, like they do in many programming language you may be familiar with. Only one case will ever execute. So they’re is no need to break. Switch is truly a shorthand for if else statements.

If the value is <5, the first case will run. If it is between 5 and 15 the device case will run, and so on.

See: http://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#switch-expression

For the use of switch in Xtend