Virtual Presence Device

Has anybody created a virtual presence device?

I’ve been unhappy with the mobile presence performance of the smartphone app. I am currently running this python project (https://github.com/balloob/home-assistant) on my server to monitor wifi devices connected to my router. I use this to automatically set the mode to “Home” or Away" in Smartthings.

However, I think a better way to do it would be to create a virtual presence device that gets its home or away status from “Home Assistant” (or anything else for that matter). That way, I could install any of the smartapps that use presence sensors.

But, I’m a little unsure how to go about writing this device type. Logically, it seems quite simple:
The virtual device would check the python server on a schedule, process the json result, and update presence status if necessary.

I looked through the example code for Presence and Mobile Presence device types but didn’t get very far.

Any tips?

1 Like

You can add polling capabilities to a SmartThings device, but you are at the mercy of the existing infrastructure in terms of when the device will get polled. For a presence device you would probably want to get maximum reliability, as well as a minimum delay in between state changes.

I am unsure whether you can have a device schedule an event handler that it uses to query the status from your python server. Even if you could, it seems like you might want to avoid that in order to reduce the load on the ST cloud. There are restrictions in place that require you to set your scheduling intervals sufficiently large that it would make introduce a delay in presence state changes. Also, you’d have to expose your python server to the internet, as long as LAN capabilities are missing / undocumented and in beta.

You might have more luck driving it the other way around: Make the python server inform the SmartThings cloud of presence changes. In order to do that you would add custom capabilities to your virtual presence device (setAbsent, setPresent) and drive these through a SmartApp that you would have to create. In your SmartApp, create some REST endpoints, which would allow you to make HTTP requests from your python server to update the virtual presence device.

Can you add REST endpoints directly to device handlers these days? That would allow you to implement everything in the device handler, rather than using the SmartApp as a proxy. I don’t think you can do that, but maybe someone with more knowledge about this can chime in.

Either way, creating that SmartApp wouldn’t be a big deal, since your device handler would simply be a thin wrapper, whereas most of your logic would live inside the SmartApp. Additionally, this strategy gives you much more flexibility in terms of adding multiple virtual presence devices and driving them through the same SmartApp straight from the mobile app.

Thanks for the info. I guess I’ll go the smartapp route.

It would be nice if the hub could do some things locally as opposed to relying entirely on the smartthings cloud. Some very basic automation tasks would become much easier.

I’m very interested in doing the same thing @impliciter, so I would be willing to help you out with the SmartThings App, and trying to figure out the Virtual Presence Device.

How reliable is that home-assistant project?

I’ve been impressed with the home-assistant project so far although I’m really only using it to monitor wifi devices. It has a lot more going on than that. It took minutes to setup but I was already running a router with Tomato so I did not have to modify anything.

Additionally, I’m using it in a round about way. I’m running home-assistant on a windows server on which I’m using Eventghost to make the Mode changes whenever wifi device status changes. It’s a nice setup because my wife doesn’t even need the Smartthings app installed.

I supppose cleaner way to do it would be to modify the home-assistant code to fire off the HTTP GET to change the mode directly. I already run Eventghost for Infrared control among other things so no big deal.

The mode changes are pretty timely. Usually before I even make it in the house.

As to the Virtual Presence Device, I really don’t know where to start. The documentation is seriously lacking. I guess a SmartApp should be able to set the presence capability — [“present”, “not present”] of a virtual presence device.

@impliciter, you are definitely on the right track. Here is a rough overview of how I’d approach it:

  1. Create a new device handler. Give it presence capabilities. This is your virtual presence device. Your code would probably look similar to the mobile presence device handler.
  2. You would want to add some sort of identifier preference setting to your custom device handler. This setting will allow you to input an id when you later add the device. The id will map from your phone’s MAC address (or network name, or whatever information your router software gives you) to the associated presence device.
  3. Create a new smart app with a custom REST endpoint. Check out this tutorial: http://build.smartthings.com/blog/tutorial-creating-a-custom-rest-smartapp-endpoint/
  4. Give your smart app a “Presence Devices” input. This is the input that you use to tell the app which virtual presence devices it should managed.
  5. You would want to interface with at least two REST API call: /myapp/{presence_device_id}/setpresent and /myapp/{presence_device_id}/setabsent. presence_device_id is the device id from #2.
  6. The two API handlers would each iterate over all the virtual presence devices set on the input from #4, pick the one where the id (the setting from #2) matches presence_device_id, and then call device.presence = “present” or device.presence = “not present” respectively.
  7. From your python script you can call: https://graph.api.smartthings.com/api/smartapps/endpoints/xxx/myapp/{presence_device_id}/{setpresent|setabsent} respectively, when the phone with presence_device_id changes status.

EDIT: After implementing the SmartApp and device handler code. You would want to go to the web IDE and add any number of devices, using your new device handler as type. Then for each one of these devices set the presence_device_id preference to the respective MAC address or network name of the phone. Then install an instance of your newly created SmartApp, and set all the virtual presence devices you just created on the “Presence Devices” input.

1 Like

Thanks for the reply Florian.

I worked through your suggestion. The smartapp seems like it should be very simple. I started out with a single Virtual presence sensor.

preferences {
	section("Allow Endpoint to Control These Things...") {
		input "presence", "capability.presenceSensor", title: "Who?", multiple: true
	}
}

// Map endpoints to set presence
mappings {

	path("/setpresent/") {
		action: [
			GET: "setPresent"
		]
	}
	path("/setnotpresent/") {
		action: [
			GET: "setNotPresent"
		]
	}
    
}

def installed() {}

def updated() {}

// Set Present/Not Present
def setPresent() {
    presence.presence = "present"
}
def setNotPresent() {
    presence.presence = "not present"
}

When I call the setPresent or setNotPresent via the app endpoint, I get the following error:
{"error":true,"type":"java.lang.IllegalArgumentException","message":"argument type mismatch"}

I used the “Mobile Presence” device verbatim for the device type but didn’t see anything that should be changed.

Any ideas?

Thanks.

1 Like

Any progress on this?

Lots of people have done variations on it, I think the following is the most recent:

Were you looking for something specific?

Thanks for the reply.

That link looks interesting, although the OP hasn’t posted the code yet, seems like once he does it might just fit the bill.

I basically want the same thing, me and my roommates all have smart phones and I would like to track presence via WiFi connectivity. I have a router running Tomato and I’ve gotten “Home-Assistant” tracking presence, just looking to add that functionality to Smartthings

Ok, you made me post it :smile: - if you have something running already determining the presence from the router, you just need to push that status into a REST endpoint so it can update the “presence device” in ST. That’s most of the ugly code - the rest is fairly simple.

1 Like

I wrote a guide to what I ended up with. I used ‘Home Assistant’ for a while with a veralite. When I moved back to Smartthings I setup my router to do the detection. The router script I’m using could use some work. Specifically, I continually sets the virtual presence device instead of only setting on a changed condition. See link:
Wifi Presence Sensor

1 Like

Based on the rest of the thread, it sounds like you might be looking for a router based solution, but I wanted to add that if you are running Android on your mobile devices, you can use Tasker to build a custom presence solution:

In the example, I use WiFi connectivity to determine presence, but I would recommend a multi-faceted location solution like AutoLocation if you want a bit better accuracy. If you end up going with WiFi, you may have to put some sort of exit delay in place to prevent false exits if the phone temporarily loses WiFi connectivity.

1 Like

:arrow_up:️ This is the biggest problem with any presence indicator based on mobile phones. They get turned off. Or are still on but drop connectivity.

The idea of devices like the zigbee fob is that they’re always on and do nothing but broadcast so theoretically if there’s no local interference they should provide a more consistent presence indication than a phone.

I’m using iBeacons at my house, but I found I got the best results for presence indication if I used a plugged in tablet as my listening device and put the iBeacon in the car or the person’s backpack. So the iBeacon comes and goes with the person, the listener device stays home as a base station.

I also use transitional modes rather than just time outs. But that becomes exponentially more complex when you’re trying to track multiple people, so not useful for many families.

It really just comes down to what works at your house. :blush:. As @joshua_lyon
says, plan ahead for what happens when someone reboots their phone.

I think it would be cool to create a virtual presence device type that COMBINES various aspects of other presence techniques.

  • Life360
  • Wifi/MAC
  • Code Entry on lock
  • Continued in-home activity after unlocking/arrival
  • Track BT via beacon.

That way you have a single, reliable presence for each person.

I have technologically-inept roommates… One of them has an Android phone and was easily able to set up Life360 to work PERFECTLY… 100% reliable. He knows that he should leave Wi-Fi or at least mobile data running.

However, my other two roommates have iPhones, and it was worse than pulling teeth to help them get the app installed and configured. Explaining to them basics like, having Wi-Fi on, or mobile data was excruciating at best. Worst part is, they still keep disabling one or both, which severely limits my ability to track home vs. away.

I cannot explain why the Apple users tend to disable Wi-Fi and/or Mobile Data, but I know that they typically re-enable the Wi-Fi when they’re home for a bit. Currently, with the Life360 implementation, this means that when they leave, they appear to be home 24/7. If I made it so on-wifi-disconnect, the overall presence of that person was marked AWAY, assuming all others also showed that, I’d be in heaven.

Eventually they’d learn to leave Wi-Fi on while at home, but right now I’ve got a dangerous false-positive of them being home, therefore preventing my security system from arming.

1 Like

I wrote a device type that allows you to control presence by a switch. I’m using it with the Tasker (android) app to use WiFi as presence. I’ll publish it this evening.

ah so then you’d have to write a smartapp to combine the other presence types to trigger that same switch?

Here you go!

Can I ask what you are doing with tasker to detect the presence of other devices on wifi?

Is this directed at someone specific? I don’t recall anyone in this thread using Tasker to detect other devices on the same WiFi network, although it could be done.