In this project we take a Raspberry Pi 2 and use it to send some pH data to the Microsoft Cloud. The Raspberry Pi 2 seems like it might be overkill for this purpose but there are a few other nice things that we can do with this computer. We can write a few estimation algorithms to "clean up" the noisy output of the sensor. This work will mostly be done in Python while the work on the microsoft Azure side will be mostly in NodeJS for now. We use Microsoft's DocumentDB framework to store the data and retrieve it. We are also making the hardware side open source so feel free to also use "portal-0"
Embedded Code Overview
saveFile.py
The purpose of this file is to initialize the communication with the Atlas Scientific probe and then write it to a file. It just repeats this process endlessly. You should probably run it in the background. You could also take out the 'print' statements but I leave them in there so you can 'see' it working on the embedded side.
import serial # required for communication with boards
import time, datetime
from time import strftime # used for timestamps
#USB parameters
usbport = '/dev/ttyACM0'
ser = serial.Serial(usbport, 9600, timeout = 0) # sets the serial port to the specified port, with a 9600 baud rate
# Timeout = 0 tells the serial port to not wait for input if there is non
# declare and initialize the data buffers
line = ""
user_input = ""
#clear serial buffer
ser.write("\r")
#turn on LEDS
ser.write("L,1\r")
#enable streaming
ser.write("C,1\r")
def check_ph_level(line):
# compares the ph reading to a value and displays if its higher or lower
try:
ph = float(line) # converts the string into a floating point number
if(ph >= 7.5):
print("High"+ "\n")
if(ph < 7.5):
print("Low"+ "\n")
except ValueError:
# if the string is not a valid floating point number, dont do anything
pass
filename = "data.txt" ## "/hummingbirdembedded1/models/data.txt" ## "
#main loop
while True:
# sensor receive
data = ser.read() # get serial data
if(data == "\r"): # if its terminated by a newline
print("> " + strftime("%Y-%m-%d %H:%M:%S") +
" Received from sensor: " + line + "\n") #print the timestamp and received data to the main screen
check_ph_level(line) # calls function to check ph levels
with open(filename,"r+") as f:
f.seek(0)
f.write("P " + line)
f.close()
line = "" # clears the input
time.sleep(5)
else:
line = line + data # if the line isn't complete, add the new characters to it
time.sleep(5)
postData.py
Here is how you post the data. Like I said we are giving out the key for anyone to post to our service. You can also see the hash algorithm. This took awhile to figure out so I hope someone can benefit from it.
import re, requests, json ,datetime, time
import urllib
import hashlib
import hmac
import base64
class sensor(object):
def __init__(self, sType=None, value=None, unit=None, status=None):
self.sType = sType
self.value = value
self.unit = unit
self.status = status
class Device(object):
def __init__(self, power=None, sensor=sensor, ID=None, name=None, version=None, deviceStatus=None):
self.deviceStaus = deviceStatus
self.power = power
self.sensor = sensor
self.ID = ID
self.name = name
self.version= version
def uploadData():
sD = ""
key = 'YOMfbmtih/oEERPw3u3ha2wazXR0N2uSFsN61+cKjpM='
url = 'https://vivaplanetbusservicedev.servicebus.windows.net/hummingbirdqueue/messages'
keyName = 'DevicePolicy'
now = datetime.datetime.utcnow()
then = datetime.datetime(1970, 1, 1, 0, 00, 00, 000000)
expiry = str(int((now-datetime.datetime(1970,1,1)).total_seconds())) ## '1440710529' ##
##print str(expiry)
resourceUri = urllib.quote_plus(url).lower()
message = bytes(resourceUri).encode('utf-8') + '\n' + expiry
##print message
secret = bytes(key).encode('utf-8')
##print secret
signature = urllib.quote_plus(base64.b64encode(hmac.new(secret,message,hashlib.sha256).digest()))
##print signature
signature = re.sub("(%[0-9A-F][0-9A-F])", lambda m: m.group(0).lower(),...
Read more »