Filebased rules don't fire reliably, mostly only after the 4th trigger event

Hi,

I have many file-based rules for my zigbee-buttons all around my house to react on the different button presses to switch lights or power plugs. In the logs I can see that the triggering event is received by OH but the rule does not fire on the first occurence of the trigger. Most of the time I need four button presses to let the rule fire, in theses cases the rule ist then fired 2-3 times which leads to strange results.
Here is one of my rules for an Aqara Opple Switch that I use in my bedroom:

rule "ZB-Opple SZ"
when
	Item OPPL_ZB_SZ changed
then
switch OPPL_ZB_SZ.state
{
	case "button_1_single" : {
		logInfo("switches.rules", "ZB Schalter SZ button 1 single")
		if(WLED_SchlaZi.state==OFF){
		WLED_SchlaZi.sendCommand(ON)
		}
		else {
			var Number preset = (WLED_SchlaZiPreset.state as Number)
			preset = preset + 1
			WLED_SchlaZiPreset.sendCommand(preset)
			if (preset==16) preset = 0
		}
		}
	case "button_2_single" : {
		logInfo("switches.rules", "ZB Schalter SZ button 2 single")
		WLED_SchlaZi.sendCommand(OFF)
		
	}
	case "button_6_single" : {
		logInfo("switches.rules", "ZB Schalter SZ button 6 single")
		if(SW_KUE_Wasser.state==OFF)SW_KUE_Wasser.sendCommand(ON)
		else(SW_KUE_Wasser.sendCommand(OFF))
	}
	case "button_3_single" : {
		logInfo("switches.rules", "ZB Schalter SZ button 3 single")
		SW_FAN_SZ.sendCommand(ON)
		FAN_SZ_Timer.sendCommand(30)
		FAN_SZ_Speed.sendCommand(25)
		FAN_SZ_Swing.sendCommand(ON)
		//FAN_SZ_Mode.sendCommand(2)
		
	}
	case "button_4_single" : {
		logInfo("switches.rules", "ZB Schalter SZ button 4 single")
		SW_FAN_SZ.sendCommand(OFF)
	}
	case "triple" : {
		logInfo("switches.rules", "ZB Schalter SZ triple")

	}
}
OPPL_ZB_SZ.postUpdate("")
end

Apart from connection issues in the zigbee network this rule has worked quite flawlessly for the last two years - the described issue occued about two months ago and is quite consistent since then.

My other rules work as they should, so I’m quite lost in finding the issue.

Best regards,
Florian

I suspect what’s happening is that the rule is just taking a long time to react to that first trigger.

What hardware are you running on?

There is a known limitation with Rules DSL and, on certain architectures (i.e. 32-bit Java) JS Scripting, where the very first run of a rule can take some time. And if a rule isn’t triggered frequently it becomes unloaded and the next trigger after it’s unloaded can take some time.

There are several threads on the forum with tricks to keep a rule loaded in memory to prevent this initial delay.

But, there could be other things going on here to. That’s why I ask what hardware you are running. If you are out of RAM, the rule might have been swapped out and when it is triggered it needs to be retrieved from disk and restored to RAM before the rule can actually run.

Did anything change two months ago? Perhaps an upgrade to OH 4 which requires more RAM than OH 3 did?

Assuming it’s not a RAM issue or something else like that the best I can recommend is reimplementing this one rule (and any others that need to be really timely) in a rules language that has less of a first run hit, such as jRuby. JS Scripting can be very fast too if run on 64-bit Java.

I’m running in a virtual machine with 8GB of RAM and 4 virtual CPUs on Debian, the physical CPU is a Core I5.
What I tried today is how the rules react, when the item is changed through the karaf console using,

bundle:send

in that case the rules fire immediately. Also all the other rules (cron based, reacting on temperature changes, reacting on window openings, etc.) work as expected.

Nothing special, I went to OH4 long before and did not have these problems - also my bindings didn’t change dramatically - that’s why I’m quite lost here.

One thing the problematic rules have in common ist that I use switch:case here - could that be a problem?

And htop doesn’t show any issues?

Possibly but maybe not in the way you may think.

The state of an Item is not fixed. Once the rule triggers the state of the Item may not match the state that caused the rule to trigger. While this is super true for commands, where the Item is updated in parallel with the triggering of the rule, it’s also a potential problem with changed or update triggers as the Item may change between when the rule was triggered and the Item.state is called.

Always use newState instead of trying to pull the state of the Item that triggered the rule.

You don’t actually log out the state that triggered the rule and your switch statement doesn’t have a default meaning if the state isn’t one of the cases, the rule silently does nothing. Maybe the rule is triggering and not doing anything because the binding changed what it sends?

Never assume, always verify. Add a default that logs out newState or add a log statement before the switch to log out newState (also change the switch to work off of newState.

You can enable logging of rule events to events.log by setting openhab.event.RuleStatusInfoEvent to INFO. That will show you definitively whether and when the rule is triggered and since it’s logged to the same file as the Item changed events it’s easy to correlate the change with the rule trigger.

In all the years I’ve never seen a case where events are just ignored on the event bus. Something else is going on.

cool, as so often before you had the right idea an pushed me to the right direction: I use zigbee2mqtt for my zigbee devices and obviosly some time in the past the behavior changed in the form, that the action that triggers my rules changes back to NULL right after the button press which leads to what you describe. The item updates, triggers the rule but as soon as the cases are to be processed the item is already updated to NULL and therefore does not fit to any of the cases of my rule anymore.

Now I just have to understand how I can use newState here to circumvent this - I somehow have a feeling that I’d need a lastState here :slight_smile:

No. See Rules | openHAB. When you have a rule triggered by an Item received update or Item changed trigger, newState holds the state that caused the rule to trigger. So even if the Item changed state later, you still have access to the state that caused the rule to trigger.

Always use the implicit variables because you can never guarantee that the Item is still in the state that caused the rule to trigger or, in the case of commands, that the Item has actually changed state in response to the command.

:smiley: thanks again, that is what I will do, tried it with the first rule already, works like a charm!