Device.events()

Hey guys,

I’m trying to write a simple device handler for a temperature sensor that I made and it works great, my DH can show the current temperature and humidity % of my device.

But I’d like to add a graph of the temperature for let’s say the last 24h and I’ve been playing with some undocumented htmlTile to integrate a graph in my device and it seems to work ok, except I can’t find a way to retrieve the last events for my device.

According to the doc, device.events() or device.eventsSince(…) should be all I need and it seems to work, except I can’t access the events once I receive those, the api restricts me from getting any property or method!!

If I do for example a very simple loop like this:

device.events().each {
  log.debug(it.data)
}

I get this exception:

java.lang.SecurityException: Getting properties on class physicalgraph.event.DefaultEvent is not allowed

How am I supposed to get the info from the events if I can’t access it?

So, anyone has any experience with this?

I really like my smartthings hub, but this is really badly documented and a weird api to use!

Try to just log the log.debug “${it}”
.events() i don’t think returns a Map

1 Like

This is what I tried at first. This somehow works, as it doesn’t throw any exception, but it outputs nothings.

I’m guessing the internal toString method returns nothing, so this why I’m trying to call either some methods or access some attributes.

According to the doc, it should work, but either the doc is wrong, or I’m missing something

http://docs.smartthings.com/en/latest/smartapp-developers-guide/devices.html#querying-event-history

It returns Event objects with implied Getter methods (not properties).

I do this:

def result = device.eventsBetween(start, end)?.collect{
    	[
            "date": formatDate(it.date),
            "deviceID": it.deviceId,
            "name": it.name,
            "displayName": it.displayName,
            "description": it.description,
            "descriptionText": it.descriptionText,
            "unit": it.unit,
            "source": it.source,
            "value": it.value,
            "isDigital": it.isDigital(),
            "isPhysical": it.isPhysical(),
            "isStateChange": it.isStateChange()
...
       ]
2 Likes

I know… but implied getters and props are the same in groovy, but I tried your exact code and I’m still getting

java.lang.SecurityException: Getting properties on class physicalgraph.event.DefaultEvent is not allowed

Something is weird… So far I’ve been trying all this in the simulator only, maybe this is the problem, I’ll give it a try on my phone tomorrow.

Simulator is bad, just update the driver on the production device…

2 Likes

I must have said this 1000x: Never trust the Simulator.

1 Like

ok, simulator is obviously not reliable, but I just tried the same thing on my phone, and I still get this stupid security exception whenever I try to access anything on the events.

Maybe I am doing something wrong creating the events, but it is pretty straightforward.

My device handler is a pretty simple temperature sensor which defines an updateTemp command and I hava a smartapp acting as a MQTT bridge which calls the updateTemp command on my device whenever it receives a real temp update from the actual device through MQTT. (device is an esp8266 based diy temp sensor)

Then, inside the updateTemp method in my device, I simply do:

sendEvent(name: “temperature”, value: temp)

All of this works pretty well, my device actually gets updated and shows the temp and in the "recently’ tab in the app, I can see the events are being processed. I just cant access those stupid events in my code. Maybe I’ll give the rest API a try. From what I understand, it is also possible to retrieve the events for a device this way, so I could just call the rest api using hubaction, or I could probably also call my MQTT server directly to retrieve the events from there, but all of this sounds a bit silly. since I am supposed to be able to get those events with a simple myDevice.events() call inside my code.

The more I code on this thing, the more I hate this platform, it is really slick to use, but god is this development platform bad!

That’s why Samsung & SmartThings has spent the roughly the past 1.5 years building the new SmartThings IoT Cloud with new API.

At SDC last year there was a lot of chatter and demos of a revamped IDE environment, but that obviously was dropped when Samsung put weight on consolidation, and Robert Parker was brought on board as CTO.


Not sure what quirk you are running into, but the code I linked in post above definitely works in a SmartApp: Device.events() - #4 by tgauchat

maybe it cant work in a device handler, only in a smartapp.

Well… whenever I have some more free time, I will work on a workaround using either the rest API or calling directly my MQTT server like I mentionned, but I should not have to do this!!

Anyway… reminds me why I have a Sony TV and an iphone :slight_smile:

1 Like

That’s is quite likely a good theory. There are many non-obvious differences between a SmartApp and a Device Handler and Device Instance, particularly because there are different wrapper classes used under-the-covers even when the API methods have the same names!

I found this post while dealing with the same physicalgraph.event.DefaultEvent problem in my garage door sensor Device Handler, and even though the post is a month old I just want to confirm for anyone interested that you cannot use device.events() within a Device Handler. I now understand why the documentation does not list the .events() method among those usable for Device Handlers (http://docs.smartthings.com/en/latest/ref-docs/device-handler-ref.html). As stated above, the DeviceWrapper for Device Handlers is not the same as the one for SmartApps, and so it does not contain that method–sort of.

Interestingly, when you do use device.events() it does not cause an error right away because it is a valid method, but not the one you expect. When you print the output using:
device.events.each() { log.debug "$it" }
Then it outputs a bunch of information that looks to be the ZigBee data received from the device (it includes cluster, attrId, etc.). It does not return a SmartThings EventWrapper.

I managed to find a workaround though. I wanted to get the last event where the garage door was stationary. You cannot access past events, but you can access the most current value of an attribute. So I simply made a custom attribute and set it only when the door is inactive. Then it is merely a matter of:
device.currentValue(customAttribute)

Thanks everyone for the help!