Rule does not trigger switch state

Hello
I have following rule defined:

rule "Handtuchtrockner"

when
    Item Audio_Handtuchtrockner__Bad_Handtuchtrockner_oben_rechts received command
then
    switch receivedCommand {
        case INCREASE : {
            logInfo("Handtuchtrockner","Handtuchtrockner Increase")
			
			if (KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == "ON") {
				logInfo("Handtuchtrockner","Handtuchtrockner OFF")
				events.sendCommand(KNX_Device_Aktor_A2_Bad_Handtuchtrockner, "OFF");
			} 
			else if (KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == "OFF") {
				logInfo("Handtuchtrockner","Handtuchtrockner ON")
				events.sendCommand(KNX_Device_Aktor_A2_Bad_Handtuchtrockner, "ON");
			}

        }
		case DECREASE : {
            logInfo("Handtuchtrockner","Handtuchtrockner Decrease")
            
			if (KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == "ON") {
				logInfo("Handtuchtrockner","Handtuchtrockner OFF")
				events.sendCommand(KNX_Device_Aktor_A2_Bad_Handtuchtrockner, "OFF");
			} 
			else if (KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == "OFF") {
				logInfo("Handtuchtrockner","Handtuchtrockner ON")
				events.sendCommand(KNX_Device_Aktor_A2_Bad_Handtuchtrockner, "ON");
			}
        }
    }
end

The log shows this:

 [INFO ] [b.core.model.script.Handtuchtrockner] - Handtuchtrockner Decrease
 [INFO ] [b.core.model.script.Handtuchtrockner] - Handtuchtrockner Decrease
 [INFO ] [b.core.model.script.Handtuchtrockner] - Handtuchtrockner Increase
 [INFO ] [b.core.model.script.Handtuchtrockner] - Handtuchtrockner Increase

This means the rule is working but it does not enter the “if else” cases although the item “KNX_Device_Aktor_A2_Bad_Handtuchtrockner” exists as a switch.

Does anyone know what I am doing wrong?

Thanks

This is Rules DSL so you have to follow Rules DSL conventions.

In Rules DSL, .state is the raw Java State Object. For a Switch, the state is an OnOffType, not a String. In fact, .state is never just a String in Rules DSL. ON is not the same thing as the String "ON" so the if conditions are always false.

Either compare to the OnOffType ON or convert the .state to a String.

if (KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == ON) {
if (KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state.toString == ON) {

Also, in Rules DSL you don’t use events to send a command. If you know the name of the Item use:

KNX_Device_Aktor_A2_Bad_Handtuchtrockner.sendCommand("OFF") // notice no ;

or you can call sendCommand without referencing events.

sendCommand(KNX_Device_Aktor_A2_Bad_Handtuchtrockner, "ON")

In the future, don’t rely on example code found on the forum unless you know what rules language that code is written in. Your code looks like you found an old Nashorn JavaScript rule as your example.

Be sure to use Rules | openHAB as your reference for Rules DSL.

And if this came from an AI ChatBot, unless you’ve create a custom bot loaded up with the OH docs, the code they generate is almost always next to worthless. You have to almost be an expert in Rules to identify and fix the code to work in the first place.

Finally, this rule is way over done. You do the same thing whether the command is INCREASE or DECREASE and you always toggle the KNX Item.

rule "Handtuchtrockner"

when
    Item Audio_Handtuchtrockner__Bad_Handtuchtrockner_oben_rechts received command
then
    // 1. Decide if the rule needs to run
    // I'll be generous and assume this Item may receive ON/OFF or Number commands that should be ignored.
    if(receivedCommand != INCREASE && receivedCommand != DECREASE) return; // this is the only place where a ; is required

    // 2. Calculate what to do
    logInfo("Handtuchtrockner","Handtuchtrockner " + receivedCommand)
    logInfo("Handtuchtrockner","Handtuchtrockner " + KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state)
    val newCommand = KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == ON ? OFF : ON

    // 3. Do it
    KNX_Device_Aktor_A2_Bad_Handtuchtrockner.sendCommand(newCommand)
end

Small issue: It should be && not ||

if(receivedCommand != INCREASE && receivedCommand != DECREASE) return;

:slight_smile:

No, I think the && is correct. If receivedCommand is neither INCREASE nor DECREASE we want to return. || won’t work. Consider the following.

Let’s say receivedCommand is ON. ON != INCREASE so the rule immediately returns. Once one clause of an || evaluates to true the whole thing is evaluated to true. So far, so good.

Now let’s say receivedCommand is DECREASE. DECREASE != INCREASE so the rule immediately returns. Again, once one clause of an || evaluates to true the whole || clause is true and it never even checks for receivedCommand != DECREASE. This is not what we want.

An && clause requires both operands to be true for the condition to be true meaning that if receivedCommand is neither INCREASE nor DECREASE (in this case) the rule immediately returns which is what we want…

1 Like

Yes, that’s the point…
take a look at your rule… :wink:

Doh!

1 Like

Thanks for the very good input - I am always learning something new :slight_smile:

When I am using your rule I got following error:

 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'Handtuchtrockner.rules' has errors, therefore ignoring it: [12,75]: no viable alternative at input '?'
[12,81]: mismatched input ':' expecting 'end'

This error goes to this line:

val newCommand = KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == ON ? OFF : ON

Do I need to convert to string here or the dsl rule do not like this kind of expression?

Wrong syntax for the ternary operator in Rules DSL.

val newCommand = if(KNX_Device_Aktor_A2_Bad_Handtuchtrockner.state == ON) OFF else ON

cool - now it works perfectly!!

By the way, I used the && and for me it is correct.

Thanks a lot!!

Yes, sure. It was a typo in the first place (I guess)

:+1: