Trending & Analyzing SmartThings Devices (Part 4 of 4)

Table of Contents

What is Grafana

Grafana is an analytics platform that allows you to create rich dashboards, define alerting logic when values exceed specified ranges, and visualize your data across a number of different formats. You can get a good idea of the capabilities of Grafana by just clicking through the official and community submitted dashboards on the Grafana website. The beauty of Grafana is its ability to visualize incredibly complex data sets in a way that still looks really sexy.

Getting Started

Much like the installation of InfluxDB back in Part 3, the installation of Grafana is pretty straight forward. If you're using a separate server for Grafana and haven't performed the steps on it from Part 2, make sure your OS is up to date. I'm using Ubuntu 16.04, so running a sudo apt-get update && sudo apt-get upgrade && sudo reboot does the trick. If you're using a local device (such as a virtual machine, Raspberry Pi or Pine64) you're also going to want to make sure you have a static IP set.

Installing Grafana

Before we start the installation, we need to install the libfontconfig package, as Grafana depends on this. If you forget to do this, your Grafana install will simply fail and you'll have to come back and do it.

sudo apt-get install libfontconfig

Installation starts by grabbing the download url from Grafana's website for your OS, then downloading and installing Grafana with the supplied commands.

wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.4.2_amd64.deb

sudo dpkg -i grafana_4.4.2_amd64.deb

With the packages installed, we can start Grafana by simply running sudo service grafana-server start.

We'll also want to ensure that Grafana starts automatically with our server by running sudo update-rc.d grafana-server defaults 95 10

We can now access our fresh Grafana installation by opening a web browser to http://{server-ip}:3000.

Configuring Grafana

Because I'm running Grafana inside my own network, protected by my own firewall, I want to enable anonymous access. This will allow me to easily run my Grafana dashboard on a computer in my office so I can quickly and easily glance at it. If your server is publicly accessible you'll undoubtedly want to keep it secured and take some additional steps to harden your server.

Grafana's configuration file is located at /etc/grafana/grafana.ini, so we'll edit it by running sudo nano /etc/grafana/grafana.ini.

Find the "Anonymous Auth" section, and set the enabled flag to true to allow anonymous access:

;enabled = true

Note that this configuration does not completely open up Grafana. You still need to login with either the default admin account or another admin account you create in order to administer dashboards. Anonymous access simply allows users access to dashboards directly as viewers.

Save the grafana.ini file by exiting Nano (Ctrl + X), and confirm that you want to save your changes. You now must restart Grafana for the new settings to take effect by running sudo service grafana-server restart.

Once the service has been restarted, point your web browser to http://{server-ip}:3000. You'll be prompted to login, and can use the default admin/admin credentials.

The last step required to configuration is to change the admin password. Grafana doesn't force you to do this, but it's always a best practice to change a default password when you first install something.

Click on the Grafana logo at the top left corner, and navigate down to admin > profile.

Scroll to the bottom of the page and "Change Password".

Adding the First Data Source

Now that we've got Grafana up and running, the fun begins. Click the Grafana logo at the top left, then select "Data Sources".

Grafana has native support for InfluxDB, so we don't need to download any special packages to make a connection to the InfluxDB that we created in Part 2. Mapping the data source is super simple, just select "InfluxDB" as the data source type, and give it a name. Provide the URL to the InfluxDB instance, complete with the port (8086). Also change the Access type to "direct" since we don't need a proxy in this example. Lastly, specify the name of the InfluxDB database. I generally use the database name as the name of the data source, but that's personal preference.

Click "Add", and you should be presented with a screen indicating your data source was correctly added and working. This process validates connectivity to InfluxDB, so as long as you see a success message here we're good to go.

Our First Dashboard

There's a ton we can do with Grafana to display the devices on our SmartThings platform, or connect to additional services outside the purview of SmartThings. In future blog posts, I'll expand on some of the more complex capabilities here, but for now we'll just create a dashboard that shows the status of some of our sensors.

I'm a big fan of showing a nice clean and easy to read snapshot of sensors; especially contact sensors and water sensors. If a door has been left open or if a water sensor is wet, I want to easily see that. Grafana is the perfect platform for displaying these types of widgets. For our first dashboard, we'll show some temperatures, door sensors and water sensors.

Plugins

Everything you see on this dashboard is configurable within the UI, except for the installation of the Clocks plugin. Solely for that reason we'll start there. On the Grafana server, simply install the clocks plugin by running sudo grafana-cli plugins install grafana-clock-panel, then restart the Grafana server with sudo service grafana-server restart.

There's also an extensive list of plugins available on the Grafana website.

Creating a Dashboard

Click the Grafana logo at the top left and navigate to "Dashboards" > "New".

We're now taken to a brand new, blank dashboard.

Let's start by adding the clock widgets. The first widget you add to the dashboard is always the easiest since the panel selector is already displayed. Click "Clock" to insert a new clock panel.

Now click on the "Panel Title" to display the panel's options, and click "Edit".

Here you'll see the options on a pretty basic panel.

On the "General" tab, set the title (in this case "UTC TIME"), and set the dimension properties (span of "4", and height of "100px").

On the "Options" tab, we'll set the time format to 24 hours, and set the UTC offsets to 0 so that we get a UTC clock.

Now, simply click the "X" at the right of the options panel to go back to the dashboard.

Panels can easily be duplicated, which is useful if you want to make another one with the same formatting and don't want to have to reconfigure everything by hand. Click the panel title (now "UTC TIME") to expose the panel's options, and click "Duplicate".

Now we'll edit one of the two clocks, so that we can make one local time. To do this, click the panel title > "Edit". On the "General" tab, change the title to "LOCAL TIME". On the "Options" tab, change the UTC offset to match your timezone. In my case -4 Hours for Eastern Standard Time. Click the "X" to the right of the options panel to go back to the dashboard.

Now, let's add some data from our SmartThings hub, starting with the hub's "Mode" (used to indicate Home, Away, etc.). Hover over the top left edge (vertical ellipsis icon) of the row containing the clocks, and click "Add Panel".

Add a "Singlestat" panel, by clicking it from the panel selections.

As with the other panels, click the new empty panel's title to expose the panel options, and click "Edit" to configure the panel.

You'll instantly see that this panel type has a lot more options than the clocks did, starting with this Metrics tab, which allows us to define the query or queries that will surface data for the panel.

The query wizard is incredibly intuitive, and in most cases helps you build your query by restricting the types of measurements and where conditions you can use based on your previous selections. Click "select measurement" and select "stLocation". Next, click the word "value" in the select field condition, and you'll see a list of fields available to be used when querying "_stLocation".

Select "mode", then click "mean()" > "Remove" to remove the default aggregation. Since the value that is reported for "Mode" is going to be text, click the "Plus" after "field(mode)", and navigate to "Selectors" > "Last". Last allows us to query for the last value in the data set for this field, helping to ensure that we get the current value displayed in our dashboard. We'll talk more about different selectors and aggregations in future posts. Lastly, click the "null" inside of "fill(null)", and select "Previous". Using a "Previous" fill will select the last data point in the previous interval if there isn't a data point in this interval. Let's say your mode hasn't changed in 3 hours, but your dashboard is reporting in 10 minute cycles. Without a "Previous" fill, the current reporting interval would have no data.

Finally, simply set your panel title (in my case "SMARTTHINGS MODE"), and close the options panel to go back to the dashboard.

Panels can be reordered within their row by simply clicking and dragging the panel title to alter the panel's position.

Now let's add a new row, by clicking "Add Row", and select a "Singlestat" as the first panel in that row.

What you do with this panel will depend on what sensors you have available, but I'll provide a couple of examples that you can reverse engineer to meet your own needs.

Let's start with a temperature sensor (in this case the Fibaro Motion Sensor, that also reports luminescence, temperature, and shock). By using a "WHERE deviceName equals" condition, we can ensure that we're pulling the data from a specific device. In this case "FROM autogen temperature WHERE deviceName = Garage Motion Detector". We want to select the field(value), and like before, ensure that we're looking at the last value in the data set by using the last() selector, and fill(previous).

Next we'll move to the "Options" tab, and make our panel a little easier to read by adding some color coding. We'll set the stat to "Current" since it's the most recent and/or current value for the sensor, and set the Unit to "Temperature" > "Farehneit (°F)".

In the coloring section, we'll check "Background" to color the box behind the value, and define some thresholds so that the color changes dynamically based on the value. In this case thresholds of 32, 90, 100 ensure that the box is blue for any value below freezing, green for any value between 32 and 90, and red for any value between 90 and 110.

We'll also enable Spark lines, so that the panel gives you a quick glance of the temperature trend of that sensor.

Finally, we'll close the options panel to go back to the dashboard.

Up until this point, we've simply been displaying the value that comes right out of the sensor. That doesn't really work for us if we want to display the status of a door sensor. These sensors report a binary value to the controller, and you probably don't want to see "0" or "1" on your dashboard. Using Grafana we can translate numerical values to text, and display our own user-friendly values for our sensors.

To display this, we'll add a new singlestat panel to show the Open or Closed status of a garage door. Much like our previous queries, we'll use the last() selector and fill(previous) to get the most recent value, but this time we'll use "valueBinary" for the field, instead of "value".

The sensor I'm using reports 1 when the sensor is closed, and 0 when open. We'll set the coloring on the Options tab to fill the background with Red if the value is less than 1, and Green if it's 1 or more. This means that our panel will light up Red when the garage door is open.

Lastly, we want to make our panel say something a little more meaningful than "1" or "0". Using the "Value Mappings" tab, we'll set "value to text" mapping, and define values so that "1" translates to "CLOSED" and "0" translates to "OPEN".

And once again, close the options panel to return to the dashboard and admire what we've learned.

My Aeotec Water Sensors (located under each furnace to detect surplus condensate runoff) are configured in exactly the same way. Simply duplicate the "Garage Door" contact sensor panel, change the device names to poll the right device, and change the value mappings so that "0" translates to "Wet" and "1" translates to "Dry". I also had to reverse the thresholds to indicate 1,0 instead of 0,1 used for the contact sensor, since the water sensors report 1 when Dry.

The final trick to learn, is that any panel in Grafana can be edited with JSON. Click a panel's title, then click the "hamburger" icon, and select "Panel JSON".

You're now shown the full JSON object that makes up a given panel's configuration. This allows you to set precise colors, or make changes to the panel configuration that aren't permitted within the UI. This also lets you easily copy panels from one dashboard to another by simply copying and pasting the JSON.

A full list of all the panel JSONs displayed in this post are available at github.com/webdes03/Grafana.

Dashboard Refresh

The last step is to define the refresh interval for your dashboard by clicking on the "stopwatch" symbol at the top right corner of the dashboard.

By using now-24h or similar expressions in the "From" time range, the dashboard will automatically update the data based on the current time. Also be sure to set a refresh interval to ensure the data is re-queried and the metrics displayed on the dashboard are current. Lastly, save your dashboard by using the Ctrl + S shortcut, or by clicking on the save icon in the header.

Kiosk Mode

Grafana supports a kiosk mode right out of the box, which is great if you want to display your dashboard on a computer monitor or TV. Simply append "&kiosk=true" to the end of your dashboard's URL, and any unnecessary UI component is hidden for a nice clean look.

Next Steps

We've now got Grafana up and running, it's reporting on values from our SmartThings devices, and that data is being sent reliably. In future Home Automation posts, we'll build more advanced visuals in Grafana, and use the principles of SmartApps from Part 3 to deploy more custom components to our SmartThings ecosystem.