Last active
August 8, 2017 16:05
-
-
Save hamidzr/8f70d9147af024a19e3da9b50ac1c0c5 to your computer and use it in GitHub Desktop.
helper script to normalize and upload sensor readings from an arduino to thingspeak's MQTT broker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python2.7 | |
# normalize and publish weather sensor readings to thingspeak | |
from time import sleep | |
import datetime | |
import serial # install pySerial | |
import paho.mqtt.client as mqtt | |
import sys | |
SERIAL_PORT = sys.argv[2] if len(sys.argv) > 2 else '/dev/ttyUSB1' | |
MQTT_HOST = 'mqtt.thingspeak.com' | |
MQTT_TOPIC = 'channels/305027/publish/{}'.format(sys.argv[1]) | |
SENDING_WINDOW = 15 #average how many messages before sending? | |
ser = serial.Serial(SERIAL_PORT, 115200) # Establish the connection on a specific port | |
# Set the PUBLISH messages to have a QoS value of 0. | |
# Set the connection RETAIN flag to 0. | |
# Set the connection CleanSession flag to 1. | |
client = mqtt.Client() | |
client.connect(MQTT_HOST) | |
def createPayload(fieldValues): | |
payload = [] | |
for idx, val in enumerate(fieldValues): | |
payload.append("field{}={}".format(idx+1, val)) | |
# we are assuming that there is no delay between reading from serial and creating the payload | |
payload = '&'.join(payload) + "&created_at={}&timezone=America/Chicago".format(datetime.datetime.now().isoformat(), ) | |
return payload | |
def readNextValues(): | |
line = ser.readline() # QUESTION does this block untill a new line is available? | |
rawValues = line.split(',') | |
rawValues[-1] = rawValues[-1].replace('\r\n','') | |
values = [] | |
for value in rawValues: | |
values.append(float(value)) | |
print(values) | |
return values | |
# averages an accumulated array of sensor values. | |
def averageReadings(valuesArr): | |
averageSensorValues = [0] * len(valuesArr[0]) # init with 0 | |
for x in range(0,SENDING_WINDOW): | |
for y in range(0,len(averageSensorValues)): | |
averageSensorValues[y] += valuesArr[x][y] | |
for x in range(0,len(averageSensorValues)): | |
averageSensorValues[x] /= SENDING_WINDOW | |
averageSensorValues[x] = round(averageSensorValues[x],2) | |
return averageSensorValues | |
client.loop_start() # starts a spawns a background thread to keep the connection up | |
while True: | |
gatheredValues = [] | |
while len(gatheredValues) < SENDING_WINDOW: | |
try: # guard against the unexpected | |
gatheredValues.append(readNextValues()) | |
except Exception as e: | |
print(e) | |
continue # to next iteration | |
# calculate the average of these readings. | |
avgSensorValues = averageReadings(gatheredValues) | |
# send it to server | |
print('average is', avgSensorValues) | |
client.publish(MQTT_TOPIC, createPayload(avgSensorValues)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment