Best way to write rules

Hi guys,

I’ve been using Openhab2 now since 2 months back. And I have written some rules that control my z-wave sucurity system. Now I’ve started to wonder which way is the best way to write rules or the best practice.

Below are two examples of rules that do the same thing in my system. I can use either one. It’s for my garage door in this case example.
Would you guys use more nestled if statements or write more “rule” clauses for each thing you want to do?

Example 1. Shorter using more if clauses

var Timer timer3 = null

rule garage_door
when
	Item Door_Contact_Garage received update
then
	if (Virtual_Arming_Garage.state == ARMED && Door_Contact_Garage.state == OPEN) {
		sendCommand(Virtual_AlarmState_Garage, "ON")
		sendCommand(Switch_Siren_Garage, "ON")
	}
	else {
		if (Door_Contact_Garage.state == CLOSED) {
			sendCommand(Light_LEDLamp_Garage, 0)
			timer3 = createTimer(now.plusSeconds(300)) [|
				sendCommand(Virtual_Arming_Garage, ARMED)
			]
		}
		else {
			sendCommand(Light_LEDLamp_Garage, 100)
		}
	}
end

rule reset_alarm_garage
when
	Item Virtual_Arming_Garage received update
then
	if (Virtual_Arming_Garage.state == DISARMED && Virtual_AlarmState_Garage.state == ON) {
		sendCommand(Switch_Siren_Garage, "OFF")
		sendCommand(Virtual_AlarmState_Garage, "OFF")
	}
end

Example 2. More lines and more rules but perhaps simpler to understand

var Timer timer3 = null

rule "Garage door opens when armed"
when
	Item Door_Contact_Garage received update
then
	if (Virtual_Arming_Garage.state == ARMED && Door_Contact_Garage.state == OPEN) {
		sendCommand(Virtual_AlarmState_Garage, "ON")
	}
end


rule "Garage door opens when disarmed"
when 
	Item Door_Contact_Garage received update
then
	if (Virtual_Arming_Garage.state == DISARMED && Door_Contact_Garage.state == OPEN) {
		sendCommand(Light_LEDLamp_Garage, 100)
	}
end

rule "Garage door is closed"
when
	Item Door_Contact_Garage received update
then
	if (Virtual_Arming_Garage.state == DISARMED && Door_Contact_Garage.state == CLOSED) {
		sendCommand(Light_LEDLamp_Garage, 0)
		timer3 = createTimer(now.plusSeconds(300)) [|
			sendCommand(Virtual_Arming_Garage, ARMED)
			]
	}
end

rule "Sound the alarm!"
when
	Item Virtual_AlarmState_Garage changed to ON
then
	sendCommand(Switch_Siren_Garage, "ON")
end


rule "Reset the alarm through the site map"
when
	Item Virtual_Arming_Garage received update
then
	if (Virtual_Arming_Garage.state == DISARMED && Virtual_AlarmState_Garage.state == ON) {
		sendCommand(Switch_Siren_Garage, "OFF")
		sendCommand(Virtual_AlarmState_Garage, "OFF")
	}
end

I’m trying to understand how to think when writing rules as my rules grow and I can make the right choices in the beginning.

A while back there was an interesting thread on this:

Maybe the discussion in there helps

Nice, thanks Markus. I’ll take a read through that thread. It sounds promising. :slight_smile:

OP from that other thread here. I’ve gone back and forth on this. I’m a professional software developer, so I’m pretty big on making modular and reusable code as much as possible. The openhab rule language doesn’t make that the easiest as the reusable “functions” are really a bit of a hack.

When I was still on openhab 1, I tried the jsr223 module and loved it because it allowed me to use a real programming language (I used Javascript although others like python are available) and could do things like more complex organizations and reusable rule templates. Last I checked, jsr223 or something similar was not ready for normal use on openhab 2. When it is ready, I will probably translate my rules over to it.

Since I migrated most of my stuff over to openhab2, I’ve been using the openhab rule language again. Of your two examples, I’ve been going more with rules that look like that second. The way my brain works, I think about the various distinct things that need to happen, as well as the different exceptions or edge cases within that functionality. Breaking it up into small rules allows the “rule name” string to say exactly and specifically what that rule should do, similar to what you have.

There’s really no better way to do it, just whatever feels easier and more maintainable to you. I think I might do fewer longer rules in some situations.

A couple things you might consider to make your rules easier to write and maintain:

  1. A single rule can have multiple triggers by combining them with " or ". If the exact same rule could be triggered by various items.
  2. I never loved working with timers like you have there. I always felt like there were too many places where I had to manually expire them if certain actions happened before they completed, and it was hard to keep track of. There’s a module called “expire” that you can find of you search this forum. I recommend it because it’s an easy way to have automatic timers. Basically you set an item up to have a default and give it a time limit. Every time you update that item, the timer resets. When the time you specify has passed without an update, the module I’ll automatically switch it back to its default state. Expire made my rules a lot more pleasant to write.

Hope that helps!