User Tools

Site Tools


oak:tutorials:python-get

Oak: using python and Particle.variable() to get data from the Oak

In this example, we'll show one way you can make the data sent by the Oak useful with python. You can install python as described in the firmware over serial tutorial. Make sure for the below that you're using python version 2.x (e.g. 2.7), not python v3.

Components used

Part Quantity Identification
Oak with solid headers 1
Breadboard 1
Temperature sensor 1
Battery pack 1
Jumper wires 3

To verify your python environment, open a Command Prompt or terminal and type python and press enter. If python is working properly, you should enter a session:

Python 2.7.11 (default, Mar  3 2016, 11:00:04) 
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

If that happens, you're all set! If not, you should get python in order before proceding. Type quit() and press enter to quit this session.

Concepts

python

python is a programming language. It offers a wide range of capabilities through “modules” which can be imported. Since it has wide adoption as a good general programming language and is relatively fast, it is used in many fields for academic and industry purposes. The modules make it very easy to do certain tasks without having to write the code yourself.

For some examples, it is easy to grab web pages with the module urllib, easy to import and read json data with the json module, and smtplib will make it very simple to send an email with python, as shown below. Since you will often want to use a computer of some sort to act on the data you collect with the Oak, knowing a little about how to program is a a useful skill.

Circuit

This tutorial will utilize a TMP36 analog temperature sensor, but a digital temperature sensor or anything that can generate a changing value read by the Oak will work. The circuit is quite simple:

Here's the setup in real life, with the outer TMP36 pins plugged directly into Vcc and ground, and a soldered jumper connecting the middle pin to A0. It's connected to power using a surplus store 4 x AA battery pack. You could jumper everything to a breadboard just as well if you don't have access to a soldering iron.

tmp36-hookup.jpg

Code

Oak: reading the sensor

To read the temperature, we'll convert the analog reading to millivolts and then to degrees Celsius as described in this Adafruit tutorial. The variable will be accessible through the Particle.variable() function, which we'll read with python and then use to email a notification when it falls below a certain level.

Here's the Oak code:

double tempC = 0;
int analog = 0;
double mv;

void setup()
{                

  // the Particle.variable() function takes two arguments:
  // 1) the name of the Particle variable. This is how you interact
  //    with the Particle cloud to access the value
  // 2) the local variable name to be stored in the cloud variable
  Particle.variable("temp", tempC);

  // we'll configure the on-board LED to blink
  // this is handy for simply making sure the Oak is running your sketch
  pinMode(1, OUTPUT);
  digitalWrite(1, LOW);
  pinMode(A0, INPUT);
  
}


void loop()
{

  // with the tmp36, the temperature is found using this formula:
  // temp in C = (millivolts out - 500)/10
  // we're reading an analog value (0-1023) which is proportional
  // to the analog reference voltage, which on the Oak is 3.3v for Vcc.

  // get the analog value
  analog = analogRead(A0);

  // convert to millivolts
  // if your temperature readings are incorrect; adjust the 2700 value below
  // this *should* be 3300 for a 3.3V analog device, however plain and simple
  // sometimes the sensor needs calibration
  mv = analog * 2700.0 / 1024.0;
    
  // convert from mV to degrees C
  tempC = (mv - 500.0) / 10.0;
 
  // flash the LED
  digitalWrite(1, HIGH);
  delay(100);
  digitalWrite(1, LOW);
  delay(500);
  
}

After uploading this sketch, we can do a test call to the Particle API as described in the Particle.variable() tutorial.

Testing the code

$ curl https://api.particle.io/v1/devices/id_here/temp?access_token=token_here
{
  "cmd": "VarReturn",
  "name": "temp",
  "result": 19.609375,
  "coreInfo": {
    "last_app": "",
    "last_heard": "2016-03-20T17:44:21.275Z",
    "connected": true,
    "last_handshake_at": "2016-03-20T17:43:52.080Z",
    "deviceID": "12345678",
    "product_id": 82
  }

Code: reading the Particle data with python

With that working properly, let's go about reading that data from a computer using python. For the utter basics, we need to import urllib and json to get the API response and read it in. We've added some other modules in order to delay a loop (time), get the current time (datetime), and send an email (smtplib and MIMEText). The core of the functionality is simply in getting and parsing the data; save the following code as temp-get.py:

## import what we need
import urllib
import json

## simplify the url a bit
## replace placeholders for device_id and token below!
base = "https://api.particle.io/v1/devices/"
device_id = "device_id_here"
token = "token_goes_here"

## change this if you used a different Particle.variable() name
var = "/temp"
option = "?access_token="

## put together the full url to query
url = base + device_id + var + option + token

# opens/reads the URL and then parses the json response
data = urllib.urlopen(url).read()
data_json = json.loads(data)

## gets the json value under the "result" key
temp = round(float(data_json["result"]), 2)

print temp

Each time you run the code above, python will print the value stored in results, which corresponds to our call for the temp variable defined by Particle.variable():

$ python ./temp-get.py
19.84

$ python ./temp-get.py
20.14

Code: sending an email with python

If that works, you can now put python to work, checking the temperature with some frequency and doing something in response. Perhaps you might want to check if something gets down to a certain temperature and then email you about it. For this tutorial, we'll imagine that you have put a beer in the freezer and want an email when it's cold.

This is the algorithm we'll use:

  • get the temperature
  • log the current time and temperature in a log file
  • see if it's below a cut off
  • if so, send an email and quit
  • if not, wait a little bit (no sense reading once a second here) and repeat

If we move the code above into a while loop, we can accomplish this flow like so:

## import what we need
## added in time and email requirements
import urllib
import json
import smtplib
import datetime
from time import sleep
from email.mime.text import MIMEText

## simplify the url a bit
## replace placeholders for device_id and token below!
base = "https://api.particle.io/v1/devices/"
device_id = "device_id_here"
token = "token_goes_here"

## change this if you used a different Particle.variable() name
var = "/temp" 
option = "?access_token="

## put together the full url to query
url = base + device_id + var + option + token

# initialize a variable so we know when to stop the loop
email = 0

# as long as email is 0, run the below again and again
while email == 0:

    # same code as above; get URL data, convert to json and extract temp
    data = urllib.urlopen(url).read()
    data_json = json.loads(data)

    temp = round(float(data_json["result"]), 2)

    # store the current system time for this reading
    now = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S")

    # define some cutoff; if the temperature is below 5C, do this:
    if temp < 5 :
    
        # this composes the message
        msg = MIMEText("The beer is cold; it's " + str(temp) + " C!")
        addy = "your_email_address@here.com"
        msg["Subject"] = "Get to the freezer!"
        msg["From"] = addy
        msg["To"] = addy

        # this will send an email from you, to you, through your smtp server
        # google your email provider and "smtp settings" to find out yours
        print "emailing..."
        smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
        smtpserver.ehlo()
        smtpserver.starttls()
        smtpserver.ehlo()
        smtpserver.login(addy, "your_email_password")
        smtpserver.sendmail(addy, addy, msg.as_string())
        smtpserver.close()

        # now we set email to 1 so the while loop stops
        email = 1

    # each time through, add the time and temperature to a file
    # you may have to create this file if it doesn't exist
    log = open("/path/to/tmp36_data-log.csv", "a")
    log.write(str(temp) + "," + now + "\n")
    log.close()

    # wait 10 seconds and repeat
    sleep(10)

# when all done (email sent), tell us
print "done"

Unfortunately, long wires on the TMP36 thwarted my attempts to record an actual beer's temperature in my freezer, so I simply put the bundle out on my porch (Minnesota). The nice part about storing the data to a local log file is you can plot it easily by importing the csv formatted file into Excel, LibreOffice, etc.

Based on the temperature outside, I adjusted the cutoff to 11C (if temp < 11 above) after I saw it wasn't going to drop below 10C. Here's what I got!

Conclusion

This tutorial taught a little about how to collect data from the Oak with python so that some functionality could be enabled. In this instance, we were sending an email; some real life applications might be:

  • letting you know it's near freezing so you can cover your plants and protect from frost
  • an alert about the temperature at a cabin so you can wirelessly turn on the heat and your pipes don't freeze
  • a notification that your beer in the freezer is now cold so you don't forget and have it explode in your ice tray…

Perhaps you can imagine other ways you'd like to “act” on some bit of data you could collect with the Oak. Hopefully this helps you in some small way to start on such a project!

oak/tutorials/python-get.txt · Last modified: 2016/03/24 18:54 by jwhendy