Revision abe2d7e5
Added by David Sorber about 13 years ago
| 525.743/code/rpi_client.py | ||
|---|---|---|
|
from bfcslib.tmp512 import TMP512
|
||
|
|
||
|
# Global variables
|
||
|
DEBUG = False
|
||
|
|
||
|
NUM_SENSORS = 4
|
||
|
sensor_iterator = itertools.cycle(range(0, NUM_SENSORS))
|
||
|
CURRENT_IDX = sensor_iterator.next()
|
||
| ... | ... | |
|
|
||
|
THRESHOLD_TEMP = 82
|
||
|
|
||
|
HOST = '10.0.0.4' # phallanx for testing
|
||
|
HOST = '192.168.1.2'
|
||
|
PORT = 2243
|
||
|
REMOTE_DATA_INTERVAL = 20 # in seconds
|
||
|
|
||
| ... | ... | |
|
RPIO.setwarnings(False)
|
||
|
|
||
|
print 'Beer Fermentation Control System - RPI Client'
|
||
|
|
||
|
# Check for the debug command line argument
|
||
|
if len(sys.argv) > 1:
|
||
|
if sys.argv[1] == '-d':
|
||
|
DEBUG = True
|
||
|
|
||
|
# Make sure the script is being run as root before continuing
|
||
|
if os.geteuid() != 0:
|
||
| ... | ... | |
|
|
||
|
# Reset variables
|
||
|
temps = []
|
||
|
if interval_counter == REMOTE_DATA_INTERVAL + 1:
|
||
|
if interval_counter == REMOTE_DATA_INTERVAL:
|
||
|
interval_counter = 0
|
||
|
|
||
|
# Grab the current date/time
|
||
| ... | ... | |
|
ss_display.display_number(temp)
|
||
|
|
||
|
# Bit 'o debug information
|
||
|
print now.strftime('%m/%d/%Y %H:%M:%S')
|
||
|
for idx in xrange(NUM_SENSORS):
|
||
|
print '\t Sensor %d: %d' % (idx + 1, temps[idx])
|
||
|
if DEBUG:
|
||
|
print now.strftime('%m/%d/%Y %H:%M:%S')
|
||
|
for idx in xrange(NUM_SENSORS):
|
||
|
print '\t Sensor %d: %d' % (idx + 1, temps[idx])
|
||
|
|
||
|
# Sort all the temperature readings for easier manipulation
|
||
|
temps.sort(reverse=True)
|
||
| ... | ... | |
|
|
||
|
# Send a reading to the server once every minute
|
||
|
if interval_counter == REMOTE_DATA_INTERVAL:
|
||
|
print 'Sending reading to server...',
|
||
|
sys.stdout.flush()
|
||
|
if DEBUG:
|
||
|
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'
|
||
|
if DEBUG:
|
||
|
print 'DONE'
|
||
|
except:
|
||
|
print 'ERROR'
|
||
|
if DEBUG:
|
||
|
print 'ERROR'
|
||
|
|
||
|
interval_counter += 1
|
||
|
|
||
|
# Read once ever second
|
||
|
time.sleep(1)
|
||
|
# Read once every second (approximated to account for processing
|
||
|
# latencies)
|
||
|
time.sleep(0.9)
|
||
|
|
||
|
s.close()
|
||
|
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
sys.exit(main())
|
||
|
sys.exit(main())
|
||
| 525.743/code/server.py | ||
|---|---|---|
|
|
||
|
from bfcslib.sensor_reading import SensorReading
|
||
|
|
||
|
DB_PATH = '/Users/dsorber/Desktop/beer_temps.db'
|
||
|
HOST = '10.0.0.4'
|
||
|
DB_PATH = '/home/dsorber/bfcs/beer_temps.db'
|
||
|
HOST = '192.168.1.1'
|
||
|
PORT = 2243
|
||
|
|
||
|
def main():
|
||
| ... | ... | |
|
|
||
|
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()
|
||
|
try:
|
||
|
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()
|
||
|
except:
|
||
|
print 'FAILED'
|
||
|
db_conn.close()
|
||
|
continue
|
||
|
|
||
|
db_conn.close()
|
||
|
|
||
|
print 'SUCCESS'
|
||
|
|
||
|
conn.close()
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
sys.exit(main())
|
||
|
sys.exit(main())
|
||
| 525.743/code/web/app.wsgi | ||
|---|---|---|
|
|
||
|
# Generate the stream and then render it to HTML
|
||
|
stream = template.generate(**response_args)
|
||
|
response_body = stream.render('html', doctype='html')
|
||
|
response_body = stream.render('html', doctype='html', encoding='utf-8')
|
||
|
|
||
|
# Set the appropriate response headers
|
||
|
response_headers = [('Content-Type', 'text/html'),
|
||
|
response_headers = [('Content-Type', 'text/html; charset=utf-8'),
|
||
|
('Content-Length', str(len(response_body)))]
|
||
|
|
||
|
elif environ['PATH_INFO'].startswith('/day/'):
|
||
| ... | ... | |
|
|
||
|
# Generate the stream and then render it to HTML
|
||
|
stream = template.generate(**response_args)
|
||
|
response_body = stream.render('html', doctype='html')
|
||
|
response_body = stream.render('html', doctype='html', encoding='utf-8')
|
||
|
|
||
|
# Set the appropriate response headers
|
||
|
response_headers = [('Content-Type', 'text/html'),
|
||
|
response_headers = [('Content-Type', 'text/html; charset=utf-8'),
|
||
|
('Content-Length', str(len(response_body)))]
|
||
|
else:
|
||
|
# User supplied an invalid URL
|
||
| ... | ... | |
|
|
||
|
# Return the response body. (Notice it is wrapped in a list although it
|
||
|
# could be any iterable.)
|
||
|
return [response_body]
|
||
|
return [response_body]
|
||
Adding some charset info to make sure mod_wsgi doesn't puke on UTF-8 encoded strings. Also added a "-d" (debug enable) switch to the RPi client so that it only prints out debug information if you want it to. Finally, I added a try except block around the database insert code in the server daemon so that the whole daemone doesn't crash when there is an error.