How to: Raspberry Pi HLT/Boiler Controller

Discussion in 'Beer Brewing "How-To" Guides' started by Robbo100, Jan 10, 2014.

Help Support The Homebrew Forum UK by donating:

  1. Jul 31, 2014 #81

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    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.
     
  2. Jul 31, 2014 #82

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     
  3. Aug 1, 2014 #83

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
  4. Aug 1, 2014 #84

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     
  5. Aug 1, 2014 #85

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    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: Aug 1, 2014
  6. Aug 1, 2014 #86

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     
  7. Aug 2, 2014 #87

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    Cool. Post some photos of your setup when it is up and running - it would be good to see.
     
  8. Aug 10, 2014 #88

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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 ;^)
     
  9. Aug 11, 2014 #89

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    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.
     
  10. Aug 11, 2014 #90

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    Message removed by Pakman as I think I found the answer once I'd posted the question ;^)
     
  11. Aug 11, 2014 #91

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    What was the answer? - just in case someone else has the same problem?
     
  12. Aug 11, 2014 #92

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     
  13. Aug 11, 2014 #93

    Fil

    Fil

    Fil

    Landlord. Supporting Member

    Joined:
    Oct 17, 2011
    Messages:
    4,115
    Likes Received:
    975
    grab the sources again smells like a corrupt download,
     
  14. Aug 12, 2014 #94

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    So is it working now?
     
  15. Aug 12, 2014 #95

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     
  16. Aug 12, 2014 #96

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    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.
     
  17. Aug 13, 2014 #97

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     
  18. Aug 13, 2014 #98

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    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.
     
  19. Aug 13, 2014 #99

    Robbo100

    Robbo100

    Robbo100

    Regular.

    Joined:
    Dec 21, 2012
    Messages:
    401
    Likes Received:
    21
    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.
     
  20. Aug 14, 2014 #100

    Pakman

    Pakman

    Pakman

    Regular.

    Joined:
    Oct 10, 2012
    Messages:
    226
    Likes Received:
    3
    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
     

Share This Page