Beer IoT (Part 3)

Published Sunday, January 29, 2017 by Bryan

My code is ugly, but it works, so it's time to post part three of this series. In part one, I downloaded data captured by my BeerBug. In part two, I uploaded it to the Helium platform. In this entry, I'll read use Helium's API to query and graph the data.

If I were dealing with a currently-active data source, Helium's dashboard would allow me to view what was happening. That is a fantastic resource for developers, because it takes one step of uncertainty out of the equation by allowing inspection in the middle of the pipeline. But, "currently-active" is limited to 90 days in the dashboard, and my data is about a year old, so I need something else.

What I have built are a few simple D3 graphs:

Each graphs the average value for a time slice as a dark line, with a lighter band around it marking the range from minimum to maximum. It's crude, but it gets the point across. You can move earlier and later in the range by dragging left and right. Zoom in by holding shift while dragging to select a region. Zoom out by holding alt while dragging to select a region.

As I said before, it's ugly, but I've put the code in a gist, if you're looking for examples to follow (it's neither well-organized nor well-documented, but if you're also working with the Helium API, you may pick up on a clue of what you're looking for).

Some things that made this graphing easy:

  • Helium supports CORS, so I didn't even have to set up a proxy webservice. Loading graph.html from a file:// URL still allowed me to make requests to Helium to for the data.
  • D3 has a wide variety of basic example graphs. What I started with was a basic mash-up of the Line Chart and Bitvariate Area Chart examples.
  • Helium's API will give you the latest data for your sensor (note: no 90-day window here), if you don't provide an end filter, and also include a "previous" link in the response to get the next-latest data.

Some things that made this graphing hard (or at least tricky):

  • D3 defaults to local time, but Helium is all in UTC. Forgetting to translate leads to confusing debugging about why offset calculations are wrong.
  • Helium's API will always¬†give you the latest data for your sensor, if you don't provide an end filter. That is, you can really only follow "previous" links backward through time. Once you follow a "previous" link, you'll get a "next" link, but you should already have the data that link would give you. You can't begin with a start filter and expect to follow "next" links to the latest data.

I'm posting this simple viewer now instead of waiting until I've had time to clean it up more, because the next step is probably a rewrite. As expected, Helium's API works really well for supporting a simple dashboard: if you're concerned with recent updates, and then scrolling back in time from there, the API makes it easy. But, what I learned during a Helium presentation at a meetup this week is that the real purpose of this API is to allow Helium's servers to act as a transport between your sensors and your own servers. The expectation is that you'll grab data from Helium, store it in your own database, and serve your app from your own storage.

Helium-as-transport is an interesting bet. It's focusing on exactly the problem I've had with my BeerBug: I have to rely on their site for the tool to be useful. If Helium can keep the path from device to my analysis up more reliably, they will succeed in their goal of making sensor IoT more available to people that want to focus on the sensing and the analysis, whtout worrying about the infrastructure in between (i.e. bascially everyone).

Update: Part 4 is up - hardware on display!

Categories: Development