Presence Simulation

Hi

Is there any alternative to GCAL to record how lights are changed and use it for presence simulation.

/Mike

1 Like

I’m not sure what exactly you are asking but I think what you want is to control your lights based on whether you are home or not without using the GCAL binding.

I do just this in my setup. I detect presence using Bluetooth and a custom script that detects when devices with a certain address are nearby and posts its presence to openHAB over MQTT. I also use the Network Health binding to detect whether certain IP addresses are active on the LAN. I assigned static IPs to both my and my wife’s phone so between the two I’m able to pretty reliably tell when one or the other of us are home.

For lighting I have one set of rules to set switches for time of day states (e.g. night, morning, day, evening) and another set of rules which check both the presence switches and time of day switches to determine their behavior.

All that being said, if I wanted to simulate presence for testing, I would add another Switch Item into the mix used to calculate presence and drop that Switch onto my sitemap so I could change the Presence state manually.

1 Like

Hi @rlkoshak

I already have presence detection from my DD-WRT Router.

But what I want is presence simulation like the GCAL binding that records every change of the light when we are home and then replay it when we are away.

This create a more realistic behavior than fixed schedules or randomized.

/Mike

Ah, that is something else entirely.

There is nothing built in to openHAB to let you do that. However, I can think of a few ways to implement it.

The first way that comes to mind is to set up persistence so all your state changes are saved to the database. Also, put your Lights into a group (lets call it gLights for this example). Then have a rule that runs on a cron trigger, lets say every five minutes, that only does something if you are away. This rule will loop through all of the members of gLights and set its state to whatever it was set to 24 hours ago.

You can customize as desired.

rule "Simulate lights"
when
    Time cron "0 0/5 * * * ?"
then
    if(Presence.state != ON){
        gLights.members.forEach[light | light.sendCommand(light.historicState(now.minusHours(24)).state)]
    }
end

NOTE: I just typed this in. You might need to monkey around with the call to historicState to get the right value out of it. There are also surely some typos.

8 Likes

Hi @rlkoshak

I do store every event in an SQL Database and have all Lights in a group called Lights :smile:

I like your suggestion and will play around with it.

/Mike

Great idea. You could add a days variable to control how many days in the past to go back to, like 7 for a weekly routine.

...then
    var int days = 7
    if(Presence.state != ON){
        gLights.members.forEach[light | light.sendCommand(light.historicState(now.minusDays(days)).state)]
    }
end
2 Likes

This is brilliant, would be a much better solution to what I was eventually planning on doing.

one silly question, is the historic state stored in log? i have turned logging off and wondering if I need to turn that back on.

historicState is stored in what ever persistence provider you have configured. See the Persistence wiki page for details on which ones are supported and how to configure them.

The tl;dr is that openHAB will save the values of your Items into a database and historicState queries that database for the past values.

Thanks Rich.

Added persistence to the list of things to learn more about. :smile:

Hi

I am implementing this.
Can I have some help to change the script so it just send the command if the state is different.

/Mike

var newState = //something
if(MyItem.state != newState) {
    // do stuff
}

@rlkoshak

How do i use that in the forEach loop?

/mike

val newState = // something
MyGroup.members.forEach[item |
    if(item.state != newState {
        // do stuff
    }
]

You can only reference final variables from a forEach. Declaring newState as a val instead of var does that. However, final means that once it is assigned you cannot change newState.

All,
I am trying to implement this but seem to have (simple?) syntax problems:
I get:
Incompatible types. Expected java.lang.String but was org.openhab.core.types.State
for
G_Lights.members.forEach[light | light.sendCommand(light.historicState(now.minusDays(days)).state)]

What am I missing to transform string into state!?

Not sure why it’s not working, but try adding .toString:

G_Lights.members.forEach[light | light.sendCommand(light.historicState(now.minusDays(days)).state.toString)]
1 Like

Thanks!
The error is gone. now I need to check fucntionality. :slightly_smiling:

1 Like

Hi, could you tell me how you do presence detection with dd-wrt?

I’m using Owntracks, wich is great, but never hurts to add another source.

Thanks

/mike

Resurrecting this thread (I also moved it to the Scripts & Rules category :)) to ask some simple “technical” questions (for me to understand better the state stuff):

Why do I have to use state.toString in the following rule:

var int days = 7

rule "Simulate Lights on Vacation"
when
        Time cron "0 0/5 * * * ?"
then
        if (Vacation_Mode.state == ON) {
                gGF_Lights?.members.forEach[item |
                        logInfo("Vacation",item + " got " + item.historicState(now.minusDays(days)).state)
                        item.sendCommand(item.historicState(now.minusDays(days)).state.toString)
                ]
        }
end

The above rule works fine (with .state.toString). It cycles through all (21) members of the gGF_Lights group and “replays” the state from 1 week behind (stored in my default persistence = mapdb)

Without .toString in the sendCommand line, I get:

2017-07-14 11:05:00.144 [INFO ] [ipse.smarthome.model.script.Vacation] - P03_Wh_Light (Type=SwitchItem, State=OFF, Label=P03 Wh. Light, Category=switch, Groups=[gGF_P03_Warehouse, gGF_Lights, gKNX]) got OFF
2017-07-14 11:05:00.145 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule Simulate Lights on Vacation: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null

Interestingly enough, the logInfo entry displays past week’s state without adding .toString :slight_smile: (but it adds alot of not needed info for the item (like Type= etc)… is there a way to filter those out?)

Ps: Also, should I use: gGF_Lights?.members.forEach or gGF_Lights.members.forEach in my rule? (I think that with and/or without the question mark, it works)

Ps2: Another type of question here: The rule fires every 5 mins. Is there a way to “enable” such rule only when I flick to “Vacation_Mode” switch to ON? Meaning that the when trigger condition would change to Item Vacation_Mode changed from OFF to ON… afterwards… maybe find a way to run the cron job.
I am just thinking to avoid the recurrent execution of the rule when I don’t really need it.

Ps3: OH 2.2.0 Snapshot Build #985

Ps4: Thanx to @rlkoshak & @watou for the examples they provided in this thread. I build my rule based on their inputs.

I found 1 answer :slight_smile:

and enhanced a bit the rule (added a small delay timer between each command to avoid spamming the KNX Bus):

var int days = 7

rule "Simulate Lights on Vacation"
when
	Time cron "0 0/5 * * * ?"
then
	if (Vacation_Mode.state == ON) {
		gGF_Lights.members.forEach(light,i |
			createTimer(now.plusMillis(i*50)) [|
			logInfo("Vacation",light + " got " + light.historicState(now.minusDays(days)).state)
			light.sendCommand(light.historicState(now.minusDays(days)).state.toString)
			]
		)
	}
end
Previous rule result:
2017-07-14 13:55:00.001 [ItemCommandEvent          ] - Item 'P03_Wh_Light' received command OFF
2017-07-14 13:55:00.002 [ItemCommandEvent          ] - Item 'P04_LED' received command OFF
2017-07-14 13:55:00.003 [ItemCommandEvent          ] - Item 'P04_Mirror' received command OFF
2017-07-14 13:55:00.003 [ItemCommandEvent          ] - Item 'P05_Light' received command OFF
2017-07-14 13:55:00.004 [ItemCommandEvent          ] - Item 'P06_Large_LED' received command OFF
2017-07-14 13:55:00.005 [ItemCommandEvent          ] - Item 'P06_Small_LED' received command OFF
2017-07-14 13:55:00.005 [ItemCommandEvent          ] - Item 'P07_Large_LED' received command OFF
2017-07-14 13:55:00.009 [ItemCommandEvent          ] - Item 'P07_Small_LED' received command OFF
2017-07-14 13:55:00.009 [ItemCommandEvent          ] - Item 'P08_LED' received command OFF
2017-07-14 13:55:00.010 [ItemCommandEvent          ] - Item 'P08_Ventilator' received command ON
2017-07-14 13:55:00.010 [ItemCommandEvent          ] - Item 'P08_Light' received command OFF
2017-07-14 13:55:00.013 [ItemCommandEvent          ] - Item 'P08_Terrace_Large_LED' received command OFF
2017-07-14 13:55:00.013 [ItemCommandEvent          ] - Item 'P08_Terrace_Small_LED' received command OFF
2017-07-14 13:55:00.013 [ItemCommandEvent          ] - Item 'P09_Light' received command OFF
2017-07-14 13:55:00.014 [ItemCommandEvent          ] - Item 'P10_Light' received command OFF
2017-07-14 13:55:00.016 [ItemCommandEvent          ] - Item 'P11_Small_LED' received command OFF
2017-07-14 13:55:00.016 [ItemCommandEvent          ] - Item 'P11_Large_LED' received command OFF
2017-07-14 13:55:00.019 [ItemCommandEvent          ] - Item 'P11_Light' received command OFF
2017-07-14 13:55:00.020 [ItemCommandEvent          ] - Item 'P11_Terrace_Light' received command OFF
2017-07-14 13:55:00.021 [ItemCommandEvent          ] - Item 'P01_Exterior_Light' received command OFF
2017-07-14 13:55:00.021 [ItemCommandEvent          ] - Item 'mP3_03_01_O' received command OFF
New, with small delay result:
2017-07-14 14:00:00.079 [ItemCommandEvent          ] - Item 'P03_Wh_Light' received command OFF
2017-07-14 14:00:00.129 [ItemCommandEvent          ] - Item 'P04_LED' received command OFF
2017-07-14 14:00:00.180 [ItemCommandEvent          ] - Item 'P04_Mirror' received command OFF
2017-07-14 14:00:00.233 [ItemCommandEvent          ] - Item 'P05_Light' received command OFF
2017-07-14 14:00:00.283 [ItemCommandEvent          ] - Item 'P06_Large_LED' received command OFF
2017-07-14 14:00:00.336 [ItemCommandEvent          ] - Item 'P06_Small_LED' received command OFF
2017-07-14 14:00:00.385 [ItemCommandEvent          ] - Item 'P07_Large_LED' received command OFF
2017-07-14 14:00:00.434 [ItemCommandEvent          ] - Item 'P07_Small_LED' received command OFF
2017-07-14 14:00:00.486 [ItemCommandEvent          ] - Item 'P08_LED' received command OFF
2017-07-14 14:00:00.537 [ItemCommandEvent          ] - Item 'P08_Ventilator' received command ON
2017-07-14 14:00:00.588 [ItemCommandEvent          ] - Item 'P08_Light' received command OFF
2017-07-14 14:00:00.636 [ItemCommandEvent          ] - Item 'P08_Terrace_Large_LED' received command OFF
2017-07-14 14:00:00.687 [ItemCommandEvent          ] - Item 'P08_Terrace_Small_LED' received command OFF
2017-07-14 14:00:00.738 [ItemCommandEvent          ] - Item 'P09_Light' received command OFF
2017-07-14 14:00:00.789 [ItemCommandEvent          ] - Item 'P10_Light' received command OFF
2017-07-14 14:00:00.842 [ItemCommandEvent          ] - Item 'P11_Small_LED' received command OFF
2017-07-14 14:00:00.898 [ItemCommandEvent          ] - Item 'P11_Large_LED' received command OFF
2017-07-14 14:00:00.949 [ItemCommandEvent          ] - Item 'P11_Light' received command OFF
2017-07-14 14:00:01.000 [ItemCommandEvent          ] - Item 'P11_Terrace_Light' received command OFF
2017-07-14 14:00:01.050 [ItemCommandEvent          ] - Item 'P01_Exterior_Light' received command OFF
2017-07-14 14:00:01.102 [ItemCommandEvent          ] - Item 'mP3_03_01_O' received command OFF

Unbelievable accuracy… I am in love with my openHAB system :slight_smile:
21 commands send within 21 milliseconds (first version without the delay)
21 commands send within 21*(1+50)=1071ms (second version with the 50ms delay between them)