zamzon
(mads m)
January 15, 2018, 8:34pm
1
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
Willemde20
(Willem Spoelstra)
January 15, 2018, 8:43pm
2
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.
zamzon
(mads m)
January 15, 2018, 8:56pm
3
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
Willemde20
(Willem Spoelstra)
January 15, 2018, 9:02pm
4
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
rossko57
(Rossko57)
January 15, 2018, 9:10pm
5
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!
Josar
(Josar)
January 15, 2018, 9:18pm
6
@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:
}
zamzon
(mads m)
January 17, 2018, 6:17pm
7
Willemde20:
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
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
zamzon
(mads m)
January 17, 2018, 6:23pm
8
@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!
Willemde20
(Willem Spoelstra)
January 17, 2018, 6:39pm
9
there need to me " " around the START, STOP
it needs to look like
case "START":{
// code here
}
Sharpy
(Aaron Sharp)
January 17, 2018, 7:36pm
11
why cant you use if like that ?
Willemde20
(Willem Spoelstra)
January 17, 2018, 9:03pm
12
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.
Hope i have made things easier to understand.
Greeting Willem
Josar
(Josar)
January 18, 2018, 12:26am
13
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.