Okay! So I leave for college in less than 30 days, but I’d like to make sure my tomatoes to continue to grow once I leave so I’ve taken some steps to make sure that my departure goes smoothly.
Here’s a video of my revised setup:
There are a few key differences between this setup and my previous one:
The main one is that the watering system has been 100% re-vamped. The water distribution happens via a hose with holes in it instead of using the tray at the bottom of the plant grid in the previous video.
It also takes, uploads and tweets a picture of itself using a raspberry pi camera module.
It also creates a new mysql table every two weeks, and in turn, renders a new kind of graph. The renderscript.php file receives an argument from the python script which is the table code.
Here’s the python script:
#Timing setup from datetime import datetime from apscheduler.scheduler import Scheduler import time import datetime import sys import os now =datetime.datetime.now() #import logging #if you start getting logging errors, uncomment these two lines #logging.basicConfig() #GPIO setup import RPi.GPIO as GPIO GPIO.setmode(GPIO.BOARD) GPIO.cleanup() pin = 26 #pin for the adc GPIO.setup(pin, GPIO.OUT) NPNtrans = 3 #the pin for the npn transistor GPIO.setup(NPNtrans, GPIO.OUT) sampleLED = 5 #the indicator LED GPIO.setup(sampleLED, GPIO.OUT) pump = 7 #pin for the pump GPIO.setup(pump, GPIO.OUT) GPIO.output(pump, False) #the adc's SPI setup import spidev spi = spidev.SpiDev() spi.open(0, 0) #sets up the program's ability to write to a mysql database import MySQLdb con = MySQLdb.connect('localhost','piplanter_user','piplanter_pass','piplanter'); cursor = con.cursor() #tweepy setup, you must use the keys given to you when you create your app import tweepy consumer_key="" consumer_secret="" access_token="" access_token_secret="" #"logs in" to twitter, auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) #Flickr Setup import flickrapi api_key = '' api_secret = '' flickr = flickrapi.FlickrAPI(api_key, api_secret, format='json') (token, frob) = flickr.get_token_part_one(perms='write') if not token: raw_input("Press ENTER after you authorized this program") flickr.get_token_part_two((token, frob)) #Variable Setup ontime = 60 global table_number table_number = 0 #fuction that can read the adc def readadc(adcnum): # read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7) if adcnum > 7 or adcnum < 0: return -1 r = spi.xfer2([1, 8 + adcnum << 4, 0]) adcout = ((r[1] & 3) << 8) + r[2] return adcout def water(): print "===== Starting Watering Process =====" GPIO.output(NPNtrans, True) GPIO.output(sampleLED, True) time.sleep(1) sensor1_before = readadc(0) sensor2_before = readadc(1) sensor3_before = readadc(2) sensor4_before = readadc(3) before = "WATERING START / Moisture Before - " + "Sensor 1:" + str(sensor1_before) + " Sensor 2:" + str(sensor2_before) + " Sensor 3:" + str(sensor3_before) + " Sensor 4:" + str(sensor4_before) + " - Average:" + str((float(sensor1_before+sensor2_before+sensor3_before+sensor4_before)/4)) api.update_status(before) print before GPIO.output(pump, True) time.sleep(ontime) GPIO.output(pump, False) time.sleep(60) #gives the water time to penetrate the soil sensor1_after = readadc(0) sensor2_after = readadc(1) sensor3_after = readadc(2) sensor4_after = readadc(3) after = "WATERING COMPLETED / Moisture After - " + "Sensor 1:" + str(sensor1_after) + " Sensor 2:" + str(sensor2_after) + " Sensor 3:" + str(sensor3_after) + " Sensor 4:" + str(sensor4_after) + " - Average: " + str((float(sensor1_after+sensor2_after+sensor3_after+sensor4_after)/4)) api.update_status(after) print after GPIO.output(NPNtrans, False) GPIO.output(sampleLED, False) print "====== Watering Process Complete =====" def hourlyUpdate(): GPIO.output(pump, False) print "----------start----------\n" GPIO.output(NPNtrans, True) GPIO.output(sampleLED, True) time.sleep(1) sampleTime = time.ctime() mst1 = 1024-readadc(0) mst2 = 1024-readadc(1) mst3 = 1024-readadc(2) mst4 = 1024-readadc(3) pot1 = readadc(4) ldr1 = readadc(5) millivolts = readadc(6)*(3300.0/1024.0) temp_c = ((millivolts - 100.0)/10)-40.0 tmp1 = (temp_c * 9.0 / 5.0) + 32 print 'Polling Probes \n' #prints debug info to console print sampleTime,"|","MST1:",mst1,"MST2:",mst2,"MST3:",mst3,"MST4:",mst4,"Pot1:",pot1,"LDR1:",ldr1,"TMP1:",tmp1 #prints the debug info global table_number print 'Adding Data To Table: ' + str(table_number) #adds the data to the mysql table global table_number cursor.execute('INSERT INTO piplanter_table_'+ table_code +'(Time,mst1_V,mst2_V,mst3_V,mst4_V,pot1_V,ldr1_V,tmp1_F) VALUES(%s,%s,%s,%s,%s,%s,%s,%s)',(sampleTime,mst1,mst2,mst3,mst4,pot1,ldr1,tmp1)) con.commit() #this is important for live updating GPIO.output(NPNtrans, False) #turns the probes off print 'Data Collected, Disengaging Probes \n' #takes a picture of the plants print 'Taking Picture with Raspberry Pi Camera Board' picture_dir = '/home/pi/documents/piplanter/images/' os.system('raspistill -o ' + picture_dir + str(time.strftime('%m-%d-%y_%H-%M-%S')) + '.jpg') print 'Capture Successfull: ' + picture_dir + str(time.strftime('%m-%d-%y_%H-%M-%S')) + '.jpg' #finds the newest image in the directory print '\nUploading Picture To Flickr' picture_allfiles = sorted(os.listdir(picture_dir), key=lambda p: os.path.getctime(os.path.join(picture_dir, p))) picture_newest = picture_dir+picture_allfiles[-1] print 'File for upload: ' + picture_newest #prints location and file to console #uploads the picture of the plants to flickr picture_title = 'Picture @ ' + str(sampleTime) picture_response = flickr.upload(filename=picture_newest, title=picture_title, format='etree') #uploads the file to flickr picture_photoID = picture_response.find('photoid').text #gets the id of the photo for constructing a url print 'Picture Upload Successful, Photo ID: ' + picture_photoID + '\n' #more debug info time.sleep(10) #renders the image of the graph print "Graph Render Start" global table_code os.system('php /opt/bitnami/wordpress/piplanter/renderScript.php ' + table_code ) #renders the .png file print "Graph Render Complete \n" #finds the newest image in the directory print 'Uploading Graph To Flickr' graph_allfiles = sorted(os.listdir('/opt/bitnami/wordpress/piplanter/renders/'), key=lambda p: os.path.getctime(os.path.join('/opt/bitnami/wordpress/piplanter/renders/', p))) graph_newest = '/opt/bitnami/wordpress/piplanter/renders/'+graph_allfiles[-1] print 'File for upload: ' + graph_newest #prints location and file to console graph_title = 'Graph @ ' + str(sampleTime) graph_response = flickr.upload(filename=graph_newest, title=graph_title, format='etree') #uploads the file to flickr graph_photoID = graph_response.find('photoid').text #gets the id of the photo for constructing a url print 'Graph Upload Successful, Photo ID: ' + graph_photoID + '\n' #more debug info #tweets the images and data send = 'Brghtnss: ' + str(format((((float(ldr1)/1024)*100)),'.0f')) + '% / ' + 'Tmprtr: ' + str(format(tmp1,'.0f')) + ' Dg F' + ' / Avg Plnt Moisture: '+ str(format(float((float((mst1+mst2+mst3+mst4)/4)/1024)*100),'.0f')) + '%' + ' Graph: ' + 'http://www.flickr.com/photos/97350286@N08/'+ str(graph_photoID) + ' Pic: ' + 'http://www.flickr.com/photos/97350286@N08/' + str(picture_photoID) #builds the text of the tweet print "Tweeting:" , send #for debug purposes api.update_status(send) #tweets the tweet time.sleep(.1) GPIO.output(sampleLED, False) print "\n-----------end-----------" def table_update(): global table_number table_number = table_number + 1 global table_code table_code = str(time.strftime('%m_%d_%y_%H_%M_%S')) + '__' + str(table_number) print 'Creating Table: ' + table_code cursor.execute('USE piplanter') con.commit() cursor.execute('CREATE TABLE piplanter_table_'+ table_code +'(Sample_Number INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Time VARCHAR(100), mst1_V VARCHAR(100), mst2_V VARCHAR(100), mst3_V VARCHAR(100), mst4_V VARCHAR(100), pot1_V VARCHAR(100), ldr1_V VARCHAR(100), tmp1_F VARCHAR(100) );') con.commit() table_update() hourlyUpdate() scheduler = Scheduler(standalone=True) scheduler.add_interval_job(hourlyUpdate, hours=1) scheduler.add_interval_job(water, days=1) scheduler.add_interval_job(table_update, weeks=2) scheduler.start() #runs the program indefianately once every hour
Here’s the .php script:
<?php /* Include all the classes */ include("/srv/www/lib/pChart/class/pData.class.php"); include("/srv/www/lib/pChart/class/pDraw.class.php"); include("/srv/www/lib/pChart/class/pImage.class.php"); $myData = new pData(); /* Create your dataset object */ $db = mysql_connect("localhost", "piplanter_user", "piplanter_pass"); //location of server, db username, db pass mysql_select_db("piplanter", $db); $Requete = "SELECT * FROM `piplanter_table_" . $argv[1] . "`"; //table name $Result = mysql_query($Requete, $db); /*This fetches the data from the mysql database, and adds it to pchart as points*/ while($row = mysql_fetch_array($Result)) { $Time = $row["Time"]; $myData->addPoints($Time,"Time"); $mst1_V = $row["mst1_V"]; $myData->addPoints($mst1_V,"mst1_V"); $mst2_V = $row["mst2_V"]; $myData->addPoints($mst2_V,"mst2_V"); $mst3_V = $row["mst3_V"]; $myData->addPoints($mst3_V,"mst3_V"); $mst4_V = $row["mst4_V"]; $myData->addPoints($mst4_V,"mst4_V"); $ldr1_V = $row["ldr1_V"]; $myData->addPoints($ldr1_V,"ldr1_V"); $tmp1_F = $row["tmp1_F"]; $myData->addPoints($tmp1_F,"tmp1_F"); } $myData-> setSerieOnAxis("tmp1_F", 0); //assigns the data to the frist axis $myData-> setAxisName(0, "Degrees F"); //adds the label to the first axis $myData-> setSerieOnAxis("ldr1_V", 1); $myData-> setAxisName(1, "LDR"); $myData-> setSerieOnAxis("mst1_V", 2); $myData-> setSerieWeight("mst1_V",2); $myData-> setSerieOnAxis("mst2_V", 2); $myData-> setSerieOnAxis("mst3_V", 2); $myData-> setSerieOnAxis("mst4_V", 2); $myData-> setAxisName(2, "Relative Moisture"); $myData->setAbscissa("Time"); //sets the time data set as the x axis label $myData-> setSerieWeight("mst1_V",1); //draws the line tickness $myData->setPalette("mst1_V",array("R"=>58,"G"=>95,"B"=>205,"Alpha"=>80)); //sets the line color $myData-> setSerieWeight("mst2_V",1); $myData->setPalette("mst2_V",array("R"=>39,"G"=>64,"B"=>139,"Alpha"=>80)); $myData-> setSerieWeight("mst3_V",1); $myData->setPalette("mst3_V",array("R"=>0,"G"=>34,"B"=>102,"Alpha"=>80)); $myData-> setSerieWeight("mst4_V",1); $myData->setPalette("mst4_V",array("R"=>67,"G"=>110,"B"=>238,"Alpha"=>80)); $myData-> setSerieWeight("ldr1_V",2); $myData-> setSerieTicks("ldr1_V", 4); $myData-> setSerieWeight("tmp1_F",2); $myData-> setSerieTicks("tmp1_F", 4); $myPicture = new pImage(4000,500,$myData); /* Create a pChart object and associate your dataset */ $myPicture->setFontProperties(array("FontName"=>"/srv/www/lib/pChart/fonts/pf_arma_five.ttf","FontSize"=>6)); /* Choose a nice font */ $myPicture->setGraphArea(130,40,3900,300); /* Define the boundaries of the graph area */ $myPicture->drawScale(array("LabelRotation"=>320)); /* Draw the scale, keep everything automatic */ $Settings = array("R"=>250, "G"=>250, "B"=>250, "Dash"=>1, "DashR"=>0, "DashG"=>0, "DashB"=>0); /*The combination makes a cool looking graph*/ $myPicture->drawPlotChart(array("DisplayValues"=>TRUE)); $myPicture->drawLineChart(); $myPicture->drawLegend(30,320); //adds the legend //$date-> date("d-M-Y:H:i:s"); //$myPicture->autoOutput(); /* Build the PNG file and send it to the web browser */ $myPicture->render("/opt/bitnami/wordpress/piplanter/renders/".date("d-M-Y_H:i:s").".png"); ?>
Thank you for reading!