[SOLVED] Problem with case and switch in rules

Hi,

I’m having a serious problem with my rulesets, and I don’t know where to start debugging. I monitor this for months now and hope some of you can give me an idea how to overcome…

I have several rulesets based on case and switch. For my hue bulbs or my rollershutters par example. So in my sitemap I have entries like these:

    Selection item=Rollladen_Szene
        label="Szenen"
        icon="sofa"
        mappings=[0="Wähle",
                  1="Alle auf",
                  2="Sonnenschutz",
                  3="Alle zu"]

Rollladen_Szene, of course, is an item of type number. In my rules file, I take Rollladen_Szene and do the switch:

rule "Rollladen Szene"
  when
    Item Rollladen_Szene received command
  then
    logInfo("Rollladen", "Gesendet: " +Rollladen_Szene.state)
    switch(Rollladen_Szene.state) {
      case 1: {
               ...
      }
      case 2: {
               ...
      }
      case 3: {
               ...
      }
      Rollladen_Szene.postUpdate(0)
  end

So what’s my problem? I choose - browser or app, makes no difference - one of the cases, and the possibility the rollershutters change is about 60 to 40. I added logInfo statements after then, so I can see:

  • yes, OH2 enters my rule and
  • yes, it’s about to be executed and
  • yes, Rollladen_Szene is recognized the right way.

But - many times nothing happens. Even I get my log output that Rollladen_Szene is recognized as let’s say 2, the case 2: {...} statement is often not entered.
It would be much easier when it would never work - but that’s not the case. Sometimes everything is fine, sometimes I remain in the dark. My hue bulb ruleset acts similar: sometimes I just tap on selection and immediately the bulb scene is loaded and the lights power - and sometimes I tap on selection, OH enters the rule and leaves it without any comment. When I tap again and again on the same selection it’s eventually loaded. But that’s no intended behaviour for a ruleset, isn’t it? :wink:

So what should I do? Should I avoid using this case-switch thing? Is it officially supported? If it is: what am I doing wrong? What could you suggest?

Thank you very much!
Marianne

  • Platform information:
    • Hardware: 4 core Atom, 2GB RAM
    • OS: Debian 9
    • Java Runtime Environment: zulu-8.28.0.1
    • openHAB version: openhab2-2.2.0-1

Try
case 1.0:
The reason being that Number is not an Integer

Try also:

Switch(Rollladen_Szene.state.toString) {
    case "1":

You use received command, this does not ensure that the item state is already set. As this will be done asynchronous.
I won’t go in detail but, that an command was received does not mean that the state of the item which received the command is already processed and set.

Use implicit variables like receivedCommand , triggeringItem to get the state depending to the event that triggered the rule.

Best would be to use received command and receivedCommand

https://docs.openhab.org/configuration/rules-dsl.html#implicit-variables

Have a look at the rules in this examples how to use them.

1 Like

Thanks @Josar, of course. Why didn’t I think of that…

That’s it.

Hi,

thank you all for your quick responses!

@vzorglub In fact, for the rollershutters I missed this toString and the quotation marks. But for the hue bulbs I realized it that way weeks ago… but it makes no difference?

@Josar I’ll play around with that and see if it helps. Thanks a lot to put implicit variables in focus, seems I ignored them… :innocent:

I’ll observe :heart:

Cheers,
Marianne

If you use toString then you should also use strings to compare to, imho.
I think it is not strictly a musst as the evaluation uses Object.equals(Object)

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

rule "Rollladen Szene"
  when
    Item Rollladen_Szene received command
  then
    logInfo("Rollladen:",  triggeringItem.name.toString + " sendete: " + receivedCommand)
   
    switch(receivedCommand.toString ) {
      case "1": {
               ...
      }
      case "2": {
               ...
      }
      case "3": {
               ...
      }
      // Reseting the scene, but then you never know which scene should be active, or not?
      Rollladen_Szene.postUpdate(0)
  end

This seems to do the trick (I just implemented it after your posting). But I’ll test any further.

These Eclipse documents are very hard to understand for me as I’m not a developer - I just want to be my rollershutters act as sun protection :sunglasses:

Have to hack some rule files now…

Cheers,
Marianne

The .toString will not solve the problem.

As @Josar pointed out:

You can not check the itemXXX.state immediately after a “Item itemXXX received a command”.
The Rollladen_Szene.state will update later after the Rollladen_Szene received the command.
And there is a certain likelihood to read the old Rollladen_Szene.state in your rule.

I can see two options for you:
I perfer 1.)

1.) use the
when
Item Rollladen_Szene changed

2.) use the implicit variable: receivedCommand
https://docs.openhab.org/configuration/rules-dsl.html#implicit-variables

Explanation of different events you may find here:
(I have had the same problem before.)
https://community.openhab.org/t/design-pattern-separation-of-behaviors/15886/3?u=bigmountainski

Try it :

rule “Rollladen Szene”
when
Item Rollladen_Szene received command
then
logInfo(“Rollladen”, "Gesendet: " +Rollladen_Szene.state)
switch ((receivedCommand as DecimalType).intValue) {
case 1: {

}
case 2: {

}
case 3: {

}
Rollladen_Szene.postUpdate(0)
end

With Rollladen_Szene as Number in your item file

Hi,

just as a final notice: I did this switch(receivedCommand.toString) magic and everything is working like expected now.

Thank you all for your patience and have a nice weekend :green_heart:
Marianne

1 Like