Wednesday, January 13, 2016

Logging SmartThings to the Internet of Things


I got a SmartThings hub for Christmas. It does a lot of cool things, but it doesn't draw graphs for things like temp, humidity, etc. Well, I had to fix that, so this post describes that journey and, frankly, it's easy enough that you can do it too.


If you are someone who wants to skip the journey and just get the app, jump to my TLDR section below.  Otherwise . ..

The Backstory

So yay for cool Christmas presents! I had not researched SmartThings.  They had been on the periphery of my geek radar but I hadn't gotten to them yet.  Apparently my brother had checked into them and I think the gift was his way of telling me to get off the X10 junk I have working (some most of the time) in my house.  I had looked at zwave/zigbee stuff in the past, and frankly the cost to replace all the X10 stuff I bought off ebay was a little higher than I liked.
Image copyright Samsung

Well, with a new toy in hand, I had to explore a bit. Turns out, this thing is really cool.  Besides supporting a wide range of zwave, zigbee, bluetooth, and even wifi (tcp) devices, it has an open marketplace of SmartApps that allow truly sophisticated and intelligent behaviors. There is even an If This Then That channel to add even more integration and sharing/linking options.  But I digress.  I found that there was a lack of graphing in the app and for some reason I fixated on this.  Many SmartThings devices update their current temperature and/or humidity periodically and you can see it in their status or history log but I didn't find a way to see this over time. It looks like there has been an attempt to do some work on this based on a thread in SmartThings very active forum, Losing hope: charts and graphs. But the last time I checked the graphing project was offline. They thread title also didn't inspire hope.

I just wanted to chart my temperature and I decided to use Adafruit IO as my IoT service. I'd learned about them in my last post:  On Air Light for Streamers and I thought their dashboard capability would work great to show a graph of my temperature feed.

So I checked to see if I could use IFTT as a middleman between SmartThings and Adafruit IO because they support both, but it doesn't appear that IFTT has a "Temperature Update" event in their SmartThings channel.  While it would have been a "no code" fix, it would also have been kind of Rube Goldberg-esque to leverage two web services for one measly graph.

Time to look deeper.  After all, what's the use in owning a thing (especially a smart one) if you don't know how to really pwn it? Turns out SmartThings has a very well documented API for writing SmartApps and even creating new SmartThings integration. This allows you to write apps that handle events from your SmartThings like door opens, or temperature updates as well as take actions like turn on power, unlock doors, play sounds, turn on irrigation, or dim the lights.

The Project

So I looked like I would need to:
  1. Learn to write to a whole new API
  2. In a language I didn't use (Groovy)
  3. Handle a temperature update event
  4. Integrate with an IoT API 
  5. Post the data
Disappointed, I figured it'd take me a few weeks in spare time at best. I took a peek at how big the learning curve mountain would be and got blown away.  The whole project only took me a little over an hour!  Seriously, I'm not bragging on me (I'm just a hack at this), but I am duly impressed at the quality of the tutorial, examples, and development environment that are all provided.  They have a web based IDE for writing the code integrated with a built in simulator for running your code.  You don't even have to own a device to get started. I followed their tutorial to understand what was happening inside a SmartApp and how to use their IDE and tools and then copied and pasted chunks of code from their Too Hot example app. It showed how to simply handle temperature update events. To post data I would need HTTP tools.  Turns out SmartThings has several great HTMLPost,Get,Del,Head, etc methods built-in so I just needed to formulate my POST request properly and send it over.

Adafruit IO Integration

During my last project I learned that Adafruit IO requires a custom header with a key to post to your feed. You can see how to do this with curl in this code snippet from DeckerEgo (he also has an awesome blog of DIY geekery.)  If you haven't used Adafruit IO before follow their (also) excellent tutorial on setting up your account and feeds. In order to post the AIO key header, I needed to use the httpPostJson function which allowed me to modify the header values.

SmartApp Structure

The app is designed to ask the user for:
  • Which temperature sensor to listen to
  • AIO username
  • AIO Key
  • AIO Feed
Once installed (it runs in your hub or the cloud, not your phone) it subscribes to the updates for the device you indicated. Upon receiving an update it posts it to your selected feed with the credentials you added during installation.  It's that simple.

Publishing

After running the SmartApp in the simulator and seeing it update my feed I simply published it to myself and installed it in my SmartThings instance. After I learn a bit more about this, I might submit a request to make the app itself public.
Until then, if you want to do the same, follow the steps below.

TLDR

Ok, if the journey was too long and you just want to learn how to get this SmartApp for yourself start here to make it work for you.

  1. Setup your SmartThings stuff - get their app and follow their instructions
  2. Setup your SmartThings developer account
  3. Setup your Adafruit IO Account and Feed (note your username, AIO key, and feed name)
  4. Create a new SmartApp in your SmartThings account
  5. Paste in the code from my github repo but use your own namespace i.e. replace the LCGT in the line: namespace: "lcgt",
  6. Save the app and test it out for yourself it you like
  7. Publish the SmartApp to yourself
  8. Install the SmartApp to your hub using the SmartThings App.  Input your creds and feed name from above.
In the future I plan on investigating if I can allow you to select they type of event you want to listen for and post.  I could see wanting to see all sorts of events mapped onto a graph.  Door open events showing up on a temp chart could lead to some interesting correlations.

Thanks for taking the journey with me and happy hacking.






7 comments:

  1. Hey Ben,

    I've been following your blog for a while now and it really fascinates me that you are so passionate about learning new things, trying new things out.

    Really appreciate the work you are doing here man. Keep up the good work!

    Regards,
    Bhargav from WaterSoftenerGuide.com

    ReplyDelete
  2. Hello,
    The article on Logging Smart Things to the Internet of Things is nice,it give detail information about IOT Product .Thanks for sharing this valuable information. Its really useful for me.internet of things services

    ReplyDelete
  3. Hi.

    Tried your code but I am getting the following respons:

    something went wrong: groovyx.net.http.HttpResponseException: Forbidden

    Any insight?

    ReplyDelete
    Replies
    1. Didn't get the notice you had commented. Sorry for the delay. Is it still not working for you? It sounds like you may need to make sure you are using your key in the header.

      Delete
  4. Great piece of work Ben, I cannot get it to log at the moment bit will have a play after work today. Also have you ever thought of expanding this so switches, light levels and thermostats settings/values can be used?

    ReplyDelete
    Replies
    1. I have had a play and managed to log switches, (as 1 or 0), as well...now to to drop the graphs that are produced on AIO into other web pages...thanks again :)

      Delete
    2. Thanks for the feedback. Glad you've gotten it up and working. Adding switches is a fantastic update. Let me know how things go!

      Delete