NULL state handling in rules - Question

i have a quick question related to NULL state of a switch.

My rule does not work as it should and my naive assumption is that a NULL would crash my rule…
Once upon @rlkoshak show me an efficient way and step-by-step approach…

The question is if a NULL in the switch state would pass the first IF or it would break up as its not a “valid” state… (?)
The rule itself does check a heating temp. If its not higher than 35degree it would start an alarm once (Timer variable)

rule "NG4vlauf - NoTempAlert - Notification"
    Item ESPhofer_EGvlauf received update
  if (NG4vlauf_Timer.state == ON) return;
  if ((now.getHour() < 5) || (now.getHour() >= 17)) return;
  if (ESPhofer_EGvlauf.state < 35) {
       val actions = getActions("pushover", "pushover:pushover-account:account")
       actions.sendMessage("LowTemp Alert | " + ESPhofer_EGvlauf.state +"°C", "NG4 EGvlauf")

It is a valid state so it will pass that first if. Where most people run into trouble is when they assume that their Item can only be ON or OFF or a Number or something like that and when the Item is NULL it fails because you can’t do math with NULL (for example).

OK Thanks a lot for the clarification.

Simply the alarm does not trigger.
I found out that the time part seems to be problematic.

As soon as i comment it out, the rule works…

// if ((now.getHour() < 5) || (now.getHour() >= 23)) return;

Cross checking…the rule says that it will RETURN until 4:59 and after 23:49.
I hope you say that this understanding is wrong, as otherwise i would not know what is the problem…

Kind Regards

When it doesn’t work as expected, log stuff out. Is now.getHour() returning what you expect?

As written I would expect the rule to exit between 00:00 and 04:59 and between 23:00 and 23:59.

hm, thanks - i did logInfo the now.getHour() and it seems to work properly…

2021-12-20 23:30:58.321 [INFO ] [rg.openhab.core.model.script.Heating] - Time: 23

btw. if i want to also involve minutes does this structure make sense or is that too simple/too clumpsy?
It should ignore the core of the rule until its 5:15…

if (((now.getHour() < 5) && (now.getMinute() < 15)) || (now.getHour() > 16)) return;

I’ve now changed it to this, hope it will finally wok as it should:

if (((now.getHour()*60 + now.getMinute()) < 316) || (now.getHour() > 16)) return;

I would have chosen like
(not tested)

val start = now.withHour(5).withMinute(15).withSecond(0)
//now.withTime(5, 15, 0, 0) will also do
val end = now.withHour(17).withMinute(0).withSecond(0)
if(now.isAfter(start) && now.isBefore(end)) return

And I guess it has to be


without semicolon. If you wrote it within {} it has to be with semicolon. Not sure but I think I made that experience a while ago

if ((now.getHour() < 5) || (now.getHour() >= 17)) {

Just to circle back around, no this does not make sense. And when you want to do comparisons like that it’s better to use actual date times instead of looking just at piece parts.

As written the first part will only evaluate to true if the hour is greater than 5 and the minute is greater than 15. It it will be true for 06:16 but false for 06:14.

While that works, it’s really hard to understand what that code does just by looking at it which makes it hard to maintain or share with others. This is why Oliver’s approach is better. It’s much more clear what each of those numbers mean.

No, return should always have the semicolon or else it will treat what ever the next line of code returns as the return value. You don’t want that to happen.

That was my understanding, too. I lookup up in my rules and found this strange behaviour when using return; in combination with switch case:
(rule shortend)

	Channel "shelly:shellydimmer:d0a8e8:device#alarm" triggered
	switch (receivedEvent) {
		case 'OVERTEMP', case 'OVERPOWER', case 'OVERLOAD', case 'LOAD_ERROR':
		logInfo(rulename, "receivedEvent: '{}'",receivedEvent)

in this case return; with semicolon results in the following error:

[WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'test2.rules' has errors, therefore ignoring it: [30,10]: extraneous input ';' expecting '}'

while return without semicolon is accepted without problems

That is most likely something weird going on with the switch statement. Scope is weird in Xtend switch statements and it’s dangerous to try top generalize what goes on in a switch to other contexts. I would expect the following to work though.

default: {
1 Like

I changed the rule accordingly. You’re right - no complaints now from openHAB :slight_smile:

Thanks both of you @rlkoshak && @Oliver2.

Your approach of course is way more easy to read and maintain.
Have a good holiday season!