Help build the future of open source observability software Open positions

Check out the open source projects we support Downloads

The actually useful free plan

Grafana Cloud Free Tier
check

10k series Prometheus metrics

check

50GB logs, 50GB traces, 50GB profiles

check

500VUk k6 testing

check

20+ Enterprise data source plugins

check

100+ pre-built solutions

Featured webinar

Getting started with grafana LGTM stack

Getting started with managing your metrics, logs, and traces using Grafana

Learn how to unify, correlate, and visualize data with dashboards using Grafana.

Lighting up your dashboards: How to visualize the CheerLights IoT project in Grafana Cloud

Lighting up your dashboards: How to visualize the CheerLights IoT project in Grafana Cloud

2025-09-26 9 min

I recently joined the Developer Advocacy team here at Grafana Labs, and have been exploring ways to accelerate my Grafana learning journey. 

Like many others in the Grafana community, my introduction to the open source project happened when I needed a way to easily visualize data that resided in external databases, mostly using SQL queries. And, since one of my long-time personal interests outside of work is experimenting with Internet of Things (IoT) devices, I decided to bring that passion into my Grafana learning and see how the two could connect.

In this blog post, I’ll show you how I built a Grafana Cloud dashboard that shows the current and previous states of the popular CheerLights IoT project. Continue reading to learn how to set up this project at home — or, feel free to skip ahead and check out the live CheerLights dashboard I’ve made available on Grafana Play.

A quick overview of CheerLights

Created by Hans Scharler in 2011, CheerLights is a global network of synchronized light installations that can be controlled by anyone. For those learning about IoT devices, I consider CheerLights a good next step after completing the “Hello, World!” LED blink project.

Anyone can set the current CheerLights color using a bot in the project’s Discord, or by interacting with the project’s BlueSky or Mastodon accounts. Here’s an example of setting the CheerLights color from Discord, which is how I usually do it.

Chat interface showing CheerLights commands with color options like Red, Green, and Blue. A message sets CheerLights to red.

In the example above, I chose to set the CheerLights color to red. You can see the full range of supported colors in the bot’s initial response.

So what happens when a new color is set? Every CheerLights installation — which could be a physical light display, or virtual displays on web pages, widgets, or apps — in the world receives this update by one or more of the following methods:

  • By subscribing to messages on the project’s MQTT broker.
  • By consuming a JSON feed from the project’s ThingSpeak Channel.

Here’s an example of a CheerLights installation I built using a matrix of multi-colored LEDs. It shows the current color in the center and the previous 12 around the outside.  

A photo of CheerLights installation that is an LED light display with red, blue, green, and yellow sections.

To learn more about the CheerLights architecture, please check out the project’s website.

Gathering data for the dashboard

I decided to build my CheerLights dashboard using the Grafana Cloud free tier. (If you don’t already have a free Grafana Cloud account, you can sign up for one today). 

Building a dashboard to display only the latest CheerLights color seemed a little too simple, so I decided to incorporate additional analytics into Grafana Cloud. The CheerLights JSON feed was the perfect data source for this, as it contains information about the 100 most recent colors.

The following is what the feed (available here on ThingSpeak) looks like.

{
  "channel": {
    "id": 1417,
    "name": "CheerLights",
    …
  },
  "feeds": [
    {
      "created_at": "2025-06-24T21:41:13Z",
      "entry_id": 1037549,
      "field1": "blue",
      "field2": "#0000ff"
    },
    {
      "created_at": "2025-06-24T21:41:37Z",
      "entry_id": 1037550,
      "field1": "pink",
      "field2": "#ffc0cb"
    },
    …
  ]
}

I’ve omitted some of the data items here for brevity, so imagine that the feeds key contains an array of 100 objects, each containing the information about a single color change. The last object in that array represents the current color.

This seemed to be exactly what I needed to show both the current color and some analysis of previous colors on a dashboard, without having to store data in a database. But I wondered: how do I get data from a JSON API endpoint into my Grafana Cloud dashboard?

Choosing a data source: to Infinity and beyond!

My previous experience with Grafana data sources was limited to PostgreSQL and MySQL, as I’d mostly been working with relational databases. But I knew that Grafana Labs’ big tent philosophy enables users to visualize data from a wide variety of sources. A quick search through Grafana docs suggested that the Infinity data source plugin was the one I needed.

The Infinity data source is a universal plugin to pull data from various systems into Grafana — whether it’s Grafana OSS, Grafana Enterprise, or, in our case, Grafana Cloud — using existing REST APIs. If you want to learn more, I suggest checking out this blog post and learning journey dedicated to the Infinity data source. 

Reading CheerLights data into Grafana Cloud

The first objective was to get the data from the JSON feed into Grafana Cloud, and to be able to show it as is. A table panel made a lot of sense for this, so I started there. Like other panel types, the table needs a data source, so I selected Infinity (grafanacloud-infinity).

Screenshot of Grafana Infinity data aource setup page with options for authentication, documentation, and private data source connection.

The Infinity data source has a plethora of configuration options and different ways to parse data. The CheerLights feed is a fairly straightforward JSON structure accessible at an API endpoint with no authentication or custom HTTP headers required, which greatly simplifies things. Note, however, that custom headers, POST requests, and other configuration options are supported here, as well.

Configuring the Infinity data source

I configured the Infinity data source as shown below, giving it the URL of the JSON feed and path to the array feeds, which contained the data I needed.

Screenshot of the Grafana Cloud UI displaying configuration options for the Infinity data source.

The field names in the feed aren’t that meaningful, so I configured alternate names for them and made sure Grafana Cloud interpreted the created_at timestamps in the data as time rather than as a string.

In the Transformations tab, I configured a single transformation to sort the data in reverse time order, so that the most recent entry came first. 

Grafana Cloud UI showing a 'Sort by' transformation in progress, with 'time' selected as the field and reverse option toggled on.

Adding a splash of color

Finally, I wanted to use the CheerLights colors as the background for each row in the table.

Table showing columns for color names, hex codes, and timestamps. Includes colors like red, pink, yellow, and green.

I achieved this by configuring a set of value mappings that mapped the CheerLights color names to colors that can then be used to highlight rows in the table.

Grafana Cloud interface showing value mappings with color options. A color picker is open, displaying RGB (255, 165, 0) for orange.

In order to get the background color to appear across every column in the table, I set the table cell type to “Colored background” and made sure that each column’s cell type property was set to “Auto.”

Showcasing the current color

The most prominent component of any CheerLights installation is usually a display of the current color. The stat panel looked like a good choice for displaying the color and its name as a sort of “hero” metric.

A stat panel with a bright orange background and the word 'orange' in bold white text, displayed under the label 'Current Color.'

This turned out to be very simple to configure: I just set the data source to the table panel that I previously added to the dashboard, and then set up similar value mappings to make the colored background work.

To get the most recent color from the data source, I selected the “Last” reducer function (remember — the data has the most recent color last) and the name of the data field containing the color name as text when configuring the stat panel.

Grafana Cloud interface showing visualization options with a dropdown for 'Stat,' calculation settings, and a 'Calculate' button for data analysis.

Adding basic analytics with bar charts

It’s great to show the current state of the system, but I also wanted to add value to the dashboard by introducing some basic analytics. Given the data I had, I set out to answer the following questions by adding a couple of bar chart panels to the dashboard:

  • Which CheerLights colors are the most popular?
  • How regularly is the color updated?

Neither of these panels required a new data source — I could simply re-use the existing data from my original table in each of them.

Displaying CheerLights colors by popularity

Having selected the existing table panel as the data source for my first bar graph, I needed to aggregate the data by color and get a count of each color value. To make the graph easy to read, I wanted the colors sorted by frequency, so the highest to lowest count.

I achieved this by using a couple transformations when adding the data source. The first transformation grouped the data by the color field, then counted the number of records for each, and ignored the time that the color was selected, as it wasn’t relevant here.

The Grafana Cloud UI showing options to configure a transformation, including group by color and calculate count, with sorting by color_hex count in reverse order.

The second transformation sorted the resulting count in descending order, giving me a bar chart that looked like the one below.

A bar chart in Grafana Cloud titled 'Last 100 by Color,' showing red with the highest value, followed by orange, oldlace, pink, cyan, yellow, purple, magenta, blue, and green.

As before, I used value mappings to color the bars with the correct CheerLights color codes.

Counting color changes per hour

The final panel is where I got a little more ambitious, and had to perform a number of transformations on the data. As with the other panels, I re-used the existing data source from my original table.  

Here’s what the final bar graph looked like.

A bar chart in Grafana Cloud titled 'Color Changes per Hour,' showing spikes on 30 June.

This required a bit more data wrangling than with the previous panels. In order to count the number of changes per hour, I first needed to work out which hour “bucket” each color change fell into.

I achieved this by first taking the timestamp for each entry and dividing it by 3,600,000 (one hour in milliseconds). This gave me the number of hours since the date epoch. I then used a floor transformation to round this down to the nearest whole number of hours, before multiplying by 3,600,000 again to get the timestamp representing the start of the hour in which the color change happened. 

The Grafana Cloud UI showing three sections for adding fields for transformations.

Then, I added another transformation to group by these new “start of hour” timestamps and count the number of entries in each, similar to the previous bar graph.

Pulling all the data together

After adding all of the different panels and arranging them to my liking, here’s what the final dashboard looked like.

A Grafana Cloud dashboard displaying color data: a large 'orange' stat panel, bar chart of color usage, color change table, and hourly color change graph.

I now have a centralized way to view the current CheerLights color, review the history of color changes, and see other general trends related to the CheerLights project. For example, in the above screenshot, we can see that red has been the most popular color recently, and that there was an unusually high number of color changes at 9 AM on June 30th.

As mentioned earlier, I’ve added this dashboard to Grafana Play, our public sandbox environment where you can learn about all things Grafana. Be sure to check it out!

Wrapping things up… for now

So what did I learn from building this relatively simple dashboard?  

First, I discovered that Grafana Cloud can read, transform, visualize, and aggregate data from sources other than databases. I also learned about the Infinity data source, and how to re-use data from one panel as the data source for another, minimizing duplicate API requests.

This isn’t the end of my journey with CheerLights and Grafana Cloud, so please stay tuned for more fun, IoT-related projects. 

Grafana Cloud is the easiest way to get started with metrics, lots, traces, dashboards, and more. We have a generous forever-free tier and plans for every use case. Sign up for free now!