Category Archives: Raspberry Pi

Safe SCP and Delete

My current project involves creating many files on a Raspberry Pi, then immediately transferring them to a more traditional linux server with normal spinning disk hard drives and more system resources.

In order to reduce writes on the Rasberry Pi’s SD card, I intend to store these files on a ramdisk, then I need a safe way to copy the files to the remote server.  In the event a connection is unavailable, this script will detect that the connection failed, and move the file to a failback directory (on the SD card) instead of deleting it after the scp command completes.  If the file is moved to the failback directory, an accompanying json file is also created to store the necessary information.

Assumptions:

  • Script will be run from the source computer.
  • Both computers will be running current versions of OpenSSH.
  • Public key authentication is set up so that it does not require a password to ssh from the source to the destination.
  • scpis installed on the source, and located at /usr/bin/scp. (Verify using the command: which scp).

Variables required for the function:

  • source_file – This is the absolute location of the file to be transferred
    Example: /home/user/temp/transfer_this_file.jpg
  • destination_directory – This is the destination location as would be specified when using the scp command.
    Example: user@remotehost:/home/user/destination_directory/
  • failback_directory – Absolute location of the failback directory on the source computer.
    Example: /home/user/failback/

Python modules imported:

  • subprocess – Yes, I realize that os could be used instead of subprocess, but I’m already using subprocess for other functions in the same file.
  • os
  • uuid
  • json

The variable p is returned as to report on the status of the original transfer.  A zero is returned of the transfer was successful.  A one is returned if the transfer failed.

#! /usr/bin/python

import subprocess
import os
import uuid
import json

destination_directory = "user@remotehost:/home/user/incoming"
fail_directory = "user@notahost:/notadirectory"
fail_user = "bobert@remotehost:/home/ryan/temp"
fallback = "/home/pi/motion/fallback/"

def safe_scp(source_file, destination_directory, fallback_directory):
	# /usr/bin/scp -qB /source_filesystem/source_file.jpg user@host:/destination/
	cmd = "/usr/bin/scp -qB "+str(source_file)+" "+str(destination_directory)
	cmd = cmd.split()
	p = subprocess.Popen(cmd).wait()
	if (p == 1):
		# upload failed, move it to the fallback directory
		filename = os.path.split(source_file)[1]
		#
		# Using os.path to create an absoltue filename underneath the failback
		# directory for rename.
		fallback_file = os.path.abspath(os.path.join(fallback_directory, filename))
		os.rename(source_file, fallback_file)
		# generate filename with info to upload
		json_data = {
			"source_file" : fallback_file,
			"destination_directory" : destination_directory,
			"fallback_directory" : fallback_directory }
		# using uuid to ensure a truly unique filename
		json_filename = "failed_upload-"+str(uuid.uuid4())+".json"
		# creating the absolute filename under the failback directory
		json_filename = os.path.join(fallback_directory, json_filename)
		f = open(json_filename, "w")
		f.write(json.dumps(json_data))
		f.close()
	else:
		# delete source file in case of a successful transfer.
		os.remove(source_file)
	return p

# usage: I've created a bunch of blank text documents to test the transfer.

# simulating errors
print safe_scp("/home/pi/motion/1.txt", fail_directory, fallback)
#print safe_scp("/home/pi/motion/2.txt", fail_user, fallback)
# above line was commented out later in testing after a conflict with denyhosts
print safe_scp("/home/pi/motion/2.txt", fail_directory, fallback)

# normal operation
print safe_scp("/home/pi/motion/3.txt", destination_directory, fallback)
print safe_scp("/home/pi/motion/4.txt", destination_directory, fallback)
print safe_scp("/home/pi/motion/5.txt", destination_directory, fallback)
exit()

A quick note: Careful when playing around with intentionally failed authentication.  My computer is set up to block an ip after a number of failed login attempts.  I actually locked myself out from my Raspberry Pi when testing, and it took me longer than I care to admit to figure out what the exact problem was.  Hope this helps!

DIY Raspberry PI Camera Case

I’m currently working on a image analysis program using my Raspberry Pi and the Raspberry Pi camera.  Once that is in a complete state, and running full time, I plan to purchase a commercially produced mount.  In the meantime, I decided to make a little DIY Raspberry Pi mount.

Most hobby electronics ship in small electrostatic bags.  I keep every one of these I get.  I used one, trimmed it down, then cut a small hole for the camera to peek out.   This particular bag contained a Raspberry Pi.

Step 1 - Electrostatic bag

(forgive my crappy cameraphone focus, but I’m not going to take it apart again just to get more pictures.)

Next, I cut some cardboard to an approximate width of the camera board.  I used very thick cardboard and a boxcutter.

Step 2 - Cut some cardboard

 

Then, I taped one end of the electrostatic bag to to the cardboard so that I could wrap the bag around the cardboard.  Be sure to position it so the camera board will be centered on the cardboard.  I decided to use Scotch tape for this project as it would stick well to the bag.  I feared that duct tape would leave residue.

Step 3 - Tape the bag

Then, just wrap the bag around the cardboard and tape the other edge.

Step 4 - Wrap the bag

I used more tape, and just re-enforced the hole I had cut in. It may be difficult to see.

2013-08-28 11.36.30

I’m personally mounting my camera to look out the window, so I used more cardboard to sit in between the camera and the window.

2013-08-28 11.40.22Then, I just taped the whole thing to the window.  As you may have noticed, I added more cardboard below the camera to tilt the camera downward.

Tape to the windowThis will do just fine!  Again, I’ll be ordering a commercially produced mount  to replace this once my code is ready.  At that point, I’ll be mounting the camera higher on the window to avoid looking through the screen.  I like the mount currently for sale on Adafruit, but I’m also hoping for more variety in the coming weeks or months.

While I’m at it, I reviewed the Raspberry Pi here on Element 14’s community site: http://www.element14.com/community/roadTestReviews/1520

PiFace Digital Review

I was selected by Element14 to write a review for the PiFace Digital.

2013-05-20-21.04.50-768x1024

They were kind enough to ship me a free one, so I’m only going to link to the review on their page:
http://www.element14.com/community/roadTestReviews/1457

Here is the purchase link:
http://www.newark.com/piface/piface-digital/daugther-card-pi-face-expansion/dp/48W3976?COM=rasp-accessory-group

I’m currently working on a project to control and monitor the garage doors in my home.  I will document that project here once I’m able to work on it more, and get something working.