Lighting up your dashboards: How to visualize the CheerLights IoT project in Grafana Cloud
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.

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.

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
).

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.

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.

Adding a splash of color
Finally, I wanted to use the CheerLights colors as the background for each row in the table.

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.

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.

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.

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 second transformation sorted the resulting count in descending order, giving me a bar chart that looked like the one below.

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.

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.

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.

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!