Project

General

Profile

Download (4.75 KB) Statistics
| Branch: | Tag: | Revision:
856d156b dsorber
import cPickle
317c2b10 dsorber
import datetime
e376a628 dsorber
import itertools
856d156b dsorber
import os
import socket
e376a628 dsorber
import sys
317c2b10 dsorber
import time
e376a628 dsorber
import RPIO

317c2b10 dsorber
from bfcslib.relay import Relay
from bfcslib.sensor import Sensor
856d156b dsorber
from bfcslib.sensor_reading import SensorReading
e376a628 dsorber
from bfcslib.seven_seg import SevenSegmentDisplay
from bfcslib.status_led import LED
from bfcslib.tmp512 import TMP512

317c2b10 dsorber
# Global variables
abe2d7e5 David Sorber
DEBUG = False

e376a628 dsorber
NUM_SENSORS = 4
sensor_iterator = itertools.cycle(range(0, NUM_SENSORS))
CURRENT_IDX = sensor_iterator.next()
SENSORS = None

317c2b10 dsorber
THRESHOLD_TEMP = 82

abe2d7e5 David Sorber
HOST = '192.168.1.2'
856d156b dsorber
PORT = 2243
REMOTE_DATA_INTERVAL = 20 # in seconds

e376a628 dsorber
def button_isr(gpio_id, val):
global CURRENT_IDX
global SENSORS

317c2b10 dsorber
# Turn off previous sensor indicator LED
SENSORS[CURRENT_IDX].led.off()
e376a628 dsorber
# Update current index
# print 'CURRENT_IDX: %s' % CURRENT_IDX
CURRENT_IDX = sensor_iterator.next()

317c2b10 dsorber
# Turn on new sensor indicator LED
SENSORS[CURRENT_IDX].led.on()
e376a628 dsorber
def main():
global CURRENT_IDX
global SENSORS

856d156b dsorber
# Disable "channel already in use" warnings
RPIO.setwarnings(False)

e376a628 dsorber
print 'Beer Fermentation Control System - RPI Client'
abe2d7e5 David Sorber
# Check for the debug command line argument
if len(sys.argv) > 1:
if sys.argv[1] == '-d':
DEBUG = True
e376a628 dsorber
856d156b dsorber
# 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)

e376a628 dsorber
# Setup the sensor status LEDs
sensor1_led = LED(24)
sensor2_led = LED(25)
sensor3_led = LED(8)
sensor4_led = LED(7)

# Setup both TMP512's
tmp512_1 = TMP512(0x5d)
tmp512_2 = TMP512(0x5c)

317c2b10 dsorber
# Create the sensor objects to encapsulate a status LED and temperature
# sensor channel
sensor1 = Sensor(sensor1_led, tmp512_1.temp_sensor2)
sensor2 = Sensor(sensor2_led, tmp512_1.temp_sensor1)
sensor3 = Sensor(sensor3_led, tmp512_2.temp_sensor2)
sensor4 = Sensor(sensor4_led, tmp512_2.temp_sensor1)

# Create the global list of all the sensor objects
SENSORS = [sensor1, sensor2, sensor3, sensor4]
e376a628 dsorber
# Turn on initial sensor LED
317c2b10 dsorber
SENSORS[CURRENT_IDX].led.on()
e376a628 dsorber
# Setup 7 seg display
317c2b10 dsorber
ss_display = SevenSegmentDisplay()

# Setup relay
relay = Relay()
relay_state = False
e376a628 dsorber
# Setup pushbutton
317c2b10 dsorber
# Use the BCM addressing scheme, set GPIO 22 as input
e376a628 dsorber
RPIO.setmode(RPIO.BCM)
RPIO.setup(22, RPIO.IN)

# Setup switch interrupt with debounce
RPIO.add_interrupt_callback(22, button_isr, edge='rising',
pull_up_down=RPIO.PUD_DOWN, threaded_callback=True,
debounce_timeout_ms=150)

# Wait for interrupts in a non-blocking fashion
RPIO.wait_for_interrupts(threaded=True)

# Main loop
856d156b dsorber
interval_counter = 0
e376a628 dsorber
while True:

856d156b dsorber
# Reset variables
317c2b10 dsorber
temps = []
abe2d7e5 David Sorber
if interval_counter == REMOTE_DATA_INTERVAL:
856d156b dsorber
interval_counter = 0
317c2b10 dsorber
856d156b dsorber
# Grab the current date/time
317c2b10 dsorber
now = datetime.datetime.now()

e376a628 dsorber
# Iterate over all temperature sensors and read their temp
for idx in xrange(NUM_SENSORS):
317c2b10 dsorber
# Get the current temperature reading
temp = SENSORS[idx].temp
temps.append(temp)

# Display the currently selected temp sensor value
e376a628 dsorber
if idx == CURRENT_IDX:
317c2b10 dsorber
ss_display.display_number(temp)

# Bit 'o debug information
abe2d7e5 David Sorber
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])
317c2b10 dsorber
# Sort all the temperature readings for easier manipulation
temps.sort(reverse=True)

if relay_state:
# Relay is on, decide if we need to turn it off
if temps[0] < THRESHOLD_TEMP and \
temps[1] < THRESHOLD_TEMP and \
temps[2] < THRESHOLD_TEMP and \
temps[3] < THRESHOLD_TEMP:
relay_state = False
relay.off()
else:
# Relay is off, decide if we need to turn it on
if temps[0] > THRESHOLD_TEMP and temps[1] > THRESHOLD_TEMP:
relay_state = True
relay.on()

856d156b dsorber
# Send a reading to the server once every minute
if interval_counter == REMOTE_DATA_INTERVAL:
abe2d7e5 David Sorber
if DEBUG:
print 'Sending reading to server...',
sys.stdout.flush()
856d156b dsorber
reading = SensorReading(now, temps[0], temps[1], temps[2],
temps[3], relay_state)
try:
s.sendall(cPickle.dumps(reading))
abe2d7e5 David Sorber
if DEBUG:
print 'DONE'
856d156b dsorber
except:
abe2d7e5 David Sorber
if DEBUG:
print 'ERROR'
856d156b dsorber
interval_counter += 1

abe2d7e5 David Sorber
# Read once every second (approximated to account for processing
# latencies)
time.sleep(0.9)
317c2b10 dsorber
856d156b dsorber
s.close()
317c2b10 dsorber
e376a628 dsorber
if __name__ == '__main__':
abe2d7e5 David Sorber
sys.exit(main())