Get started with your IoT devices using iotery.io
Tags: tutorial, python, javascript
Published: 2019-06-13 12:11:38

[Iotery](https://about.iotery.io) is a managed IoT (Internet of Things) service that was born out of the need to eliminate the complexities of configuring and deploying with the various IoT cloud players of today: AWS IoT, GCP Core IoT, Azure IoT.  Iotery attempts to provide developers a way to get their IoT devices connected to the cloud in under 15 minutes.  This tutorial aims to provide you with an example to get started in 15 minutes.

What you will need for this tutorial:
1. Raspberry Pi (not required, but will be cooler!)
2. Basic knowledge of Python
3. Basic knowledge on how to set up and connect to your Raspberry Pi

## Setting up an Iotery Account
Iotery gives a generous free tier that allows up to 5 devices for free for life.  For most hobbyists, this should be more than enough!  Setting up a free account is easy: [https://dashboard.iotery.io](https://dashboard.iotery.io/register-team-manager).  

Iotery splits different environments into what they call `teams`.  For this tutorial, we will just be using a single `team` called `speedy-fast` - you will want to create your own name.

> If you are doing production-ready stuff - you will want to create two teams - one for production and one for testing.

![](https://thepracticaldev.s3.amazonaws.com/i/88i4a316su43xpgnsh61.png)

Once we have our team, we are presented with an initial screen to create a `Device Type`.  Before we speed off on doing something, let's make a quick plan.

## Let's make a plan
Let's say we want to set up a device (a "thing") to report a temperature every 5 minutes to the cloud. Let's also have our device report the temperature when we send it a command.

Here's a simple diagram of what we will be doing:

![](https://thepracticaldev.s3.amazonaws.com/i/xc3zru795gkp122vrvmn.png)

## Configuring Iotery for our Temperature Sensor
We need to do four things in the Iotery dashboard to get ready to report data to the cloud:
1. Create our temperature sensor `Device Type`
2. Create our temperature sensor `Device`
3. Create our temperature `Data Type`
4. Create a `Command Type`

#### Creating the Device Type
We need to set up Iotery to allow our Raspberry Pi to report.  Since our Raspberry Pi is acting as a (really beefy) temperature sensor, we will [create a device type](https://iotery.io/device-types/create) in Iotery Dashboard called `Temperature Sensor`.  All devices that are temperature sensors will be derived from this `device type` (for our purposes, we will only need one device - our Raspberry Pi!).

![](https://thepracticaldev.s3.amazonaws.com/i/t12ar3n0whvlpa40u8rd.png)

>We can also just use the [REST API](https://iotery.io/docs/account-manager#tag/Device-Types/paths/~1device-types/post) to create a device type.

#### Creating the Device
Next, we need to [create a `device`](https://iotery.io/devices/create).  You can set the `serial`, `key`, and `secret` to whatever you want - this is how you give your device its identity.  We will use this later to authenticate our Raspberry Pi with Iotery.

> Just like the device type creation, we can also just the [REST API](https://iotery.io/docs/account-manager#tag/Devices/paths/~1devices/post) to create our device. Oh, there is also a [JavaScript Node.js SDK](https://www.npmjs.com/package/iotery-server-sdk)!

![](https://thepracticaldev.s3.amazonaws.com/i/w9f69oiwo621bgivxapb.png)

The choice of `secret` is yours - just make sure to keep it secret!  In this tutorial, we have opted to use `BASIC` authentication, so we will just use the `serial`, `key`, and `secret` to authenticated.  Also make sure to set the `Device Type` to the `Temperature Sensor` device type we created previously.

> If you want to be even more secure, you can use the `KEYED` option and use X.509 certificates for cryptographically signed authentication with Iotery.

#### Creating Data Types
In order to report data to the cloud, we need to tell Iotery what type of data to expect.  In this case, we will be reporting a temperature, so we need to make a `Temperature` data type and assign it to our `Temperature Sensor` device type.

![](https://thepracticaldev.s3.amazonaws.com/i/04xaezv600c10beqb67l.png)

Once we create it, make a note of the `enum` you chose to name it.  This will be used in the `data` packet when we send data up (it is not case sensitive!).

> You can use the [REST API](https://iotery.io/docs/account-manager#tag/Data-Types/paths/~1data-types/post) to do this too!

We will set up the command later - let's get our temperature sensor (Raspberry Pi) reporting to the cloud!

## Setting up our Raspberry Pi Temperature Sensor
> The code and project below can be found [here](https://github.com/bjyurkovich/iotery-in-15-minutes-raspberry-pi).

Since we now have Iotery set up with our temperature sensor identity, we can get to coding our Raspberry Pi.  Iotery provides an [embedded Python SDK](https://pypi.org/project/iotery-embedded-python-sdk/) to make life easier connecting our devices to the cloud!  Let's set up our project.

> If you need help setting up your Raspberry Pi, there are a number of tutorials on the web.  Make sure to install Python 3.  Here is an [example tutorial](http://www.knight-of-pi.org/installing-python3-6-on-a-raspberry-pi/) to install Python 3 on your pi.   If you do not have a Raspberry Pi, that's okay - you can do this on your laptop...you just won't be able to report a real temperature.

Logging into our Raspberry Pi on the command line, we will create a folder in our `home` directory and `cd` into it:

```
mkdir iotery-temperature-sensor
cd iotery-temperature-sensor
```

Once in the folder, we will [create a virtual environment](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/), making sure to use `python3` as the primary interpreter:

```
virtualenv -p python3 venv
```

and we will activate the `virtualenv`:

```
source venv/bin/activate
```

You will know if it worked if there is a little `(venv)` at the beginning of your terminal line.

In the activated virtual environment, we will install the `iotery-embedded-python-sdk`:

```
pip install iotery-embedded-python-sdk
```

We are ready to start coding our sensor!

## Sensor Code
To start, let's create a file `main.py` in our `iotery-temperature-sensor` folder that will be our sensor application file:

```
touch main.py
```

Open `main.py` in your favorite Python IDE (we like [VSCode](https://code.visualstudio.com)) and get to coding:

```python
from iotery_embedded_python_sdk import Iotery

# team ID found on the dashboard: https://iotery.io/system
TEAM_ID="188baf45-8d55-11e9-c121-d283610663ed" 
iotery = Iotery()
d = iotery.getDeviceTokenBasic(data={"key": "temp-sensor-key",
                                     "serial": "temp-sensor-1", "secret": "my-secret", "teamUuid": TEAM_ID})

# set token for subsequent iotery calls
iotery.set_token(d["token"])

# get info about the device
me = iotery.getMe()

print(me["name"])
```

In this code snippet, we instantiate the `Iotery` class, then call `getDeviceTokenBasic`, passing in the identity that we created on the iotery dashboard for the device. Once we authenticated with Iotery, we got a `token` back, that we can use for other calls, like `getMe()`.

> Don't forget to replace the `TEAM_ID` with the ID of your team (see the System page on the dashboard) as well as `my-secret` with the secret that you used when creating the device.

Great!  We are now connected with Iotery.  When you run the code above, you should see the name of your device `temp-sensor-1` printed to the console.

### Reading temperature
We are going to create a helper function to read the Raspberry Pi's CPU temperature (unfortunately, the Pi does not come with a built in temperature sensor).  In a new file called `read_temperature.py`, we write

```python
import os
import random

# we checking for a real Pi - this code will also work on your computer
real_pi = True
try:
    import RPi.GPIO as GPIO
    real_pi = True
except:
    real_pi = False

def current_cpu_temperature():
    # gets the current CPU temperature of the Pi
    if real_pi:
        temp = os.popen("/opt/vc/bin/vcgencmd measure_temp").readline()
        temp = temp.replace("temp=","")
        temp = temp.replace("'C","")
        return float(temp)
    else:
        return 50 + int(random.random()*100)/100

```

and now we can add it to our `main.py` with a loop that reports our temperature data every 5 minutes.

```python
from iotery_embedded_python_sdk import Iotery
from read_temperature import current_cpu_temperature
from time import sleep


# team ID found on the dashboard: https://iotery.io/system
TEAM_ID="188baf45-8d55-11e9-c121-d283610663ed" 
iotery = Iotery()
d = iotery.getDeviceTokenBasic(data={"key": "temp-sensor-key",
                                     "serial": "temp-sensor-1", "secret": "my-secret", "teamUuid": TEAM_ID})

# set token for subsequent eatery calls
iotery.set_token(d["token"])

# get info about the device
me = iotery.getMe()

print(me["name"])

while True:
    t = iotery.getCurrentTimestamp()
    temp = current_cpu_temperature()

    # https://iotery.io/docs/embedded/#tag/Embedded/paths/%7E1embedded%7E1devices%7E1:deviceUuid%7E1data/post
    data = {"packets":[{
        "timestamp": t,
        "deviceUuid": me["uuid"],
        "deviceTypeUuid": me["deviceTypeUuid"],
        "data":{"temperature": temp}
    }]}
    iotery.postData(deviceUuid=me["uuid"], data=data)
    sleep(60 * 5) # sleeps for 60 * 5 seconds (5 min)
```

We've added a few lines of code to `main.py`.  The primary addition are the new `import` dependencies (first few lines), and the `while True` loop, which will run forever.

That loop simply gets the current timestamp from the Iotery server (you could also use the local time if you wanted with `int(time.time())`), gets the current temperature from our function we created, then posts the data to Iotery, and then sleeps for 5 minutes.

If you check out your device page in the dashboard, you can see the last time your device reported in the Live Data section.
![](https://thepracticaldev.s3.amazonaws.com/i/v1aporax2angd6c0z1so.png)

Great, we are reporting to the cloud, and we still have some time left to set up our device to respond to a command to report!

## Setting up Commands for our Temperature Sensor
We would like to be able to request the temperature any time from our Pi, so we need to send it a command.  Just like before, we must tell Iotery what command types we will be sending.  We just need one command: `REPORT_TEMPERATURE`.
![](https://thepracticaldev.s3.amazonaws.com/i/h396hn2cltep5ybs8uqb.png)


But how do we get our Pi to listen for the command?  We can use [MQTT](http://mqtt.org).  Simply put, MQTT allows our devices to remain in constant contact with Iotery and get real-time data (including commands).  [Iotery provides a fully managed MQTT broker](https://iotery.io/docs/mqtt) that we can have our Pi connect to and receive commands.

We will use a [Python MQTT library](https://pypi.org/project/paho-mqtt/) to connect to Iotery's broker.  Let's install it in the same folder as our application code (make sure you are still in your virtual environment!):

```
pip install paho-mqtt
```

and let's add the necessary code to `main.py`

```python
from iotery_embedded_python_sdk import Iotery
from read_temperature import current_cpu_temperature
from time import sleep, time
import paho.mqtt.client as mqtt
import ssl


# team ID found on the dashboard: https://iotery.io/system
TEAM_ID="188baf45-8d55-11e9-c121-d283610663ed" 
iotery = Iotery()
d = iotery.getDeviceTokenBasic(data={"key": "temp-sensor-key",
                                     "serial": "temp-sensor-1", "secret": "my-secret", "teamUuid": TEAM_ID})

# set token for subsequent eatery calls
iotery.set_token(d["token"])

# get info about the device
me = iotery.getMe()

#  Set up the MQTT stuff
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    #once connected, subscribe to the command topic
    client.subscribe("devices/" + me["uuid"] + "/commands")
    

# The callback for when something is published to the broker.
def on_message(client, userdata, msg):
    print("Received from topic" + msg.topic)
    print("Message: " + str(msg.payload))

    if msg.topic == "devices/" + me["uuid"] + "/commands":
        # There is only one command for now, so we will just report.  If we add more later, we can look at the `commandTypeEnum` to control actions
        t = iotery.getCurrentTimestamp()
        temp = current_cpu_temperature()
        # https://iotery.io/docs/embedded/#tag/Embedded/paths/%7E1embedded%7E1devices%7E1:deviceUuid%7E1data/post
        data = {"packets":[{
            "timestamp": t,
            "deviceUuid": me["uuid"],
            "deviceTypeUuid": me["deviceTypeUuid"],
            "data":{"temperature": temp}
        }]}
        iotery.postData(deviceUuid=me["uuid"], data=data)
        print("data posted!")

client_id = TEAM_ID + ":" + str(iotery.getCurrentTimestamp()*1000) + ":" + me["uuid"] #Iotery client ID format
client = mqtt.Client(client_id)
client.on_connect = on_connect # set the connect handler to run when mqtt connects
client.on_message = on_message # the function that runs when we get a message

# username and password are your device's uuid and it's token we got back from auth above
client.username_pw_set(me["uuid"], password=d["token"])

# To use MQTTS (secure MQTT), we need to configure TLS
client.tls_set(ca_certs=None, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED,
    tls_version=ssl.PROTOCOL_TLS, ciphers=None) 

#  connect to the broker
client.connect("mqtt.iotery.io", port=8885, keepalive=60)

client.loop_start() # make sure to start the mqtt loop!

# the main application loop!
while True:
    t = iotery.getCurrentTimestamp()
    temp = current_cpu_temperature()

    # https://iotery.io/docs/embedded/#tag/Embedded/paths/%7E1embedded%7E1devices%7E1:deviceUuid%7E1data/post
    data = {"packets":[{
        "timestamp": t,
        "deviceUuid": me["uuid"],
        "deviceTypeUuid": me["deviceTypeUuid"],
        "data":{"temperature": temp}
    }]}
    iotery.postData(deviceUuid=me["uuid"], data=data)
    sleep(60 * 5) # sleeps for 60 * 5 seconds (5 min)
```

We added a lot of code functionality!  Let's go through the additions one by one.

#### Add the necessary imports
We need to add the necessary libraries.
```python
from iotery_embedded_python_sdk import Iotery
from read_temperature import current_cpu_temperature
from time import sleep, time
import paho.mqtt.client as mqtt
import ssl
```
We added the MQTT library `paho.mqtt.client` and `ssl`.  We need `ssl` to use Iotery's secure MQTT option (MQTTS, MQTT over TLS).

#### MQTT callbacks
The MQTT library we are leveraging uses interrupts, so we must provide functions to handle the cases when our application connects to the broker, as well as when a message comes in.

```python
#  Set up the MQTT stuff
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    #once connected, subscribe to the command topic
    client.subscribe("devices/" + me["uuid"] + "/commands")
    

# The callback for when something is published to the broker.
def on_message(client, userdata, msg):
    print("Received from topic" + msg.topic)
    print("Message: " + str(msg.payload))

    if msg.topic == "devices/" + me["uuid"] + "/commands":
        # There is only one command for now, so we will just report.  If we add more later, we can look at the `commandTypeEnum` to control actions
        t = iotery.getCurrentTimestamp()
        temp = current_cpu_temperature()
        # https://iotery.io/docs/embedded/#tag/Embedded/paths/%7E1embedded%7E1devices%7E1:deviceUuid%7E1data/post
        data = {"packets":[{
            "timestamp": t,
            "deviceUuid": me["uuid"],
            "deviceTypeUuid": me["deviceTypeUuid"],
            "data":{"temperature": temp}
        }]}
        iotery.postData(deviceUuid=me["uuid"], data=data)
        print("data posted!")
```
> For simplicity of this tutorial, we have not set the `command` as `executed`. In a real application, we will want to notify Iotery that our device has set our [command executed](https://iotery.io/docs/embedded#tag/Embedded/paths/~1embedded~1command-instances~1:commandInstanceUuid~1executed/patch) or with the python SDK: `iotery.setCommandInstanceAsExecuted(deviceUuid=me["uuid"], commandInstanceUuid=command_from_broker["uuid"])`

The `on_connect` callback handler runs when our Pi connects to the broker.  MQTT has a `publish/subscription` model, where a client (our Pi) must `subscribe` to topics.  We want to subscribe to the [command topic](https://iotery.io/docs/mqtt) for our device so we get commands when we send them: `client.subscribe("devices/" + me["uuid"] + "/commands")`.

#### MQTT set up and connection to broker
We need to provide the appropriate address for the broker along with our credentials.

```python
client_id = TEAM_ID + ":" + str(iotery.getCurrentTimestamp()*1000) + ":" + me["uuid"] #Iotery client ID format
client = mqtt.Client(client_id)
client.on_connect = on_connect # set the connect handler to run when mqtt connects
client.on_message = on_message # the function that runs when we get a message

# username and password are your device's uuid and it's token we got back from auth above
client.username_pw_set(me["uuid"], password=d["token"])

# To use MQTTS (secure MQTT), we need to configure TLS
client.tls_set(ca_certs=None, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED,
    tls_version=ssl.PROTOCOL_TLS, ciphers=None) 

#  connect to the broker
client.connect("mqtt.iotery.io", port=8885, keepalive=60)
```

The `client_id` must be in a specific format in order to connect to the broker.  You will will also notice that we have opted to use MQTTS (MQTT over TLS) that encrypts all our data while in transit.  We must tell the MQTT library that we are doing this with our `client.tls_set(...)` function.

#### Starting the MQTT loop
The library we are using is threaded, so we must tell our application to start the loop (before our `while True` directive):
```python
client.loop_start()
```

### Sending the Command
Now that we have a working connection with the broker, we are almost done!  We just need to send the command now. We can do this in the [Iotery Dashboard](https://iotery.io/devices) by viewing the `Device` we want to command (in our case, our Pi).
![](https://thepracticaldev.s3.amazonaws.com/i/xv8zj6mpv04qaxhs0wc0.png)

As soon as you send the command, you should see our Pi print out the command message and a `data posted!` string to the terminal.

> You can also use the [REST API](https://iotery.io/docs/account-manager#tag/Devices/paths/~1devices~1:deviceUuid~1notification-instances/post) to send the command from your cloud or consumer mobile app that you build.

## Wrapping up
If you made it to this point, nice work (you get extra points if you did in 15 minutes)!  We now have a Raspberry Pi (or your computer) connected to the cloud reporting data. If you implemented the MQTT communication, you can also send it real-time commands!

We have just brushed the surface of Iotery with this example.  Iotery also provides the ability to:
1. Create Device Networks where only one of the devices acts as a gateway
2. Create Device Groupings
3. Create schedules for your devices and commands
4. Create notifications and alerts with severity and priority
5. Manage firmware
6. Use webhooks to create value-added applications with the [Account Manager API](https://iotery.io/docs/account-manager) that allows you to connect your own apps and manage your own experience without being locked-in with ballooning infrastructure costs.
7. Use webhooks to train your own AI models and analytics!

...and much more.