Simulate presence by randomly switching lights - any rules existing?

All,

I am looking for a rule to randomly switch lights in the evenings to simulate presence.
In the timeframe between sunset and e.g. 11 pm check a random value and in case of … switch on a light for n minutes, with n between 10 to 30 minutes randomly. And repeat that again and again until 11 pm.

Any idea or rule already available ?

Thanks in advance

1 Like

Hi Dirk,

This is how I do it:

items:

Group Lights_Random

rules:

var Timer tRandomLights = null

rule "Randomly turn on & off lights between 07.00-23.00 if before or after sunset and if alarm is activated"
	when
		Time cron "0 */10 7-23 * * ?"
	then
		if ((AlarmMode.state == 2) && (now.isBefore((Sunrise_Time.state as DateTimeType).calendar.timeInMillis) || now.isAfter((Sunset_Time.state as DateTimeType).calendar.timeInMillis))) {

			// Only turn a light on/off ocasionally
		 	if ((new java.util.Random).nextInt(2) == 1) { 
		 	
		 		// Create a timer with a random value
				var int randomTime = (new java.util.Random).nextInt(300)
				logInfo("org.openhab","Setting random lights timer to " + randomTime + " seconds.")
				tRandomLights = createTimer(now.plusSeconds(randomTime)) [|
					var randLightIndex = (new java.util.Random).nextInt(Lights_Random.members.size)
			 		var randLightStateCurrent = Lights_Random.members.get(randLightIndex).state
			 		var randLightStateNew = if (randLightStateCurrent == ON) OFF else ON
			 		logInfo("org.openhab","Switching light " + Lights_Random.members.get(randLightIndex).name + " from " + randLightStateCurrent + " to " + randLightStateNew)
			 		sendCommand(Lights_Random.members.get(randLightIndex), randLightStateNew)
		        ]
			}
		}
end

rule "Turn all lights off at 23.10 if alarm is activated"
	when
		Time cron "0 10 23 * * ?"
	then
		if (AlarmMode.state == 2) {
		 	logInfo("org.openhab","Turning all the random lights off.")
		 	sendCommand(Lights_Random, OFF)
		}
end

Hope it helps :smile: Let me know if you have any questions.

19 Likes

It just works. Better then expected. Thanks very much :grinning:

Glad I could help :smile:

Hi Andreas,

may bee that your scipt work for me - too. But i get an error on “Sunrise_time”.

Thank you
Hubertus

Ah right. You need to install the Astro binding:

And these are the items needed in your items file:

DateTime Sunrise_Time   	"Sunrise [%1$tH:%1$tM]"		{astro="planet=sun, type=rise, property=end"}
DateTime Sunset_Time   		"Sunset [%1$tH:%1$tM]"		{astro="planet=sun, type=set, property=start"}

Thanks, i had installed Astro befor - only the itmes where named : Sonnenaufgang and SonnenUntergang. So i changed the script and … it works fine. Great job!

Hi Andreas,

some off my lights are connected to dimmers. They have no ON / OFF, only “0” for OFF or 1-100 (as percent) for ON. So i modified your rule:

from:
var randLightStateCurrent = Lights_Random.members.get(randLightIndex).state
var randLightStateNew = if (randLightStateCurrent == ON) OFF else ON

to:
var randLightStateCurrent = Lights_Random.members.get(randLightIndex).state
// Dimmers “0” = OFF
if randLightStateCurrent == 0 randLightStateCurrent = OFF
// changed to !=OFF so all values from 1-100 are seen as ON
var randLightStateNew = if (randLightStateCurrent != OFF) OFF else ON

One more question:

if the rule switch some lights on and the the sun rise up … the lights went on until sun down?

BR
Hubertus

I just implemented this rule and I am getting a very lengthy error message upon execution and don’t know where to start. Do I have a JAR missing, or some binding, or ??? Here is the start of the error:

2016-03-04 06:20:00.010 [ERROR] [.o.m.r.i.engine.ExecuteRuleJob] - Error during the execution of rule Randomly turn on & off lights between 05.00-23.00 if before or after sunset and if alarm is activated java.lang.ClassCastException: Cannot cast org.openhab.core.types.UnDefType to org.openhab.core.library.types.DateTimeType at java.lang.Class.cast(Unknown Source) ~[na:1.8.0_73] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._evaluateCastedExpression(XbaseInterpreter.java:386) ~[na:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_73] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_73] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_73]

[RESOLVED] - My Sunrise and Sunset times were null because they hadn’t refreshed for some reason.

Thanks for the help.

Hello!

Here’s the way I’ve been using OpenHAB for anti-burglar lights:

  • First, I have two items for the sunrise (General_Sunrise_State) and the sunset (General_Sunset_State), and two global timer variables:

    var Timer GeneralAntiBurglarLightsTimer
    var Timer GeneralAntiBurglarLightsOffTimer

  • Using two rules, I change the state of the General_Night_State:

rule "General - Sunrise - State"
when
   Item General_Sunrise_State changed to ON
then
   sendCommand(General_Night_State, OFF)
end

rule "General - Sunset - State"
when
   Item General_Sunset_State changed to ON
then
   sendCommand(General_Night_State, ON)
end
  • Besides that, I have alarm state item (General_Alarm_State) with 4 values:
    0) Off
    1. Home
    2. Short-term away
    3. Long-term away (used for anti-burglar lights),

and Alarm_Detection_State (value set to 1, one minute after an item General_Alarm_State received values 2 or 3)

After setting all this up, there are two rules - one for turning the lights on/off at a semi-random interval (when all the conditions are met), and one for turning a random lights timer off (at specific time of a day, with random offset)

First rule, for turning lights on/off (60% chance of turning light on, 40% chance of turning light - semi-random interval between 5 and 60 minutes):

rule "General - Night - State"
when
   Item General_Night_State received update
then
   if ((General_Night_State.state == ON) && (General_Alarm_State.state == 3) && (General_Alarm_Detection_State.state == 1)) {
   	  var Integer RandomInterval = (Math::floor((Math::random * (60 - 5) + 5).doubleValue).intValue)
   	  
   	  GeneralAntiBurglarLightsTimer = createTimer(now.plusMinutes(RandomInterval)) [|
   	     Dimmers?.members.forEach(dimmer|
   	        sendCommand(dimmer, if(Math::random > 0.6) 0 else 100))
   	        
         postUpdate(General_Night_State, ON)
      ]
   } 
   
   if ((General_Night_State.state == OFF) && (General_Alarm_State.state == 3) && (General_Alarm_Detection_State.state == 1)) {
      if(GeneralAntiBurglarLightsTimer != null) {
         GeneralAntiBurglarLightsTimer.cancel
         GeneralAntiBurglarLightsTimer = null
      }      	
      
      sendCommand(Dimmers, 0)
   }
end

You can change minimum and maximum interval values in this part of code (5 minutes minimum, 60 minutes maximum):
Math::floor((Math::random * (60 - 5) + 5).doubleValue

Percentage of on/off ratio could be changed here (> 0.6 meaning 60% chance for on, 40% chance for off):
Math::random > 0.6

Second rule uses cron expressions as trigger for turning anti-burglar lights off (with 5-30 minutes random offset):

rule "General - Anti-burglar - Disarm"
when
   Time cron "0 0 1 ? * MON-FRI *" or
   Time cron "0 0 3 ? * SAT *" or
   Time cron "0 30 0 ? * SUN *"
then
   if ((General_Alarm_State == 3) && (General_Alarm_Detection_State == 1)) {
   	  if (GeneralAntiBurglarLightsTimer != null) {
         GeneralAntiBurglarLightsTimer.cancel
         GeneralAntiBurglarLightsTimer = null
   	  }
   	  
   	  var Integer RandomInterval = (Math::floor((Math::random * (30 - 5) + 5).doubleValue).intValue)
   	  
   	  GeneralAntiBurglarLightsOffTimer = createTimer(now.plusMinutes(RandomInterval)) [|
   	     sendCommand(Dimmers, 0)
   	  ]
   }
end

You can change offset (set randomly between 5 and 30 minutes) here:
Math::floor((Math::random * (30 - 5) + 5).doubleValue

This is just my way of dealing with this, but maybe someone will find it useful.

Best regards,
Davor

1 Like

Thank what seems like a great concept but…
My lights (mostly dimmers) are still not working.
Perhaps they can’t be turned ON/OFF but instead need 0 or 100?

I don’t get errrors in logger but all dimmers that are logged, such as:
UpdstairsHall got command ON
never turn on.

Hello!

Were you using @anordvall or my example? If you were using mine, you could split your lights into two groups (Switches and Dimmers), and then adapt the part of the code that sends a command to use ON/OFF for switches and 0/100 for dimmers.

     Dimmers?.members.forEach(dimmer|
        sendCommand(dimmer, if(Math::random > 0.6) 0 else 100))

At this part of the code, you could just add:

     Switches?.members.forEach(switch|
        sendCommand(switch, if(Math::random > 0.6) OFF else ON))

This implies you have 2 groups named Switches and Dimmers, and you’ve assigned a switch and a dimmer items to those groups respectively.

Best regards,
Davor

@davorf

Could you explain you determine your “short term away” and your “long term away” items? I really like that feature and would love to implement it.

Thanks.

Hello!

Not sure if this is the thing you’ve asked about, but this is what each alarm mode does:

  • Off - pretty self-explanatory :slight_smile:
  • Home - After switching it on, it’s active instantaneously; It reacts only on door/window sensors, ignores motion sensors, and sounds an alarm instantaneously if door/window sensor changes from CLOSE to OPEN
  • Away (Short-term) - After switching it on, it activates one minute after changing General_Alarm_State item (so you have time to leave home without activating alarm); It reacts on both, door/window sensors and motion sensors; After activating, it turns all the lights off; If door/window or motion sensors are activated and it’s past sunset, it turns some lights on; If door/window or motion sensors are activated it waits for a minute (so you have time to deactivate it), and then sounds an alarm
  • Away (Long-term) - Behaves the same as Short-term, but it activates presence simulator (turning lights on/off at semi-random interval) after sunset, and deactivates presence simulator at dedicated time (semi-random time between 0:30 and 3:00, depending on the day of the week and a random additional time - 5 to 30 minutes)

All 3 modes (except off) check if the doors/windows are open in the moment of the activation (home mode instantaneously, other two after they get activated - one minute after turning it on), and send a notification if something is open after activating, so you don’t leave your doors/windows open.

I hope this explanation helps you implementing it.

Best regards,
Davor

That does answer some questions, but I do have one still remaining.

Are your short-term and long-term alarm states activated by different codes/switches? Or do you designate a long-term by the time elapsed since you set the alarm?

For example:

Set X = 1200 (minutes)
Alarm.sendcommand(“Arm”)
Start alarm_timer

when alarm_timer <= X
then alarm_type = 'short-term’
else alarm_type = ‘long-term’

Hello!

No, it’s just the name of the alarm mode. I choose the type of the alarm with Selection widget (although there are some other ways to set it too - NFC for short-term away alarm and turning all alarms off, Night mode for Home alarm etc). But I start the long-term away alarm by explicitly choosing it from the selection widget.

Best regards,
Davor

Perhaps I’m trying to make this harder then it should be but I’d like to do something slightly different which I’m having trouble working out. I’d like to have a variable that is assigned a random time each morning at 12:05am such that the random time is between the astro binding of civilDusk and 11pm. Then I’d like to assign that variable to a text item so I can display it in the sitemap so I can check each day the random time. Then I’d like to rules file to run a rule each day that the current time matches the random time which then turns on lights. Your code helps me think through how I might do that and the alarmmode idea is a good one I didn’t think of so I can turn this function on and off with the app.

However, I’m having trouble working through the first 2 steps of this:

  • create a random time - the util.random shows up several times in your code so I’m not sure what I should be using to just create a random time I can use to compare to [now] (see below)

  • set up the rule to fire when now = my random time, would it be:
    when
    Time now = myrandomtimevariable

Hi Everyone,

I’m trying to use a modified version of the rule in openhab2, but I’m not having much luck.
Only thing I see in the log is "Configuration model ‘randomlights.rules’ is either empty or cannot be parsed correctly!"
Can anyone see a problem with this?

var Timer tRandomLights = null

rule "Randomly turn on & off lights between 16.00-23.00 if after sunset and nobody is home"
	when
		Time cron "0 0/5 16-23 * * ?"
	then
		if ((Presence.state == OFF) && (now.isBefore((LocalSun_Rise.state as DateTimeType).calendar.timeInMillis) || now.isAfter((LocalSun_Set.state as DateTimeType).calendar.timeInMillis))) {

			// Only turn a light on/off ocasionally
		 	if ((new java.util.Random).nextInt(2) == 1) { 
		 	
		 		// Create a timer with a random value
				var int randomTime = (new java.util.Random).nextInt(300)
				logInfo("org.openhab","Setting random lights timer to " + randomTime + " seconds.")
				tRandomLights = createTimer(now.plusSeconds(randomTime), [|
					var randLightIndex = (new java.util.Random).nextInt(RandomLights.members.size)
			 		var randLightStateCurrent = RandomLights.members.get(randLightIndex).state
			 		var randLightStateNew = if (randLightStateCurrent == ON) OFF else ON
			 		logInfo("org.openhab","Switching light " + RandomLights.members.get(randLightIndex).name + " from " + randLightStateCurrent + " to " + randLightStateNew)
			 		sendCommand(RandomLights.members.get(randLightIndex), randLightStateNew)
		        ])
			}
		}
end

rule "Turn all random lights off at 23.10 if nobody is home"
	when
		Time cron "0 10 23 * * ?"
	then
		if (Presence.state == OFF) {
		 	logInfo("org.openhab","Turning all the random lights off.")
		 	sendCommand(RandomLights, OFF)
		}
end

Regards,
Josh

Does there not follow a Loading model 'xyz.rules'?

2017-05-28 17:15:05.313 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'xyz.rules'
2017-05-28 17:15:05.336 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'xyz.rules' is either empty or cannot be parsed correctly!
2017-05-28 17:15:38.795 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'xyz.rules'

I’m seeing this very often and all the rules are loading without any problems after that WARN message.