Hello! Here are some images of the new grow setup:
and here is the working version of the code:
import time from time import sleep from time import strftime import tweepy consumer_key="" consumer_secret="" access_token="" access_token_secret="" auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) PiPlanter_Full = False import logging logging.basicConfig() from apscheduler.scheduler import Scheduler import os import sys import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) # Start of mysql setup import MySQLdb user = MySQLdb.connect(host="localhost",user="root",passwd="") cursor = user.cursor() MySQLdb_Name = 'PiPlanter' + strftime("_%m_%d_%Y_%I_%M_%S%p") mysql_table_name = MySQLdb_Name + '_table' mysql_create = 'CREATE DATABASE IF NOT EXISTS PiPlanter' mysql_grant = "GRANT ALL ON `" + MySQLdb_Name + "`.* TO 'piplanter'@'localhost' IDENTIFIED BY 'password'" mysql_use = 'USE PiPlanter' if PiPlanter_Full == True: #Full PiPlanter mysql_table = "CREATE TABLE " + mysql_table_name + "(Sample_Number INT NOT NULL AUTO_INCREMENT PRIMARY KEY,Time VARCHAR(100),P_TMP0 VARCHAR(100),P_MST0 VARCHAR(100),P_TMP1 VARCHAR(100),P_MST1 VARCHAR(100),P_TMP2 VARCHAR(100),P_MST2 VARCHAR(100),P_TMP3 VARCHAR(100),P_MST3 VARCHAR(100),A_TMP0 VARCHAR(100),A_LDR0 VARCHAR(100),A_LDR1 VARCHAR(100),A_MST0 VARCHAR(100))" else: #Simple PiPlanter mysql_table = "CREATE TABLE " + mysql_table_name + "(Sample_Number INT NOT NULL AUTO_INCREMENT PRIMARY KEY,Time VARCHAR(100),P_MST0 VARCHAR(100),P_MST1 VARCHAR(100),A_TMP0 VARCHAR(100),A_LDR0 VARCHAR(100))" #A new database must be created each time the program runs cursor.execute(mysql_create) cursor.execute(mysql_grant) cursor.execute(mysql_use) cursor.execute(mysql_table) pins = {'MST_Enable' : 8} #assign names to GPIO pins for d in pins.itervalues(): GPIO.setup(d,GPIO.OUT) #first ADC setup on SPI port 1 import spidev spi_1 = spidev.SpiDev() spi_1.open(0, 1) #first ADC setup on SPI port 0 import spidev spi_0 = spidev.SpiDev() spi_0.open(0, 0) #this function can be used to find out the ADC value on ADC 0 def readadc_0(adcnum_0): if adcnum_0 > 7 or adcnum_0 < 0: return -1 r_0 = spi_0.xfer2([1, 8 + adcnum_0 << 4, 0]) adcout_0 = ((r_0[1] & 3) << 8) + r_0[2] return adcout_0 #this function can be used to find out the ADC value on ADC 1 def readadc_1(adcnum_1): if adcnum_1 > 7 or adcnum_1 < 0: return -1 r_1 = spi_1.xfer2([1, 8 + adcnum_1 << 4, 0]) adcout_1 = ((r_1[1] & 3) << 8) + r_1[2] return adcout_1 #this function converts a given value from the ADC and turns it into usable data def convertadc(adcinput,unit): millivolts = adcinput*(3300.0/1024.0) #converts the ADC value to milivolts temp_c = ((millivolts - 100.0)/10)-40.0 percent = (adcinput/1024.0)*100 if unit == 'c' : #used for a temperature sensor to return Celsius return temp_c elif unit == 'f' : #used for a temperature sensor to return Fahrenheit temp_f = (temp_c * 9.0 / 5.0) + 32 return temp_f elif unit == 'mV': return millivolts elif unit == '%': return percent else: print "convertadc input error" return 0 #returns a usable numerical value from the ADC def pollsensor(sensor,unit,precision,samples): GPIO.output(pins['MST_Enable'], True) if PiPlanter_Full == True: #Full PiPlanter sensors = {\ 'P_TMP0' : convertadc(readadc_0(0),unit),\ 'P_MST0' : convertadc(readadc_0(1),unit),\ 'P_TMP1' : convertadc(readadc_0(2),unit),\ 'P_MST1' : convertadc(readadc_0(3),unit),\ 'P_TMP2' : convertadc(readadc_0(4),unit),\ 'P_MST2' : convertadc(readadc_0(5),unit),\ 'P_TMP3' : convertadc(readadc_0(6),unit),\ 'P_MST3' : convertadc(readadc_0(7),unit),\ 'A_TMP0' : convertadc(readadc_1(0),unit),\ 'A_LDR0' : convertadc(readadc_1(1),unit),\ 'A_LDR1' : convertadc(readadc_1(2),unit),\ 'A_MST0' : convertadc(readadc_1(3),unit)} else: #Simple PiPlanter sensors = {\ 'P_MST0' : convertadc(readadc_0(0),unit),\ 'P_MST1' : convertadc(readadc_0(1),unit),\ 'A_TMP0' : convertadc(readadc_0(2),unit),\ 'A_LDR0' : convertadc(readadc_0(3),unit)} outputsum = 0 for x in range(0,samples): #An averaging algorithm that creates a more precise reading outputsum = outputsum + sensors[sensor] output = round(outputsum/samples, precision) GPIO.output(pins['MST_Enable'], False) return output #samples all sensors, outputs different formats of the data to be used in other places in the program def sampleallsensors(sensor_precision,sensor_samples,form): if PiPlanter_Full == True: #Full PiPlanter current_sensors = {\ 'P_TMP0' : pollsensor('P_TMP0' , 'f', sensor_precision, sensor_samples),\ 'P_MST0' : pollsensor('P_MST0' , '%', sensor_precision, sensor_samples),\ 'P_TMP1' : pollsensor('P_TMP1' , 'f', sensor_precision, sensor_samples),\ 'P_MST1' : pollsensor('P_MST1' , '%', sensor_precision, sensor_samples),\ 'P_TMP2' : pollsensor('P_TMP2' , 'f', sensor_precision, sensor_samples),\ 'P_MST2' : pollsensor('P_MST2' , '%', sensor_precision, sensor_samples),\ 'P_TMP3' : pollsensor('P_TMP3' , 'f', sensor_precision, sensor_samples),\ 'P_MST3' : pollsensor('P_MST3' , '%', sensor_precision, sensor_samples),\ 'A_TMP0' : pollsensor('A_TMP0' , 'f', sensor_precision, sensor_samples),\ 'A_LDR0' : pollsensor('A_LDR0' , '%', sensor_precision, sensor_samples),\ 'A_LDR1' : pollsensor('A_LDR1' , '%', sensor_precision, sensor_samples),\ 'A_MST0' : pollsensor('A_MST0' , '%', sensor_precision, sensor_samples)} else: #Simple PiPlanter current_sensors = {\ 'P_MST0' : pollsensor('P_MST0' , '%', sensor_precision, sensor_samples),\ 'P_MST1' : pollsensor('P_MST1' , '%', sensor_precision, sensor_samples),\ 'A_TMP0' : pollsensor('A_TMP0' , 'f', sensor_precision, sensor_samples),\ 'A_LDR0' : pollsensor('A_LDR0' , '%', sensor_precision, sensor_samples)} if form == 'MySQL': if PiPlanter_Full == True: #Full PiPlanter output = "INSERT INTO " + mysql_table_name + "(Time, P_TMP0, P_MST0, P_TMP1, P_MST1, P_TMP2, P_MST2, P_TMP3, P_MST3, A_TMP0, A_LDR0, A_LDR1, A_MST0)" + " VALUES(NOW()" + "," + str(current_sensors['P_TMP0']) + "," + str(current_sensors['P_MST0']) + "," + str(current_sensors['P_TMP1']) + "," + str(current_sensors['P_MST1']) + "," + str(current_sensors['P_TMP2']) + "," + str(current_sensors['P_MST2']) + "," + str(current_sensors['P_TMP3']) + "," + str(current_sensors['P_MST3']) + "," + str(current_sensors['A_TMP0']) + "," + str(current_sensors['A_LDR0']) + "," + str(current_sensors['A_LDR1']) + "," + str(current_sensors['A_MST0']) + ")" else: #Simple PiPlanter output = "INSERT INTO " + mysql_table_name + "(Time, P_MST0, P_MST1, A_TMP0, A_LDR0)" + " VALUES(NOW()" + "," + str(current_sensors['P_MST0']) + "," + str(current_sensors['P_MST1']) + "," + str(current_sensors['A_TMP0']) + "," + str(current_sensors['A_LDR0']) + ")" elif form == 'Console': if PiPlanter_Full == True: #Full PiPlanter output = 'Debug Update:' + ' P_TMP0: ' + str(str(current_sensors['P_TMP0'])) + ',' + ' P_MST0: ' + str(str(current_sensors['P_MST0'])) + ',' + ' P_TMP1: ' + str(str(current_sensors['P_TMP1'])) + ',' + ' P_MST1: ' + str(str(current_sensors['P_MST1'])) + ','+ ' P_TMP2: ' + str(str(current_sensors['P_TMP2'])) + ','+ ' P_MST2: ' + str(str(current_sensors['P_MST2'])) + ','+ ' P_TMP3: ' + str(str(current_sensors['P_TMP3'])) + ','+ ' P_MST3: ' + str(str(current_sensors['P_MST3'])) + ',' + ' A_TMP0: ' + str(str(current_sensors['A_TMP0'])) + ',' + ' A_LDR0: ' + str(str(current_sensors['A_LDR0'])) + ','+ ' A_LDR1: ' + str(str(current_sensors['A_LDR1'])) + ','+ ' A_MST0: ' + str(str(current_sensors['A_MST0'])) else: #Simple PiPlanter output = 'Debug Update:' + ' P_MST0: ' + str(str(current_sensors['P_MST0'])) + ',' + ' P_MST1: ' + str(str(current_sensors['P_MST1'])) + ',' + ' A_TMP0: ' + str(str(current_sensors['A_TMP0'])) + ',' + ' A_LDR0: ' + str(str(current_sensors['A_LDR0'])) elif form == 'Twitter': if PiPlanter_Full == True: #Full PiPlanter output = 'Ambient LDR: ' + str(round(((current_sensors['A_LDR0'] + current_sensors['A_LDR1'])/2),1) ) + '%, ' + 'Ambient Tmp: ' + str(round(current_sensors['A_TMP0'],1)) + 'DF, ' + 'Average Plant Tmp: ' + str(round( (current_sensors['P_TMP0'] + current_sensors['P_TMP1'] + current_sensors['P_TMP2'] + current_sensors['P_TMP3'] )/4, sensor_precision-2)) + 'DF, ' + 'Ambient Mst: ' + str(round(current_sensors['A_MST0'],2)) + '%, ' + 'Average Plant Mst: ' + str(round( (current_sensors['P_MST0']+current_sensors['P_MST1']+ current_sensors['P_MST2']+ current_sensors['P_MST3'] )/4 ,1)) + '%' else: #Simple PiPlanter output = 'Ambient Light: ' + str(round((current_sensors['A_LDR0']),1)) + '%, ' + 'Ambient Temp: ' + str(round(current_sensors['A_TMP0'],1)) + 'DF, ' + 'Average Plant Mst: ' + str(round( (current_sensors['P_MST0']+current_sensors['P_MST1'])/2 ,1)) + '%' else: print "convertadc input sampleallsensors" return 0 return output pumps = {'PUMP0' : 7, 'PUMP1' : 11, 'PUMP2' : 13, 'PUMP3' : 16} #assign names to GPIO pins for k in pumps.itervalues(): GPIO.setup(k,GPIO.OUT) #pumps a given amount of water from a given pump def pumpwater(pump,volume): LPM = 4.00 #L per minute ontime = volume*(60/LPM) GPIO.output(pumps[pump],True) time.sleep(ontime) GPIO.output(pumps[pump],False) output = 'Pumped ' + str(volume) + ' L of water into plants in ' + str(ontime) + ' seconds.' return output #Sets up proper directories for folders and images def visualssetup(time): #checks if directories above exist if not os.path.exists(str(os.getcwd()) + '/videos/'): os.makedirs(str(os.getcwd()) + '/videos/') if not os.path.exists(str(os.getcwd()) + '/videos/dailys/'): os.makedirs(str(os.getcwd()) + '/videos/dailys/') if not os.path.exists(str(os.getcwd()) + '/images/'): os.makedirs(str(os.getcwd()) + '/images/') if not os.path.exists(str(os.getcwd()) + '/images/dailys/'): os.makedirs(str(os.getcwd()) + '/images/dailys/') global current_dailypicdir current_dailypicdir = str(os.getcwd()) + '/images/dailys/' + str(time) + '/' os.makedirs(current_dailypicdir) global current_dailyvideodir current_dailyvideodir = str(os.getcwd()) + '/videos/dailys/' + str(time) + '/' os.makedirs(current_dailyvideodir) def picture(dir,cycle): image = dir + str(cycle).zfill(4) + '.jpg' picture_command = 'raspistill -o ' + dir + str(cycle).zfill(4) + '.jpg' os.system(picture_command) return image def rendervideo(): time = strftime("%m-%d-%Y_%I-%M-%S%p") global current_videodir scheduler.shutdown(shutdown_threadpool=False) render_command = 'sudo mencoder -nosound mf://' + current_dailypicdir + '*.jpg -mf w=2592:h=1944:type=jpg:fps=15 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=2160000:mbd=2:keyint=132:v4mv:vqmin=3:lumi_mask=0.07:dark_mask=0.2:mpeg_quant:scplx_mask=0.1:tcplx_mask=0.1:naq -o ' + current_dailyvideodir + 'output.avi' os.system(render_command) def daily(): visualssetup(strftime("%m-%d-%Y_%I-%M-%S%p")) api.update_status(pumpwater('PUMP0',3)) global cycle cycle = 0 def hourly(): cursor.execute(sampleallsensors(3,20,'MySQL')) user.commit() print sampleallsensors(3,20,'Console') pumpwater('PUMP0', .5) global current_dailypicdir api.update_status(sampleallsensors(3,20,'Twitter') + " https://esologic.com/?page_id=1042") picture(current_dailypicdir,cycle) #pumpwater('PUMP0', 1) global cycle cycle = cycle + 1 if __name__ == '__main__': daily() hourly() scheduler = Scheduler(standalone=True) scheduler.add_interval_job(hourly, hours=1) scheduler.add_interval_job(daily, days=1) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass
I’ll do a much more thorough post when the project is further along. For those playing along at home, you can see that I’ve totally re-written the code for this new version. So far, it has much less functionality but much more stability and flexibility.