Getting device object from an event


(www.rboyapps.com - Make your home your butler!) #1

I have an app in which I select multiple motion sensors and subscribe to events.
The issue is once I the event handler is called I’m trying to find out which device generated the event then call a custom handler on the device.

so according to the docs

event.device

should return the device object, hence I should call

event.device.customHandler()

to call my handler. When I’m debugging it, I can see $event.device shows the name of the device, however when it does event.device.customHandler() I’m getting a null object exception.

What am I missing here? Isn’t the event.device a device object on which I can call the handler?
The work around is to get the event.deviceId and then match that with the list of devices selected, which is kinda roundabout.


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #2

Your syntax looks right to me, but some SmartApps are convoluted, so it’s hard to find a live example.

If you have the patience, take a guess as to any SmartApps which may do something like this and see if how they are doing it.

For example, Button Controller looks up the Device List from the preference Map, and then has no problem calling device.command. … But I guess that’s pretty much the “roundabout” solution you mention in the last line of your post. Hmmm.

I’m just wondering if there is an object reference error (Device vs. Device ID), so lots of debugging output might be necessary to confirm the behavior.

I’m also assuming you’ve tested a simple case of “device.customHandler()” so that you know that Device Type Command is working fine for a direct reference?


(Mike Maxwell) #3

It’s not too bad if you use find:

//get the dimmer that's been turned on
def dimmer = dimmers.find{it.id == evt.deviceId}

(www.rboyapps.com - Make your home your butler!) #4

Thanks, yes I did end up doing that, but I’m curious as to why evt.device doesn’t work to retrieve the device object.

finally I’m using (which works)

stuff.find{evt.deviceId == it.id}.customHandler()

@urman @duncan - any thoughts on the above as why evt.device.customHandler() doesn’t work?


(John S) #5

It sure seems like it should have the device in there.

Have you tried putting it in a variable first?

def d = evt.device
d.command()

(www.rboyapps.com - Make your home your butler!) #6

Yes it didn’t work :frowning:
even tried def d = evt.device as Device and it says unrecognized


(Jim Anderson) #7

Can you paste in the exception you see in the logs? Will help us debug. Thanks!


(www.rboyapps.com - Make your home your butler!) #8

2a64754e-4fd1-4e10-888e-d6c5c15558b1 9:33:16 AM: error java.lang.NullPointerException: Cannot invoke method getReadOnly() on null object @ line 121


(Jim Anderson) #9

Thanks. I see that error too… I have a question out to engineering, will follow up when I hear something.


(www.rboyapps.com - Make your home your butler!) #10

Great, that’ll solve another issue, tracking the devices in a map array object. That also doesn’t seem to work.

when tracking active devices, I want to store the device objects that I want to track but again it doesn’t work so I need to resort to storing device Id’s.

e.g.

state.deviceList = [] // Reset the list
for (dev in selectedDevices) {
    state.deviceList.add(dev) // add device to be monitored
}

This doesn’t work for probably the same reason. Later when I get an event, I try to compare evt.device to the list of objects in the state.deviceList it doesn’t match it. I have to resort to matching device id’s. i.e this won’t work

state.deviceList.contains(evt.device)


(Jim Anderson) #11

We’ve verified the reported behavior, and have created a ticket to make sure that the device instance returned from an event behaves the same as a device in any other context.

I’ll follow up here when the ticket is resolved; until then, you’ll need to use the workaround found here.

Thanks for point this out; apologies for the confusing behavior.


(www.rboyapps.com - Make your home your butler!) #12

@Jim any update on this?

From what I’m seeing in the latest documentation - the device object is no longer even listed.


(Jim Anderson) #13

Where do you see this missing from?

Here is the Event docs with how to get the device: http://docs.smartthings.com/en/latest/ref-docs/event-ref.html#device

I just tried a very simple example that shows getting the Device from the event, and invoking a command, and verified this is working:

preferences {
	section("Title") {
		input "theswitch", "capability.switch", required: true
	}
}

def installed() {
	log.debug "Installed with settings: ${settings}"
	initialize()
}

def updated() {
	log.debug "Updated with settings: ${settings}"
	unsubscribe()
	initialize()
}

def initialize() {
	subscribe (theswitch, "switch.on", handler)
}

def handler(evt) {
    def d = evt.device
    log.debug "evt.device: $d"
    if (d) {
    	if (evt.value == "on") {
        	d.off()
        }
    }
}

(www.rboyapps.com - Make your home your butler!) #14

This is where I’m looking:
https://graph.api.smartthings.com/ide/doc/event

so I can assume this functionality has been fixed now. Will try it out later. Maybe you also want to update the link above.


(Jim Anderson) #15

Whoa - those pages should be redirecting to the new API docs I lined to above (http://docs.smartthings.com/en/latest/ref-docs/reference.html). We’ll look into why they aren’t redirecting… in the meantime, update your bookmark - those old docs on graph.api.smartthings.com aren’t being updated.


(Niv Gal Waizer) #16

was this issue solved?