Validation issue in a rule

i moved to openhab3 from 2.5 and upon starting i get this log for this only one rule :

[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'alarm.rules', using it anyway:
This expression is not allowed in this context, since it doesn't cause any side effects.

never show that at openhab 2.5…this is my rule :

var Timer siren_timer = null
rule "intruder_alarm"
when 
    Item motion_sensors changed to ON
	or
	Item doors_windows_contacts changed to OPEN
then
	if(Alarm_State.state==("Enabled")) {
	     Alarm.postUpdate("Enabled")		 
	}	
end
rule "Cleaning"
when 
	Item doors_windows_contacts changed from CLOSED to OPEN
then
	if(Alarm_State.state==("Cleaning")) {
	     Alarm.postUpdate("Enabled")		 
	}	
end
rule "NGleak"
when 
    Item NGalarm changed to ON
then
         Alarm_State.postUpdate("NGleak")
		 sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxx")
         sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxxx")
         gVolume.sendCommand(80)
	     say("Natural Gas leak detected please evacuate the house.")
		 Thread::sleep(5000)
		 gVolume.sendCommand(60)
         sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxI&message=alarm")
         val mailActions = getActions("mail","mail:smtp:mailserver")
         mailActions.sendMail("xxxxxxxxxxxx@gmail.com, xxxxxxxxx@yahoo.co.uk", "GAS LEAK!!!", "NATURAL GAS LEAK!")
	     XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	     XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(7)
		 XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
         XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
	     All_Lights.sendCommand(ON)	
end
rule "fire_alarm"
when 
    Item XiaomiMijiaHoneywellFireAlarmDetector_SmokeDetected changed to ON
then
         Alarm_State.postUpdate("Fire")
		 sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxxx")
         sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxx")
         gVolume.sendCommand(80)
	     say("Fire,please evacuate the house with safety.")
		 Thread::sleep(5000)
		 gVolume.sendCommand(60)
         sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&message=alarm")
         val mailActions = getActions("mail","mail:smtp:mailserver")
         mailActions.sendMail("xxxxxxxxxxxxxxxx@gmail.com,xxxxxxxxxxxx@yahoo.co.uk", "FIRE!!!", "FIRE!FIRE!FIRE!")
	     XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	     XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(7)
		 XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
         XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
	     All_Lights.sendCommand(ON)	
end
rule "fire_warning"
when
    Item XiaomiMijiaHoneywellFireAlarmDetector_ParticleDensity changed
then
    if (XiaomiMijiaHoneywellFireAlarmDetector_ParticleDensity.state>=(40)) {
	     Alarm_State.postUpdate("Smoke")
		 sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxxxxxxxx")
         sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxxx")
	     gVolume.sendCommand(80)
	     say("Too much smoke ,fire warning.")
		 Thread::sleep(5000)
		 gVolume.sendCommand(60)
	     sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxI&message=alarm")
		 val mailActions = getActions("mail","mail:smtp:mailserver")
         mailActions.sendMail("xxxxxxxxxxxx@gmail.com,xxxxxxxxxx@yahoo.co.uk", "FIREWARNING!!!", "TOO MUCH SMOKE")
	     XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	     XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(1)
		 XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
         XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
		 }
end
rule "water_leak"
when
    Item WaterLeakSensor1_LeakDetected changed from OFF to ON
	or
	Item WaterLeakSensor2_LeakDetected changed from OFF to ON
then
    if (waterprotection.state==(ON)) {
	    Alarm_State.postUpdate("Water Leak")
		sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxx")
        sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxxx")
        Tasmvalve.sendCommand(OFF)
		All_Lights.sendCommand(ON)
	    gVolume.sendCommand(80)
	    say("Water leak detected.")
		Thread::sleep(5000)
		gVolume.sendCommand(60)
	    sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxx&message=alarm")
        val mailActions = getActions("mail","mail:smtp:mailserver")
        mailActions.sendMail("xxxxxxxxxxx@gmail.com, xxxxxxxxx@yahoo.co.uk", "WATER LEAK!!!", "WATER LEAK DETECTED PLEASE CHECK IT OUT!")
	    XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	    XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(7)
        XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
        XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
		}
    else {
	    gVolume.sendCommand(80)
        say("Water leak detected but the water protection is off.")
		Thread::sleep(5000)
		gVolume.sendCommand(60)
    }
end
rule "home"
when
    Item EntranceContact_OpenStatus changed from CLOSED to OPEN
	or
	Item MbedroomContact_OpenStatus changed from CLOSED to OPEN
	or
	Item KitchenContact_OpenStatus changed from CLOSED to OPEN
	or
	Item DiningRoomContact_OpenStatus changed from CLOSED to OPEN
	or
	Item LivingRoomContact_OpenStatus changed from CLOSED to OPEN
	or
	Item BedroomContact_OpenStatus changed from CLOSED to OPEN
then
    if(Home_State.state==("Enabled")) {
	 XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	 XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(10009)
	 XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
     XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
	 All_Lights.sendCommand(ON)
     sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&message=alarm")
     val mailActions = getActions("mail","mail:smtp:mailserver")
	 mailActions.sendMail("xxxxxxxxxxxxxx@gmail.com,xxxxxxxxxxxx@yahoo.co.uk", "ALARM!!!", "ALARM IS ON ,CHECK IT OUT.")
	}	
end
rule "alarm"
when
    Item Alarm changed to "Enabled"
then
    sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxxx")
    sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxxx")
    sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&message=alarm")
	val mailActions = getActions("mail","mail:smtp:mailserver")
	mailActions.sendMail("xxxxxxxxxx@gmail.com, xxxxxxxxx@yahoo.co.uk", "ALARM!!!", "ALARM IS ON ,CHECK IT OUT.")
	XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(10005)
	XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
    XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
	All_Lights.sendCommand(ON)
    Siren.sendCommand(ON)
    siren_timer = createTimer(now.plusMinutes(5)) [|
        if(Alarm.state==("Enabled")) {
		    Siren.sendCommand(ON)
		    siren_timer.reschedule(now.plusMinutes(5))
		}
	    else {
        Siren.sendCommand{OFF}
        if (siren_timer !== null) {
		    siren_timer.cancel
		    siren_timer = null
			logInfo("sirenTimer", "setting siren_timer to null")
		    }
        }		
    ]
end

i cant find what is causing that warning…any ideas?

Nothing shows up with a quick visual scan. Usually you’ll see that error inside a lambda. Your best bet is to comment out all but one rule in that file, save it and see if the validation error reappears. If not uncomment the next rule until the warning appears again. Then you’'ll know which rule is generating the warning.

From there perhaps it can be narrowed down.

But note, it’s not an error nor is it a warning log statement. The rules likely work as it needs to as written.

Other things that can help is to eliminate all this duplicated code. You basically have the same code over and over again with only minor changes to what the alerts are.

For example, the first two rules could be combined to:

rule "Intruder of cleaning"
when
    Item motion_sensors changed to ON or
    Item doors_windows_contacts change to OPEN
then
    var alarmState = Alarm_State.state

    if(Alarm_State.state == "Enabled") {
        alarmState = "Enabled"
    }
    else if(Alarm_State.state == "Cleaning"
              && triggeringItemName == "doors_windows_contacts" 
              && oldState == "CLOSED") {
        alarmState = "Enabled"
    }

    if(Alarm.state != alarmState){
        Alarm.postUpdate(alarmState)
    }
end

So this is slightly more complex so why is it better? Well, assuming that the warning or error is coming from these two rules, to fix the problem requires only a single change to the code, not two identical changes. Also, what if you wanted to do more than just update Alarm to “Enabled”? You’d have to code that twice but combined you only have to code and maintain it in one place.

The first two rules is probable not necessary really but I wanted to use them as a simple example.

But the differences between NGleak, fire_alarm, fire_warning, and water_leak are very minor. If the error is in one of those rules, you’ll have to fix the problem in four different places. If you decide to change the behavior, maybe add a Telegram message or something like that you’ll need to add that in four different places.

There are several approaches one could use but this might be one of the rare cases where a lambda would be appropriate. However if these rules are likely to run at the same time there could be problems. So combining the ones that are likely to happen close together can mitigate that.

val loadAndShowUI = [ |
    sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxxxxxxxx")
    sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxxx")
]

val sayAlert = [ String message |
    gVolume.sendCommand(80)
    say(message)
    Thread::sleep(5000)
    gVolume.sendCommand(60)    
]

val sendAlerts = [ String subject, String message | 
    sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxI&message=alarm")
    val mailActions = getActions("mail","mail:smtp:mailserver")
    mailActions.sendMail("xxxxxxxxxxxx@gmail.com, xxxxxxxxx@yahoo.co.uk", subject, message)
]

val setGateway = [Integer selector, HSBType color |
    XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
    XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(selector)
    XiaomiMiSmartHomeGateway_Color.sendCommand(color)
    XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
]

rule "NGleak"
when 
    Item NGalarm changed to ON
then
    Alarm_State.postUpdate("NGleak")
    loadAndShowUI.apply()
    sayAlert.apply("Natural Gas leak detected please evacuate the house.")
    sendAlerts.apply["GAS LEAK!!!", "NATURAL GAS LEAK!"]
    setGateway.apply(7, HSBType::RED)
    All_Lights.sendCommand(ON)
end

rule "fire_alarm"
when 
    Item XiaomiMijiaHoneywellFireAlarmDetector_SmokeDetected changed to ON
then
    Alarm_State.postUpdate("Fire")
    loadAndShowUI.apply()
    sayAlert.apply("Fire,please evacuate the house with safety.")
    sendAlerts.apply["FIRE!!!", "FIRE!FIRE!FIRE!"]
    setGateway.apply(7, HSBType::RED)
    All_Lights.sendCommand(ON)
end

rule "fire_alarm"
when 
    Item XiaomiMijiaHoneywellFireAlarmDetector_ParticleDensity changed
then
    if(XiaomiMijiaHoneywellFireAlarmDetector_ParticleDensity < 40){
        return;
    }
    Alarm_State.postUpdate("Smoke")
    loadAndShowUI.apply()
    sayAlert.apply("Too much smoke ,fire warning.")
    sendAlerts.apply["FIREWARNING!!!", "TOO MUCH SMOKE"]
    setGateway.apply(1, HSBType::RED)
end

rule "water_leak"
when 
    Item WaterLeakSensor1_LeakDetected changed from OFF to ON
    or
    Item WaterLeakSensor2_LeakDetected changed from OFF to ON
then
    if(waterprotection.state == OFF){
        sayAlert.apply("Water leak detected but the water protection is off.")
        return;
    }

    Alarm_State.postUpdate("Water Leak")
    loadAndShowUI.apply()

    Tasmvalve.sendCommand(OFF)
    All_Lights.sendCommand(ON)

    sayAlert.apply("Water leak detected.")
    sendAlerts.apply["WATER LEAK!!!", "WATER LEAK DETECTED PLEASE CHECK IT OUT!"]
    setGateway.apply(7, HSBType::RED)
end

...

You can get the idea for the rest. The advantage here is that you only have to update/fix the code in one place and you’ve fixed all your rules. You only have to add new capabilities in one place and you’ve added it to all your rules.

One concern I have with these rules through is that it is likely that multiple copies of each rule might be running at the same time and sending commands in parallel. This is particularly a concern with the say command and sleep. The particle alarm might go off and then half a second later the fire alarm might go off. In that case both rules will be trying to say at the same time which could cause problems. So that part might best be implemented using Design Pattern: Separation of Behaviors. Then it will wait the full five seconds before processing the second say command.

thnx mate for your detailed answer,i found that the rule causing the validation issue is :

rule "alarm"
when
    Item Alarm changed to "Enabled"
then
    sendHttpGetRequest("http://192.168.1.30:2323/?cmd=toForeground&password=xxxxxxxxxx")
    sendHttpGetRequest("http://192.168.1.30:2323/?cmd=loadUrl&url=http://192.168.1.150:8080/habpanel/index.html%23/view/Alarm&password=xxxxxxxxxx")
    sendHttpGetRequest("https://autoremotejoaomgcd.appspot.com/sendmessage?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&message=alarm")
	val mailActions = getActions("mail","mail:smtp:mailserver")
	mailActions.sendMail("xxxxxxxxxx@gmail.com, xxxxxxxxx@yahoo.co.uk", "ALARM!!!", "ALARM IS ON ,CHECK IT OUT.")
	XiaomiMiSmartHomeGateway_SoundVolume.sendCommand(100)
	XiaomiMiSmartHomeGateway_SoundSelector.sendCommand(10005)
	XiaomiMiSmartHomeGateway_Color.sendCommand(HSBType::RED)
    XiaomiMiSmartHomeGateway_Brightness.sendCommand(100)
	All_Lights.sendCommand(ON)
    Siren.sendCommand(ON)
    siren_timer = createTimer(now.plusMinutes(5)) [|
        if(Alarm.state==("Enabled")) {
		    Siren.sendCommand(ON)
		    siren_timer.reschedule(now.plusMinutes(5))
		}
	    else {
        Siren.sendCommand{OFF}
        if (siren_timer !== null) {
		    siren_timer.cancel
		    siren_timer = null
			logInfo("sirenTimer", "setting siren_timer to null")
		    }
        }		
    ]
end

and particularly this last timer part here :

    siren_timer = createTimer(now.plusMinutes(5)) [|
        if(Alarm.state==("Enabled")) {
		    Siren.sendCommand(ON)
		    siren_timer.reschedule(now.plusMinutes(5))
		}
	    else {
        Siren.sendCommand{OFF}
        if (siren_timer !== null) {
		    siren_timer.cancel
		    siren_timer = null
			logInfo("sirenTimer", "setting siren_timer to null")
		    }
        }		
    ]

i am using timers starting and rescheduling this way in other rules too but never gave me this warning message about validation problem…

You’ll have to narrow it down to a specific line of code, not just the block of code. And again, it’s not even really a warning level log, it’s an info log statement so it’s not really a problem.

Note:

That block of code executes when the siren_timer expires. There will never be a case where that block of code is executing and siren_timer is null. And if that block of code is running, the Timer has expired already. There is nothing to cancel. So just set siren_timer to null. The rest of that code is pointless.