How to Create Device Events

On the device side, the device must send sensor data to the SmartApp. I assume this is done with a device event (API | SmartThings Developers).

I would need an example or instructions on where to find the required object syntax.

value: object
Value associated with the event. The valid value depends on the capability.

data: object
Key value pairs about the state of the device. Valid values depend on the capability.

I think you use the terminology a little different to I do. To me the SmartApp and the Device are one and the same thing. so when, in that link, they say …

When a Device is managed by a SmartApp, the Device is responsible for creating events to update the Device attributes on the SmartThings Platform.

… I think it makes more sense if they say ‘the SmartApp is responsible for …’. It is the API equivalent of the old Groovy sendEvent or emitting an event in an Edge driver.

The details of each capability can be pulled from the API or read in a tarted up form (with links to the JSON) in the Capabilities Reference in the developer docs. In the most common cases the value object is a simple object like a string or number.

In our case, the device is cloud webhook. All communication is handled by http POST or GET commands. All our devices are first connected to our cloud. Our cloud handles all communication with the SmartThings/SmartApp.

We don’t use the SmartApp.
const SmartApp = require("@smartthings/smartapp");

Since we use the serverless services, I don’t think we can even use it.

Yes I understand. We just visualise a SmartApp differently. To me it is the app in your cloud that is communicating with SmartThings and managing your cloud connected devices.

In SmartThings device attributes, your sensor data, are updated using device events and for your cloud connected device those events are created using the API POST you referred to.

So for a simple device like a contact sensor you would do a POST to https://api.smartthings.com/devices/{{deviceId}}/events with the JSON body:

{
  "deviceEvents": [
    {
      "component": "main",
      "capability": "contactSensor",
      "attribute": "contact",
      "value": "open"
    }
  ]
}

I don’t know why the API reference doesn’t include an example payload in this case.

1 Like

Thanks, I got this working.

Hi @orangebucket,
I’m trying to do something similar but I may not understand this correctly. I am using @TAustin HTTPDevice to send HTTP commands to a device on my network - which works fine.

But the device can change states outside of ST so I want to use the API to update the state when it changes outside of ST so that the ST status is synchronized to the state of the device. Is this the right way to use Create Device Events?

My body looks like this

{
  "deviceEvents": [
    {
      "component": "main",
      "capability": "switch",
      "attribute": "switch",
      "value": "on"
    }
  ]
}

The response is 403-Forbidden
I’ve been able to do many other API actions on this same device. Reading the device works, commanding the device works, and anything else I’ve tried.

I’ve tried the same thing with a Z-Wave physical switch that is connected to my hub and I get the same 403-Forbidden.

Am I using this API function correctly? Can I update the state or status of a device with an API call without triggering the command on the device? I want the switch to display it is on without commanding the switch to turn on. I want to do the same thing with a dimmer - set the level to a value between 0 and 100 because it was set outside of ST.

This is how I understand things:

An Edge driver will ‘emit events’ to set the state of the device it is implementing within SmartThings. In a similar fashion the Create Device Event API call is the way of setting the state when a SmartApp is implementing the device. So it only works when the SmartApp that created the device makes the call.

Device events can also be used to set the state of devices of type VIRTUAL. Indeed it is how you are expected to set the state of the devices when there aren’t any capability commands to use. However Todd’s devices are virtual in a more generic sense. They are actually of type LAN. So they are expected to work within the attribute/command model.

I’m not sure I fully understand that last sentence. I think you’re saying that for a device, like a Z-wave switch, I won’t be able use the Create Device Events API - which makes sense. Can I use Create Device Events for Todd’s devices? Am I just running into a device limitation or should I be able to do it with Todd’s HTTPDevice switch or dimmer?

What I think I am saying, which may be wrong, is that setting the device attributes, which is done by creating events, is envisioned as a function of whatever is acting as the device driver or handler. In this case the Edge driver. So it shouldn’t work.

The create device events API call is used where an application is acting as the device driver.

I can’t see any reason why a driver couldn’t handle your requirement. It just needs to handle commands that set the attributes without actually involving the actual device. It is in the gift of the driver though. I’ve not used Todd’s driver to know if it can already do this. I can see why it wouldn’t.

You could, of course, completely work around the problem by using separate virtual devices set using automations to represent the device state. It’s analogous to what a number of us do with mobile presence. Generally mobile presence is accurate when it is reported, but it doesn’t always report and also we care about where we are, not where our phones are. So we set virtual presence sensors using automations based on mobile presence but correct them manually or automatically as required. The difference is that for mobile presence it is a very ‘correct’ solution, whereas in your case it would be more of a fudge.

Hi, @johnsev.

As @orangebucket mentioned, this specific endpoint is for devices created by a SmartApp which is different from an Edge driver (the base of @TAustin’s integration).

Only the device handler can issue a status change and that’s why using the API with the commands for something like Switch or SwitchLevel works, because it calls the corresponding capability handler.
For events of capabilities without commands in their definition, the driver must issue the event but the how depends on its configuration, that’s why it would be interesting to know if Todd’s integration also supports receiving status changes to reflect them on the SmartThings side.

In the case of Z-Wave and Zigbee devices, the reports of their Command Classes and Clusters respectively go through the corresponding handlers. When you issue a command from the API, the driver sends the Z-Wave or Zigbee message to change the status in the physical device but you cannot send commands to capabilities without commands like “temperatureMeasurement” since only the device reports should populate them.