DSFU – Adding Email Functionality, Better User Experience, Stable Set Adding

Big post for this project, here’s a video:

This version of the code implements a few really cool features.

First things first I added 10 LEDs that display the percent uploaded of the batch. For example if 13 / 100 photos have been uploaded, the first LED will light up. If 56 / 100 the first 5 LEDs will light up. Eventually the 10 junk LEDs will be replaced with a bar graph which will be mounted externally on the front panel of the enclosure.

I am using every single available output on my Pi now, but I was able to get away with adding 1 more LED that I should be able to use by using a transistor array explained here:

On the code side of things, I updated the way photos are added to the set. It uses the same principal as described in the previous post (using APscheduler to do the adding on an interval). All of these changes can be seen below, it’s still very poorly commented however.

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

in_flickr = 11
GPIO.setup(in_flickr, GPIO.IN)
in_hdd = 13
GPIO.setup(in_hdd, GPIO.IN)
button = 15
GPIO.setup(button, GPIO.IN)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)
both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)
hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)

stat_LED = 26
GPIO.setup(stat_LED, GPIO.OUT)

LED_bar_1 = 18
GPIO.setup(LED_bar_1, GPIO.OUT)
LED_bar_2 = 16
GPIO.setup(LED_bar_2, GPIO.OUT)
LED_bar_3 = 23
GPIO.setup(LED_bar_3, GPIO.OUT)
LED_bar_4 = 21
GPIO.setup(LED_bar_4, GPIO.OUT)
LED_bar_5 = 19
GPIO.setup(LED_bar_5, GPIO.OUT)
LED_bar_6 = 12
GPIO.setup(LED_bar_6, GPIO.OUT)
LED_bar_7 = 10
GPIO.setup(LED_bar_7, GPIO.OUT)
LED_bar_8 = 8
GPIO.setup(LED_bar_8, GPIO.OUT)
LED_bar_9 = 24
GPIO.setup(LED_bar_9, GPIO.OUT)
LED_bar_10 = 22
GPIO.setup(LED_bar_10, GPIO.OUT)

global led_bar
led_bar = []

led_bar.insert(0,18)
led_bar.insert(1,16)
led_bar.insert(2,23)
led_bar.insert(3,21)
led_bar.insert(4,19)
led_bar.insert(5,12)
led_bar.insert(6,10)
led_bar.insert(7,8)
led_bar.insert(8,24)
led_bar.insert(9,22)

for x in xrange(10):
			GPIO.output(led_bar[x],False)

import os

from apscheduler.scheduler import Scheduler
import logging
logging.basicConfig()
import time

#Flickr Setup
import flickrapi

api_key = ''
api_secret = ''

flickr = flickrapi.FlickrAPI(api_key, api_secret, format='json', cache=True)

(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))

#email setup
import smtplib

import math

def sd_walk():

	global file_list
	global file_number
	global filename
	global file_current

	global file_size
	global file_size_total

	print '-Starting File Index'

	for path, subdirs, files in os.walk(image_dir):
		for filename in files:
				if os.path.splitext(filename)[1].lower() in ('.jpg','jpeg'):

					listfiles = os.path.join(path, filename)

					file_list.insert(file_number,listfiles)
					print '--File: ' + str(file_number+1) + ' - ' + 'Size: ' + str(round(float(os.path.getsize(listfiles))/(1024),2)) + ' KB ' + ' Added To List: ' + str(listfiles)
					file_size_total = file_size_total + os.path.getsize(listfiles)
					file_number = file_number + 1

	print '-Indexing Completed ' + 'Total Files: ' + str(file_number) + ' - Total Size: ' + str(round(float(file_size_total)/(1024*1024*1024),2)) + ' GB' + '\n'
	print '---Starting Upload'

def upload_file():

	global file_list
	global file_number
	global filename
	global listfiles
	global file_current

	global file_size
	global file_size_total

	global led_bar

	if file_current == int(len(file_list)):
		print '\n----All Files Dealt With...Terminating \n'
		global scheduler
		scheduler.shutdown(shutdown_threadpool=False)
	else:

		percent = round((float(file_current+1) / float(len(file_list)))*100,0)
		led = round((float(file_current+1) / float(len(file_list)))*10,0)

		file_size = file_size + float(os.path.getsize(file_list[file_current]))/(1024)

		print '----File: ' +  str(file_current+1) + ' / ' + str(len(file_list)) + ' - ' + str(round(file_size,2)) + ' KB' + ' / ' + str(round(float(file_size_total)/(1024*1024*1024),2)) + ' GB' + ' - ' + str(percent) + '% Done' + ' - ' + 'LEDs: ' + '1-' + str(led) + ' Lit'
		print '------File For Upload: ' + file_list[file_current]

		for x in xrange(int(led)):
			GPIO.output(led_bar[x],True)

		upload_response = flickr.upload(filename = file_list[file_current], format='etree')
		upload_ID = upload_response.find('photoid').text
		print '------Uploaded - Photo ID: ' + upload_ID

		id_list.insert(file_current,upload_ID)

		file_current = file_current + 1

def flickr_upload():

	global id_list
	id_list = []

	global file_list
	file_list = []

	global file_current
	file_current = 0

	global file_number
	file_number = 0

	global file_size
	file_size = 0

	global file_size_total
	file_size_total = 0

	sd_walk()

	global scheduler
	scheduler = Scheduler(standalone=True)
	scheduler.add_interval_job(upload_file,seconds=20)
	scheduler.start()

	print '--Uploading completed - Adding Files To Set'

	set_name = 'Uploaded At ' + time.strftime('%m-%d-%y_%H-%M-%S')
	print '\n---Creating Set: ' + set_name
	print '---Primary Photo: ' + id_list[0]
	json_string = flickr.photosets_create(title=set_name, primary_photo_id=id_list[0])
	global set_id
	set_id = json_string.split('"')[5]
	print '---Set Created: ' + set_id
	print '---Adding Files To list'

	global flickr_setno
	flickr_setno = 0

	global scheduler
	scheduler = Scheduler(standalone=True)
	scheduler.add_interval_job(flickr_addset,seconds=1)
	scheduler.start()

	print '--All Photos Added, Flickr Process Complete \n'

	flickr_email(set_id,file_current,set_name)

def flickr_addset():

	global id_list
	global set_id
	global flickr_setno

	if flickr_setno == int(len(id_list)):
		print '\n---All IDs Dealt With...Terminating \n'
		global scheduler
		scheduler.shutdown(shutdown_threadpool=False)

	else:
		flickr.photosets_addPhoto(photoset_id=set_id, photo_id=id_list[flickr_setno])
		print '----Photo: ' + str(flickr_setno+1) + ' Of ' + str(len(id_list)) + ' Added To Set: ' + str(set_id) + ' ID: ' + str(id_list[flickr_setno])
		flickr_setno = flickr_setno + 1

def flickr_email(idd,total_files,name):

	global file_size_total

	fromaddr = ''
	toaddrs = ''
	username = ''
	password = ''
	server = smtplib.SMTP('smtp.gmail.com:587')
	server.ehlo()
	server.starttls()
	server.ehlo()
	server.login(username,password)

	print 'Sending Email'

	SUBJECT = 'Your Photos Have Been Uploaded!'

	TEXT = (

		'Hello! \n\n'
		'You Uploaded a total of: ' + str(total_files) + ' Files' '\n'
		'Which Was: ' + str(float(file_size_total)/(1024*1024*1024)) + ' GB' + '\n\n'

		'Your Set is Named: "' + str(name) + '" \n\n'
		'You can View These Photos Here: \n'

		'http://www.flickr.com/photos/99154806@N04/sets/' + str(idd)

		)

	msg = 'Subject: %s\n\n%s' % (SUBJECT, TEXT)
	server.sendmail(fromaddr, toaddrs, msg)
	time.sleep(10)
	server.quit
	print 'Email Sent \n'

while 1:

	global led_bar

	GPIO.output(stat_LED, False)

	if GPIO.input(in_flickr):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)

	elif GPIO.input(in_hdd):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)

	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)

	if GPIO.input(button):
		GPIO.output(stat_LED, True)

		print '\n======Start=====\n'

		print 'Mounting SD'
		time.sleep(10)
		global image_dir

		image_dir = '/mnt/SD/'
		os.system('hdparm -z /dev/sda1/')
		os.system('mount -t vfat /dev/sda1/ ' + image_dir)
		print 'SD Mounted \n'

		if GPIO.input(in_flickr):

			flickr_upload()

			print 'SD Unmouting'
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + image_dir)
			print 'SD Unounted'
			print '======End======'
			GPIO.output(stat_LED, False)

			for x in xrange(10):
				GPIO.output(led_bar[x],False)

		elif GPIO.input(in_hdd):

			hdd_upload()

			print 'SD Unmouting'
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + image_dir)
			print 'SD Unounted'
			print '======End======'
			GPIO.output(stat_LED, False)

			for x in xrange(10):
				GPIO.output(led_bar[x],False)

		else:

			both_upload()

			print 'SD Unmouting'
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + image_dir)
			print 'SD Unounted'
			print '======End======'
			GPIO.output(stat_LED, False)

			for x in xrange(10):
				GPIO.output(led_bar[x],False)

Thanks for reading!

Pi Uploader | Reliable Batch Uploads to Flickr

Here’s a video:

So basically the program indexes every single file on the SD card and then starts a scheduled interval process to upload them every single upload to flickr every 20 seconds. From there, it creates a set and indexes all of the upload responses and then walks though that list and adds each photo to that list. Then it emails the set URL with some other data.

I had a lot of problems with the flickr API timing out, and solved this problem by using APscheduler (easily my favorite package). You can see a more in depth chronicling my struggle on my twitter account.

I really want this project to be polished so I probably won’t be done with it for a while. I want to like 3D print a really nice looking enclosure and use a lot of panel mount components.

Here’s the python script:

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

in_flickr = 11
GPIO.setup(in_flickr, GPIO.IN)
in_hdd = 13
GPIO.setup(in_hdd, GPIO.IN)
button = 16
GPIO.setup(button, GPIO.IN)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)
both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)
hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)
uploading_LED = 26
GPIO.setup(uploading_LED, GPIO.OUT)
ready_LED = 24
GPIO.setup(ready_LED, GPIO.OUT)
stat_LED = 22
GPIO.setup(stat_LED, GPIO.OUT)

import os

from apscheduler.scheduler import Scheduler
import logging
logging.basicConfig()
import time

#Flickr Setup
import flickrapi

api_key = ''
api_secret = ''

flickr = flickrapi.FlickrAPI(api_key, api_secret, format='json', cache=True)

(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))

#email setup
import smtplib

def sd_walk():

	global file_list
	global file_number
	global filename
	global file_current

	print '-Starting File Index'

	for path, subdirs, files in os.walk(image_dir):
		for filename in files:
				if os.path.splitext(filename)[1].lower() in ('.jpg','jpeg'):

					listfiles = os.path.join(path, filename)

					file_list.insert(file_number,listfiles)
					print '--File: ' + str(file_number+1) + ' Added To List: ' + str(listfiles)
					file_number = file_number + 1

	print '-Indexing Completed \n'
	print '---Starting Upload'

def upload_file():

	global file_list
	global file_number
	global filename
	global listfiles
	global file_current

	if file_current == int(len(file_list)):
		print '\n----All Files Dealt With...Terminating \n'
		global scheduler
		scheduler.shutdown(shutdown_threadpool=False)
	else:
		print '----Uploaing File: ' +  str(file_current+1) + ' Of: ' + str(len(file_list)) + ' : ' + file_list[file_current]

		upload_response = flickr.upload(filename = file_list[file_current], format='etree')
		upload_ID = upload_response.find('photoid').text
		print '------Uploaded - Photo ID: ' + upload_ID

		id_list.insert(file_current,upload_ID)

		file_current = file_current + 1

def flickr_upload():

	global id_list
	id_list = []

	global file_list
	file_list = []

	global file_current
	file_current = 0

	global file_number
	file_number = 0

	sd_walk()

	global scheduler
	scheduler = Scheduler(standalone=True)
	scheduler.add_interval_job(upload_file,seconds=20)
	scheduler.start()

	print '---Uploading completed - Adding Files To Set'

	set_name = 'Uploaded At ' + time.strftime('%m-%d-%y_%H-%M-%S')
	print '\n----Creating Set: ' + set_name
	print '----Primary Photo: ' + id_list[0]
	json_string = flickr.photosets_create(title=set_name, primary_photo_id=id_list[0])
	global set_id
	set_id = json_string.split('"')[5]
	print '----Set Created: ' + set_id
	print '----Adding Files To list'

	global flickr_setno
	flickr_setno = 0

	global scheduler
	scheduler = Scheduler(standalone=True)
	scheduler.add_interval_job(flickr_addset,seconds=1)
	scheduler.start()

	print '---All Photos Added, Flickr Process Complete \n'

	flickr_email(set_id,file_current,set_name)

def flickr_addset():

	global id_list
	global set_id
	global flickr_setno

	if flickr_setno == int(len(id_list)):
		print '\n----All IDs Dealt With...Terminating \n'
		global scheduler
		scheduler.shutdown(shutdown_threadpool=False)

	else:

		flickr.photosets_addPhoto(photoset_id=set_id, photo_id=id_list[flickr_setno])
		print '-----Photo: ' + str(flickr_setno+1) + ' Of ' + str(len(id_list)) + ' Added To Set: ' + str(set_id) + ' ID: ' + str(id_list[flickr_setno])
		flickr_setno = flickr_setno + 1

def flickr_email(idd,total_files,name):

	fromaddr = ''
	toaddrs = ''
	username = ''
	password = ''
	server = smtplib.SMTP('smtp.gmail.com:587')
	server.ehlo()
	server.starttls()
	server.ehlo()
	server.login(username,password)

	print 'Sending Email'
	SUBJECT = 'Your Photos Have Been Uploaded!'
	TEXT = 'Hello!\n\nYou Uploaded a total of: ' + str(total_files) + '\nYour Set is Named: "' + str(name) + '" \nYou can View These Photos Here: \n\n http://www.flickr.com/photos/99154806@N04/sets/' + str(idd)
	msg = 'Subject: %s\n\n%s' % (SUBJECT, TEXT)
	server.sendmail(fromaddr, toaddrs, msg)
	time.sleep(10)
	server.quit
	print 'Email Sent \n'

while 1:

	GPIO.output(ready_LED, True)
	GPIO.output(uploading_LED, False)
	GPIO.output(stat_LED, False)

	if GPIO.input(in_flickr):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)

	elif GPIO.input(in_hdd):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)

	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)

	if GPIO.input(button):
		GPIO.output(uploading_LED, True)
		GPIO.output(ready_LED, False)

		print '======Start====='

		print 'Mounting SD'
		time.sleep(1)
		global image_dir

		image_dir = '/mnt/SD/'
		os.system('mount -t vfat /dev/sda1/ ' + image_dir)
		print 'SD Mounted'

		if GPIO.input(in_flickr):

			flickr_upload()

			print 'SD Unmouting'
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + image_dir)
			print 'SD Unounted'
			print '======End======'
			GPIO.output(uploading_LED, False)
			GPIO.output(ready_LED, True)

		elif GPIO.input(in_hdd):

			hdd_upload()

			print 'SD Unmouting'
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + image_dir)
			print 'SD Unounted'
			print '======End======'
			GPIO.output(uploading_LED, False)
			GPIO.output(ready_LED, True)

		else:

			both_upload()

			print 'SD Unmouting'
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + image_dir)
			print 'SD Unounted'
			print '======End======'
			GPIO.output(uploading_LED, False)
			GPIO.output(ready_LED, True)

Thanks for reading!

Pi Uploader | Updating Code for Mounting and Mounting Capabilities

This program can now handle mounting and unmounting the SD card on /mnt/SD (you will have to make that dir with root privileges)

#time setup
import time

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

in_left = 11
GPIO.setup(in_left, GPIO.IN)
in_right = 13
GPIO.setup(in_right, GPIO.IN)
button = 16
GPIO.setup(button, GPIO.IN)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)
both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)
hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)
uploading_LED = 26
GPIO.setup(uploading_LED, GPIO.OUT)
ready_LED = 24
GPIO.setup(ready_LED, GPIO.OUT)
stat_LED = 22
GPIO.setup(stat_LED, GPIO.OUT)

#for the cp command
import os
import os.path

#setup for datestamping folders
import time

#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))

#Storage Locations
sdcard = '/mnt/SD'
destination = '/media/usb0/'

#these functions will be filled later, but right now it's just a simple led blink
def flickr_upload():
	print "Uploading Photos To Flickr"

	flickr_number = 0

	flickr_upload_list = []

	for path, subdirs, files in os.walk(sdcard):
		for filename in files:
			listfiles = os.path.join(path, filename)
			upload_response = flickr.upload(filename = listfiles, format='etree')
			upload_ID = upload_response.find('photoid').text
			flickr_upload_list.insert(flickr_number,upload_ID)
			print 'Photo ' + str(flickr_number) + ' uploaded' + ' ID: ' + upload_ID + ' : ' + str(flickr_upload_list[flickr_number])
			flickr_number = flickr_number + 1

	set_name = 'Uploaded At ' + time.strftime('%m-%d-%y_%H-%M-%S')

	print 'Creating Set: ' + set_name

	json_string = flickr.photosets_create(title=set_name, primary_photo_id=flickr_upload_list[0])
	set_id = json_string.split('"')[5]

	print 'Set Created: ' + set_id
	print 'Adding Files To list'

	for s in flickr_upload_list:
		flickr.photosets_addPhoto(photoset_id=set_id, photo_id=s)
		print 'Photo: ' + s + ' Added To Set: ' + set_id

	print "Flickr Upload Completed"

def hdd_upload():
	print "Uploading Photos To the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)

	print 'Creating Folder'

	foldername = time.strftime('%m-%d-%y_%H-%M-%S')
	os.system('mkdir ' + destination + foldername)

	print 'Folder Created: ' + destination + foldername

	hdd_number = 0

	for path, subdirs, files in os.walk(sdcard):
		for filename in files:
			hdd_number = hdd_number + 1
			listfiles = os.path.join(path, filename)
			print 'Copying File: ' + str(number) + ' ' + listfiles
			command = 'cp ' + listfiles + ' ' + destination + foldername
			print command
			os.system(command)

	print "HDD Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)
	time.sleep(2)

def both_upload():
	print "Uploading Photos To Flickr and the HDD"
	hdd_upload()
	flickr_upload()
	print "Double Upload Completed"

while 1:

	GPIO.output(ready_LED, True)
	GPIO.output(uploading_LED, False)
	GPIO.output(stat_LED, False)

	if GPIO.input(in_left):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)

	elif GPIO.input(in_right):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)

	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)

	if GPIO.input(button):

		GPIO.output(uploading_LED, True)
		GPIO.output(ready_LED, False)

		time.sleep(10)
		os.system('mount -t vfat /dev/sda1/ ' + sdcard)
		print 'SD Mounted'

		if GPIO.input(in_left):
			flickr_upload()
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + sdcard)
			print 'SD Unounted'
			GPIO.output(uploading_LED, False)
			GPIO.output(ready_LED, True)
		elif GPIO.input(in_right):
			hdd_upload()
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + sdcard)
			print 'SD Unounted'
			GPIO.output(uploading_LED, False)
			GPIO.output(ready_LED, True)
		else:
			both_upload()
			time.sleep(10)
			os.system('umount -t vfat /dev/sda1/ ' + sdcard)
			print 'SD Unounted'
			GPIO.output(uploading_LED, False)
			GPIO.output(ready_LED, True)

Pi Uploader | Uploading and Photoset population with Flickr

Here’s a video!

So now, when in Flickr Upload mode, the program will:

1. Walk through all Sub-Directories and find every image file

2. Upload all of those photos to Flickr

3. Get the photo ID’s of each of those photos and then index them into a list

4. Use that list to create a Photoset (Flickr’s equivalent of a Photo Album) named after the time the photos were uploaded.

As I said in the video, I want eventually (if the weather stays this bad, tomorrow) add email functionality to the program so it will send the user an email when all of the photos have been uploaded / the set of those photos.

Here’s the source used in the video:

#time setup
import time

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

in_left = 11
GPIO.setup(in_left, GPIO.IN)
in_right = 13
GPIO.setup(in_right, GPIO.IN)
button = 16
GPIO.setup(button, GPIO.IN)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)
both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)
hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)
uploading_LED = 26
GPIO.setup(uploading_LED, GPIO.OUT)
ready_LED = 24
GPIO.setup(ready_LED, GPIO.OUT)
stat_LED = 22
GPIO.setup(stat_LED, GPIO.OUT)

#for the cp command
import os
import os.path

#setup for datestamping folders
import time

#Flickr Setup
import flickrapi
api_key = '2bfb7e8be01e5f9f37e2e140076c6efa'
api_secret = 'fb4295ce55e7e0dd'
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))

#Storage Locations
sdcard = '/media/usb0/'
destination = '/media/usb0/'


#these functions will be filled later, but right now it's just a simple led blink
def flickr_upload():
	print "Uploading Photos To Flickr"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	
	
	flickr_number = 0
	
	flickr_upload_list = []

	for path, subdirs, files in os.walk(sdcard):
		for filename in files:
			listfiles = os.path.join(path, filename)
			upload_response = flickr.upload(filename = listfiles, format='etree')
			upload_ID = upload_response.find('photoid').text
			flickr_upload_list.insert(flickr_number,upload_ID)
			
			print 'Photo ' + str(flickr_number) + ' uploaded' + ' ID: ' + upload_ID + ' : ' + str(flickr_upload_list[flickr_number])
			flickr_number = flickr_number + 1
	
	set_name = 'Uploaded At ' + time.strftime('%m-%d-%y_%H-%M-%S')
	
	print 'Creating Set: ' + set_name
	
	json_string = flickr.photosets_create(title=set_name, primary_photo_id=flickr_upload_list[0])
	set_id = json_string.split('"')[5]
	
	print 'Set Created: ' + set_id
	print 'Adding Files To list'
	
	for s in flickr_upload_list:
		flickr.photosets_addPhoto(photoset_id=set_id, photo_id=s)
		print 'Photo: ' + s + ' Added To Set: ' + set_id
	

	print "Flickr Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

def hdd_upload():
	print "Uploading Photos To the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	
	print 'Creating Folder'
	
	foldername = time.strftime('%m-%d-%y_%H-%M-%S')
	os.system('mkdir ' + destination + foldername)
	
	print 'Folder Created: ' + destination + foldername
	
	hdd_number = 0
	
	for path, subdirs, files in os.walk(sdcard):
		for filename in files:
			hdd_number = hdd_number + 1
			listfiles = os.path.join(path, filename)
			print 'Copying File: ' + str(number) + ' ' + listfiles
			command = 'cp ' + listfiles + ' ' + destination + foldername
			print command
			os.system(command)

	print "HDD Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)
	time.sleep(2)
	
def both_upload():
	print "Uploading Photos To Flickr and the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	hdd_upload()
	flickr_upload()
	print "Double Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)
		

while 1:
	
	GPIO.output(ready_LED, True)
	GPIO.output(uploading_LED, False)
	GPIO.output(stat_LED, False)
	
	if GPIO.input(in_left):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)
		
	elif GPIO.input(in_right):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)
		
	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)
		
	if GPIO.input(button):
			
		if GPIO.input(in_left):
			flickr_upload()
		elif GPIO.input(in_right):
			hdd_upload()
		else:
			both_upload()

Pi Uploader | Copy from SD card to HDD

Here’s a video!

So half of the core functionality of the device is done! It’s a pretty simple solution to walk through all of the files in the directory. I actually might check if having sub-folders will mess the process up and it probably will, if that’s the case I’ll try and publish a fix for later tonight.

Anyway’s here’s the source:

#time setup
import time

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

in_left = 11
GPIO.setup(in_left, GPIO.IN)
in_right = 13
GPIO.setup(in_right, GPIO.IN)
button = 16
GPIO.setup(button, GPIO.IN)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)
both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)
hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)
uploading_LED = 26
GPIO.setup(uploading_LED, GPIO.OUT)
ready_LED = 24
GPIO.setup(ready_LED, GPIO.OUT)
stat_LED = 22
GPIO.setup(stat_LED, GPIO.OUT)

#for the cp command
import os

#setup for datestamping folders
import time

#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))

#these functions will be filled later, but right now it's just a simple led blink
def flickr_upload():
	print "Uploading Photos To Flickr"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)

	print "Flickr Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

def hdd_upload():
	print "Uploading Photos To the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)

	folder = time.strftime('%m-%d-%Y_%H-%M-%S')

	print "Creating Directory for Copy"
	os.system('mkdir ' + '/media/usb0/' + folder)
	print 'Folder Created: ' + folder

	for filename in os.listdir('/media/usb1'):
		GPIO.output(stat_LED, True)
		print 'Copying File: ' + filename
		GPIO.output(stat_LED, False)
		os.system('cp /media/usb1/' + filename + ' /media/usb0/' + folder + '/')

	print "HDD Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

def both_upload():
	print "Uploading Photos To Flickr and the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	hdd_upload()
	flickr_upload()
	print "Double Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

while 1:

	GPIO.output(ready_LED, True)
	GPIO.output(uploading_LED, False)
	GPIO.output(stat_LED, False)

	if GPIO.input(in_left):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)

	elif GPIO.input(in_right):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)

	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)

	if GPIO.input(button):

		if GPIO.input(in_left):
			flickr_upload()
		elif GPIO.input(in_right):
			hdd_upload()
		else:
			both_upload()

EDIT: So the above code won’t walk through sub-folders on the SD card, here’s an updated source:

#time setup
import time

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

in_left = 11
GPIO.setup(in_left, GPIO.IN)
in_right = 13
GPIO.setup(in_right, GPIO.IN)
button = 16
GPIO.setup(button, GPIO.IN)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)
both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)
hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)
uploading_LED = 26
GPIO.setup(uploading_LED, GPIO.OUT)
ready_LED = 24
GPIO.setup(ready_LED, GPIO.OUT)
stat_LED = 22
GPIO.setup(stat_LED, GPIO.OUT)

#for the cp command
import os
import os.path

#setup for datestamping folders
import time

#Flickr Setup
import flickrapi
api_key = '2bfb7e8be01e5f9f37e2e140076c6efa'
api_secret = 'fb4295ce55e7e0dd'
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))

#test = flickr.photosets_create(title="test", primary_photo_id="9253811236")

#print test

sdcard = '/media/usb0/'
destination = '/media/usb1/'

#these functions will be filled later, but right now it's just a simple led blink
def flickr_upload():
	print "Uploading Photos To Flickr"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)

	print "Flickr Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

def hdd_upload():
	print "Uploading Photos To the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)

	print 'Creating Folder'

	foldername = time.strftime('%m-%d-%y_%H-%M-%S')
	os.system('mkdir ' + destination + foldername)

	print 'Folder Created: ' + destination + foldername

	number = 0

	for path, subdirs, files in os.walk(sdcard):
		for filename in files:
			number = number + 1
			listfiles = os.path.join(path, filename)
			print 'Copying File: ' + str(number) + ' ' + listfiles
			command = 'cp ' + listfiles + ' ' + destination + foldername
			print command
			os.system(command)

	print "HDD Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)
	time.sleep(2)

def both_upload():
	print "Uploading Photos To Flickr and the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	hdd_upload()
	flickr_upload()
	print "Double Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

while 1:

	GPIO.output(ready_LED, True)
	GPIO.output(uploading_LED, False)
	GPIO.output(stat_LED, False)

	if GPIO.input(in_left):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)

	elif GPIO.input(in_right):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)

	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)

	if GPIO.input(button):

		if GPIO.input(in_left):
			flickr_upload()
		elif GPIO.input(in_right):
			hdd_upload()
		else:
			both_upload()

Pi Uploader | A basic skeleton

So like I said in my previous post I’m attempting to make a dead simple Flickr uploader. Video explaining this setup here:
http://youtu.be/Ll0SOO-jmr4

Here’s a picture of how it’s all wired up, this will likely not change throughout the duration of the project:

uploader

Image generated by fritzing.

And here’s the python code, it’s very rudimentary:

#time setup
import time

#GPIO setup
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

flickr_LED = 3
GPIO.setup(flickr_LED, GPIO.OUT)

both_LED = 5
GPIO.setup(both_LED, GPIO.OUT)

hdd_LED = 7
GPIO.setup(hdd_LED, GPIO.OUT)

in_left = 11
GPIO.setup(in_left, GPIO.IN)

in_right = 13
GPIO.setup(in_right, GPIO.IN)

button = 16
GPIO.setup(button, GPIO.IN)

uploading_LED = 26
GPIO.setup(uploading_LED, GPIO.OUT)

ready_LED = 24
GPIO.setup(ready_LED, GPIO.OUT)

b_LED = 22
GPIO.setup(b_LED, GPIO.OUT)

def flickr_upload():
	print "Uploading Photos To Flickr"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	time.sleep(5)
	print "Flickr Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

def hdd_upload():
	print "Uploading Photos To the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	time.sleep(5)
	print "HDD Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

def both_upload():
	print "Uploading Photos To Flickr and the HDD"
	GPIO.output(uploading_LED, True)
	GPIO.output(ready_LED, False)
	time.sleep(5)
	print "Double Upload Completed"
	GPIO.output(uploading_LED, False)
	GPIO.output(ready_LED, True)

while 1:

	GPIO.output(ready_LED, True)
	GPIO.output(uploading_LED, False)
	GPIO.output(b_LED, False)

	if GPIO.input(in_left):
		#print "left"
		GPIO.output(flickr_LED, True)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, False)

	elif GPIO.input(in_right):
		#print "right"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, False)
		GPIO.output(hdd_LED, True)

	else:
		#print "mid"
		GPIO.output(flickr_LED, False)
		GPIO.output(both_LED, True)
		GPIO.output(hdd_LED, False)

	if GPIO.input(button):

		if GPIO.input(in_left):
			flickr_upload()

		elif GPIO.input(in_right):
			hdd_upload()
		else:
			both_upload()

Thanks for reading!

Integrating twitter to the Raspberry Pi

Here’s a video of the system working:

I wanted to create a way to push data from my Raspberry Pi monitoring plant growth to myself. Instead of creating an email server and sending emails, or setting up an sms client, I decided to install tweepy and use twitter and python to send me the data.

First thing’s first, I had to create a dummy account (@eso_rpi) and sign up for the Twitter Dev Program, which is a free way to access the API. You will need to generate a set of consumer keys and access tokens for your app. The process is pretty simple, and the tweepy example is pretty straight forward. If you run into trouble you could easily google it as the process is pretty well documented.

Here’s my code, you will need to download and install tweepy and apscheduler for this to work:

#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=""

#APscheduler setup
from datetime import datetime
from apscheduler.scheduler import Scheduler
import time
import sys
import logging #if you start getting logging errors, uncomment these two lines
logging.basicConfig()

#the adc's SPI setup
import spidev
spi = spidev.SpiDev()
spi.open(0, 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

#"logs in" to twitter,
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)

def readandtweet():

	millivolts = (readadc(0)*(3300.0/1024.0))
	temp_c = (((millivolts - 100.0)/10)-40.0)

	tmp1 = str(format(((temp_c * 9.0 / 5.0) + 32),'.2f')) #converts the value from the tmp sensor into a useable fahrenheit

	ldr1 = str(format(((100-(float(readadc(1))/1024)*100)),'.2f')) #makes the value produced by the LDR into a percentage

	send = 'Brightness: ' + ldr1 + '% / ' + 'Temperature: ' + tmp1 + ' Deg F' #builds the text of the tweet

	print "Tweeting:" , send  #for debug purposes

	api.update_status(send) #tweets the tweet

readandtweet() #runs the program once on start

#this executes the function every 30 mins
scheduler = Scheduler(standalone=True)
scheduler.add_interval_job(readandtweet, minutes=30)
scheduler.start()

The wiring diagram is the same as it is here, except there is an ldr connected to port 1:

There you go!