Introduction: VentMan: DIY Automated HVAC Vent Controls

PROBLEM:

My house has these old air vents for the heating and cooling with large damper flaps on them. The two vents on the main floor of the house easily hog all the available air from the furnace blower fan if they're open more than half and inch, depriving the upper floor of any heating or cooling. It was too much hassle to remember to open and close the vents manually at night or to try to balance the temperature throughout the house.

SOLUTION:

I hooked up a 12v linear actuator to each damper flap and control it with a raspberry pi and 2-channel relay. The pi also runs a flask server to listen for open/close commands from my central server, or opens/closes them on a cron schedule.

Supplies

PARTS (per vent):

  • 12v Actuator (the kind used for car lock/unlock functions)
  • 2-channel 5V relay
  • Raspberry Pi (Zero is sufficient) & power supply
  • Jumper wires / 22-guage wire
  • 12V DC Power Supply (min 1 amp)

COST: I only really had to buy the actuators, which went for less than $9 each on amazon. To power them I used old 12V 1-amp and 1.5amp adapters from old soho routers. The relays are about $5 each, and a pi zero wireless about $15.

Step 1: Step 1: Wire Pi GPIO to Relay and Actuator

I had two vents to enable, so some pictures are of one vent's setup, and some another. I had a pi zero W and a pi model 2 lying around, so I used those.

I followed this tutorial to learn how to use the 2-channel relay to reverse the DC polarity to the actuator, in order to make it extend and retract.

Step 2: Step 2: Install Actuator

The actuators came with an extension rod and some other mounting hardware, but I kept it simple and just used the extension rod. It also came with a clip that's supposed to be used to hook onto another rod to lock a car door, but I bent the metal side of my vent flap a little to let me attach the two screws to the side.

To fit it right, I pulled the actuator arm out to the extended position, closed the vent flap, and drilled pilot holes into the side of the duct. I then inserted 3" wood screws into the two mounting holes on the actuator and into the side of the duct in the pilot holes. The actuator will now extend to close the vent, and retract to open it 1".

Step 3: Step 3: Connect

In my basement I ran the two power leads to the actuator through the bottom of each duct. One luckily had a cleaning hole already drilled, so I used that. The other just needed to small 1/4" hole drilled for the wires to poke through.

Connect the power leads of the actuator in the relays. Find power for the pi and the actuator's DC power supply, and start them up.

Step 4: Step 4: Code

The relay is triggered mainly by a cron job running either an open or close python script. The scripts are here. I make mine work alongside some other scripts I have that know when the home is occupied or not, and adjusts the thermostat accordingly:

https://github.com/onetrueandrew/green_ecobee

Scripts also available here.

open.py

import RPi.GPIO as GPIO<br>import time<br>import datetime<br>import csv<br><br>channel1 = 18 #GPIO pin to relay 1<br>channel2 = 23 #GPIO pin to relay 2<br>current_datetime = str(datetime.datetime.now().strftime("%Y-%m-%dT%H:%M"))<br><br># GPIO setup<br>GPIO.setmode(GPIO.BCM)<br>GPIO.setup(channel1, GPIO.OUT)<br>GPIO.setup(channel2, GPIO.OUT)<br><br>def HIGH(pin):<br>    GPIO.output(pin, GPIO.HIGH)<br><br>def LOW(pin):<br>    GPIO.output(pin, GPIO.LOW)<br><br>if __name__ == '__main__':<br>    try:<br>        #RETRACT TO OPN<br>        LOW(channel1)<br>        HIGH(channel2)<br>        time.sleep(0.5)<br>        GPIO.cleanup()<br>        open_log = [current_datetime,'closed']<br>        with open(r'/home/pi/dev/vent.log','a') as log:<br>                writer = csv.writer(log)<br>                writer.writerow(open_log)<br>    except KeyboardInterrupt:<br>        GPIO.cleanup()<br>

close.py

import RPi.GPIO as GPIO<br>import time<br>import datetime<br>import csv<br><br>channel1 = 18 #hookup to relay1<br>channel2 = 23 #hookup to relay2<br>current_datetime = str(datetime.datetime.now().strftime("%Y-%m-%dT%H:%M"))<br><br># GPIO setup<br>GPIO.setmode(GPIO.BCM)<br>GPIO.setup(channel1, GPIO.OUT)<br>GPIO.setup(channel2, GPIO.OUT)<br><br>def HIGH(pin):<br>    GPIO.output(pin, GPIO.HIGH)<br><br>def LOW(pin):<br>    GPIO.output(pin, GPIO.LOW)<br><br>if __name__ == '__main__':<br>    try:<br>        #EXTEND TO CLOSE<br>        HIGH(channel1)<br>        LOW(channel2)<br>        time.sleep(0.5)<br>        GPIO.cleanup()<br>        open_log = [current_datetime,'opened']<br>        with open(r'/home/pi/dev/vent.log','a') as log:<br>                writer = csv.writer(log)<br>                writer.writerow(open_log)<br>    except KeyboardInterrupt:<br>        GPIO.cleanup()<br>

Step 5: Step 5: Test

Test the open and close scripts. As a bonus I wrote myself something called "haunted house mode" which will just flap the vent really fast and loud, for fun.

Schedule the vents how you like, or make them more intelligent using external temperature sensors.

The actuators are not continuously powered, so a human can still open/close the vents manually if they want.