Development with SmartThings API

According to ST marketing publications, a Thing is a “smart device.” As in Internet of Things. Interchangeable terms.

Which make SmartThings “smart smart devices”, but I guess it sounded better than “SmarterThings.” :wink:

1 Like

I started playing with SmartThings, specifically Device Types, last week. The documentation does not effectively describe the object model and workflow. I’ve wasted a lot of hours experimentally determining how things work, sifting through templates, and searching the forums. This last method for finding information found a lot of results that indicate that it has been this way for a while.

How about a clear list of types, with their properties and methods, along with their relationship (if any) to the metadata. Then, map the metadata back to the types, and show us where in the workflow they come into play (so we have an idea of context and scope).

I’ll probably make a more detailed post in the Devices forum (because Device Type, not SmartApp) regarding what I [think I] figured out in the last week.

3 Likes

This is a worthwhile effort and contribution to the Community. Thank-you!

Please aim to make it a FAQ Topic under this Category:

http://community.smartthings.com/c/devices-integrations/faq

You will get plenty of us to pitch in to answer your piece by piece questions and suggest edits.

SmartThings is working on better documentation, but sometimes the best way is to… demonstrate what documentation “we” think is essential.

PM me if you want any help.

Terminology of tiles vs. widgets aside, I think the first-exposure confusion is because people see “App”, and start looking for something that they interact with. A SmartApp is, if I understand correctly, not something that you interact with. It’s UI is limited to configuration because the SmartApp’s function is tie together devices and services with whatever additional rules are coded into the SmartApp. Meanwhile, what the user can use to control devices are the Device Types, which have the Tile UI, and nothing sounding like “app” in their name.

I think the confusion might also distract from the point that the intent is for any UI to be used primarily for configuration of automated relationships, or for simple mode-change request (though these, more often than not, would probably be coming into one of these relationships from someplace other than the SmartApps UI).

Personally I never had that feeling, but I agree it was perhaps an unfortunate choice of terminology that a User Experience consultant might have fixed. But that ship has long sailed.

The Mobile App is a relatively distinct piece of the system, can perhaps be used rarely, and yet people need a way to visualize the growing complexity of their home, devices, and SmartApps.

If I were to wildly speculate, I would not be surprised to see a complete overhaul of the Mobile App (+ an html app) just because UI overhauls are rather common (Skype, PayPal, Google mobile apps,…) and can be done independently of back end architecture changes.

[quote=“llamas, post:17, topic:10921, full:true”]Meanwhile, what the user can use to control devices are the Device Types, which have the Tile UI, and nothing sounding like “app” in their name.

[/quote]

I think it’s a little different than that, because of the Hello Home Actions, which are limited option scenes. (When X happens, have this device do that. For multiple devices.)

I suspect in the future the most typical homeowner will simply find devices through the pretty automated pairing process. This will use standard device types.

After that, the interaction will be through setting up the Hello Home Actions or using the future Rules Engine through the mobile app, once for each rule set.

And after that, it’s letting the automatic stuff run automatically, and initiating manual actions through either the ST mobile app or a physical controller.

So I think most customers will never touch the IDE, or look at the code for a Device Handler.

( Oh, another weird terminology thing…you’re writing in Groovy, a language which runs in the Java environment. But what the IDE calls MY DEVICES are I think actually device handlers, not device types. The device types are included inline in the groovy code for the smartapp, and are a typical OO interface.)

So most coders will write or borrow device handlers, and work with those through the custom code in a smartapp.

Once the smartapp is written, it has to be associated with some trigger. This could be a timed schedule or a device doing something, often a switch or a sensor.

Also, be very careful when using the word “mode.” It doesn’t just mean a device state in SmartThings, like turning a light On or Off. Those are not considered Modes. Instead, see this explanation:

From Development home page:

Device types are the abstraction layer that allow developers to build applications that connect and communicate with new types of devices and SmartApps. Learn more. Make your own device types using the development tools.

Regardless, my first stop for Terminology are the Class definitions under Reference Material, though it’s hardly solid.

https://graph.api.smartthings.com/ide/documentation

What isn’t explicitly described is that (at least with Device Types) when the App/Type are installed, the source file is processed to generate multiple classes from the metadata and methods in the source. So, if you go look at a Device Type source file, it isn’t obvious what ends up where at runtime. It’s not that complex, but it is left for you to figure out for yourself.

My frustration is not that there are limitations or missing features or anything like that; it’s simply that what can be done is incompletely documented.

1 Like

I believe that one Device Class is created from each SmartDevice Type Class, not multiple.

But is this important to know? The current documentation has many thin areas, but I don’t think this is a particularly important distinction that isn’t obvious from the Class definitions…?

The documentation around device-type development in particular is lacking. It needs reorganization and expansion. I know everyone is frustrated by the lack of documentation. We’re making good improvements; perhaps not at the pace that people would like, but hang in there.

I’m curious how having those details about the runtime processing would help in writing device-type handlers? It helps to have particular use-cases in mind when writing documentation.

1 Like

Honestly, part of the problem is the language syntax in general, and especially in regards to ST. I’ve been doing dev a LONG time, and I really don’t know “groovy” (fortunately, it seems close enough to Java that I’ve managed.) However, in most any language I’ve ever worked with in the past, if I’d want to set an attribute called “switch” to “on”, I’d do something like:

switch = on

(or perhaps “this.switch = on”… or “objectName.switch = “on””)

I’m taking a wild guess that this would be the normal way to do it in “groovy” as well. I’m not sure about that, but it certainly seems reasonable. (Is there any “expert” in non-ST groovy that can comment?)

However, with ST, that appears to be one of the few ways that I CAN’T set an attribute. Instead, I have to do something like this:

createEvent ( [ name : “switch”, value: “on” ] )

Now… Perhaps I’m biased, but it seems to me that this isn’t setting an attribute, but creating an event. (Many languages do have “event” constructs.) I’d be confident in saying that 99% of developers who read that line of code, without knowledge of ST, would suggest that it creates an event named “switch” and passes “on” to that event.

So, perhaps, some documentation should be added for the “quirks” of ST. Such as… setting an attribute. Maybe a paragraph explaining that an “event” is the setting of an “attribute”

1 Like

Your wild guesses are fine; but this is where I understand a bit of the gist that @llamas is alluding to.

You see, it isn’t very well documented, but Attribute “switch” is not a “Property” of the Class SmartDevice Type; nor Class Device, nor their instances. If it were a simple Property, then, indeed, you could set its value with a simple assignment, or use a simple setter method.

There must be various run-time sibling Classes / Processes that are managing the storage of Attributes. I can’t guess their exact nature, and I am sadly too unfamiliar with back-end Java architecture to guess if there is a typical Java Pattern in use here.

Regardless, think of sendEvent() as “database update statement with side effects”. In other words, you can’t just set the variable, you have to put in motion an update of the SmartThings object database, which, in turn, triggers all the processes that have subscribed to the Event.

BTW: createEvent() does not do the same thing as sendEvent
createEvent() is just used to return a data structure (Map) of type Event, which is then used as the return value of parse(). The caller of parse() does the equivalent of sendEvent(). I think you can use the result of createEvent() as the argument to sendEvent(). Literally… create just makes a simple object and does nothing with it.

And parse() is the main entry point function of every Device instance that is called whenever SmartThings gets a message from the physical world.


So … I’m obviously guessing at some of the exact details, but I hope my explanation makes things a bit clearer.

And, yes, right or wrong, this level of detail would be nice to see in the official documentation (along with appropriate process model diagrams, etc.).

But I really do enjoy speculating and using my best guess and language knowledge to figure out and explain what is going on. Fun! :smiley:

(also relevant to @Jim)

Multiple classes, not multiple device classes. So, the device and the device type handler. What isn’t obvious from the device type definition is what ends up where at runtime. I figured it out, but it’s something that’s usually made obvious in even bare-bones documentation (think Java docs).

For instance, preferences in SmartApps are different than in Device Types. It seems like Device Type has a single implicit page with a single implicit section. I say this because if you try to define a section around the input elements, it blows up. I’m also guessing that the refreshAfterSelection attribute is either added by a decorator that isn’t used in Device Type and/or the attribute just isn’t connected to any action for the Device Type at runtime. Considering that this is intended to drive generation of dynamic pages, and there only one page in the Device Type, that’s probably what should be expected. However, I can find no other way that changes in preferences would send an event or call a method that would allow anything to be done with the new settings. Sure, if an event comes in or a command is called, the handler/command would have access to the new value. But when that setting is for whether or not auto-lock is enabled on the physical device, the changed setting is something that requires action.

Then there’s the inability to write settings values from the device type handler, which might serve as an example of why it helps to draw the distinction between classes and scopes. So, the only way to affect a change to the settings values seems to be through the UI; i.e. no programmatic way. In the use case of changing settings on the device, this makes it impossible to populate the preferences with the starting values from the controlled device or to update those values if one is changed manually. Also, the defaultValue attribute has no effect on the preferences UI, which wouldn’t address both issues just referenced, but would at least cover the initial population of values.

All of this may be due to the fact that preferences for device types are only intended to contain settings relevant to the software layer, but since the intuitive path in the UI is to select the detailed view (gear == settings) and then preferences, it’s where users are going to go. Likewise, the UI elements in preference pages are better suited to changing these values than the available tiles.

1 Like

The key thing to consider when it comes to changing state is that the state property is in an instance of the Device, while the command is running or being handled (depending on whether it’s an action or a response) in the context of a Device Type handler. So, the events are a way of signaling that the Device needs to change the state value. Asynchronously. It’s like updating UI values from a thread in .NET, if that’s helpful.

Not that this is clearly documented. I just intuited it from the fact that in all of the examples I looked at the handlers didn’t set any values, just raised events.

1 Like

Everybody, including people who’ve been coding for 20 years and college professors and documentation writers mixes up the terminology around devices once in awhile.

We all know what we mean.

  1. the physical device (the dinng room dimmer switch)

  2. the device class (like “dimmer” vs “door lock”)

  3. Device Class Identifier (like 0x11). Usually a numeric code by which the physical device will communicate its device class, but which gets called a bunch of different things (device class identifier, device ID, device class, device type, device code, device class code, etc), but is really just a way of restating 2) above

  4. the device handler (like a printer driver, this is the code that formats input and translates output for actual communication with the device)

  5. the device type, which is the interface in Java terms. This is the code structure that is included inline with the code that actually does something based on the states from the device’s capabilities. The device type has a parameter for brightness percentage, the app code sets that to a specific number like 50, the device handler puts the 50 instruction into a format the physical device understands, the device does it.

So far, so good. Device, Device Class (in word description and numeric identifier), Device Handler, Device Type.

People tended to jumble these up occasionally, not the concepts but the terms used, but it was easy to clear up. There is a thing. It knows how to do standard actions based on specific values or events. There is driver software that reformats (“normalizes”) I/o for that thing. There is an interface that provides a structured format for passing values to and from a program to the driver software.

Device, Device Class, Device Handler, Device Type.

Then a few years ago, a large division of a large company (cough IBM Lotus cough) took a widget used in the UI for mobile app development and shortened its name from “Device Type Selection Handler” to “Device Type Handler.” Ouch!

And then SmartThings came along and started talking about Smart-Device Type Handlers." Which to be honest I have no idea what they mean.

I originally thought they just meant Device Handler in the standard OO “Device, Device Class, Device Handler, Device Type” structure.

But if it really does spawn multiples of anything, it sounds more like a UI widget again, like it’s creating the Device Handler (which I don’t see being created anywhere else) and some other stuff? Maybe some behind the scenes kind of inheritance?

Honestly, I have no clue. I definitely haven’t been able to figure out why there are so many different Smart-Device Type Handlers for physical devices already using a standard communication protocol to identify their Device Class.

What am I missing?

Need to make a short comment: As opposed to the Java/Groovy Class “Device”? :question: http://docs.oracle.com/javase/tutorial/java/concepts/class.html

i.e.,: Terminology is everything in these discussions, and, unfortunately, we even have two different definitions of “Class”.

I also think there is a “Factory” involved somehow (as in, when you add a physical device to SmartThings, it spawns an instance of Class Device, using it’s Device Handler as a Factory).


I’d like to defer all this discussion due to the speculation involved, but I’m worried that we’ll never get a consistent in-depth description of the SmartThings architecture, it’s mapping to OO terms, it’s relationship to other IoT terms, and a very detailed Glossary to keep everything straight.


The bicycle page is just a Java tutorial demonstrating a generic object class for teaching purposes.

There are all kinds of classes in an OO implementation, such as a command class.

Java uses Device Class exactly as I described in pretty much everything involving a network communication protocol. (So yes, there is a DeviceClass class.)

http://www.oracle.com/technetwork/articles/javame/index-156193.html

https://docs.oracle.com/cd/E28389_01/apirefs.1111/e13403/oracle/jdeveloper/webapp/designer/DeviceRegistry.html

We’ve definitely wandered out of my pay grade now. :fearful:
Oh well.

Weekend!!! :sunny:

:stuck_out_tongue_winking_eye:

Wow. I just make a simple comment about a point of confusion in the documentation and a request to make it less confusing… (I know what it does, how to use it, etc. It was only a comment about documentation…)

However, the above quoted comment from @tgauchat has me… shocked. Terry, are you feeling okay? Is something wrong?

2 Likes

@Jim: On the documentation side, it would be nice to have more contents like the current Reference Materials, essentially:

  • Outlines of classes and their members.
  • Include protected members for classes in which developer code will be executed (e.g. a derived wrapper class that decorates the parent with command methods that we write).
  • Include UI classes. I’ve seen tile types in a few templates that aren’t mentioned anywhere else.
  • Preference pages/input classes. This is covered reasonably well in the SmartApps documentation, but it would be nice to have a concise version in the Reference Materials. Also, there are a few properties (at least) that are not mentioned in the docs (e.g. defaultValue and refreshAfterSelected on input).
  • List of the zwave and zigbee helper members.
  • Clear identification of when and in what context the elements of the script are executed. The current SmartDevice Type Class reference seems to indicate that the SmartDevice Type Handlers execute certain metadata methods, and implement certain methods.
  • Is the handler a distinct class, or just a script? I guess it doesn’t matter as long as its members are documented, which most are, I think.
  • settings, state, and similar properties; and their relationship (or lack thereof) to properties of device.
  • Are command methods run in the same scope as the handler methods?
  • Are the UI objects generated by the metadata elements visible to handler and/or command methods? If so, what methods and properties to they expose?
  • A bunch of this may become obvious if there’s a complete outline of classes/interfaces and members, since that would tell us in which scope the documented method is executing. e.g. The handler methods will clearly have access to public and protected members of the class they are listed under.
  • Documentation of the preference metadata method and its limitations in the SmartDevice Type context.
  • Documentation of the updated() method.
  • Altering the description of the <command name> method (which currently reads like the description of updated() from a SmartApp) to say something about implementation of custom commands defined in the metadata. (I assume that’s what this was supposed to be…)

(out of time for now…(added a few edits))

2 Likes