Switch/Case statement

Platform information:
Raspberry 3 Raspbian/Openhabian
openHAB version: 2.5.3

  • Issue of the topic: I wrote a list of case in a switch/case statement within a rule (textual method); If a trigger event fall in middle case choice, the statement related to that case is regulary executed but is followed by the other case event and statement instruction

So, if flip90 is triggered the rule executes steps related but also the following flip180, rotate_left and so on…

  • Rules code related to the issue
rule "Aqara Cube Control"

when
    Channel "mqtt:topic:mosquitto:testthecube:action" triggered // In abbinata al valore trigger=true nella configurazione del channel

then
       logInfo("test_AqaraCube rules", " Channel triggerd: {} ", receivedEvent.getEvent)  // test
//       logInfo("test_channel.rules", " Channel triggerd: {} ", receivedEvent)  // test

var actionName = receivedEvent.getEvent()

logInfo( "CUBO", "INFO: Channel Event = '{}'", actionName )

    switch(actionName)   {

        case "shake": {
                if (Mobile_Stato.state.toString != "ON") // != vuol dire Not Equal
   { Mobile_Stato.sendCommand(ON)}
                else 
   { Mobile_Stato.sendCommand(OFF)}
        }

        case "flip90":{
                if(Cucina_Stato.state.toString != "ON")
   { Cucina_Stato.sendCommand(ON)}
                else
   { Cucina_Stato.sendCommand(OFF)}
        }

        case "flip180":{
                if(Shelly_Switch.state.toString != "ON")
              {  Shelly_Switch.sendCommand(ON)}
                else
               { Shelly_Switch.sendCommand(OFF)}
        }

        case "rotate_left":{
                if(GTutteLeRampe.state.toString !="ON")
        { GTutteLeRampe.sendCommand(ON)}
                else
        { GTutteLeRampe.sendCommand(OFF)}
        }

        case "rotate_right":{
                if(SW_Ikea_Ingress.state.toString != "ON")
        { SW_Ikea_Ingress.sendCommand(ON)}
                else
        { SW_Ikea_Ingress.sendCommand(OFF)}
        }

        case "slide":{
                if(Toilet.state.toString != "ON")
        {Toilet.sendCommand(ON)}
                else
        { Toilet.sendCommand(OFF)} 
        } 

        default:
{   logInfo("xiaomi", "No match found for {}", actionName)}
    }
AqaraCubeAction.postUpdate(actionName)
end

I don’t think this is the right behavior expecting only one case operations executed when triggered

Java (and Xtend) uses “fall-trough” for switch statements. This means that it starts at the first match, and then continues with all commands from there. This makes it possible to write

switch (someVariable) {
   case "x":
   case "y":
      doSomething();
   case "z":
      doSomethingElse()
}

If someVariable equals x or y, doSomething() and doSomethingElse() will be executed, and if it’s z only doSomethingElse() is executed.

To change this behavior, insert a break; statement where you want to exit the switch statement. The above example would look like:

switch (someVariable) {
   case "x":
   case "y":
      doSomething();
      break;
   case "z":
      doSomethingElse()
}
2 Likes

You’ve put some helpful logInfo() in your rule, but not shown us the output of that, or your output events…

Switch-case in DSL rules works as you expect, without breaks or run-on

demo

var xx = "fred"
switch(xx)   {
    case "mary": {
        logInfo("test", "it was mary")
    }
    case "fred": {
        logInfo("test", "it was fred")
    }
    case "jane": {
        logInfo("test", "it was jane")
    }
}

only output

2020-04-04 15:35:04.015 [INFO ] [.eclipse.smarthome.model.script.test] - it was fred

Be sure your curly braces are where they should be

I stand corrected then :slight_smile:

Try switch(actionName.toString)

Hello,
i am using a raspberry 4 (4GB) with an enocean pi and OH 2.5.11. The value “bad_feuchtigkeit” comes from an nodon temperature/humidity sensor (EnOcean) and the bad_ventilator_s1 and bad_ventilator_s2 is a nodon 2Channel switch with energy measurement (that is not used here).

After I found after several days of searching in the web and in a OH2-book, I found a sample with a switch / case - command. Now the control of my fan in the bathroom depending on the humidity is working, but if I want to insert logInfos then I get in the logs the following error message:

2020-12-27 15:48:31.931 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Bad Lüfter Grundstufe’: An error occurred during the script execution: index=1, size=1

Here is my rule:

rule “Bad Lüfter:”
when
Item bad_feuchtigkeit changed
then

    switch  bad_feuchtigkeit {
      case bad_feuchtigkeit.state <= 40 : {

// logInfo(“Luefter aus”)
bad_ventilator_s1.sendCommand(OFF)
bad_ventilator_s2.sendCommand(OFF)
}
case bad_feuchtigkeit.state > 42 && bad_feuchtigkeit.state <=70 : {
// logInfo(“Luefter Stufe 1”)
bad_ventilator_s1.sendCommand(ON)
bad_ventilator_s2.sendCommand(OFF)
}
case bad_feuchtigkeit.state >72 : {
// logInfo(“Luefter Stufe 2”)
bad_ventilator_s1.sendCommand(ON)
bad_ventilator_s2.sendCommand(ON)
}
}
end

Here are the logInfo set as command, because otherwise I get the error I inserted above.

Maybe someone here can help a beginner.

Many thanks and best regards
Georg

logInfo() requires two parameter strings. People generally use the first to display a reference to rule or area of interest.

logInfo("myRule", "my message")

Hello rossko57,
thank you for your reply. I will try this in the next days.

It was hard to find a solution like the switch/case command. Can you tell me, why? Would it be possible to make the rule more exact. I think about a solution that there shouldn’t be sent a command if the previous state is the same as the following.

best regards
Georg

Not sure what you mean, sounds like -

    // wanting to command ON
if (someItem.state != ON) {
   someItem.sendCommand(ON)
}

Hello,
I want to have it in this way:

if bad_ventilator_s2 is on and the the item change would cause that a bad_ventilator_s2 would be switched on although it is already on, then there shouldn’t be any command sent. Maybe I should copy my cases and extend the copies with “&& bad_ventilator_s2.state == ON” and as command I will write “return;”.

I hope that I could explain it so better.

best regards and happy new year.
Georg

There it is

if it’s already ON, nothing happens.
I chose to test for not-ON instead of just OFF, because it will still work if your Item starts out as NULL or UNDEF states.

Hello,
if you look in my config (switch-case-scenario) then it is configured in that way that you suggested. If I got your reply right, there is no command sent to the device if the previous state is the same as the next state.
I wanted to avoid that there are commands sent, that “only polluted the air” and have no really function.

Is the switch / case command also there in the OH3? I think about updating, but I am not really sure whether there are advantages for me.

best regards
Georg