How to: Raspberry Pi HLT/Boiler Controller

The Homebrew Forum

Help Support The Homebrew Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
It's OK, I found the answer.

It was relating to a problem with the Slice of Pi/o not detecting correctly, in the same way yours did.

It turns out that yours was likely not broken, but was provably just the boot sequence causing the problem.
 
Oh bu££er - does that mean I bought a new Pi for nothing? Is there a code change somewhere that fixes the issue now?
Graham
 
Robbo
Have you allowed any-one to use your Fridge code yet?
You don't seem very happy with your brews - did cleaning your element solve the problem?
Graham
 
Hi Graham,

I did do quite a lot of work on the code. I have now changed it so that the bus address' for the thermometers are stored on a separate file on the Pi at "/home/pi/RPi_Brewery_Controller.config".

If I remember correctly the config file format needs to look like (I think, but I can't turn my Pi on at the moment to check, but can do later if this doesn't work):

Code:
Fridge_Thermometer_Wort= 28-0000057cf739
Fridge_Thermometer_Fridge_Air= 28-0000057ce432
Boiler/HLT_Thermometer_1= 28-0000057ca453
Boiler/HLT_Thermometer_2= 28-0000057be732

(clearly replacing the addresses with those appropriate for your sensors).

Re-reviewing the code, I think I wrote it such that if the RPi can't find the config file at boot, it will create it in the format below, so that the user can manually edit the file and add the appropriate bus addresses (aren't I helpful!).

Code:
Fridge_Thermometer_Wort=
Fridge_Thermometer_Fridge_Air=
Boiler/HLT_Thermometer_1=
Boiler/HLT_Thermometer_2=

Importantly, this version of code will also create log files into the "/var/www/" directory. If you have a web server installed on the PC, and the appropriate graphing files (for the boiler and the fridge), this will allow real-time graphing display from any device on your network (as per the attached photo). I achieved this by installing the web server as per the guide in this website, and modifying the associated html files. I haven't got time to post the code for the html files, but I can do that later (maybe Sunday night, or early next week, if you are interested).

The Fridge has the following functions:

- User-Setup at boot
- Power interruption protection (it will continue with the programmed cycle even if there is a power cut).
- Auto detection of fridge or boiler mode based upon the thermometer address it detects on boot.
- General navigation is simple. top button to command up or +, bottom button to command down or -, both buttons for "enter".
- Loads more, just have a play and I think you will really love what I have done with the scrolling display of thermal and timing data on the LCD.

If you want to fool the system into thinking that the fermentation cycle is over (i.e. you keep rebooting it and it always goes back to the previously programmed fermentation cycle), simply edit the file "/home/pi/Fridge_Start_Time.dat" and set the start date to a year earlier. Save the file and reboot the RPi and it will then allow you to programme a new fermentation cycle.

The code is below.

Regarding my beer - thanks for asking. I cleaned the elements and have done two lovely brews since. These brews have been the first ever use of the fridge and they have been excellent. The RPi controlled fridge has given cracking results and taken the guess work out of the fermentation process.

One last thought - you will need to make sure you connect the greenhouse heater and fridge supplies to the correct relay on the Slice of Pi/o, otherwise the system will "try" to heat or cool to infinity :doh:"





Code:
#!/usr/bin/python
# /usr/share/adafruit/webide/repositories/my-pi-projects/boiler_Mk2/Boiler_Controller_LCD.py

#*************************************************************************************
#*************************************************************************************
#*************************************************************************************

# This HLT/Boiler Controller software has been written by Robbo100 (username from 
# [url]www.thehomebrewforum.co.uk[/url]). This software uses elements of code from Daniel Berlin 
# (with some changes by Adafruit Industries/Limor Fried) and Matt Hawkins.

#*************************************************************************************
#*************************************************************************************
#*************************************************************************************

# Copyright 2012 Daniel Berlin (with some changes by Adafruit Industries/Limor Fried)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal  MCP230XX_GPIO(1, 0xin
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

#------------------------------------------------------------------------------
#                    IMPORT OTHER FUNCTIONS AND CLASSES
#------------------------------------------------------------------------------

from Adafruit_I2C import Adafruit_I2C
import smbus
import time
import os
import glob
import RPi.GPIO as GPIO
import threading
import datetime
from threading import Thread
import struct

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

#------------------------------------------------------------------------------
#                 ONE WIRE THERMOMETER SYSTEM SUB ROUTINES
#------------------------------------------------------------------------------

def read_temp_raw_1(device1_file):
    f = open(device1_file, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp_1(device1_file):
    try:
        lines = read_temp_raw_1(device1_file)
        while lines[0].strip()[-3:] != 'YES':
            time.sleep(0.001)
            lines = read_temp_raw_1(device1_file)
        equals_pos = lines[1].find('t=')
        if equals_pos != -1:
            temp_string = lines[1][equals_pos+2:]
            temp_c_1 = float(temp_string) / 1000.0
            temp_f_1 = temp_c_1 * 9.0 / 5.0 + 32.0
            return temp_c_1
    except Exception:
        temp_c_1=(-100)
        return temp_c_1


def read_temp_raw_2(device2_file):
    f = open(device2_file, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_2(device2_file):
    try:
        lines = read_temp_raw_2(device2_file)
        while lines[0].strip()[-3:] != 'YES':
            time.sleep(0.001)
            lines = read_temp_raw_2(device2_file)
        equals_pos = lines[1].find('t=')
        if equals_pos != -1:
            temp_string = lines[1][equals_pos+2:]
            temp_c_2 = float(temp_string) / 1000.0
            temp_f_2 = temp_c_2 * 9.0 / 5.0 + 32.0
            return temp_c_2
    except Exception:
        temp_c_2=(-100)
        return temp_c_2
        
#------------------------------------------------------------------------------
#                    INITIALISE THE SLICE OF PI/O
#------------------------------------------------------------------------------

MCP23017_IODIRA = 0x00
MCP23017_IODIRB = 0x01
MCP23017_GPIOA  = 0x12
MCP23017_GPIOB  = 0x13
MCP23017_GPPUA  = 0x0C
MCP23017_GPPUB  = 0x0D
MCP23017_OLATA  = 0x14
MCP23017_OLATB  = 0x15
MCP23008_GPIOA  = 0x09
MCP23008_GPPUA  = 0x06
MCP23008_OLATA  = 0x0A

class Adafruit_MCP230XX(object):
    OUTPUT = 0
    INPUT = 1

    def __init__(self, address, num_gpios):
        assert num_gpios >= 0 and num_gpios <= 16, "Number of GPIOs must be between 0 and 16"
        self.i2c = Adafruit_I2C(address=address)
        self.address = address
        self.num_gpios = num_gpios

        # set defaults
        if num_gpios <= 8:
            self.i2c.write8(MCP23017_IODIRA, 0xFF)  # all inputs on port A
            self.direction = self.i2c.readU8(MCP23017_IODIRA)
            self.i2c.write8(MCP23008_GPPUA, 0x00)
        elif num_gpios > 8 and num_gpios <= 16:
            self.i2c.write8(MCP23017_IODIRA, 0xFF)  # all inputs on port A
            self.i2c.write8(MCP23017_IODIRB, 0xFF)  # all inputs on port B
            self.direction = self.i2c.readU8(MCP23017_IODIRA)
            self.direction |= self.i2c.readU8(MCP23017_IODIRB) << 8
            self.i2c.write8(MCP23017_GPPUA, 0x00)
            self.i2c.write8(MCP23017_GPPUB, 0x00)

    def _changebit(self, bitmap, bit, value):
        assert value == 1 or value == 0, "Value is %s must be 1 or 0" % value
        if value == 0:
            return bitmap & ~(1 << bit)
        elif value == 1:
            return bitmap | (1 << bit)

    def _readandchangepin(self, port, pin, value, currvalue = None):
        assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
        #assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
        if not currvalue:
             currvalue = self.i2c.readU8(port)
        newvalue = self._changebit(currvalue, pin, value)
        self.i2c.write8(port, newvalue)
        return newvalue

    def pullup(self, pin, value):
        if self.num_gpios <= 8:
            return self._readandchangepin(MCP23008_GPPUA, pin, value)
        if self.num_gpios <= 16:
            lvalue = self._readandchangepin(MCP23017_GPPUA, pin, value)
            if (pin < 8):
                return
            else:
                return self._readandchangepin(MCP23017_GPPUB, pin-8, value) << 8

    # Set pin to either input or output mode
    def config(self, pin, mode):
        if self.num_gpios <= 8:
            self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
        if self.num_gpios <= 16:
            if (pin < 8):
                self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
            else:
                self.direction |= self._readandchangepin(MCP23017_IODIRB, pin-8, mode) << 8

        return self.direction

    def output(self, pin, value):
        # assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
        if self.num_gpios <= 8:
            self.outputvalue = self._readandchangepin(MCP23008_GPIOA, pin, value, self.i2c.readU8(MCP23008_OLATA))
        if self.num_gpios <= 16:
            if (pin < 8):
                self.outputvalue = self._readandchangepin(MCP23017_GPIOA, pin, value, self.i2c.readU8(MCP23017_OLATA))
            else:
                self.outputvalue = self._readandchangepin(MCP23017_GPIOB, pin-8, value, self.i2c.readU8(MCP23017_OLATB)) << 8

        return self.outputvalue

        self.outputvalue = self._readandchangepin(MCP23017_IODIRA, pin, value, self.outputvalue)
        return self.outputvalue

    def input(self, pin):
        assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
        assert self.direction & (1 << pin) != 0, "Pin %s not set to input" % pin
        if self.num_gpios <= 8:
            value = self.i2c.readU8(MCP23008_GPIOA)
        elif self.num_gpios > 8 and self.num_gpios <= 16:
            value = self.i2c.readU8(MCP23017_GPIOA)
            value |= self.i2c.readU8(MCP23017_GPIOB) << 8
        return value & (1 << pin)

    def readU8(self):
        result = self.i2c.readU8(MCP23008_OLATA)
        return(result)

    def readS8(self):
        result = self.i2c.readU8(MCP23008_OLATA)
        if (result > 127): result -= 256
        return result

    def readU16(self):
        assert self.num_gpios >= 16, "16bits required"
        lo = self.i2c.readU8(MCP23017_OLATA)
        hi = self.i2c.readU8(MCP23017_OLATB)
        return((hi << 8) | lo)

    def readS16(self):
        assert self.num_gpios >= 16, "16bits required"
        lo = self.i2c.readU8(MCP23017_OLATA)
        hi = self.i2c.readU8(MCP23017_OLATB)
        if (hi > 127): hi -= 256
        return((hi << 8) | lo)

    def write8(self, value):
        self.i2c.write8(MCP23008_OLATA, value)

    def write16(self, value):
        assert self.num_gpios >= 16, "16bits required"
        self.i2c.write8(MCP23017_OLATA, value & 0xFF)
        self.i2c.write8(MCP23017_OLATB, (value >> 8) & 0xFF)

# RPi.GPIO compatible interface for MCP23017 and MCP23008

class MCP230XX_GPIO(object):
    OUT = 0
    IN = 1
    BCM = 0
    BOARD = 0
    def __init__(self, busnum, address, num_gpios):
        self.chip = Adafruit_MCP230XX(busnum, address, num_gpios)
    def setmode(self, mode):
        # do nothing
        pass
    def setup(self, pin, mode):
        self.chip.config(pin, mode)
    def input(self, pin):
        return self.chip.input(pin)
    def output(self, pin, value):
        self.chip.output(pin, value)
    def pullup(self, pin, value):
        self.chip.pullup(pin, value)

if __name__ == '__main__':

#------------------------------------------------------------------------------
#                    CONFIGURE THE SLICE OF PI/O INPUT AND OUTPUTS
#------------------------------------------------------------------------------

    # Set num_gpios to 8 for MCP23008 or 16 for MCP23017!

    # mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 8) # MCP23008
    mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 16) # MCP23017

    # List outputs here
    mcp.config(7, mcp.OUTPUT) # Buzzer  
    mcp.config(12, mcp.OUTPUT) # Relay 1 on
    mcp.config(13, mcp.OUTPUT) # Relay 2 on
    
    # Set inputs with the pullup resistor enabled here
    mcp.config(14, mcp.INPUT)
    mcp.pullup(14, 1)
    mcp.config(15, mcp.INPUT)
    mcp.pullup(15, 1)

    # Set all outputs to off for startup (note - some outputs are reversed
    # depending upon connected device)
    mcp.output(7, 0)
    mcp.output(12, 1)
    mcp.output(13, 1)

#------------------------------------------------------------------------------
#                            HD44780 LCD SETUP
#------------------------------------------------------------------------------

    # Author : Matt Hawkins
    # Site   : [url]http://www.raspberrypi-spy.co.uk[/url]
    # Date   : 26/07/2012

    # The wiring for the LCD is as follows:
    # 1 : GND
    # 2 : 5V
    # 3 : Contrast (0-5V)*
    # 4 : RS (Register Select)
    # 5 : R/W (Read Write)       - GROUND THIS PIN
    # 6 : Enable or Strobe
    # 7 : Data Bit 0             - NOT USED
    # 8 : Data Bit 1             - NOT USED
    # 9 : Data Bit 2             - NOT USED
    # 10: Data Bit 3             - NOT USED
    # 11: Data Bit 4
    # 12: Data Bit 5
    # 13: Data Bit 6
    # 14: Data Bit 7
    # 15: LCD Backlight +5V**
    # 16: LCD Backlight GND
    
    # Define GPIO to LCD mapping
    LCD_RS = 17
    LCD_E  = 18
    LCD_D4 = 22 
    LCD_D5 = 23
    LCD_D6 = 24
    LCD_D7 = 25
    
    # Define some device constants
    LCD_WIDTH = 16    # Maximum characters per line
    LCD_CHR = True
    LCD_CMD = False

    LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
    LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line 

    # Timing constants
    E_PULSE = 0.00005
    E_DELAY = 0.00005

#------------------------------------------------------------------------------
#                       HD44780 LCD INITIALISATION
#------------------------------------------------------------------------------

    def lcd_init():
        # Initialise display
        lcd_byte(0x33,LCD_CMD)
        lcd_byte(0x32,LCD_CMD)
        lcd_byte(0x28,LCD_CMD)
        lcd_byte(0x0C,LCD_CMD)  
        lcd_byte(0x06,LCD_CMD)
        lcd_byte(0x01,LCD_CMD)

    def lcd_string(message):
        # Send string to display

        message = message.ljust(LCD_WIDTH," ")  

        for i in range(LCD_WIDTH):
            lcd_byte(ord(message[i]),LCD_CHR)

    def lcd_byte(bits, mode):
        # Send byte to data pins
        # bits = data
        # mode = True  for character
        #        False for command

        GPIO.output(LCD_RS, mode) # RS

        # High bits
        GPIO.output(LCD_D4, False)
        GPIO.output(LCD_D5, False)
        GPIO.output(LCD_D6, False)
        GPIO.output(LCD_D7, False)
        if bits&0x10==0x10:
            GPIO.output(LCD_D4, True)
        if bits&0x20==0x20:
            GPIO.output(LCD_D5, True)
        if bits&0x40==0x40:
            GPIO.output(LCD_D6, True)
        if bits&0x80==0x80:
            GPIO.output(LCD_D7, True)

        # Toggle 'Enable' pin
        time.sleep(E_DELAY)    
        GPIO.output(LCD_E, True)  
        time.sleep(E_PULSE)
        GPIO.output(LCD_E, False)  
        time.sleep(E_DELAY)      

        # Low bits
        GPIO.output(LCD_D4, False)
        GPIO.output(LCD_D5, False)
        GPIO.output(LCD_D6, False)
        GPIO.output(LCD_D7, False)
        if bits&0x01==0x01:
            GPIO.output(LCD_D4, True)
        if bits&0x02==0x02:
            GPIO.output(LCD_D5, True)
        if bits&0x04==0x04:
            GPIO.output(LCD_D6, True)
        if bits&0x08==0x08:
            GPIO.output(LCD_D7, True)

        # Toggle 'Enable' pin
        time.sleep(E_DELAY)    
        GPIO.output(LCD_E, True)  
        time.sleep(E_PULSE)
        GPIO.output(LCD_E, False)  
        time.sleep(E_DELAY)
#------------------------------------------------------------------------------
#			ERROR LOGGING FUNCTION
#------------------------------------------------------------------------------
    def scriptdebug(errormessage):
	errorlog = open('/home/pi/error.log', 'a')
	print >> errorlog, datetime.datetime.now(), errormessage
	errorlog.flush()	
#------------------------------------------------------------------------------
#                           BOIL FUNCTION
#------------------------------------------------------------------------------

    def boil_mode(boil_temperature):
        while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
            time.sleep(0)
        global target_temperature_glob
        target_temperature_glob = boil_temperature
        global Element_Switch_glob
        Element_Switch_glob = 0
        global Line1_String
        global Line2_String
        lcd_byte(LCD_LINE_1, LCD_CMD)
        Line1_String = " FULL BOIL MODE "
        lcd_string(Line1_String)
        lcd_byte(LCD_LINE_2, LCD_CMD)
        Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
        lcd_string(Line2_String)
        time.sleep(1);
        target_temperature_glob = 100
        while (True):
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = " FULL BOIL MODE "
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
            lcd_string(Line2_String)
            if (mcp.input(15) < 2):
                lcd_init()
            if (mcp.input(15) < 2) & (mcp.input(14) < 2):
                target_temperature_glob = 72
                while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
                    time.sleep(0)
                break
            if (Temperature > 96): # SET TO 96 DEG
                buzzer_count = 0
                while (buzzer_count < 6):
                    mcp.output(7, 1)
                    time.sleep(1)
                    mcp.output(7, 0)
                    time.sleep(1)
                    buzzer_count = buzzer_count + 1
                mcp.output(7, 0)
                Boil_Start_Time = datetime.datetime.now()
                Elapsed_Time = datetime.datetime.now()-Boil_Start_Time
                Countdown = ((60*60)-Elapsed_Time.total_seconds())
                #Countdown = ((60)-Elapsed_Time.total_seconds()) #Countdown Test Line
                while (Countdown > 0):
                    Elapsed_Time = datetime.datetime.now()-Boil_Start_Time
                    Countdown = ((60*60)-Elapsed_Time.total_seconds())
                    #Countdown = ((60)-Elapsed_Time.total_seconds()) #Countdown Test Line
                    if ((int(Countdown//60))<10):
                        Countdown_Mins = ("0" + (str(int(Countdown//60))))
                    else:
                        Countdown_Mins = str(int(Countdown//60))
                    if (int((Countdown - (int((Countdown//60)*60))))<10):
                        Countdown_Secs = ("0" + str(int(Countdown - (int((Countdown//60)*60)))))
                    else:
                        Countdown_Secs = str(int(Countdown - (int((Countdown//60)*60))))
                    global Countdown_String
                    Countdown_String = "Boil Time " + Countdown_Mins + ":" + Countdown_Secs
                    # Display temperatures on LCD
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = " FULL BOIL MODE "
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = (Countdown_String)
                    lcd_string(Line2_String)
                    if (mcp.input(15) < 2):
                        lcd_init()
                    if ((Countdown < (60*15)) & (Countdown > ((60*15)-5))):
                        buzzer_count = 0
                        while (buzzer_count < 6):
                            mcp.output(7, 1)
                            time.sleep(1)
                            mcp.output(7, 0)
                            time.sleep(1) 
                            buzzer_count = buzzer_count + 1
                        mcp.output(7, 0)
                    # Alternate the elements to turn on and off every 10 mins after 10 mins of boiling
                    if ((Countdown < (60*50)) & (Countdown > ((60*50)-5))):
                        Element_Switch_glob = 1
                    if ((Countdown < (60*40)) & (Countdown > ((60*40)-5))):
                        Element_Switch_glob = 0    
                    if ((Countdown < (60*35)) & (Countdown > ((60*35)-5))):
                        Element_Switch_glob = 2     
                    if ((Countdown < (60*25)) & (Countdown > ((60*25)-5))):
                        Element_Switch_glob = 0 
                    if ((Countdown < (60*20)) & (Countdown > ((60*20)-5))):
                        Element_Switch_glob = 1
                    if ((Countdown < (60*10)) & (Countdown > ((60*10)-5))):
                        Element_Switch_glob = 0     
                    if ((Countdown < (60*5)) & (Countdown > ((60*5)-5))):
                        Element_Switch_glob = 2
                # Display temperatures on LCD
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = " FULL BOIL MODE "
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = (" Boil Complete ")
                lcd_string(Line2_String)
                buzzer_count = 0
                while (buzzer_count < 6):
                    mcp.output(7, 1)
                    time.sleep(1)
                    mcp.output(7, 0)
                    time.sleep(1) 
                    buzzer_count = buzzer_count + 1
                mcp.output(7, 0)
                while(mcp.input(14) > 2):
                    if (mcp.input(15) < 2):
                        lcd_init()
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = (" READY FOR COOL ")
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = ("PRESS TEMP DOWN")
                    lcd_string(Line2_String)
                # Start the cooling process
                target_temperature_glob = 1 # This is needed to force the boiler to OFF in the main scropt
                while(Temperature > 28): # SET TO 28 DEG
                    # Display temperatures on LCD
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = ("  COOLING MODE ")
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
                    lcd_string(Line2_String)
                    time.sleep(1)
                    if (mcp.input(15) < 2):
                        lcd_init()
                buzzer_count = 0
                while (buzzer_count < 6):
                    mcp.output(7, 1)
                    time.sleep(1)
                    mcp.output(7, 0)
                    time.sleep(1)
                    buzzer_count = buzzer_count + 1
                mcp.output(7, 0)
                while(mcp.input(14) > 2):
                    if (mcp.input(15) < 2):
                        lcd_init()
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = ("  COOLING MODE ")
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = ("Cooling Complete")
                    lcd_string(Line2_String)
                    time.sleep(3)
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = ("SHUTDOWN CONTLR?")
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = (" HOLD TEMP DOWN ") 
                    lcd_string(Line2_String)
                    time.sleep(3)
                # Shutdown Pi
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("*****REMOVE*****")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("**BOILER POWER**")
                lcd_string(Line2_String)
                buzzer_count = 0
                while (buzzer_count < 12):
                    mcp.output(7, 1)
                    time.sleep(0.5)
                    mcp.output(7, 0)
                    time.sleep(0.5)
                    buzzer_count = buzzer_count + 1
                mcp.output(7, 0)
                time.sleep(8)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = (" SHUTTING DOWN ")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("Please Wait...")
                lcd_string(Line2_String)
                time.sleep(3)
                os.system("sudo shutdown -r now")

#------------------------------------------------------------------------------
#                    DISPLAY AND BUTTON DETECTION FUNCTION
#------------------------------------------------------------------------------

    def display(target_temperature, ):
        global target_temperature_glob
        target_temperature_glob = target_temperature
        global Element_Switch_glob
        Element_Switch_glob = -1
        global Line1_String
        global Line2_String
        while (True):
            Element_Switch_glob = -1
            # Detect Switch Presses
            if (mcp.input(15) < 2):
                target_temperature_glob = target_temperature_glob+1
                lcd_init()
            if (mcp.input(14) < 2):
                target_temperature_glob = target_temperature_glob-1
            if target_temperature_glob < 0:
                target_temperature_glob = 0
            if target_temperature_glob > 99:
                target_temperature_glob = 99 
            if (mcp.input(15) < 2) & (mcp.input(14) < 2):
                boil_temperature = target_temperature_glob
                boil_mode(boil_temperature)
            time.sleep(0.15)
            
            # Display temperatures on LCD
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("Target Temp = " + (str(target_temperature_glob)))
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
            lcd_string(Line2_String)

############################################################################################
############################################################################################
#------------------------------------------------------------------------------
#                     BOILER_HLT MODE FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################

    def Boiler_HLT_Mode(temp_reached, tens, units, target_temperature, dateString, Line1_String, Line2_String):
        global target_temperature_glob
        target_termperature_glob = target_temperature
        try:
            with open('/sys/bus/w1/devices/' + Thermometer1_Address + '/w1_slave'):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("  Thermometer")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("  No. 1 Found")
                lcd_string(Line2_String)
                time.sleep(2)
        except IOError:
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("**THERMOMETER**")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("**No. 1 ERROR**")
            lcd_string(Line2_String)
            buzzer_count = 0
            while (buzzer_count < 12):
                mcp.output(7, 1)
                time.sleep(0.1)
                mcp.output(7, 0)
                time.sleep(0.1)
                buzzer_count = buzzer_count + 1
            while(mcp.input(14) > 2):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("CONNECT DEVICE")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("TO THERMOMETERS")
                lcd_string(Line2_String)
                time.sleep(2)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("THEN HOLD TEMP")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("DOWN TO REBOOT")
                lcd_string(Line2_String)
                time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***REBOOTING***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Please Wait...") 
            lcd_string(Line2_String)
            os.system("sudo shutdown -r now")
        try:
            with open('/sys/bus/w1/devices/' + Thermometer2_Address + '/w1_slave'): 
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("  Thermometer")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("  No. 2 Found")
                lcd_string(Line2_String)
                time.sleep(2)
            
        except IOError:
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("**THERMOMETER**")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("**No. 2 ERROR**")
            lcd_string(Line2_String)
            buzzer_count = 0
            while (buzzer_count < 12):
                mcp.output(7, 1)
                time.sleep(0.1)
                mcp.output(7, 0)
                time.sleep(0.1)
                buzzer_count = buzzer_count + 1
            while(mcp.input(14) > 2):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("CONNECT DEVICE")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("TO THERMOMETERS")
                lcd_string(Line2_String)
                time.sleep(2)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("THEN HOLD TEMP")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("DOWN TO REBOOT")
                lcd_string(Line2_String)
                time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***REBOOTING***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Please Wait...") 
            lcd_string(Line2_String)
            os.system("sudo shutdown -r now")
            
            
        #------------------------------------------------------------------------------
        #                 SETUP THE BOILER LOG FILE
        #------------------------------------------------------------------------------
        
        try:
            with open('/var/www/Boiler_Log.csv'):
                os.remove('/var/www/Boiler_Log.csv')
        except IOError:
            print "No File to Delete"
            
        Boiler_Log = open('/var/www/Boiler_Log.csv', 'a')
        print >> Boiler_Log, "Date and Time" ',', "Boiler Temperature", ',', "Target Temperature", ',', "Element 1 Status", ',', "Element 2 Status"
        Boiler_Log.flush()
        
        #------------------------------------------------------------------------------
        #                 SETUP THE ONE WIRE THERMOMETER SYSTEM
        #------------------------------------------------------------------------------    
        
        base_dir = '/sys/bus/w1/devices/'
        # Setup Thermometer 1 Location
        device1_folder = glob.glob(base_dir + Thermometer1_Address)[0] 
        device1_file = device1_folder + '/w1_slave'
        # setup Thermomenter 2 Location
        device2_folder = glob.glob(base_dir + Thermometer2_Address)[0]
        device2_file = device2_folder + '/w1_slave'        
        # Initialise the Three Wire Thermometer 
            
        while(mcp.input(15) > 2):
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = (" READY TO START")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = (" PRESS TEMP UP")
            lcd_string(Line2_String)
            time.sleep(0.5)
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print "    Average Temperature = "
            print "     Target Temperature = "
            print " ____________________________________"
            print "       ", Line1_String
            print "       ", Line2_String
            print " ____________________________________"
        
        # Start Display Thread
        display_thread = Thread(target = display, args = (target_temperature, ))
        display_thread.start() 
        
        # Loop the following tasks forever
        Logging_Time = datetime.datetime.now()
        while(True):
            # Read Temperatures From Thermometers, calculate the average, and print 
            # them, along with the current global target temperature parameter, to 
            # the terminl screen
            temperature1 = read_temp_1(device1_file)
            temperature2 = read_temp_2(device2_file)
            global Temperature
            Temperature = ((temperature1+temperature2)/2)
            print ""
            print ""    
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print ""
            print "    Average Temperature = ", Temperature
            print "     Target Temperature = ", target_temperature_glob
            print " ____________________________________"
            print "       ", Line1_String
            print "       ", Line2_String
            print " ____________________________________"
            # If the measured temperature is lower than the target temperature, then
            # turn on the boilers (0 is ON, 1 os OFF)
            
            # Boiler 1
            if ((Temperature < target_temperature_glob) & ((Element_Switch_glob == -1) | (Element_Switch_glob == 0) | (Element_Switch_glob == 1))):
                mcp.output(12, 0)
                Element1 = 10
            else:
                mcp.output(12, 1)
                Element1 = 0
            # Boiler 2
            if ((Temperature < target_temperature_glob-1) & (Element_Switch_glob == -1)):
                mcp.output(13, 0)
                Element2 = 10
            elif ((Temperature < target_temperature_glob) & ((Element_Switch_glob == 0) | (Element_Switch_glob == 2))):
                mcp.output(13, 0)
                Element2 = 10
            else:
                mcp.output(13, 1)
                Element2 = 0
            # Heating Mode Temperature Reached Buzzer 
            if ((Temperature > target_temperature_glob) & (temp_reached == 0)) & (target_temperature_glob != 1):
                buzzer_count=0
                while (buzzer_count < 6):
                    mcp.output(7, 1)
                    time.sleep(1)
                    mcp.output(7, 0)
                    time.sleep(1)
                    buzzer_count = buzzer_count + 1
                mcp.output(7, 0)
                temp_reached=1
            if ((temp_reached == 1) & (Temperature <(target_temperature_glob-4))):
                temp_reached=0
            
            Logging_Time_Counter = (datetime.datetime.now() - Logging_Time)
            Logging_Time_Counter_Secs = Logging_Time_Counter.total_seconds()
            # Write the data to the log file
            if Logging_Time_Counter_Secs > 5:
                print >> Boiler_Log, datetime.datetime.now().strftime(dateString), ',', Temperature, ',', target_temperature_glob, ',', Element1, ',', Element2
                Boiler_Log.flush()
                Logging_Time = datetime.datetime.now()
        GPIO.cleanup()
        
############################################################################################
############################################################################################
    #------------------------------------------------------------------------------
    #                        THE FRIDGE MODE FUNCTION
    #------------------------------------------------------------------------------
############################################################################################
############################################################################################
    def FV_Fridge_Mode():
        # Thermometer Error Detection
        mcp.output(12, 1)
        mcp.output(13, 1)
        try:
            with open('/sys/bus/w1/devices/' + Thermometer3_Address + '/w1_slave'):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("  Thermometer")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("  No. 1 Found")
                lcd_string(Line2_String)
                time.sleep(2)
        except IOError:
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("**THERMOMETER**")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("**No. 1 ERROR**")
            lcd_string(Line2_String)
            buzzer_count = 0
            while (buzzer_count < 12):
                mcp.output(7, 1)
                time.sleep(0.1)
                mcp.output(7, 0)
                time.sleep(0.1)
                buzzer_count = buzzer_count + 1
            while(mcp.input(14) > 2):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("CONNECT DEVICE")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("TO THERMOMETERS")
                lcd_string(Line2_String)
                time.sleep(2)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("THEN HOLD TEMP")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("DOWN TO REBOOT")
                lcd_string(Line2_String)
                time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***REBOOTING***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Please Wait...") 
            lcd_string(Line2_String)
            os.system("sudo shutdown -r now")
        try:
            with open('/sys/bus/w1/devices/' + Thermometer4_Address + '/w1_slave'): 
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("  Thermometer")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("  No. 2 Found")
                lcd_string(Line2_String)
                time.sleep(2)
        except IOError:
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("**THERMOMETER**")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("**No. 2 ERROR**")
            lcd_string(Line2_String)
            buzzer_count = 0
            while (buzzer_count < 12):
                mcp.output(7, 1)
                time.sleep(0.1)
                mcp.output(7, 0)
                time.sleep(0.1)
                buzzer_count = buzzer_count + 1
            while(mcp.input(14) > 2):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("CONNECT DEVICE")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("TO THERMOMETERS")
                lcd_string(Line2_String)
                time.sleep(2)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("THEN HOLD TEMP")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("DOWN TO REBOOT")
                lcd_string(Line2_String)
                time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***REBOOTING***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Please Wait...") 
            lcd_string(Line2_String)
            os.system("sudo shutdown -r now")


        # Find out if the fermentation from previous power-down is complete or not
        try:
            with open('/home/pi/Fridge_Start_Time.dat'):       
                Ferm_Start_Time = open('/home/pi/Fridge_Start_Time.dat', 'r')
                # Create a data list from Fridge_Start_Time.dat row 1 (2nd row)
                try:
                    Ferm_Start_Data = [i.strip().split() for i in Ferm_Start_Time.readlines()][1]
                except:
                    New_Cycle()
                # Join up the first and second parameters from the list to create a single string (date time)
                Ferm_Start_Date_Time_Str = (str(Ferm_Start_Data[0]) + " " + str(Ferm_Start_Data[1]))
                # Convert the date time string into a datetime parameter
                Ferm_Start_Date_Time = datetime.datetime.strptime(Ferm_Start_Date_Time_Str, '%Y-%m-%d %H:%M:%S.%f')
                # Use the third parameter from the list and save it as int Ferm_Duration 
                Ferm_Duration = int(Ferm_Start_Data[2])
                # Convert Ferm_Duration to seconds
                Ferm_Duration_Secs = Ferm_Duration*60*60*24
                # Work out the difference between the Fermenation start date and time the current date and time
                Time_Delta = datetime.datetime.now() - Ferm_Start_Date_Time
                # Convert the time difference into seconds to then compare with the Ferm_Duration_Secs parameter
                # If duration is higher than delta, then the last cycle didn't finish, so needs sets Power Interrupt
                # flag to 1 and calls the Fridge cooling and display functions.
                Time_Delta_Secs = Time_Delta.total_seconds()
                if (Time_Delta_Secs < Ferm_Duration_Secs):
                    Power_Interrupt = 1
                    Power_Interrupt_Time = datetime.datetime.now()
                    Fridge_Run(Power_Interrupt, Power_Interrupt_Time)
                else:
                    # If the previous Fermentation is complete (i.e. no power interrupt)
                    # Delete the old Instrumentation Log File (if it exists)
                    New_Cycle()
        except IOError:
            Power_Interrupt = 0
            Power_Interrupt_Time = 0
            Fridge_Run(Power_Interrupt, Power_Interrupt_Time)
        #------------------------------------------------------------------------------
        #                 SETUP THE FRIDGE LOG FILE
        #------------------------------------------------------------------------------
        # - Only want to delete the file if the Fridge cycle is finished!
        
    def New_Cycle():
        try:
            with open('/var/www/Fridge_Log.csv'):
                os.remove('/var/www/Fridge_Log.csv')
        except IOError:
            print "No File to Delete"
                    
        Fridge_Log = open('/var/www/Fridge_Log.csv', 'a')
        print >> Fridge_Log, "Time" ',', "Fridge Temp" ',', "Wort Temp", ',', "Tgt Wort Temp", ',', "Tgt Fridge Temp" , ',', "Fridge Status", ',', "Heater Status"
        Fridge_Log.flush()
                    
        #Set the power interrupt flag to 0
        Power_Interrupt = 0
        Power_Interrupt_Time = 0
        #Gather New Fermentation Cycle Data
        # Ask User How Many Days for Fermentation
        Days_Total = 14
        lcd_init()
        while ((mcp.input(15) > 2) | (mcp.input(14) > 2)):
            if ((Days_Total >5) & (Days_Total <80)):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("Set Ferm Days")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("     = " + str(int(Days_Total)))
                lcd_string(Line2_String)
            if Days_Total == 5:
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("Set Ferm Days")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("     = " + str(int(Days_Total)) + " MIN")
                lcd_string(Line2_String)
                time.sleep(0.1)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("Set Ferm Days")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("     = " + str(int(Days_Total)))
                lcd_string(Line2_String)
                time.sleep(0.1)
            if Days_Total == 80:
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("Set Ferm Days")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("     = " + str(int(Days_Total)) + " MAX")
                lcd_string(Line2_String)
                time.sleep(0.1)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("Set Ferm Days")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("     = " + str(int(Days_Total)))
                lcd_string(Line2_String)
                time.sleep(0.1)
            if (mcp.input(15) < 2):
                Days_Total = Days_Total + 1
                time.sleep(0.1)
            if (mcp.input(14) < 2):
                Days_Total = Days_Total - 1
                time.sleep(0.1)
            if Days_Total>80:
                Days_Total = 80
            if Days_Total<5:
                Days_Total = 5
        while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
            time.sleep(0)
            # Create Data File Which Records the Desired Temperature Each Day of the Brew Cycle
        try:
            with open('/home/pi/Fridge_Cycle.dat'):
                os.remove('/home/pi/Fridge_Cycle.dat')
        except IOError:
            print "No File to Delete"    
        Fridge_Cycle = open('/home/pi/Fridge_Cycle.dat', 'a')
        print >> Fridge_Cycle, "Ferm_Day", "Tgt_Wort_Temp"
        Fridge_Cycle.flush()
        Day = 1
        Tgt_Ferm_Temp=20
        while (Day<(Days_Total+1)):
            lcd_init()
            while ((mcp.input(15) > 2) | (mcp.input(14) > 2)):
                time.sleep(0.15)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("Set Ferm Temp")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("   Day " + str(int(Day)) + " " + str(int(Tgt_Ferm_Temp)) + chr(223) + "C") 
                lcd_string(Line2_String)
                if (mcp.input(15) < 2):
                    Tgt_Ferm_Temp = Tgt_Ferm_Temp + 1
                if (mcp.input(14) < 2):
                    Tgt_Ferm_Temp = Tgt_Ferm_Temp - 1
                if Tgt_Ferm_Temp>30:
                    Tgt_Ferm_Temp = 30
                if Tgt_Ferm_Temp<-2:
                    Tgt_Ferm_Temp = -2
            while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
                time.sleep(0)
            print >> Fridge_Cycle, str(Day), Tgt_Ferm_Temp
            Fridge_Cycle.flush()
            Day = Day + 1
        # Create Data File Which Records the Date and Time Which the Fridge Controller Starts        
        try:
            with open('/home/pi/Fridge_Start_Time.dat'):
                os.remove('/home/pi/Fridge_Start_Time.dat')
        except IOError:
            print "No File to Delete"
        Fridge_Start_Time = open('/home/pi/Fridge_Start_Time.dat', 'a')
        print >> Fridge_Start_Time, "Start_Date_and_Time", "Fermentation_Duration"
        Fridge_Start_Time.flush()
        print >> Fridge_Start_Time, str(datetime.datetime.now()), Days_Total
        Fridge_Start_Time.flush()
        Fridge_Run(Power_Interrupt, Power_Interrupt_Time)                    

        
############################################################################################
############################################################################################
#------------------------------------------------------------------------------ 
#                              Fridge Cycle Function
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
  
    def Fridge_Run(Power_Interrupt, Power_Interrupt_Time):
        #------------------------------------------------------------------------------
        #                 SETUP THE ONE WIRE THERMOMETER SYSTEM
        #------------------------------------------------------------------------------    
        
        base_dir = '/sys/bus/w1/devices/'
        # Setup Thermometer 1 Location
        device1_folder = glob.glob(base_dir + Thermometer3_Address)[0] 
        device1_file = device1_folder + '/w1_slave'
        # setup Thermomenter 2 Location
        device2_folder = glob.glob(base_dir + Thermometer4_Address)[0]
        device2_file = device2_folder + '/w1_slave'        
        
        
        dateString = '%Y-%m-%d %H:%M:%S'
        global Target_Wort_Temp
        global Current_Day_No
        global Fridge_Cycle_Day
        global Remaining_Days
        global Remaining_Hours_str
        global Remaining_Mins_str
        
        try:
            with open('/home/pi/Fridge_Start_Time.dat'):       
                Ferm_Start_Time = open('/home/pi/Fridge_Start_Time.dat', 'r')
                # Create a data list from Fridge_Start_Time.dat row 1 (2nd row)
                Ferm_Start_Data = [i.strip().split() for i in Ferm_Start_Time.readlines()][1]
                # Join up the first and second parameters from the list to create a single string (date time)
                Ferm_Start_Date_Time_Str = (str(Ferm_Start_Data[0]) + " " + str(Ferm_Start_Data[1]))
                # Convert the date time string into a datetime parameter
                Ferm_Start_Date_Time = datetime.datetime.strptime(Ferm_Start_Date_Time_Str, '%Y-%m-%d %H:%M:%S.%f')                
                # Use the third parameter from the list and save it as int Ferm_Duration                     
                Ferm_Duration = int(Ferm_Start_Data[2])
                # Convert Ferm_Duration to seconds
                Ferm_Duration_Secs = Ferm_Duration*60*60*24
                # Work out the difference between the Fermenation start date and time the current date and time
                Time_Delta = datetime.datetime.now() - Ferm_Start_Date_Time
                # Convert the time difference into seconds to then compare with the Ferm_Duration_Secs parameter
                Time_Delta_seconds = Time_Delta.total_seconds()
        except IOError:
            buzzer_count = 0
            while (buzzer_count < 12):
                mcp.output(7, 1)
                time.sleep(0.1)
                mcp.output(7, 0)
                time.sleep(0.1)
                buzzer_count = buzzer_count + 1
            while(mcp.input(14) > 2):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("FILE READ ERROR")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("  REBOOT REQ'D")
                lcd_string(Line2_String)
                time.sleep(2)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("HOLD TEMP DOWN")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("    TO REBOOT")
                lcd_string(Line2_String)
                time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***REBOOTING***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Please Wait...") 
            lcd_string(Line2_String)
            os.system("sudo shutdown -r now")
        
        Logging_Time = datetime.datetime.now()
        global Fridge_Last_Run
        Fridge_Last_Run = datetime.datetime.now()
        global Compressor_Protection
        Compressor_Protection = 0
        global Heater_Status
        Heater_Status = 0
        global Fridge_Status
        Fridge_Status = 0
        global Display_Ready
        Display_Ready = 0

        
        # Start Fridge_Display Thread
        Fridge_Display_thread = Thread(target = Fridge_Display, args = (Power_Interrupt, Power_Interrupt_Time, ))
        Fridge_Display_thread.start()
        
        # Temperature regulation code goes here:
        global Wort_Temperature
        Wort_Temperature = 10
        global Fridge_Temperature
        Fridge_Temperature = 10
        global Wort_Temp_Error
        global Fridge_Temp_Error
        Heater_Hyst = 0
        Fridge_Hyst = 0
        Lock_Out = 0
        while(True):
            try:
                # Work out the difference between the Fermenation start date and time the current date and time
                Time_Delta = datetime.datetime.now() - Ferm_Start_Date_Time
                # Convert the time difference into seconds to then compare with the Ferm_Duration_Secs parameter
                Time_Delta_seconds = Time_Delta.total_seconds()
                Current_Day_No = int(Time_Delta_seconds/60/60/24) + 1
                Remaining_Days = Ferm_Duration - Current_Day_No
                if ((Ferm_Duration*24*60*60) > Time_Delta_seconds):
                    Remaining_Time_hh_mm = ((Ferm_Duration*24*60*60)-Time_Delta_seconds-(Remaining_Days*24*60*60))
                    Remaining_Hours = int(Remaining_Time_hh_mm/60/60)
                    Remaining_Mins = ((Remaining_Time_hh_mm/60) - (Remaining_Hours*60))
                    Remaining_Hours_str = str(int(Remaining_Hours))
                    if Remaining_Hours < 10:
                        Remaining_Hours_str = ("0" + str(int(Remaining_Hours)))
                    Remaining_Mins_str = str(int(Remaining_Mins))
                    if Remaining_Mins < 10:
                        Remaining_Mins_str = ("0" + str(int(Remaining_Mins)))
                    Fridge_Cycle_Day = open('/home/pi/Fridge_Cycle.dat', 'r')
                    Fridge_Cycle_Day = [i.strip().split() for i in Fridge_Cycle_Day.readlines()][Current_Day_No]
                    Target_Wort_Temp = int(Fridge_Cycle_Day[1])
                if ((Ferm_Duration*24*60*60) < Time_Delta_seconds):    
                    Remaining_Days = 0
                    Fridge_Cycle_Day = open('/home/pi/Fridge_Cycle.dat', 'r')
                    Fridge_Cycle_Day = [i.strip().split() for i in Fridge_Cycle_Day.readlines()][Ferm_Duration]
                    Target_Wort_Temp = int(Fridge_Cycle_Day[1])
                    Remaining_Days = 0
                    Remaining_Hours_str = "00"
                    Remaining_Mins_str = "00"
                Wort_Temperature_Last = Wort_Temperature
                Wort_Temperature = read_temp_1(device1_file)
                if Wort_Temperature == -100:
                    Wort_Temperature = Wort_Temperature_Last
                    Wort_Therm_Error = 1
                if Wort_Temperature != -100:
                    Wort_Temp_Error = 0
                Fridge_Temperature_Last = Fridge_Temperature
                Fridge_Temperature = read_temp_2(device2_file)
                if Fridge_Temperature == -100:
                    Fridge_Temperature = Fridge_Temperature_Last
                    Fridge_Temp_Error = 1
                if Fridge_Temperature != -100:
                    Fridge_Temp_Error = 0
                Display_Ready = 1
                # Temperature regulation script
                Wort_Temp_Delta = Target_Wort_Temp - Wort_Temperature
                if Wort_Temp_Delta > 3:
                    Air_Temp_Delta = Wort_Temp_Delta * 2
                if ((Wort_Temp_Delta < 3) & (Wort_Temp_Delta > 1)):
                    Air_Temp_Delta = Wort_Temp_Delta * 2.5
                if ((Wort_Temp_Delta <=1) & (Wort_Temp_Delta > 0.3)):
                    Air_Temp_Delta = Wort_Temp_Delta * 3 #Vary this value to get tighter or looser temperature control
                if ((Wort_Temp_Delta <=0.3) & (Wort_Temp_Delta > 0)):
                    Air_Temp_Delta = Wort_Temp_Delta * 4 #Vary this value to get tighter or looser temperature control
                if Wort_Temp_Delta < -3:
                    Air_Temp_Delta = Wort_Temp_Delta * 2
                if ((Wort_Temp_Delta > -3) & (Wort_Temp_Delta < -1)):
                    Air_Temp_Delta = Wort_Temp_Delta * 2.5
                if ((Wort_Temp_Delta >=-1) & (Wort_Temp_Delta < -0.3)):
                    Air_Temp_Delta = Wort_Temp_Delta * 3 #Vary this value to get tighter or looser temperature control
                if ((Wort_Temp_Delta >= -0.3) & (Wort_Temp_Delta < 0)):
                    Air_Temp_Delta = Wort_Temp_Delta * 4 #Vary this value to get tighter or looser temperature control
                if Air_Temp_Delta > 8:
                    Air_Temp_Delta = 8
                if Air_Temp_Delta < -15:
                    Air_Temp_Delta = -15
                Target_Fridge_Air_Temp = Wort_Temperature + Air_Temp_Delta
                #Turn Heater ON
                if ((Fridge_Temperature < (Target_Fridge_Air_Temp-0.5)) & (Heater_Hyst == 0) & (Lock_Out == 0)):
                    if Fridge_Status == 1:
                        Fridge_Last_Run = datetime.datetime.now()
                    Compressor_Protection = 0
                    Heater_Status = 1
                    Fridge_Status = 0
                    mcp.output(12, 0) #Heater ON
                    mcp.output(13, 1) #Fridge OFF
                if (Fridge_Temperature > (Target_Fridge_Air_Temp - 0.5)):
                    Heater_Hyst = 1
                    Heater_Status = 0
                    mcp.output(12, 1) #Heater OFF
                if (Fridge_Temperature < (Target_Fridge_Air_Temp - 1)):
                    Heater_Hyst = 0
                #Turn Fridge ON
                if ((Fridge_Temperature > (Target_Fridge_Air_Temp+0.5)) & (Fridge_Hyst == 0) & (Lock_Out == 0)):
                    if ((datetime.datetime.now() - Fridge_Last_Run).total_seconds()) > 180:
                        Compressor_Protection = 0
                        Fridge_Status = 1
                        Heater_Status = 0
                        mcp.output(13, 0) #Fridge ON
                        mcp.output(12, 1) #Heater OFF
                    else:
                        Compressor_Protection = 1
                if (Fridge_Temperature < (Target_Fridge_Air_Temp + 0.5)):
                    Fridge_Hyst = 1
                    Fridge_Status = 0
                    mcp.output(13, 1) #Fridge OFF
                if (Fridge_Temperature > (Target_Fridge_Air_Temp + 1)):
                    Fridge_Hyst = 0
                if ((Fridge_Temperature < (Target_Fridge_Air_Temp + 0.3)) & (Fridge_Temperature > (Target_Fridge_Air_Temp - 0.3))):
                    Lock_Out = 1
                    Fridge_Status = 0
                    Heater_Status = 0
                    mcp.output(13, 1) #Fridge OFF
                    mcp.output(12, 1) #Heater OFF
                else:
                    Lock_Out = 0
                Logging_Time_Counter = (datetime.datetime.now() - Logging_Time)
                Logging_Time_Counter_Secs = Logging_Time_Counter.total_seconds()        
                # Write the data to the log file
                if Logging_Time_Counter_Secs > 300:
                    try:
                        Fridge_Log = open('/var/www/Fridge_Log.csv', 'a')
                        print >> Fridge_Log, datetime.datetime.now().strftime(dateString), ',', Fridge_Temperature, ',', Wort_Temperature, ',', Target_Wort_Temp, ',', Target_Fridge_Air_Temp, ',', Fridge_Status, ',', Heater_Status
                        Fridge_Log.flush()
                        Logging_Time = datetime.datetime.now()
                    except IOerror, e:
                        scriptdebug(e)
            except Exception, e:
                scriptdebug(e)
############################################################################################
############################################################################################
#------------------------------------------------------------------------------ 
#                              FRIDGE DISPLAY FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
    def Fridge_Display(Power_Interrupt, Power_Interrupt_Time):
        Last_Cycle_Time = datetime.datetime.now()
        Display_Sequence = 1
        lcd_byte(LCD_LINE_1, LCD_CMD)
        Line1_String = ("   Waiting for")
        lcd_string(Line1_String)
        lcd_byte(LCD_LINE_2, LCD_CMD)
        Line2_String = ("Temperature Data") 
        lcd_string(Line2_String)
        while(True):
            if (Display_Ready == 1):
                if (mcp.input(15) < 2):
                    lcd_init()
                Current_Time = datetime.datetime.now()
                if ((int((Current_Time - Last_Cycle_Time).total_seconds())) > 8):
                    lcd_init()
                    Display_Sequence = Display_Sequence+1
                    Last_Cycle_Time = Current_Time
                if Display_Sequence > 7:
                    Display_Sequence = 1
                if (mcp.input(14) < 2):
                    Display_Sequence = Display_Sequence - 1
                    while (mcp.input(14) < 2):
                        Last_Cycle_Time = datetime.datetime.now()
                if (mcp.input(15) < 2):
                    Display_Sequence = Display_Sequence + 1
                    while (mcp.input(15) < 2):
                        Last_Cycle_Time = datetime.datetime.now()
                if Display_Sequence < 1:
                    Display_Sequence = 7
                if Wort_Temp_Error == 1:
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = ("WORT THERMOMETER")
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = ("     ERROR")
                    lcd_string(Line2_String)
                if Fridge_Temp_Error == 1:
                    lcd_byte(LCD_LINE_1, LCD_CMD)
                    Line1_String = ("FRDG THERMOMETER")
                    lcd_string(Line1_String)
                    lcd_byte(LCD_LINE_2, LCD_CMD)
                    Line2_String = ("     ERROR")
                    lcd_string(Line2_String) 
                if ((Fridge_Temp_Error == 0) & (Wort_Temp_Error == 0)):    
                    if Display_Sequence == 1:
                        lcd_byte(LCD_LINE_1, LCD_CMD)
                        Line1_String = ("Target Wort Temp")
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = ("      " + (str(Target_Wort_Temp)) + chr(223) + "C")
                        lcd_string(Line2_String)
                    if Display_Sequence == 2:
                        lcd_byte(LCD_LINE_1, LCD_CMD)
                        Line1_String = ("Wort Temperature")
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = ("    " + (str(Wort_Temperature)) + chr(223) + "C")
                        lcd_string(Line2_String)
                    if Display_Sequence == 3:
                        lcd_byte(LCD_LINE_1, LCD_CMD)
                        Line1_String = ("Fridge Air Temp")
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = ("    " + (str(Fridge_Temperature)) + chr(223) + "C")
                        lcd_string(Line2_String)
                    if Display_Sequence == 4:
                        lcd_byte(LCD_LINE_1, LCD_CMD)
                        Line1_String = ("Fermentation Day")
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = ("       " + str(Current_Day_No))
                        lcd_string(Line2_String)
                    if Display_Sequence == 5:
                        lcd_byte(LCD_LINE_1, LCD_CMD)
                        Line1_String = ("Remaining Time")  
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = ("  " + str(Remaining_Days) + " Days " + Remaining_Hours_str + ":" + Remaining_Mins_str)
                        lcd_string(Line2_String)
                    if Display_Sequence == 6:
                        if (Fridge_Status == 0) & (Compressor_Protection == 0):
                            lcd_byte(LCD_LINE_1, LCD_CMD)
                            Line1_String = ("Fridge = OFF")
                            lcd_string(Line1_String)
                        if ((Fridge_Status == 1) & (Compressor_Protection == 0)):
                            lcd_byte(LCD_LINE_1, LCD_CMD)
                            Line1_String = ("Fridge = ON")
                            lcd_string(Line1_String)
                        if ((Fridge_Status == 0) & (Compressor_Protection == 1)):
                            lcd_byte(LCD_LINE_1, LCD_CMD)
                            Line1_String = ("Fridge = PM " + str(int(180-(datetime.datetime.now() - Fridge_Last_Run).total_seconds())))
                            lcd_string(Line1_String)
                        if Heater_Status == 0:
                            lcd_byte(LCD_LINE_2, LCD_CMD)
                            Line2_String = ("Heater = OFF")
                            lcd_string(Line2_String)
                        if Heater_Status == 1:
                            lcd_byte(LCD_LINE_2, LCD_CMD)
                            Line2_String = ("Heater = ON")
                            lcd_string(Line2_String)
                    if ((Display_Sequence == 7) & (Power_Interrupt == 0)):
                        lcd_byte(LCD_LINE_1, LCD_CMD)   
                        Line1_String = ("  Power Status")
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = ("       OK        ")
                        lcd_string(Line2_String)              
                    if ((Display_Sequence == 7) & (Power_Interrupt == 1)):
                        lcd_byte(LCD_LINE_1, LCD_CMD)
                        Line1_String = ("Power Interrupt")
                        lcd_string(Line1_String)
                        lcd_byte(LCD_LINE_2, LCD_CMD)
                        Line2_String = (str(Power_Interrupt_Time))
                        lcd_string(Line2_String)
                    if ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
                        while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
                            time.sleep(0)
                        Menu_Sequence = 1
                        Timeout_Counter_Start = datetime.datetime.now()
                        while (int((datetime.datetime.now() - Timeout_Counter_Start).total_seconds())) < 7:
                            if (mcp.input(14) < 2):
                                Menu_Sequence = Menu_Sequence - 1
                                while (mcp.input(14) < 2):
                                    Timeout_Counter_Start = datetime.datetime.now()
                            if (mcp.input(15) < 2):
                                Menu_Sequence = Menu_Sequence + 1
                                while (mcp.input(15) < 2):
                                    Timeout_Counter_Start = datetime.datetime.now()
                            if Menu_Sequence > 4:
                                Menu_Sequence = 4
                            if Menu_Sequence < 1:
                                Menu_Sequence = 1
                            if Menu_Sequence == 1:
                                lcd_byte(LCD_LINE_1, LCD_CMD)   
                                Line1_String = ("Increase Day   +")
                                lcd_string(Line1_String)
                                lcd_byte(LCD_LINE_2, LCD_CMD)
                                Line2_String = ("Temperature")
                                lcd_string(Line2_String)
                            if Menu_Sequence == 2:
                                lcd_byte(LCD_LINE_1, LCD_CMD)   
                                Line1_String = ("Decrease Day   +")
                                lcd_string(Line1_String)
                                lcd_byte(LCD_LINE_2, LCD_CMD)
                                Line2_String = ("Temperature    -")
                                lcd_string(Line2_String)
                            if Menu_Sequence == 3:
                                lcd_byte(LCD_LINE_1, LCD_CMD)   
                                Line1_String = ("New Ferm       +")
                                lcd_string(Line1_String)
                                lcd_byte(LCD_LINE_2, LCD_CMD)
                                Line2_String = ("Schedule       -")
                                lcd_string(Line2_String) 
                            if (((mcp.input(15) < 2) & (mcp.input(14) < 2)) & Menu_Sequence == 3):
                                while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
                                    Timeout_Counter_Start = datetime.datetime.now()
                                while (int((datetime.datetime.now() - Timeout_Counter_Start).total_seconds())) < 7:
                                    Yes_No = 1
                                    if (mcp.input(15) < 2):
                                        Timeout_Counter_Start = datetime.datetime.now()
                                        Yes_No = Yes_No + 1
                                    if (mcp.input(14) < 2):
                                        Timeout_Counter_Start = datetime.datetime.now()
                                        Yes_No = Yes_No - 1
                                    if Yes_No < 0:
                                        Yes_No = 1
                                    if Yes_No > 1:
                                        Yes_No = 0
                                    if Yes_No == 1:
                                        lcd_byte(LCD_LINE_1, LCD_CMD)   
                                        Line1_String = ("Erase Current")
                                        lcd_string(Line1_String)
                                        lcd_byte(LCD_LINE_2, LCD_CMD)
                                        Line2_String = ("Schedule?  YES")
                                    if Yes_No == 0:
                                        lcd_byte(LCD_LINE_1, LCD_CMD)   
                                        Line1_String = ("Erase Current")
                                        lcd_string(Line1_String)
                                        lcd_byte(LCD_LINE_2, LCD_CMD)
                                        Line2_String = ("Schedule?   NO")
                            if Menu_Sequence == 4:
                                lcd_byte(LCD_LINE_1, LCD_CMD)   
                                Line1_String = ("Backup")
                                lcd_string(Line1_String)
                                lcd_byte(LCD_LINE_2, LCD_CMD)
                                Line2_String = ("One Day        -")
                                lcd_string(Line2_String) 

############################################################################################
############################################################################################
#------------------------------------------------------------------------------
#                                MAIN FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
    print "Starting Program (CTRL+Z to quit)"
    dateString = '%Y-%m-%d %H:%M:%S'
    
    try:
        with open('/home/pi/error1.log'):
            os.remove('/home/pi/error1.log')
    except IOError:
        print "No File to Delete"
        
    try:
        with open('/home/pi/error.log'):
            os.rename('/home/pi/error.log', '/home/pi/error1.log')
    except IOError:
        print "No File to Rename"   
    try:
        with open('/home/pi/RPi_Brewery_Controller.config'):
            ########################### FRIDGE THERM 1 #############################
            Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
            # Create a data list from Brewery_Controller.config row 1 (2nd row)
            Fridge_Therm1 = [i.strip().split() for i in Brewery_Config.readlines()][1]
            # Show the second item in the row (the thermometer address)
            Thermometer3_Address = str(Fridge_Therm1[1])
            ########################### FRIDGE THERM 2 #############################
            Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
            # Create a data list from Brewery_Controller.config row 1 (2nd row)
            Fridge_Therm2 = [i.strip().split() for i in Brewery_Config.readlines()][2]
            # Show the second item in the row (the thermometer address)
            Thermometer4_Address = str(Fridge_Therm2[1])
            ########################### BOILER THERM 1 #############################
            Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
            # Create a data list from Brewery_Controller.config row 1 (2nd row)
            Boiler_Therm1 = [i.strip().split() for i in Brewery_Config.readlines()][3]
            # Show the second item in the row (the thermometer address)
            Thermometer1_Address = str(Boiler_Therm1[1])
            ########################### BOILER THERM 2 #############################
            Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
            # Create a data list from Brewery_Controller.config row 1 (2nd row)
            Boiler_Therm2 = [i.strip().split() for i in Brewery_Config.readlines()][4]
            # Show the second item in the row (the thermometer address)
            Thermometer2_Address = str(Boiler_Therm2[1])
    except IOError:
        try:
            with open('/home/pi/RPi_Brewery_Controller.config'):
                os.remove('/home/pi/RPi_Brewery_Controller.config')
        except IOError:
            print "No File to Delete"
        RPi_Brewery_Controller.config = open('/home/pi/RPi_Brewery_Controller.config', 'a')
        print >> RPi_Brewery_Controller.config, "Raspberry Pi Brewery Controller Config File"
        Boiler_Log.flush()
        print >> RPi_Brewery_Controller.config, "Fridge_Thermometer_Wort="
        Boiler_Log.flush()
        print >> RPi_Brewery_Controller.config, "Fridge_Thermometer_Fridge_Air="
        Boiler_Log.flush()
        print >> RPi_Brewery_Controller.config, "Boiler/HLT_Thermometer_1="
        Boiler_Log.flush()
        print >> RPi_Brewery_Controller.config, "Boiler/HLT_Thermometer_2="
        Boiler_Log.flush()
        lcd_byte(LCD_LINE_1, LCD_CMD)
        Line1_String = ("**CONFIG FILE**")
        lcd_string(Line1_String)
        lcd_byte(LCD_LINE_2, LCD_CMD)
        Line2_String = ("**ERROR**")
        lcd_string(Line2_String)
        time.sleep(2)
        buzzer_count = 0
        while (buzzer_count < 12):
            mcp.output(7, 1)
            time.sleep(0.1)
            mcp.output(7, 0)
            time.sleep(0.1)
            buzzer_count = buzzer_count + 1
        while(mcp.input(14) > 2):
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("EDIT CONFIG FILE")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("WITH THERM DATA")
            lcd_string(Line2_String)
            time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("THEN HOLD TEMP")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("DOWN TO REBOOT")
            lcd_string(Line2_String)
            time.sleep(2)
        lcd_byte(LCD_LINE_1, LCD_CMD)
        Line1_String = ("***REBOOTING***")
        lcd_string(Line1_String)
        lcd_byte(LCD_LINE_2, LCD_CMD)
        Line2_String = ("Please Wait...") 
        lcd_string(Line2_String)
        os.system("sudo shutdown -r now")
    # Startup Display
    GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
    GPIO.setup(LCD_E, GPIO.OUT)  # E
    GPIO.setup(LCD_RS, GPIO.OUT) # RS
    GPIO.setup(LCD_D4, GPIO.OUT) # DB4
    GPIO.setup(LCD_D5, GPIO.OUT) # DB5
    GPIO.setup(LCD_D6, GPIO.OUT) # DB6
    GPIO.setup(LCD_D7, GPIO.OUT) # DB7
    # Initialise display
    lcd_init()
    # Initialise the program parameters
    temp_reached = 0
    global Temperature
    Temperature = 99
    tens = 0
    units = 0
    target_temperature = 72
    Line1_String = ""
    Line2_String = ""
    # Wait for User to start boiler
    lcd_byte(LCD_LINE_1, LCD_CMD)
    Line1_String = ("ROBBO'S BREWERY")
    lcd_string(Line1_String)
    lcd_byte(LCD_LINE_2, LCD_CMD)
    Line2_String = ("BOILER CONTROL")
    lcd_string(Line2_String)
    print ""
    print ""
    print ""
    print ""
    print "" 
    print ""
    print ""
    print ""
    print ""
    print ""
    print ""
    print "    Average Temperature = "
    print "     Target Temperature = "
    print " ____________________________________"
    print "       ", Line1_String
    print "       ", Line2_String
    print " ____________________________________"
    time.sleep(5) 

    try:
        with open('/sys/bus/w1/devices/' + Thermometer1_Address + '/w1_slave'):
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***BOILER/HLT***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("*MODE DETECTED*")
            lcd_string(Line2_String)
            time.sleep(2)
            Boiler_HLT_Mode(temp_reached, tens, units, target_temperature, dateString, Line1_String, Line2_String)
    except IOError:
        try:
            with open('/sys/bus/w1/devices/' + Thermometer3_Address + '/w1_slave'):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("***FV FRIDGE***")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("*MODE DETECTED*")
                lcd_string(Line2_String)
                time.sleep(2)
                FV_Fridge_Mode()
        except IOError:    
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("**THERMOMETER**")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("**SENSOR ERROR**")
            lcd_string(Line2_String)
            time.sleep(2)
            buzzer_count = 0
            while (buzzer_count < 12):
                mcp.output(7, 1)
                time.sleep(0.1)
                mcp.output(7, 0)
                time.sleep(0.1)
                buzzer_count = buzzer_count + 1
            while(mcp.input(14) > 2):
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("CONNECT DEVICE")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("TO THERMOMETERS")
                lcd_string(Line2_String)
                time.sleep(2)
                lcd_byte(LCD_LINE_1, LCD_CMD)
                Line1_String = ("THEN HOLD TEMP")
                lcd_string(Line1_String)
                lcd_byte(LCD_LINE_2, LCD_CMD)
                Line2_String = ("DOWN TO REBOOT")
                lcd_string(Line2_String)
                time.sleep(2)
            lcd_byte(LCD_LINE_1, LCD_CMD)
            Line1_String = ("***REBOOTING***")
            lcd_string(Line1_String)
            lcd_byte(LCD_LINE_2, LCD_CMD)
            Line2_String = ("Please Wait...") 
            lcd_string(Line2_String)
            os.system("sudo shutdown -r now")

IMG_1367.jpg
 
Last edited:
Glad you got your brews sorted.

I'll experiment with bulbs to ensure I get the fridge and heater the right way round. I'll let you know how I get on (says he hoping he doesn't get grief like last time ;^)

Graham
 
Cool. Post some photos of your setup when it is up and running - it would be good to see.
 
OK Robbo

I've built all the gubbins into a box, created the config file but I suspect that your code required all 4 thermometers connected at the same time as I'm having difficulty running the code with just the two fridge thermometers. I'll add another two sensors on Monday evening and see how I get on with it then.

P.S. Your example config file has the boiler at line 1 and 2 whereas the code wants the fridge at 1 and 2 with the boiler afterwards.

Regards

Graham (getting back into Pi ;^)
 
Hi Graham.

No, the code only wants two thermometers. It uses the addresses of the thermometers to detect if it is connected to the fridge or the HLT.

If you are only connecting a fridge, then put in dummy addressed for the boiler.

Thinking about it, the first line is line 0, so if the boiler is at line 1 And 2, then you many need a title line at the top in line 0 (the first line). Any text will do. It should probably be:

Any title in line 1
Fridge 1
Fridge 2
Boiler 1
Boiler 2

Ensuring the fridge therm for wort and air are in the correct order in the config file.
 
Message removed by Pakman as I think I found the answer once I'd posted the question ;^)
 
The program didn't want to run properly. Then found that the file had been truncated before the end (not sure how that happened) reloaded file and now it starts, locates thermometers 1 and 2 and then immediately reboots. ErrorLog file shows "Date,Time,local variable 'Ferm_Start_Date_Time' referenced before assignment.

Any ideas?

Graham
 
The program didn't want to run properly. Then found that the file had been truncated before the end (not sure how that happened) reloaded file and now it starts, locates thermometers 1 and 2 and then immediately reboots. ErrorLog file shows "Date,Time,local variable 'Ferm_Start_Date_Time' referenced before assignment.

Any ideas?

Graham

grab the sources again smells like a corrupt download,
 
Robbo
I had to totally rebuild the SD card due to messing up the auto-start configuration.
Fridge mode starts OK, it finds therms 1 and 2 , then beeps and indicates "press temp button to reboot" Error log still states "2014-08-12 15:56:02.372162 local variable 'Ferm_Start_Date_Time' referenced bef$" repeated over and over.

Do I have to manually create the first Fridge_Start_Time.dat file as I do not have one in /home/pi ? Copies of error logs attached
Graham
 
Hi Graham.

I am away from my Pi at them moment, so can't easily check, but it is worth trying to manually create the .dat file.

I will have a look at the code when I get a chance and offer you some better ideas.
 
Created a file called Fridge_Start_time.dat and filled it with lines of:-
yyyy-mm-dd hh:mm:ss.1
Now the program goes past the point where it was unable to find the times and errors on
<ValueError: time data '2014-08-13 14:44:10,1' does not match format '%Y-%m-%d %H:%M:%S.%f'> so my previous finding - that the time file needs to be there is correct. Just need to know the format for the contents to create one that works.

P.S. in para 5.2.4 in the How To the command "chmod a+x /bin/autologin.sh" needs a Sudo in front of it.

Graham
 
Like I said, I hadn't got the error checking working well yet!

I think the millisecond bit of the time needs to be different. Try writing your own command to write the date.time to the screen and copying the format.

Sorry I can't be more help at the moment. I need to add a command that if the file doesn't exits, then write a new file with the current date time.

Also, it reads from line 1 not line 0, do I probably have a title in the .dat file. This may be the source of the format problem.
 
Like I said, I hadn't got the error checking working well yet!

I think the millisecond bit of the time needs to be different. Try writing your own command to write the date.time to the screen and copying the format.

Sorry I can't be more help at the moment. I need to add a command that if the file doesn't exits, then write a new file with the current date time.

Also, it reads from line 1 not line 0, do I probably have a title in the .dat file. This may be the source of the format error message.
 
Having looked on t'internet (away from home at present) I suspect %m should be 'aug' not 08. I'll check when I'm back with Pi.
Graham
 

Latest posts

Back
Top