I was wondering if someone could help me out here.
Here’s my code snippet :
def motionInactiveHandler(evt) {
log.debug "motionInactiveHandler called: $evt"
def device = evt.device
log.debug "Device data : $device"
def motionState = device.currentState("motion")
log.debug "Motion State Value : ${motionState.value}"
log.debug "Motion State Time : ${motionState.date.time}"
runIn(inActivityTime, checkMotion, [data: [triggerDevice: device]])
}
def checkMotion(data) {
log.debug "In checkMotion scheduled method"
log.debug "Device data : ${data.triggerDevice}"
def motionState = data.triggerDevice.currentState("motion")
log.debug "Motion State Value : ${motionState.value}"
log.debug "Motion State Time : ${motionState.date.time}"
In the above, I see the device.currentState("motion") working inside motionInactiveHandler(). But data.triggerDevice.currentState("motion") doesn’t work inside checkMotion().
I end up getting the following error :
groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.grails.web.json.JSONObject.currentState() is applicable for argument types: (java.lang.String) values: [motion]
Any help in identifying how I can make this work would be really nice !!
tgauchat
(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy)
2
I’m just tossing out something to try, but I don’t know if it will help. Keep in mind that SmartThings has a hidden layer or two between your code and what actually gets compiled an executed. That’s why what looks like perfect Groovy syntax sometimes doesn’t work. There are hidden object conversions going on.
Since the runIn data is json, it looks like the device is being converted to json, resulting in your error. I think you need to pass the device id and then use find on your device list in checkMotiin to get back to the device object.
How would I find the type of the object passed in the method ? I’m unable to use class and getClass (as mentioned in the guide) as they throw Security Exception.
Could you point me to the documentation on how to do this ? I found this thread that talks about it. So I assumed this documentation page should have it. But I don’t see it there !
It probably isn’t in the documentation, but reviewing some of the example device drivers might help.
You haven’t provided enough context for me to give you the exact code you will need, but I will assume you have a list of devices in settings that includes the device you received the event for.
Given the deviceId, you can do something like:
def device = settings.deviceList.find{it.id==deviceId}
About #1, the instanceof helped
About #2, my bad for not providing the right context here, Tony. Here are my code snippets :
preferences {
// Motion Sensor Settings
section("Room-1 Motion Sensor") {
input "motionSensorRoom1", "capability.motionSensor", required: true, title: "Select sensor : "
}
// Motion Sensor InActivity Time
section("Turn off when there's been no movement for selected Time") {
input "inActivityTime", "number", required: true, title: "InActivity Time in Seconds :"
}
}
…
def motionInactiveHandler(evt) {
def triggerDevice = evt.getDevice()
log.debug "motionInactiveHandler called: $evt by device : ${triggerDevice.displayName}"
def testDev = settings.deviceList.find{it.id == triggerDevice.getId()}
log.debug "Testing if this works : settings : $settings"
log.debug "Testing if this works : devList : ${settings.deviceList}"
log.debug "Testing if this works : devices : $testDev"
...
Apologize if this is a noob question @TonyFleisher. But I’m unable to make that work too
I get the following error :
2:23:04 PM: debug Testing if this works : devices : null
2:23:04 PM: debug Testing if this works : devList : null
2:23:04 PM: debug Testing if this works : settings : [motionSensorRoom1:motionSensorRoom1, inActivityTime:2]
What am I missing here ?
1 Like
tgauchat
(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy)
9
If in doubt, it doesn’t hurt to link to a Gist or Git of the entire SmartApp. That way some folks sometimes actually copy and paste into their own environments to play around and possibly discover a solution .
It looks like you have just one motion sensor (no device list), so you don’t have a list for find, but you don’t need to pass anything to checkMotion in this case, as you can get the device direct from the settings with device = settings.motionSensorRoom1
If you had multiple devices using this handler or scheduled method, the id can be used to identify which one triggered the events.
I’m gonna take up @tgauchat 's advice. Here’s the github link to what I’ve been working with so far.
I’ve taken all your inputs and come up with what I have so far. Huge thanks to you all !
Note : As you can see, I chucked the runIn() approach in favor of the sleep x; handlerMethod() approach. This was due to two reasons :
With runIn(time, handlerMethod), I was observing that at times, the handler method was sometimes called a few seconds before t=time too, which was messing with my logic ! I believe the documentation also agrees with this observation.
runIn(time, handlerMethod, [data : [key: value]]) is mangling the type of value.
P.S. Next steps are to get the state storing to roomOccupancies working, and then to expose that status via an API. Hopefully I can get that done