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