Skip to content

Instantly share code, notes, and snippets.

@lseppala
Last active November 15, 2016 16:38
Show Gist options
  • Save lseppala/2da643d917fd8598243e98a2f1960c55 to your computer and use it in GitHub Desktop.
Save lseppala/2da643d917fd8598243e98a2f1960c55 to your computer and use it in GitHub Desktop.

Visualizing IoT Data with Helium and Plotly

Whether its building an IoT prototype or scaling out an entire commercial product, Helium provides the tools for you to to quickly develop your ideas.

I'm here to introduce you to part of Helium toolkit and to demonstrate how to integrate Heliium's IoT platform with any tool or service you desired.

We're going to use the Helium Python SDK and the Python library for Plotly. Plotly is a data visualization service that allows you to collaboratively build charts, dashboards, and presentations. The Helium Dashboard also provides informative graphs that allow you to dive into your data. Here, we're using Plotly to demonstrate how easy it is to access Helium data and quickly build a useful application through integration of Helium with other services.

Visualizing Temperature Data From a Helium Sensor

We'll begin by setting up everything we need to build a Helium-powered Python application. We'll only need two libraries for our examples: helium-python and plotly:

# Install globally
pip install helium-python plotly

# Or use virtualenv (recommended)
virtualenv venv
source venv/bin/activate
pip install helium-python plotly

The following code snippets are intended to be copied into a single file or copied piecemeal into a Python interpreter (python, pypy, ipython, etc.).

Every value denoted by Brackets (< and >) will need to be replaced with the appropriate values.

The Helium API token can be obtained from logging into the Helium Dashboard and copying the token in the Settings page. The Plotly API credentials can be obtained in the API Key section of the Settings page when logged in.

Here we go!

import helium
import plotly.plotly as py
import plotly.graph_objs as go

helium_api_token = <Helium API Token>
plotly_user_name = <Plotly User Name>
plotly_api_key = <Plotly User API Key>

# Set up the Helium Client
client = helium.Client(api_token=helium_api_token)

# Authenticate with Plotly
py.sign_in(plotly_user_name, plotly_api_key)

Next, we'll connect to a sensor and get the 50 most recent temperature readings.

sensor_id = <SENSOR UUID>
sensor = client.sensor(sensor_id)

print('Connected to sensor: ' + sensor.name)


# We specify that we want data on port 't', for temperature
temperature_timeseries = sensor.timeseries(port='t')

# We take 50 of the most recent temperature readings
temperature_data = temperature_timeseries.take(50)

We have the temperature readings, now we'll create a data visualization with Plotly.

# Get the timestamps for each data point
x_values = [helium.from_iso_date(datum.timestamp) for datum in temperature_data]

# Get the temperature value for each data point
y_values = [datum.value for datum in temperature_data]

figure = go.Scatter(
    x = x_values,
    y = y_values )

plot_layout = go.Layout(
    title = 'Temperature of ' + sensor.name,
    xaxis = {'title' : 'Time (UTC)' },
    yaxis = {'title' : 'Temperature, ˚C' } )

plot_url = py.plot({
    'layout' : plot_layout,
    'data' : [figure] })

# Let's see the URL for our new chart!
print(plot_url)

Chart of Temperature data from Sensor

The py.plot command may automatically open up a browser window with your new graph; otherwise, open the URL printed to the screen.

See how simple that was? This is the goal of the Helium platform: to empower you to build products faster.

Visualizing Complex Data from a Helium Sensor

Now that we know how to retrieve data from a sensor's timeseries, let's do something a bit more interesting. The Helium API provides powerful ways of aggregating your data to help you cut through noise and make sense of your data. The Helium API can aggregate a sensor's timeseries by minimum, maximum, or average values over definable time periods, such as minutes, hours, or days. A single Helium sensor can also represent multiple different types of data in the timeseries, such as temperature, humidity, pressure, and 4-20ma current loops. The options for retrieving data from a sensor's timeseriesis [explained in more detail in our documentation].(https://docs.helium.com/api/v1/overview.html#timeseries)

Let's graph the maximum temperature against the average atmospheric pressure for each hour over the past 72 hours.

# We get the max temperature on port 't' for each hour
hour_max_temperature = sensor.timeseries(port='t',
                                           agg_size='1h',
                                           agg_type='max' )

# We get the average pressure on port 'p' for each hour
hour_avg_pressure = sensor.timeseries(port='p',
                                           agg_size='1h',
                                           agg_type='avg' )

# We take the past 72 hours of data
hour_max_temp_data = hour_max_temperature.take(72)
hour_avg_pressure_data = hour_avg_pressure.take(72)

temp_x_values = [helium.from_iso_date(datum.timestamp) for datum in hour_max_temp_data]
pressure_x_values = [helium.from_iso_date(datum.timestamp) for datum in hour_max_temp_data]

# We access the `.max` and `.avg` attributes for the aggregate values
temp_y_values = [datum.value.max for datum in hour_max_temp_data]
pressure_y_values = [datum.value.avg for datum in hour_avg_pressure_data]

# Our figure for temperature
temp_figure = go.Scatter(
    x = temp_x_values,
    y = temp_y_values,
    name = "Temperature" )

# Our figure for pressure, graphed on a separate y-axis
pressure_figure = go.Scatter(
    x = pressure_x_values,
    y = pressure_y_values,
    name = "Pressure",
    yaxis = "y2" )

# Our graph layout, with temperature on the left y-axis and pressure on the right
plot_layout = go.Layout(
    title = 'Hourly Max Temperature and Average Pressure of ' + sensor.name,
    xaxis = {'title' : 'Time (UTC)' },
    yaxis = {'title' : 'Temperature, ˚C' },
    yaxis2 = {'title' : 'Pressure, atm', 'overlaying' : 'y', 'side' : 'right' } )

plot_url = py.plot({
    'layout' : plot_layout,
    'data' : [temp_figure, pressure_figure] })

print(plot_url)

Chart of Max Temperature and Average Pressure

With Helium, you can iterate quickly through multiple ideas to find the solution that works best for you. Had we wanted to collate minimum temperature and maximum humidity instead, it would be only a few small changes to deploy a new visualization of our sensor's data.

Visualizing Live Data from a Helium Sensor

We saw how easy it was getting historical data from a Helium sensor, but what about live data? Live data is especially important for building services that provide timely feedback on the processes you're observing. The Helium platform is designed to quickly and robustly deliver live streams of data from your sensors. In our next exmaple, we'll take advantage of Plotly's streaming API to visualize live pressure and temperature data.

Plotly Stream Tokens can be obtained on the same page the API key was found.

# We need two different Plotly Stream Tokens
temp_stream_token = <Plotly Stream Token 1>
pressure_stream_token = <Plotly Stream Token 2>

# Our live figure for temperature
temp_figure = go.Scatter(
    x = [],
    y = [],
    name = "Temperature",
    stream = go.Stream(token=temp_stream_token))

# Our live figure for pressure, graphed on a separate y-axis
pressure_figure = go.Scatter(
    x = [],
    y = [],
    name = "Pressure",
    stream = go.Stream(token=pressure_stream_token),
    yaxis = "y2" )

# Our live graph layout, with temperature on the left y-axis and pressure on the right
plot_layout = go.Layout(
    title = 'Live Temperature and Pressure of Helium-powered Sensor',
    xaxis = {'title' : 'Time (UTC)' },
    yaxis = {'title' : 'Temperature, ˚C' },
    yaxis2 = {'title' : 'Pressure, atm', 'overlaying' : 'y', 'side' : 'right' } )

plot_url = py.plot({
    'layout' : plot_layout,
    'data' : [temp_figure, pressure_figure] })

print(plot_url)

This sets up a graph with streaming capabilities in Plotly. Open the Plotly chart URL in your browser, and let's stream some data directly from our sensor into it!

from threading import Thread
import time

# We set up our two streams
temperature_stream = py.Stream(temp_stream_token)
pressure_stream = py.Stream(pressure_stream_token)

# Plotly streams close after about a minute of inactivity. We set up a thread
# to send heartbeats every 30 seconds to keep the streams alive, in the case
# our sensor reports less often.
send_heartbeat = True

def send_stream_heartbeats():
    while send_heartbeat:
        temperature_stream.heartbeat()
        pressure_stream.heartbeat()
        time.sleep(30)

heartbeat = Thread(target=send_stream_heartbeats)

# Now let's stream some data!
try:
    temperature_stream.open()
    pressure_stream.open()
    heartbeat.start()

    # We establish the live connection to our sensor
    with sensor.timeseries().live() as live:
        for data_point in live:

            # Send our temperature data to the temperature stream if the
            # reading is on port 't'
            if data_point.port == 't':
                temperature_stream.write({
                    'x' : helium.from_iso_date(data_point.timestamp),
                    'y' : data_point.value })

            # Send our pressure data to the pressure stream if the
            # reading is on port 'p'
            if data_point.port == 'p':
                pressure_stream.write({
                    'x' : helium.from_iso_date(data_point.timestamp),
                    'y' : data_point.value })

# Clean up when we cancel our stream
finally:
    temperature_stream.close()
    pressure_stream.close()
    send_heartbeat = False

You may run the stream as long as you want and hit Control-C to cancel at any time.

Chart of Live Temperature and Pressure

Next steps

We've only touched the surface of what's possible with the Helium API and toolkits. In our examples, we only used a single sensor to demonstrate how to use Helium, but using data from multiple sensors would have been just as easy. We invite you to look at our documentation and see all that we have to offer. We have also prepared a sample application applying what you've learned here to quickly create Plotly graphs from Helium sensor data. Take a look here, and feel free to reuse these concepts to build out your own product idea.

Want to Learn More About Helium? Talk to us!

  • If you’re interested in finding out more about Helium, visit www.helium.com for an overview of our products.

  • Development kits and all necessary hardware to start building connected products can be purchased at store.helium.com.

  • Join our Slack community at chat.helium.com and speak directly to the Helium team as well as other Helium developers.

  • If you’d like to discuss an upcoming project with us, let us know and we’ll get in touch soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment