If you are not dead set on using Python, take a look at JRuby
It is super simple to handle your requirement of “turn on a light for X minutes when motion was detected, and if more motion was detected before X expired, extend that timer for a further X minutes, so the light doesn’t turn off on you while you’re still moving around”.
Here are three “simple” versions that would do exactly what you want:
# A Simple rule for one sensor and one light
rule "Turn on kitchen light for 5 minutes when motion is detected" do
changed Kitchen_Motion_Sensor, to: OPEN
run do
Kitchen_Light.ensure.on for: 5.minutes
end
end
# A generic rule that applies to any motion sensors that belongs to a group
# by using a pattern in the naming convention: XXX_Motion_Sensor controls XXX_Light
rule "Turn on light for 5 minutes when motion is detected" do
changed gMotionSensors.members, to: OPEN
run do |event|
light = event.item.name.gsub("_Motion_Sensor", "_Light")
light&.ensure&.on for: 5.minutes
end
end
# A rule that takes advantage of the semantic model.
# This frees you up from having to have a specific naming convention
# Automatically find all the lights in the same room as the motion sensor
# further filters can be applied to select only certain types of lights if desired
rule "Turn on light in the room where motion is detected" do
changed gMotionSensors.members, to: OPEN
run do |event|
event.item.location
.equipments(Semantics::Lightbulb).members
.points(Semantics::Power)
.ensure.on for: 5.minutes
end
end
You can copy paste what’s inside run do ... end
into a UI rule if you prefer using UI rules. The “magic” happens inside for: 5.minutes
. To read more about this particular feature, see: Module: OpenHAB::DSL::Items::TimedCommand — openHAB JRuby
There are many other ways to achieve what you want.
For a more advanced usage, I wrote a small helper “Motion Trigger DSL” on top of JRuby for my own needs so that I can have:
- multiple motion sensors “working” for the same set of lights, or multiple sets of lights, e.g. sensors A, B, C will activate lights 1 and 2, sensors C or D, will activate light 3. This means sensor C will activate lights 1, 2, 3, but sensors A and B only activate lights 1, 2.
- keep track of manual activations (turned on at the wall) as well as motion triggered,
- not start a “motion timer” when I manually switched on the light (e.g. for a much longer “timeout”)
- debounce it (prevent the light from switching back on immediately when I manually switched it off and moved out of the room),
- optionally, automatically turn off the light when I’ve manually turned it on (not through motion).
- Make it dead simple to add more motion trigger rules, or tweak existing ones
With JRuby you can also easily have a rule that alerts you when a door or window is left open for X number of minutes, and continues to do so until the door is closed
def alert_when_open(item)
message = "Warning, the #{item.label} is #{item.state}"
Amazon_Echo_TTS.command message
notify message # Send notification to mobile app
end
rule "Alert when something stays on/open" do
changed Garage_Door, to: OPEN # A single door
changed Bedroom_Window, to: OPEN # Another item
changed BathRoom_Light, to: ON
changed gAlertWhenOpen.members, to: OPEN # A whole group of sensors
run do |event|
# Do something here when it first opened
after(15.minutes, id: event.item) do |timer|
next unless [OPEN, ON].include?(event.item.state) # it's no longer open/on
# here you can do what you want when it's been open for 15 minutes
# e.g. call a method, or just do it right in here
alert_when_open(event.item)
timer.reschedule unless timer.cancelled?
end
end
end
You can also copy paste this rule body (inside run do .... end
) into a UI rule.
The customisation possibilities are endless, e.g. you can very easily make it so the alert duration is customisable for each item