SmartThings Data Visualisation using InfluxDB and Grafana

Hi all,

Here’s a write-up of how I’m using InfluxDB and Grafana to visualise SmartThings device states in charts and dashboards.

The solution uses a custom SmartApp I’ve written to send data from SmartThings to InfluxDB. Crucially it supports the database server being on the same private LAN as the SmartThings hub, so there’s no need to make your database server accessible from the internet.

I’m quite pleased with it so far. In conjunction with my Evohome (Connect) SmartApp I’m getting some great graphs of my home heating behaviour and energy usage.

Here’s an example of a temperature chart:

Here’s an Evohome Heating Zone chart with some overlays:

I aim to post another article covering some of the more-advanced Grafana features like templating and annotations in the next few weeks.

Z.

26 Likes

Thanks for the write-up! This is great.

Finally got around to setting this up, things are working well so far. I have one issue, any device with an ’ gives and influxdb error within grafana. Is there a way around that or will I need to reconsider my device naming conventions? For example Mike’s Office Light, can’t add to any of the graphs.

This is awesome though, I’ll replace both my Google Sheets and ThingSpeak logging with this!

Yes thanks @zcapr17 for throwing all of this together. You saved me a lot of time I would have needed to try and learn another piece of software…

I do have a question because I suck at graphing.

What do you suggest for displaying motion or switch patterns?

@zcapr17 Thanks for sharing this. This is freaking awesome and it’s saving me a few dollars a month from not having to use grovestream.

This is cool. I’m doing something similar with Elasticsearch+Kibana/Grafana hosted on a Raspberry Pi v2.

Things can be a real pain to get running on that platform, so if you’re looking for hints on using ELK and/or Grafana on a Pi, check out my new blog intranetofstuff.com.

Cheers.

1 Like

The graphs look really cool. Do I understand correctly that the InfluxDB/Grafana approach basically requires a linux server (at home or online)? It’s not a Windows approach?

Thanks,

Mike

Correct. I just run Ubuntu in a virtualbox instance on my primary computer that is on 24/7. You can use a pi as well.

You could look in to installing natively or running Docker on your windows machine, but it does require the machine to be on 24/7.

I actually just set this up using Docker on my Synology, since it’s already on. Great writeup, @michaelahess. I’ve got some fine tuning to do, and want to start doing more monitoring points but it’s up and running.
Progress

Wait, what did I write up?

And how’d you get this online with raintank.io, I’m very confused right now.

Sorry, meant to thank @zcapr17 for the writeup.

As to raintank.io, that’s just a screenshot - Raintank is the umbrealla over Grafina.

Sorry for the confusion!

1 Like

I take it you’re asking about “motion or switch patterns” in that these things are a binary state, either on (motion) or off (no motion).

I have graphed this case in Grafana:

  1. A switch’s status is fed into the database (I use ElasticSearch) with a status of 1 (on) or 0 (off). The same could be done with a motion sensor. This is the first step, getting data into your database.

  2. Put that data series on a graph. By default Grafana creates a histogram. Change the metric from “count” to “max” based on the field that represents the event value in your data (i.e., the field that has a 1 or 0 in it). You use “max” here so that for whatever aggregation bucket Grafana puts your data into the value will only reach “1” for “on” or “motion” because values greater than 1 don’t have any meaning (i.e., if you used “sum”)

  3. At this point Grafana gives you a saw-tooth graph pattern as your data swings between 0 and 1. You can fix this in the Graph/Display tab by selecting the “Staircase” option.

  4. Clean up the Y axis. Grafana supports 2 Y-axes on each graph, this assumes you leave it on the Left Y axis. I often put this binary series on the right Y axis instead so I can graph something else against it (like house fan on/off graphed against temperature). On the Graph/Axes tab, set Y-min and Y-max to 0 and 1, respectively for your desired Y axis. Optionally set a label for the axis and deselect “Show”.

The result is a clean graph of on/off or motion/no motion data.

3 Likes

Sorry for not answering this question, I’ve been away for some time. @tcjennings answer is spot on.

Note, my InfluxDB Logger SmartApp will already create valueBinary for any pretty much any attribute that can be represented as a binary value. You just need to graph the series using the Staircase option. To achieve the Window Function / Optimisation / Is Heating overlays in my original post (above) I put the binary values on a second axis to get the overlay effect.

I’m graphing door open/close stuff but it seems closed doors are a 1 and open a 0. Is there an easy way to reverse that?

Yes, you can just change it in the handleEvent() method of the InfluxDB Logger SmartApp.

Depending on exactly which type of sensor you are using you’ll just need to change around the calculation of the binary values for the appropriate event (i.e. switch ‘1i’ and ‘0i’):

	else if ('contact' == evt.name) { // contact: Calculate a binary value (closed = 1, open = 0)
		unit = 'contact'
		value = '"' + value + '"'
		valueBinary = ('closed' == evt.value) ? '1i' : '0i'
		data = "${measurement},deviceId=${deviceId},deviceName=${deviceName},groupName=${groupName},unit=${unit} value=${value},valueBinary=${valueBinary}"
	}
	else if ('door' == evt.name) { // door: Calculate a binary value (closed = 1, open/opening/closing/unknown = 0)
		unit = 'door'
		value = '"' + value + '"'
		valueBinary = ('closed' == evt.value) ? '1i' : '0i'
		data = "${measurement},deviceId=${deviceId},deviceName=${deviceName},groupName=${groupName},unit=${unit} value=${value},valueBinary=${valueBinary}"
	}

Note, I decided to make closed == 1 and open == 0 to keep things logically consistent with all the other types of sensor, i.e. 1 == thing being sensed is there, 0 == thing being sensed is not there.

1 Like

@michaelahess, did you ever since the apostrophe issue? I’m considering trying the InfluxDB route here and I have apostrophes in my device names, so keen to know if you got it to work?

I renamed all my devices to not need them. Sucked for a few, but I’ve gotten used to bad grammar now. :slight_smile:

Right all, the apostrophe issue…

I had assumed that the cause of the issue was either InfluxDB not liking tag values with apostrophes or with Grafana not liking them. Well, I just tried to re-create the problem by sticking an apostrophe in a random device name and to my surprise it showed up in InfluxDB and it showed up in Grafana too!

So, can those of you with this issue let me know if your values get into InfluxDB and hence whether the issue is with InfluxDB or Grafana? In either case, what versions of InfluxDB and Grafana are you using?

Meanwhile, as a work-around, you can simply add an additional string replace into the escapeStringForInfluxDB() function in the SmartApp code. This will replace apostrophes with underscores:

private escapeStringForInfluxDB(str) {
	if (str) {
		str = str.replaceAll(" ", "\\\\ ") // Escape spaces.
		str = str.replaceAll(",", "\\\\,") // Escape commas.
		str = str.replaceAll("=", "\\\\=") // Escape equal signs.
		str = str.replaceAll("\"", "\\\\\"") // Escape double quotes.
		str = str.replaceAll("'", "_")  // Escape apostrophes. << Add this line.
	}
	else {
		str = 'null'
	}
	return str
}

HTH

1 Like

When I do this, will it create new devices in the database or are they correlated to something else? When I first set this up, I swear I renamed an outlet and suddenly had two displaying, one with historical and the other current data. Then of course my Grafania queries weren’t working as the name changed.

That will depend on how you’ve set up your queries in Grafana. If you’re grouping by DeviceName then yes, it will appear as new series, as the name will be different. However, if you group by DeviceId, then no, because the DeviceId will still be the same. HTH.

1 Like