Multiple case in switch statement

But I’ll bet you are not OH 1.8. Useful to know, though.

@rossko57: I am running openHAB 1.8.2

@HomeAutomation: Which OH version?

I’m running OH 2.4. Could be the case.

I suspect case statements like this was added after OH 1.8 then.

Is it still not possible (when you’re on the latest OH3.X stable version) to use a range of numbers in one case statement?

Because I have a rollershutter that I also like to add to HomeKit, but in that case HomeKit wil send a number where the rollershutter position should go. 100 is open and 0 closed but if you want it half closed, it will send 50 for example.
So if I want to implement this to a rule I should get 100 lines of cases…

Now the rule is quite simple (and I like to keep it that way):

rule "Rollershutter back"
when
    Item shutterBack received command
then
val mqttActions = getActions("mqtt","mqtt:broker:mosquitto")
    switch (receivedCommand) {
        case UP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutteropen")
        case STOP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterstop")
        case DOWN :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterclose")
    }
end

If I could add something like:

case 1-100 :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/ShutterPosition1")

Could that work?

default?

Some ideas in this thread

Thanks for the quick answer, are there some documentations how to use this default option? Don’t get it quite yet by reading this thread, also a search on the web on “openhanded default rule” didn’t gave me the results I’m looking for.

Rules DSL is based on the Xtend language. There is a link to the Xtend docs in the Rules DSL docs. The reference for switch is here: Xtend - Expressions

You will see that you can use a full boolean expression for the case so the following should work:

case receivedCommand >= 1  && receivedCommand <= 100 :

The last part of that section discusses fall through which is a standard behavior with switch statements in all programming languages. default is the clause if no other case matches.

Thanks, that looks great, I now see how the thread could have helped me :slight_smile: so I first adjusted the rule to this:

rule "Rollershutter back"
when
    Item shutterBack received command
then
val mqttActions = getActions("mqtt","mqtt:broker:mosquitto")
    switch (receivedCommand) {
        case UP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutteropen")
        case STOP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterstop")
        case DOWN :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterclose")
        case receivedCommand => 0  && receivedCommand <= 100 :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/ShutterPosition1", "50")
    }
end

First with a fixed output command over MQTT to see if it works, but it keeps giving me this error:

2022-12-07 19:01:47.394 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'shutterBack' received command 0
2022-12-07 19:01:47.404 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'shutterBack' changed from 100 to 0
==> /var/log/openhab/openhab.log <==
2022-12-07 19:01:47.404 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'rollershutterCommand-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow(T,org.eclipse.xtext.xbase.lib.Procedures$Procedure1) on instance: null in rollershutterCommand

I don’t get where the null should come from, because you can see that it receives a number value…
Any thoughts?

null comes in any time you Xtend can’t figure out what to do based on the current context.

=> is a completely different operator (called a double arrow and I can’t imagine you will ever encounter this operator while writing rules) from >= (greater or equal than). They do different things and are not interchangeable.

When you want to make a comparison, the > or < always goes first.

I’m not sure that is possible; receivedCommand is a command type object, not a numeric variable. Try
receivedCommand as Number <= 100

Unfortunately that results in the following error when I try to save the rule:
2022-12-08 00:05:16.124 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'rollershutterCommand.rules' has errors, therefore ignoring it: [13,76]: no viable alternative at input '100'

Line 13 is this one in the rule:
case receivedCommand => 0 && receivedCommand <= 100 :
And character 76 is the “<” symbol.

Yoou don’t seem to have acted on either of the suggestions?

1 Like

please read this

Oh, for some reason I missed the part what rlkoshak mentioned… :face_with_peeking_eye:
So after reading it, I tried this:

        case receivedCommand >= 0  && receivedCommand <= 100 :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/ShutterPosition1", "50")

This doesn’t throw any error, but also the case don’t get triggered. As soon as I change receivedCommand to receivedCommand as Number, it keeps complaining this: “no viable alternative at input”

So since rossko57 mention that the receivedCommand isn’t a numeric variable, I tried this:

rule "Rollershutter back"
when
    Item shutterBack received command
then
val mqttActions = getActions("mqtt","mqtt:broker:mosquitto")
var Number shutterPosistion = receivedCommand as Number
logInfo("Rollershutter rule", "First part, value of shutterPosistion is = " + shutterPosistion.toString)
    switch (receivedCommand) {
        case UP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutteropen")
        case STOP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterstop")
        case DOWN :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterclose")
        case shutterPosistion >= 0  && shutterPosistion <= 100 :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/ShutterPosition1", "50")
    }
logInfo("Rollershutter rule", "Second part, value of shutterPosistion is = " + shutterPosistion.toString)
end

But again, the case don’t to seemed triggered by the value, also tried including the loginfo inside the switch{} part but that seem te be possible either, who can help me out?

I’m not an expert in Rules DSL and I haven’t used it in a while, but try this:

rule "Rollershutter back"
when
    Item shutterBack received command
then
val mqttActions = getActions("mqtt","mqtt:broker:mosquitto")
logInfo("Rollershutter rule", "First part, value of shutterPosistion is = " + shutterPosistion.toString)
    switch (receivedCommand) {
        case UP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutteropen")
        case STOP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterstop")
        case DOWN :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterclose")
        default : {
            var shutterPosistion = (receivedCommand as Number)
            if (shutterPosistion >= 0  && shutterPosistion <= 100) {
              mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/ShutterPosition1", "50")
            }
        }
    }
logInfo("Rollershutter rule", "Second part, value of shutterPosistion is = " + shutterPosistion.toString)
end

This isn’t going to work if receivedCommand is for example STOP.
See JimT suggestion to only attempt number if you already know it is not UP/DOWN/STOP

You might like to think about the logic a bit more though … if it is a command that is not UP/DOWN/STOP, what else could it be apart from a number 0-100?

Thanks, that did the trick, I now ended up with this rule and it works like I wanted. If controlled by the rollershutter buttons from OH, it does what it suppose to de, when controlled by Apple HomeKit, it also does what you command it to do:

rule "Rollershutter back"
when
    Item shutterBack received command
then
val mqttActions = getActions("mqtt","mqtt:broker:mosquitto")
    switch (receivedCommand) {
        case UP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutteropen")
        case STOP :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterstop")
        case DOWN :
            mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/Backlog", "shutterclose")
        default : {
            var shutterPosistion = (receivedCommand as Number)
            if (shutterPosistion >= 0  && shutterPosistion <= 100) {
              mqttActions.publishMQTT("cmnd/Shelly25RollerShutter_Back/ShutterPosition1", shutterPosistion.toString)
            }
        }
    }
end

Maybe if somebody is looking for something similar, this will help.

Yea I checked the openHAB Log Viewer when I used the Apple HomeKit item to see what command it will send when you do different things with it. It will always send a number between 0-100, so for now, this rule will work like it suppose to do :slight_smile:

Yes, my point was that the following code is therefore redundant

It’s always true, you don’t ever get to this test if it were UP/DOWN/STOP