More if´s in a rule

Hi

I have to make a rule that sends a message to an item depending on what another item string has of value

rule Start_w2811

when
  Item w2811ts changed

then

if (w2811ts == START) {
w2811.sendCommand("{\"state\": \"ON\"}")
}
if (w2811ts == STOP) {
w2811.sendCommand("{\"state\": \"OFF\"}")
}
if (w2811ts == PAUSE) {
w2811.sendCommand("{\"state\": \"PAUSE\"}")
}
if (w2811ts == FORWAD) {
w2811.sendCommand("{\"state\": \"FORWAD\"}")
}
if (w2811ts == BACK) {
w2811.sendCommand("{\"state\": \"BACK\"}")
}

end

I know a can’t write “IF” so many times, but how do I write this rule if I need more if’s

You should use a switch case construction.

rule Start_w2811

when
  Item w2811ts changed

then
    switch{
        case w2811ts == START:
            w2811.sendCommand("{\"state\": \"ON\"}")
            break;
        case w2811ts == STOP:
            w2811.sendCommand("{\"state\": \"OFF\"}")
            break;
        case w2811ts == PAUSE:
            w2811.sendCommand("{\"state\": \"PAUSE\"}")
            break;
        case w2811ts == FORWAD:
            w2811.sendCommand("{\"state\": \"FORWAD\"}")
            break;
        case w2811ts == BACK: 
            w2811.sendCommand("{\"state\": \"BACK\"}")
            break;
        default:
            break;
    }


end

Now you can add more cases to it.

Hi
I get this error running the rule

2018-01-15 21:54:31.588 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘sendmqtt2.rules’ has errors, therefore ignoring it: [8,9]: mismatched input ‘case’ expecting ‘}’

[8,14]: missing ‘{’ at ‘w28112’

[8,21]: no viable alternative at input ‘==’

[8,29]: mismatched input ‘:’ expecting ‘end’

when
  Item w28112 changed

then
    switch{
        case w28112 == START:
            w2811.sendCommand("{\"state\": \"ON\"}")
            break;
        case w28112 == STOP:
            w2811.sendCommand("{\"state\": \"OFF\"}")
            break;
        case w28112 == PAUSE:
            w2811.sendCommand("{\"state\": \"PAUSE\"}")
            break;
        case w28112 == FORWAD:
            w2811.sendCommand("{\"state\": \"FORWAD\"}")
            break;
        case w28112 == BACK:
            w2811.sendCommand("{\"state\": \"BACK\"}")
            break;
        default:
            break;
    }


end

try this

rule Start_w2811

when
  Item w2811ts changed

then
    switch (w2811ts.state){
        case START:{
            w2811.sendCommand("{\"state\": \"ON\"}")
            break;
        }
        case STOP:{
            w2811.sendCommand("{\"state\": \"OFF\"}")
            break;
        }
           
        case PAUSE:{
            w2811.sendCommand("{\"state\": \"PAUSE\"}")
            break;
        }
        case FORWAD:{
            w2811.sendCommand("{\"state\": \"FORWAD\"}")
            break;
        }
        case BACK:{ 
            w2811.sendCommand("{\"state\": \"BACK\"}")
            break;
        }
        default:{
            break;
        }
            
    }


end

But you can write that many if() as you wish.

You can also build if-else, like so

if (w2811ts.state == "START") {
    w2811.sendCommand("{\"state\": \"ON\"}")
} else if (w2811ts.state == "STOP") {
    w2811.sendCommand("{\"state\": \"OFF\"}")
} else if (w2811ts.state == "PAUSE") {
    w2811.sendCommand("{\"state\": \"PAUSE\"}")
} else {
    logInfo("whoops", "unexpected value")
}

EDIT @Josar is quite right, we must look at the Item .state. Fixed my example!

@zamzon xtend expressions.

switch w2811ts {
        // if w2811ts is a stringItem the string is in the state, you want to compare the state 
        case w2811ts.state == "START":  w2811.sendCommand("{\"state\": \"ON\"}") // no break xtend does not fall trough
        case ...
        default:
    }

Hi

If I send START to the string w2811ts, I get the following error in the log

2018-01-17 19:14:55.600 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Start_w28112': The name 'START' cannot be resolved to an item or type; line 8, column 14, length 5

@Josar

If Í insert your code I get the following error

2018-01-17 19:21:17.614 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'sendmqtt.rules'

2018-01-17 19:21:17.640 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'sendmqtt.rules' is either empty or cannot be parsed correctly!

there need to me " " around the START, STOP

it needs to look like

case "START":{
 // code here
}

It works
Thanks :slight_smile:

why cant you use if like that ?

You can use the if(…){…} if(…){…}… for ever. in theory.

But it is smarter to do it with a switch case like

Switch(item.state){
   case "option 1":{
  //do stuff
  break;
}case "option 2":{
      //do stuff
      break;
    }
}

Or using a if else construction like this:

if(option=1){
 //do stuff
}else if(option == 2){
 //do other stuff
}else{
 //do stuff that can happen to any situation other then in the if above 
}

So it stops going through the option after it has doen the option it needed to do when the condition has been met. the execution time will be shorter.

You can do it the way as in using if(…){…} and repeating that. but it is smarter and easier in my opinion to think like:

"if my light is off then turn it on else if is it dark in the room then turn the light on "

For me it’s easier to think that way and write the code for it. :upside_down_face:

Hope i have made things easier to understand.

Greeting Willem

The rules are not java they are Xbase and therefore share a lot with xtend.

And using xtend as it is supposed to, makes it a lot easier to write instead of using lots of brackest and uneccessary breaks. And it is easier to read.

switch w2811ts.state {
        case "START":  w2811.sendCommand("{\"state\": \"ON\"}") // no break xtend does not fall trough
        case "STOP": ...
        default: ...
    }

And you may do thinks witch you would not be able to do with a java switch case. see the link posted above.