Getting device object from an event

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.

1 Like

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?

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}
1 Like

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?

1 Like

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()
1 Like

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

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

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

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

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)

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.

3 Likes

@Jim any update on this?

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

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()
        }
    }
}

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.

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.

2 Likes

was this issue solved?