Rule not working with rain sensor

Hi,

I try to keep my mowing robot informed by my external Rain Sensor.
If my RainSensor gets activated, the mowing robot should get the value 2 - partymode to stop.
After 300seconds (later 2hours) it should turn back to normal mode 1 when no rain is detected. (2 hours to get rid of wet grass).

The items are as follows:
Rain Sensor:
String RainSensor_OutValue { http="<[beckhoff:2000:JSONPATH($.Rainsensor)]" }
and for Input for the mowing robot:
Number LandroidScheduleMode (showing a switch with two modes on sitemap: Switch item=LandroidScheduleMode mappings=[1=“Normal”, 2=“Party”])

So my rule looks like this, but doesn’t work, I never get pushed or see anything in log output:

val int timerRainDelay = 300 /*7200 2h */
var Timer timerRain = null

rule "RegensensorLandroid"
when
        Item RainSensor_OutValue changed
then
        /* LandroidScheduleMode 1 - normal, 2 - party */
        if (LandroidScheduleMode.state == 2 && RainSensor_OutValue.state == 'off'){
                logInfo("myRule","Regen beendet - Landroid Partymode noch aktiv.")
                if(timerRain!==null){
                        timerRain.cancel
                }
                timerRain = createTimer(now.plusSeconds(timerRain)) [|
                sendPushbulletNote("DEFAULT","klaus......@mail.com","Landroid gestartet - Regen Ende vor 2h","Landroid wurde in Normalmodus versetzt, da es zu Regnen aufgehört hat!")
                timerRain = null
                LandroidScheduleMode.postUpdate("1")]
        }
        if (LandroidScheduleMode.state == 1 && RainSensor_OutValue.state == 'on'){
                logInfo("myRule","Regen begonnen - Landroid Partymode nicht aktiv.")
                timerRain.cancel
                timerRain = null
                LandroidScheduleMode.postUpdate("2");
                sendPushbulletNote("DEFAULT","klaus.....@mail.com","Landroid gestoppt - Regen eingesetzt","Landroid wurde in Partymodus versetzt, da es zu Regnen begonnen hat!")
        }
end

I think my conditions always false because of no log entry.
Only Log entry if rain starts in events.log is that:
2022-05-23 15:20:42.261 [vent.ItemStateChangedEvent] - RainSensor_OutValue changed from off to on
and later if rain is over:
2022-05-23 15:23:41.845 [vent.ItemStateChangedEvent] - RainSensor_OutValue changed from on to off

Can anyone find my bug?
thanks

Add logging to see what state the LandroidScheduleMode and RainSensor_OutValue are when the rule runs. This will tell you if the conditions are evaluating to false and show you the rule is running.

Next, make sure you are comparing like to like. RainSensor_OutValue.state returns an Object of type State. We know it’s also a StringState because we happen to know that the Item is a StringItem. But neither a State nor a StringState are a String. Sometimes rules DSL can autoconvert things for you and other times it can’t. Eliminate this as the source of the problem by calling toString() so you are comparing a String to a String.

RainSensor_OutValue.state.toString() == 'off'

It’s a little better on the Number side. You just need to cast the State to a Number because a NumberItem carries a DecimanType which is a Number.

LandroidScheduleMode.state as Number == 2

As a final caution, it’s really important to know what version of OH you are running as there has been a ton of changes over just the last year. I can see you are using nothing later than 2.5 since you are still using the old 1.x HTTP binding. Without the Item definitions though I wouldn’t have known that. If you were using the later HTTP binding you’d be able to convert that RainSensor_OutValue to a Switch which would be easier to work with over all.

thanks for your fast reply, trying openhab version 2.x

logging can be found in openhab.log:
[WARN ] [clipse.smarthome.model.script.myRule] - Schedule mode changed to1

rule checker
when
        Item LandroidScheduleMode changed
then
        logWarn("myRule","Schedule mode changed to"+LandroidScheduleMode.state)
end

ok simulated rain:
got in log:
2022-05-23 16:35:01.459 [INFO ] [clipse.smarthome.model.script.myRule] - Rain detected
2022-05-23 16:35:03.202 [INFO ] [clipse.smarthome.model.script.myRule] - Regen begonnen - Landroid Partymode nicht aktiv.
2022-05-23 16:35:03.207 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘RegensensorLandroid’: cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.cancel() on null

I changed the if conditions to:
if (LandroidScheduleMode.state as Number == 2 && RainSensor_OutValue.state.toString() == ‘off’){

party mode is not accessed with: LandroidScheduleMode.postUpdate(“1”).
Is the String in postUpdate correct? or sendCommand(Number) ?

timerRain.cancel is a problem if no timer is set too…
thanks,

Add logging to the rule in question. We want to know the states of the Items when that rule runs. We also want to see that that rule is running. But the error seems to show that the rule is running.

If the timer doesn’t exist there’s nothing to cancel. You need to test that the timer isn’t null before cancelling it. But there is a shortcut for that.

timerRain?.cancel

I’m not sure what this is asking. You can update the state of the LandroidScheduleMode with that but it’s won’t actually go out to the binding and the device to cause a change in the end device. As documented, updates only change the state of the OH Item. If you want to cause an end device to do something, you need to send a command.

You can send 1 or "1" as an update or a command. Either will work.

OK, here full working code for me:

rule checker
when
	Item LandroidScheduleMode changed
then
	logWarn("myRule","Schedule mode changed to"+LandroidScheduleMode.state)
end

rule RegensensorLandroid
when
	Item RainSensor_OutValue changed
then
	/* LandroidScheduleMode 1 - normal, 2 - party */
	if (LandroidScheduleMode.state as Number == 2 && RainSensor_OutValue.state.toString() == 'off'){
                logInfo("myRule","Regen beendet - Landroid Partymode noch aktiv.")			
		timerRain?.cancel
		timerRain = createTimer(now.plusSeconds(timerRainDelay)) [|
		sendPushbulletNote("DEFAULT","klaus@xxxx","Landroid gestartet - Regen Ende vor 2h","Landroid wurde in Normalmodus versetzt, da es zu Regnen aufgehört hat!")
		timerRain = null
		LandroidScheduleMode.sendCommand("1")]
	}
	if (RainSensor_OutValue.state.toString() == 'on'){
		logInfo("myRule","Regen begonnen - Landroid Partymode nicht aktiv.")
		if(LandroidScheduleMode.state as Number == 1){
			LandroidScheduleMode.sendCommand("2");
			//need to send command to go home too!
		}
		timerRain?.cancel
                /*sendPushbulletNote("DEFAULT","klaus@xxxx","Landroid gestoppt - Regen eingesetzt","Landroid wurde in Partymodus versetzt, da es zu Regnen begonnen hat!")*/
	}
end

The only thing I commented, is to send a command for going home, because the ScheduleMode command (2) is only party mode. The mower will not go home with this mode…
How can I send just the “go home” in the comment on line 25 ?
thanks

is LandroidScheduleMode a string ?