Skip to content

Instantly share code, notes, and snippets.

@hamidzr
Last active August 8, 2017 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hamidzr/8f70d9147af024a19e3da9b50ac1c0c5 to your computer and use it in GitHub Desktop.
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
#!/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