commit 856d156bc2d79c21d48181cb678b3e5f99b29ca5
Author: dsorber <david.sorber@gmail.com>
Date:   Mon Apr 22 21:18:35 2013 -0400

    Made good progress tonight with the client and server apps. Added the socket connection and SensorReading object to hold the sensor readings (surprise).

diff --git a/525.743/code/bfcslib/sensor_reading.py b/525.743/code/bfcslib/sensor_reading.py
new file mode 100644
index 0000000..5339cd3
--- /dev/null
+++ b/525.743/code/bfcslib/sensor_reading.py
@@ -0,0 +1,14 @@
+
+class SensorReading(object):
+
+	def __init__(self, time, temp1, temp2, temp3, temp4, relay_status):
+		self.time = time
+
+		# Temperature readings
+		self.temp1 = temp1
+		self.temp2 = temp2
+		self.temp3 = temp3
+		self.temp4 = temp4
+
+		# Relay status
+		self.relay_status = relay_status
\ No newline at end of file
diff --git a/525.743/code/rpi_client.py b/525.743/code/rpi_client.py
index 782c070..73a5ac4 100644
--- a/525.743/code/rpi_client.py
+++ b/525.743/code/rpi_client.py
@@ -1,5 +1,8 @@
+import cPickle
 import datetime
 import itertools
+import os
+import socket
 import sys
 import time
 
@@ -7,6 +10,7 @@ import RPIO
 
 from bfcslib.relay import Relay
 from bfcslib.sensor import Sensor
+from bfcslib.sensor_reading import SensorReading
 from bfcslib.seven_seg import SevenSegmentDisplay
 from bfcslib.status_led import LED
 from bfcslib.tmp512 import TMP512
@@ -19,6 +23,10 @@ SENSORS = None
 
 THRESHOLD_TEMP = 82
 
+HOST = '10.0.0.4' # phallanx for testing
+PORT = 2243
+REMOTE_DATA_INTERVAL = 20 # in seconds
+
 def button_isr(gpio_id, val):
 	global CURRENT_IDX
 	global SENSORS
@@ -37,8 +45,39 @@ def main():
 	global CURRENT_IDX
 	global SENSORS
 
+	# Disable "channel already in use" warnings
+	RPIO.setwarnings(False)
+
 	print 'Beer Fermentation Control System - RPI Client'
 
+	# Make sure the script is being run as root before continuing
+	if os.geteuid() != 0:
+		print 'ERROR: You must run the client as root!'
+		return
+
+	# Attempt to connect to the server, make 5 attempts
+	print '\n\nAttempting to connect to server...',
+	sys.stdout.flush()
+
+	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+	tries = 5
+	while tries > 0:
+		try:
+			s.connect((HOST, PORT))
+			break
+		except socket.error:
+			tries -= 1
+			if tries == 0:
+				print 'FAILED'
+				print 'Unable to connect to %s:%s check your connection and ' \
+					  'try again.' % (HOST, PORT)
+				return
+		time.sleep(1)
+
+	# Connection was successful
+	print 'SUCCESS'
+	print 'Connected to %s:%s' % (HOST, PORT)
+
 	# Setup the sensor status LEDs
 	sensor1_led = LED(24)
 	sensor2_led = LED(25)
@@ -83,10 +122,15 @@ def main():
 	RPIO.wait_for_interrupts(threaded=True)
 
 	# Main loop
+	interval_counter = 0
 	while True:
 
+		# Reset variables
 		temps = []
+		if interval_counter == REMOTE_DATA_INTERVAL + 1:
+			interval_counter = 0
 
+		# Grab the current date/time
 		now = datetime.datetime.now()
 
 		# Iterate over all temperature sensors and read their temp
@@ -122,9 +166,24 @@ def main():
 				relay_state = True
 				relay.on()
 
+		# Send a reading to the server once every minute
+		if interval_counter == REMOTE_DATA_INTERVAL:
+			print 'Sending reading to server...',
+			sys.stdout.flush()
+			reading = SensorReading(now, temps[0], temps[1], temps[2],
+									temps[3], relay_state)
+			try:
+				s.sendall(cPickle.dumps(reading))
+				print 'DONE'
+			except:
+				print 'ERROR'
+
+		interval_counter += 1
+
 		# Read once ever second
 		time.sleep(1)
 
+	s.close()
 
 
 
diff --git a/525.743/code/server.py b/525.743/code/server.py
new file mode 100644
index 0000000..0a2f961
--- /dev/null
+++ b/525.743/code/server.py
@@ -0,0 +1,69 @@
+import calendar
+import cPickle
+import datetime
+import socket
+import sqlite3
+import sys
+
+from bfcslib.sensor_reading import SensorReading
+
+DB_PATH = '/Users/dsorber/Desktop/beer_temps.db'
+HOST = '10.0.0.4'
+PORT = 2243
+
+def main():
+
+	# Create socket and wait for connections
+	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+	s.bind((HOST, PORT))
+	s.listen(1)
+	conn, addr = s.accept()
+	print 'Connected by', addr
+
+	# Main loop
+	while True:
+
+		# Block and wait to receive data
+		data = conn.recv(65536)
+
+		# Try to unpickle any data received
+		try:
+			obj = cPickle.loads(data)
+		except:
+			print 'I got some data that I couldn\'t unpickle...'
+			print '-' * 100
+			print data
+			print '-' * 100
+			print '\n\n'
+			continue
+
+		# Is the unpickled object a SensorReading object?
+		if isinstance(obj, SensorReading):
+			print obj.time.strftime('%m/%d/%Y %H:%M:%S')
+			print calendar.timegm(obj.time.timetuple())
+			print '\tTemp 1: %s' % obj.temp1
+			print '\tTemp 2: %s' % obj.temp2
+			print '\tTemp 3: %s' % obj.temp3
+			print '\tTemp 4: %s' % obj.temp4
+			print '\tRelay is %s' % (obj.relay_status and 'on' or 'off')
+
+			# Insert the reading data into a database
+			print 'Inserting data into the database...'
+			sys.stdout.flush()
+
+			db_conn = sqlite3.connect(DB_PATH)
+			db = db_conn.cursor()
+			db.execute("INSERT INTO temp_data VALUES (%s, %s, %s, %s, %s, %s)" % 
+					   (calendar.timegm(obj.time.timetuple()), obj.temp1, 
+					   	obj.temp2, obj.temp3, obj.temp4, 
+					   	int(obj.relay_status and '1' or '0')))
+			db_conn.commit()
+			db_conn.close()
+
+			print 'SUCCESS'
+
+	conn.close()
+
+
+if __name__ == '__main__':
+	sys.exit(main())
\ No newline at end of file
