Hey @JimT ,
I just need your help once again.
Relating to your code example to the motion sensor lighting handling.
Sometimes it seems the rule is executed twice and I dont know why. Is there an error in the jruby layer or is the timer instantiated twice?
For your information. I have two motion sensors in this room…
2023-03-10 08:24:32.563 [INFO ] [rs.lighting_-_motion_sensor_lighting] - LIGHTS-MOTION-CONTROL: Dimm light in BZ, no presence anymore.
2023-03-10 08:24:32.633 [INFO ] [rs.lighting_-_motion_sensor_lighting] - LIGHTS-MOTION-CONTROL: Switched light in BZ to OFF, no presence anymore.
But it’s also happening in rooms with only one motion sensor
2023-03-10 07:41:50.260 [INFO ] [rs.lighting_-_motion_sensor_lighting] - LIGHTS-MOTION-CONTROL: Dimm light in F2, no presence anymore.
2023-03-10 07:41:50.264 [INFO ] [rs.lighting_-_motion_sensor_lighting] - LIGHTS-MOTION-CONTROL: Switched light in F2 to OFF, no presence anymore.
Maybe you have any idea…
Here is the code of the rule:
################################
# Lighting with motion sensors
rule "Lighting - Motion Sensor Lighting" do
changed groupMotionsensorPresences.members
run do |event|
room_code = homezone.getRoomCode(event.item.name)
room_code_item_number = homezone.getRoomCodeAndItemNumber(event.item.name)
# Escape if room is not allowed to be switched
#next unless @allowed_rooms.include? room_code
# Use "Motionsensors_" for the inside (BZ) and "Motionsensor_" for the outside (OS_1) sensors
enabled = items["Motionsensor_#{room_code_item_number}_enable"] ? items["Motionsensor_#{room_code_item_number}_enable"] :items["Motionsensors_#{room_code}_enable"]
dimmer = items["groupLight_#{room_code_item_number}_dimmers"] ? items["groupLight_#{room_code_item_number}_dimmers"] : items["groupLight_#{room_code}_dimmers"]
light = items["groupLight_#{room_code_item_number}_switches"] ? items["groupLight_#{room_code_item_number}_switches"] : items["groupLight_#{room_code}_switches"]
light_current_value = items["Motionsensor_#{room_code_item_number}_light"]&.state ? items["Motionsensor_#{room_code_item_number}_light"]&.state : items["groupMotionsensors_#{room_code}_light"]&.state
light_on_value = items["Motionsensors_#{room_code}_lightOnValue"]&.state
timer_duration = items["Motionsensors_#{room_code}_timerDuration"]&.state&.to_i&.seconds || 3.minutes
next if enabled.off? || light_current_value > light_on_value
# light.off ? (logger.info "LIGHTS-MOTION-CONTROL: Switched light in #{room_code} to ON (dimmer=#{dimmer}), presence is detected.") : nil
if dimmer != nil # For lights with dimmers (mainly used)
dimmer.state != getDimmerValue(room_code) ? dimmer.command(getDimmerValue(room_code)) : nil
else # For lights without dimmers
light.on
end
if event.state.on? || timers[room_code] != nil
timers[room_code]&.cancel # for library version 4.x
# for library version 5.x:
# timers.cancel(room_code)
next
end
after(timer_duration, id: room_code) do |timer|
presence = items["groupMotionsensors_#{room_code}_presence"] ? items["groupMotionsensors_#{room_code}_presence"]: items["Motionsensor_#{room_code_item_number}_presence"]
next if light.off? || enabled.off? || presence.on?
unless isRoomConditionFulfilled(room_code)
logger.info "LIGHTS-MOTION-CONTROL: Roomcondition NOT fulfilled."
next
end
if dimmer != nil # For lights with dimmers (mainly used)
if dimmer.state == getReducedDimmerValue(room_code)
light.off
logger.info "LIGHTS-MOTION-CONTROL: Switched light in #{room_code} to OFF, no presence anymore."
else
dimmer.command(getReducedDimmerValue(room_code))
logger.info "LIGHTS-MOTION-CONTROL: Dimm light in #{room_code}, no presence anymore."
timer.reschedule 30.seconds
end
else # For lights without dimmers
light.off
logger.info "LIGHTS-MOTION-CONTROL: Switched light in #{room_code} to OFF, no presence anymore."
end
end
end
end
def getDimmerValue(room_symbols)
if NightLightMode.on? && items["Motionsensors_#{room_symbols}_useNightlight"].on?
return DefaultDimmerValue_NightLight.state.to_i
else
case items["Motionsensors_#{room_symbols}_lightScene"]
when "relaxe"
return DefaultDimmerValue_Relaxe.state.to_i
when "normal"
return DefaultDimmerValue_Normal.state.to_i
when "bright"
return DefaultDimmerValue_Bright.state.to_i
end
end
end
def getReducedDimmerValue(room_symbols)
if NightLightMode.on? && items["Motionsensors_#{room_symbols}_useNightlight"].on?
return DefaultDimmerValue_NightLight.state.to_i
else
case items["Motionsensors_#{room_symbols}_lightScene"]
when "relaxe"
return (DefaultDimmerValue_Relaxe.state/2).to_i
when "normal"
return (DefaultDimmerValue_Normal.state/2).to_i
when "bright"
return (DefaultDimmerValue_Bright.state/2).to_i
end
end
end
def isRoomConditionFulfilled(room_symbols)
case room_symbols
when "F1"
(groupLight_WZ_switches.state == OFF) ? true : false # Sync to living room lights, switch floor lights only OFF, if they are also OFF
when "AZ"
((LaptopWork_NI_1_online.off? && Smartplug_Shelly_2_watt.state <= 55) || Motionsensor_AZ_1_light.state > 85) ? true : false
else
return true
end
end
I extended the rule to also use the motion sensors from the outside (another name pattern) and Items of type dimmer and switch. Some of my lights dont have dimmer items.
and the contentof the required lib “homezone”
def homezone
# Example of presence items: Motionsensor_BZ_1_presence or Motionsensor_OS_1_presence
def getRoomCode(item_name)
return item_name.split("_")[1]
end
def getRoomCodeAndItemNumber(item_name)
return item_name.split("_")[1].to_s + "_" + item_name.split("_")[2].to_s
end
end
I still use 4.0 library
org.openhab.automation.jrubyscripting:gems=openhab-scripting=~>4.0
Kind regards!