raspberry pi as a thermostat


Hardware required:

  1. Raspberry Pi
  2. 4 channel relay output board – amazon link – This relay module is 5V active low. Relay output maximum contact is AC250V 10A and DC30V 10A.
  3. Temperature sensor – buy – DS18B20
  4. 5” display
  5. Assorted wires, cases/frames/mounts

Purpose:

We need to design a thermostat which can control the heating temperature for a single-family residential home. The home has a typical forced-air central heating system (furnace) powered by propane, with a wood-fired water heater in a shed sitting beside the house.  This wood-fired hot water is circulated through supply lines to a heat exchanger in the plenum above the indoor furnace, like what a split-system AC evaporator would have.  This is a dual-fuel system:  the wood is used as primary fuel, and the propane is only for backup.

With this structure in mind, we need to

  1. Allow the user to control system by only adjusting the in-home air temperature
  2. Integrate both “heat-on” calls for heat into one UI
  3. Integrate the forced-air blower fan control for both sources
  4. Integrate an automatic fail-over from wood to propane
    1. if water temp goes low, or,
    2. indoor air temp does not rise after certain time.
  5. Allow separate failover temperature setpoints
  6. Allow manual override of fuel system
  7. Monitor the water temperature from the boiler
    1. alarm if temp goes low

inputs map:

  1. air temp sensor
  2. water temp sensor (optional)

outputs map:

  1. run fan
  2. run propane heat

I am using the raspberry pi GPIO pins 17, 27, 22, and 23 as my digital outputs.

references:

code snippets:

from flask import Flask, render_template
import datetime
import RPi.GPIO as GPIO
app = Flask(__name__)
GPIO.cleanup()
pin_list = [17,27,22,23]
GPIO.setmode(GPIO.BCM)
try:
  GPIO.setup(pin_list, GPIO.OUT, initial=GPIO.HIGH)
  #GPIO.setup(pin_list, GPIO.HIGH)
except:
  print "error: gpio not set up right"
  GPIO.cleanup()
  GPIO.setup(pin_list, GPIO.OUT, initial=GPIO.HIGH)
finally: 
  print "reached finally"

@app.route("/")
def index():
  #now = datetime.datetime.now()
  #timeString = now.strftime("%Y-%m-%d %H:%M")
  templateData = {
    #'title' : 'HELLO!',
    #'time': timeString,
    'relay17': not GPIO.input(17),
    'relay22': not GPIO.input(22),
    'relay23': not GPIO.input(23),
    'relay27': not GPIO.input(27)
  }
  return render_template('index.html', **templateData)
  
@app.route("/relay/<pin>")
def relay(pin):
  currentPin = int(pin)
  print "relaypowered : " + str(not GPIO.input(currentPin))
  if GPIO.input(currentPin):
    GPIO.output(currentPin, GPIO.LOW)
  else:
    GPIO.output(currentPin, GPIO.HIGH)
 # return "relaypowered : " + str(not GPIO.input(currentPin))
  return index()

@app.route("/exit")
def exit():
  GPIO.cleanup()
  sys.exit()

try:
  if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80, debug=False)
except KeyboardInterrupt:
  print "keyboard inturrupt"
finally:
  print "exiting with cleanup"
  GPIO.cleanup()
<!DOCTYPE html>
   <head>
      <title>GPIO Control</title>
      <link rel="stylesheet" href='../static/style.css'/>
   </head>

   <body>
		<h1>Actuators</h1>
		<h2> Status </h2>
		<h3> Relay 17 ==>  {{ relay17  }}</h3>
      <h3> Relay 22 ==>  {{ relay22  }}</h3>
      <h3> Relay 23 ==>  {{ relay23  }}</h3>
      <h3> Relay 27 ==>  {{ relay27  }}</h3>

		
		<br>
		<h2> Commands </h2>
		<h3> 
         Relay on pin 17 ==> 
		{% if not relay17 %}		
			 <a href="/relay/17" class="button">TURN ON</a>  
		{% else %}
			<a href="/relay/17" class="button">TURN OFF</a>
		{% endif %}
		</h3>
		<h3>
         Relay on pin 22 ==> 
			<a href="/relay/22" class="button">TURN ON</a>  
			<a href="/relay/22" class="button">TURN OFF</a>
		</h3>
		<h3> 
			Relay on pin 23 ==>  
			<a href="/relay/23" class="button">TURN ON</a>  
			<a href="/relay/23" class="button">TURN OFF</a>
		</h3>
		<h3> 
			Relay on pin 27 ==> 
			<a href="/relay/27" class="button">TURN ON</a>  
			<a href="/relay/27"  class="button">TURN OFF</a>
		</h3>

   </body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *