So, I finally got around to cleaning up the code a bit and commenting it in order to share it. First off, this is not in any way professional or “clean”. It is just me throwing some stuff down to get it to work. I am not really an OO guy; I think procedurally and so that’s how I code. I have borrowed pieces from others, specifically from Adafruit (the ADC reading code) and I do realize I could be using a lot of loops to run through things, but hey, I’m not worried about size, speed, or cleanliness; just that it works. 🙂 If you are going to use this, be aware of 3 things:
1. You’ll need to sign up for your own API from Weather Underground.
2. You’ll need make sure you’ve installed all the necessary libraries on your Pi. (Read Adafruit’s reading analog data tutorial for this piece. I’ll try to put something together in order to show all of the steps necessary to get this to work.)
3. You’ll need to change your MySQL connection variables
So without further adieu:
#!/usr/bin/env python
import time
import os
import RPi.GPIO as GPIO
import MySQLdb
import urllib2
#set up some GPIO settings
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# set up pin that provides power to moisture probes
GPIO.setup(17, GPIO.OUT)
GPIO.output(17, True)
#read inside temperature sensor. temperature = temp in degrees C
tfile = open("/sys/bus/w1/devices/28-000004d608e1/w1_slave")
text = tfile.read()
tfile.close()
temperaturedata = text.split("\n")[1].split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
#go get outside humidity from weather underground using api
#reading json file to line that contains humidity and pulling
#out the numbers in the text
req = urllib2.Request('http://api.wunderground.com/api/****************/conditions/q/TX/Forney.json')
response = urllib2.urlopen(req)
read_until = 52
humid_line = 54
correctline = []
correct_humid_line = []
lines = []
for line_number, line in enumerate(response.readlines()):
if line_number == read_until:
correctline.append(line)
elif line_number == humid_line:
correct_humid_line.append(line)
else:
lines.append(line)
pull_humid = ','.join(correct_humid_line)
out_humid = pull_humid[-6:-4]
out_humid = round(float(out_humid),1)
# convert celsius to fahrenheit for inside temp
temp_F = ( temperature * 9.0 / 5.0 ) + 32
# show only one decimal place for temperature
temp_F = "%.1f" % temp_F
temp_C = temperature
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout /= 2 # first bit is 'null' so drop it
return adcout
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler. Since I am using 2 ADCs
#I have 2 chip select pins. 25 for the first one and 8 for the
#second one
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
SPICS1 = 8
# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
GPIO.setup(SPICS1, GPIO.OUT)
# set up the pin locations of the different probes. Can only be
#0-7 as there are only 8 pins per ADC
readadc0 = 0
readadc2 = 2
readadc3 = 3
readadc4 = 4
readadc5 = 5
readadc6 = 6
readadc7 = 7
readadc8 = 0
readadc9 = 1
readadc10 = 2
readadc11 = 3
readadc12 = 4
readadc13 = 5
readadc15 = 7
# read the analog pins. Assigning reads to sensor variables
lux_sens0 = readadc(readadc0, SPICLK, SPIMOSI, SPIMISO, SPICS)
moisture_sens1 = readadc(readadc2, SPICLK, SPIMOSI, SPIMISO, SPICS)
lux_sens1 = readadc(readadc3, SPICLK, SPIMOSI, SPIMISO, SPICS)
moisture_sens2 = readadc(readadc4, SPICLK, SPIMOSI, SPIMISO, SPICS)
lux_sens2 = readadc(readadc5, SPICLK, SPIMOSI, SPIMISO, SPICS)
moisture_sens3 = readadc(readadc6, SPICLK, SPIMOSI, SPIMISO, SPICS)
lux_sens3 = readadc(readadc7, SPICLK, SPIMOSI, SPIMISO, SPICS)
moisture_sens4 = readadc(readadc8, SPICLK, SPIMOSI, SPIMISO, SPICS1)
lux_sens4 = readadc(readadc9, SPICLK, SPIMOSI, SPIMISO, SPICS1)
moisture_sens5 = readadc(readadc10, SPICLK, SPIMOSI, SPIMISO, SPICS1)
lux_sens5 = readadc(readadc11, SPICLK, SPIMOSI, SPIMISO, SPICS1)
moisture_sens6 = readadc(readadc12, SPICLK, SPIMOSI, SPIMISO, SPICS1)
lux_sens6 = readadc(readadc13, SPICLK, SPIMOSI, SPIMISO, SPICS1)
humid_sens = readadc(readadc15, SPICLK, SPIMOSI, SPIMISO, SPICS1)
# convert reading from humidity sensor to humidity based on formula
# from datasheet
sensor_humid = (((humid_sens*3.3/1023/3.3)-.1515)/.00636)
humid = sensor_humid /(1.0546 - .00216 * float(temp_C))
inhumid = round(humid,1)
# convert lux into relative terms
#lux0
if lux_sens0 < 10:
lux0 = "Dark"
elif lux_sens0 < 200:
lux0 = "Dim"
elif lux_sens0 < 500:
lux0 = "Light"
elif lux_sens0 < 800:
lux0 = "Bright"
else:
lux0 = "Very Bright"
#lux1
if lux_sens1 < 10:
lux1 = "Dark"
elif lux_sens1 < 200:
lux1 = "Dim"
elif lux_sens1 < 500:
lux1 = "Light"
elif lux_sens1 < 800:
lux1 = "Bright"
else:
lux1 = "Very Bright"
#lux2
if lux_sens2 < 10:
lux2 = "Dark"
elif lux_sens2 < 200:
lux2 = "Dim"
elif lux_sens2 < 500:
lux2 = "Light"
elif lux_sens2 < 800:
lux2 = "Bright"
else:
lux2 = "Very Bright"
#lux3
if lux_sens3 < 10:
lux3 = "Dark"
elif lux_sens3 < 200:
lux3 = "Dim"
elif lux_sens3 < 500:
lux3 = "Light"
elif lux_sens3 < 800:
lux3 = "Bright"
else:
lux3 = "Very Bright"
#lux4
if lux_sens4 < 10:
lux4 = "Dark"
elif lux_sens4 < 200:
lux4 = "Dim"
elif lux_sens4 < 500:
lux4 = "Light"
elif lux_sens4 < 800:
lux4 = "Bright"
else:
lux4 = "Very Bright"
#lux5
if lux_sens5 < 10:
lux5 = "Dark"
elif lux_sens5 < 200:
lux5 = "Dim"
elif lux_sens5 < 500:
lux5 = "Light"
elif lux_sens5 < 800:
lux5 = "Bright"
else:
lux5 = "Very Bright"
#lux6
if lux_sens6 < 10:
lux6 = "Dark"
elif lux_sens6 < 200:
lux6 = "Dim"
elif lux_sens6 < 500:
lux6 = "Light"
elif lux_sens6 < 800:
lux6 = "Bright"
else:
lux6 = "Very Bright"
# convert moisture into relative terms
# moisture1
if moisture_sens1 < 150:
moisture1 = "Dry"
elif moisture_sens1 < 350:
moisture1 = "Moist"
else:
moisture1 = "Wet"
# moisture2
if moisture_sens2 < 150:
moisture2 = "Dry"
elif moisture_sens2 < 350:
moisture2 = "Moist"
else:
moisture2 = "Wet"
# moisture3
if moisture_sens3 < 150:
moisture3 = "Dry"
elif moisture_sens3 < 350:
moisture3 = "Moist"
else:
moisture3 = "Wet"
# moisture4
if moisture_sens4 < 150:
moisture4 = "Dry"
elif moisture_sens4 < 350:
moisture4 = "Moist"
else:
moisture4 = "Wet"
# moisture5
if moisture_sens5 < 150:
moisture5 = "Dry"
elif moisture_sens5 < 350:
moisture5 = "Moist"
else:
moisture5 = "Wet"
# moisture6
if moisture_sens6 < 150:
moisture6 = "Dry"
elif moisture_sens6 < 350:
moisture6 = "Moist"
else:
moisture6 = "Wet"
# get temp from outside sensor. Needed to do this down lower
# as to not get readings from sensors confused
# they are attached to the same pin
tfile1 = open("/sys/bus/w1/devices/28-000004cfffc6/w1_slave")
text1 = tfile1.read()
tfile1.close()
temperaturedata1 = text1.split("\n")[1].split(" ")[9]
temperature1 = float(temperaturedata1[2:])
temperature1 = temperature1 / 1000
temp_F1 = ( temperature1 * 9.0 / 5.0 ) + 32
temp_F1 = "%.1f" % temp_F1
#set in and out temps to variables I can understand
in_temp = temp_F
out_temp = temp_F1
#printing out the readings. Not needed, but used for testing purposes
print("temp_F:", temp_F)
print("temp_F1:", temp_F1)
print("lux0:", lux0)
print("moisture1:", moisture1)
print("lux1", lux1)
print("moisture2:", moisture2)
print("lux2", lux2)
print("moisture3:", moisture3)
print("lux3", lux3)
print("moisture4:", moisture4)
print("lux4", lux4)
print("moisture5:", moisture5)
print("lux5", lux5)
print("moisture6:", moisture6)
print("lux6", lux6)
print("Inside humid:", round(inhumid,1), "%")
print("Outside humid:", round(float(out_humid),1), "%")
print("moisture_sens1:", moisture_sens1)
print("moisture_sens2:", moisture_sens2)
print("moisture_sens3:", moisture_sens3)
print("moisture_sens4:", moisture_sens4)
print("moisture_sens5:", moisture_sens5)
print("moisture_sens6:", moisture_sens6)
#setting the pin that provides the power to the moisture sensors
# to an input as to not provide power in between readings
GPIO.output(17, False)
GPIO.cleanup()
#setting up pin for heater switch
power_pin = 22
GPIO.setup(power_pin, GPIO.OUT)
GPIO.setup(power_pin, False)
# if temperature is below a certain point, turn the heater on
if float(temp_F1) < 50:
GPIO.output(power_pin, True)
htr_status = "ON"
else:
GPIO.output(power_pin, False)
htr_status = "OFF"
print("heater", htr_status)
#setting up pin for pump switch
pump_pin = 11
GPIO.setup(pump_pin, GPIO.OUT)
GPIO.setup(pump_pin, False)
#check to see how many moisture sensors are reading as "Dry"
moisture_count = 0
if moisture1 == "Dry":
moisture_count = moisture_count + 1
if moisture2 == "Dry":
moisture_count = moisture_count + 1
if moisture3 == "Dry":
moisture_count = moisture_count + 1
if moisture4 == "Dry":
moisture_count = moisture_count + 1
if moisture5 == "Dry":
moisture_count = moisture_count + 1
if moisture6 == "Dry":
moisture_count = moisture_count + 1
# if more than a certain amount of sensor read "Dry", then turn on the pump
if float(moisture_count) > 1:
GPIO.output(pump_pin, True)
pump_status = "ON"
else:
GPIO.output(pump_pin, False)
pump_status = "OFF"
print("pump status:", pump_status)
# alarm setup if pump is not coming on. (Will use this later when I
# add the float sensor to the rain barrel to make sure the pump
# doesn't come on when there's no water.) This will act as my alarm
# if there is no water in the barrel
if moisture_count > 3 and pump_status == "OFF":
moisture_alarm = "ON"
else:
moisture_alarm = "OFF"
# Placing data into the database
# Open database connection
db = MySQLdb.connect(host="IP Address", port=3306, user= "user_name", passwd="Password" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Prepare SQL query to INSERT a record into the database.
sql = "INSERT INTO weather_tracking.weather_results (inside_temp, outside_temp, inside_humid, outside_humid, lux0_value, lux0_txt, moisture1_value, moisture1_txt, lux1_value, lux1_txt, moisture2_value, moisture2_txt, lux2_value, lux2_txt, moisture3_value, moisture3_txt, lux3_value, lux3_txt, moisture4_value, moisture4_txt, lux4_value, lux4_txt, moisture5_value, moisture5_txt, lux5_value, lux5_txt, moisture6_value, moisture6_txt, lux6_value, lux6_txt, pump_status, htr_status, moisture_count, moisture_alarm) VALUES (" + str(in_temp) + "," + str(out_temp) + "," +str(inhumid) + "," + str(out_humid) + "," + str(lux_sens0) + ",'" + str(lux0) + "'," + str(moisture_sens1) + ",'" + str(moisture1) + "'," + str(lux_sens1) + ",'" + str(lux1) + "'," + str(moisture_sens2) + ",'" + str(moisture2) + "'," + str(lux_sens2) + ",'" + str(lux2) + "'," + str(moisture_sens3) + ",'" + str(moisture3) + "'," + str(lux_sens3) + ",'" + str(lux3) + "'," + str(moisture_sens4) + ",'" + str(moisture4) + "'," + str(lux_sens4) + ",'" + str(lux4) + "'," + str(moisture_sens5) + ",'" + str(moisture5) + "'," + str(lux_sens5) + ",'" + str(lux5) + "'," + str(moisture_sens6) + ",'" + str(moisture6) + "'," + str(lux_sens6) + ",'" + str(lux6) + "','" + str(pump_status) + "','" + str(htr_status) + "'," + str(moisture_count) + ",'" + str(moisture_alarm) + "')"
print("sql:", sql)
#try:
# Execute the SQL command
cursor.execute(sql)
# Fetch all the rows in a list of lists.
#except:
# print "Error: Unable to Insert Data"
# disconnect from server
db.close()
Such a marvelous little computer…