Hello guys!
For this second automation, I have a selected one that uses timers to determine the absence of movement (using a motion sensor) in a particular room. Like in my previous post I will share the implementation in the Rules DSL and Jython of this automation.
This solution is not final or complete but can help new members to start with OpenHAB (at least that’s my objective
). It is based on all feedback and solutions shared by members of the community to my questions in this forum.
Automation #2 Bathroom Smart Light
Turn on the light of the bathroom if a movement is detected and the ambient light is less than 40 lux.
Turn off light of the bathroom after two minutes without detecting any movement.
Items
Switch Bathroom_Lamp { channel="mqtt:topic:MyBroker:Home:Light2"}
Switch Bathroom_Motion { channel="mqtt:topic:MyBroker:Home:Motion3"}
Number Bathroom_AmbientLight { channel="mqtt:topic:MyBroker:Home:AmbientLight2"}
Switch Bathroom_MotionTimer { expire="2m,command=OFF" }
Rules DSL Implementation
rule "(DSL) Bathroom MotionSensor changed"
when
Item Bathroom_Motion received update ON
then
val ambientLight= (Bathroom_AmbientLight.state as DecimalType).intValue()
if(ambientLight <= 40 && Bathroom_Lamp.state == OFF ) {
// Turning ON Bathroom Lamp
Bathroom_Lamp.sendCommand(ON)
// Start/Reset timer
Bathroom_MotionTimer.sendCommand(ON)
} else if( Bathroom_Lamp.state == ON ) {
Bathroom_MotionTimer.sendCommand(ON)
}
end
rule "Timer expired for Bathroom Motion Sensor"
when
Item Bathroom_MotionTimer received command OFF
then
// Timer expired, turning off the light
Bathroom_Lamp.sendCommand(OFF)
end
Jython implementation
from core.rules import rule
from core.triggers import when
from core.actions import ScriptExecution as SE
from org.joda.time import DateTime as DT
import core
timer = None
def set_timer():
global timer
if timer is None or timer.hasTerminated():
#Start new timer
timer = SE.createTimer(DT.now().plusMinutes(2), lambda: events.sendCommand("Bathroom_Lamp", "OFF"))
else:
#Reschedule timer
timer.reschedule(DT.now().plusMinutes(2))
@rule("(Py) Bathroom MotionSensor changed")
@when("Item Bathroom_Motion received update ON")
def bathroom_motion(event):
if items.Bathroom_AmbientLight.intValue() <= 40 and items.Bathroom_Lamp == OFF:
# Turning ON Bathroom Lamp
events.sendCommand("Bathroom_Lamp", "ON")
set_timer()
elif items.Bathroom_Lamp == ON:
# Light already ON, reset timer
set_timer()
In the Jython solution, I use a helper function called set_timer to start or restart the timer that will turn OFF the lamp after two minutes without no motion detected.
Happy coding!
Humberto
Note:
- In the Jython solution I’m using the deprecated Joda library. I’m using Joda’s DateTime instead of Java’s ZonedDateTime because of the ScriptExecution.createTimer requires as first argument an org.joda.time.base.AbstractInstant. Maybe, I can update this code and use plain Python timers.
- Suggestions or recommendations to improve the implementation are welcome!
- Do you have more complex automations that shares the same logic of this example? Please share it
Other automation examples
- Automation #1: Doorbell notification
- Automation #3: Smart Radiator
- Automation #4: Smart Radiator (Generic Rule)
- Automation #5: Window Alert
- Automation #6: Boiler Failure Alert
- Automation #7: Detect a particular sequence of events
Related Posts