Simple presence anti-burgular simulation

Hi,

I am trying to create a simple presence simulation, for example when I’m out of house for vacation.

I tried to use the simple method of another user in this forum: Take the state of the lamps from the prevoius week/day and turn lights on/off like that.

My code is:

rule "ABC"
when
    Time cron "0 * * ? * *" // Every minute
then
	
	if (antitheft.state==ON) {
		gLights.members.forEach[lamp|
			lamp.sendCommand(lamp.historicState(now.minusDays(1)).state.toString)
		]
	}
end

The problem is, I get an error:

Error during the execution of rule: cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null

I have a RRD4J persist service running which tracks all items of the group lights:

gLights* : strategy = everyMinute, everyChange, restoreOnStartup

Any idea why its not working?

Add some logging and find out

gLights.members.forEach[lamp|
   logInfo("report", "Item " + lamp.name)
   logInfo("report", "historic state " + lamp.historicState(now.minusDays(1)).state.toString)
   lamp.sendCommand(lamp.historicState(now.minusDays(1)).state.toString)
]

Bear in mind historicState is going to your default db

I already set my default db to rrd4j.
The log throws me my first item in the group:

[clipse.smarthome.model.script.report] - Item InnR_ColorTemperature

And after that the same error.
I am not sure if I had plugged in the InnR yesterday at that time, is it relevant for the historic data that all items are always online?

Assuming that the OH Item itself existed, I understand that historicState should return the last valid value before the target time i.e. it assumes the state held true from the previous day or whenever.
I’m not sure what happens if you ask for an Item that didn’t exist then, or never had a valid value.

With doubts about the existence of persisted data, you should use the REST API to at least check for its existence.

We should though enhance the rule to deal with oddball cases

gLights.members.forEach[lamp|
   logInfo("report", "Item " + lamp.name)
   var hist = lamp.historicState(now.minusDays(1))
   if (hist !== null) {
      logInfo("report", "historic state " + hist.state.toString)
      lamp.sendCommand(hist.state.toString)
   } else {
      logInfo("report", "db returned null")
   }
]

Are you using an everyMinute strategy? rrd4j will not work if there is not a value saved at least every minute.

In rrd4j, you will get a null returned. If the Item didn’t exist or there are no values at or before the time period than a null should be returned no matter what DB is used.

1 Like

Why don’t you use the “build in” presence simulator? It’s based on Google Calendar and you set up the items that you want to simulate your presence. When activated it mimics your activity of 14 days ago (default setting, adjustable to ex 7 days).
More info: https://www.openhab.org/addons/integrations/gcal/#presence-simulation

There are a number of reasons why one may not want to use Google Calendar. First of all, the OP’s approach is also “built in”. I would argue it is more built in because it doesn’t depend on any bindings or third party cloud service. It just requires openHAB. The CalDav binding is quite challenging to get running correctly. And, as has been kind of already mentioned, everything is local, which can be important for some users.

In concept, both approaches are basically the same though. With the Calendar approach, events are saved to a calendar and played back. In OP’s approach, events are saved to Persistence and then played back.

I use the same kind of system and I found it useful to work with now.minusMinutes for debugging. That way you are sure there is data/changes is the behavior of your light.
Don’t forget to change back to days when your done (been there)