Introduction: Smart Garage Powered by PcDuino

How many times have you driven away from home and wondering if you have closed your garage or not?

Here we will present a smart garage powered by pcDuino. The garage will alert you by sending email if the garage door is left open. If you email it to close the door, it will close the garage door and confirm back.

Step 1: Parts

In this project, we are going to use a pcDuino and WiFi dongle.  We observed that when the garage door is open, the hinge moves closer to the control unit, and moves away when the door is closed. Please see the following picture:

Step 2: Sensor to Sense the Garage Door

To detect it, we use the orange color infrared detector from CuteDigi.  Normally, it outputs a high level signal. When there are object close to it, the infrared detector will output a low level signal.

To close/open the garage door, we find that the lifemaster version uses a 16V control signal. It will toggle between open and close door when the two lines are short momentarily.  So we use aLinker relay module to control it.  We connect the infrared detector to D2, and Linker relay module to D4 of pcDuino.

The whole setup looks as below:

Step 3: Python Code

The python code is as below:


#!/usr/bin/python
#-*- coding: utf-8 -*-
import smtplib
import time
from adc import analog_read
import gpio
import time
import imaplib
import uuid
from email import email
import imaplib
import time
import uuid
from email import email
relay_pin = "gpio2"
sensor_pin="gpio4"
#the following is for sending email
server= 'smtp.gmail.com'
port = 587
sender = 'xxxxxx@gmail.com'
recipient = 'xxxxx@linksprite.com'
password='xxxxx'
subject = 'Garage Door Opened'
body = 'The garage door is open. Please check'
#the following is for receiving email
IMAP_SERVER = 'imap.gmail.com'
IMAP_PORT = '993'
IMAP_USE_SSL = True
imap_username = 'xxxxx@gmail.com'
imap_password = 'xxxxx'
num=0
message_content='1';
def delay(ms):
    time.sleep(1.0*ms/1000)
def setup():
    gpio.pinMode(relay_pin, gpio.OUTPUT)
    gpio.pinMode(sensor_pin, gpio.INPUT)
    gpio.digitalWrite(relay_pin, gpio.LOW)
body = "" + body + ""
headers = ["From: " + sender,
           "Subject: " + subject,
           "To: " + recipient,
           "MIME-Version: 1.0",
           "Content-Type: text/html"]
headers = "\r\n".join(headers)
replysubject = 'I closed Garage Door'
replybody = 'I closed Garage Door.'
replybody = "" + replybody + ""
replyheaders = ["From: " + sender,
           "Subject: " + replysubject,
           "To: " + recipient,
           "MIME-Version: 1.0",
           "Content-Type: text/html"]
replyheaders = "\r\n".join(replyheaders)
class MailBox(object):
    def __init__(self, user, password):
        self.user = user
        self.password = password
        if IMAP_USE_SSL:
            self.imap = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
        else:
            self.imap = imaplib.IMAP4(IMAP_SERVER, IMAP_PORT)
    def __enter__(self):
        self.imap.login(self.user, self.password)
        return self
    def __exit__(self, type, value, traceback):
        self.imap.close()
        self.imap.logout()
    def get_count(self):
        self.imap.select('Inbox')
        status, data = self.imap.search(None, 'UnSeen')
        return sum(1 for num in data[0].split())
    def fetch_message(self, num):
        self.imap.select('Inbox')
        status, data = self.imap.fetch(str(num), '(RFC822)')
        email_msg = email.message_from_string(data[0][1])
        return email_msg
    def delete_message(self, num):
        self.imap.select('Inbox')
        self.imap.store(num, '+FLAGS', r'\Deleted')
        self.imap.expunge()
    def print_msgs(self):
        self.imap.select('Inbox')
        status, data = self.imap.search(None, 'UnSeen')
        #for num in reversed(data[0].split()):
        status, data = self.imap.fetch(num, '(RFC822)')
        self.imap.store(num, '+FLAGS','\\Deleted')
        msg=email.message_from_string(data[0][1])
        message_content=msg.get_all("Subject")
        if  'close garage door' in message_content :
             return 1
    def get_latest_email_sent_to(self, email_address, timeout=300, poll=1):
        start_time = time.time()
        while ((time.time() - start_time) < timeout):
            # It's no use continuing until we've successfully selected
            # the inbox. And if we don't select it on each iteration
            # before searching, we get intermittent failures.
            status, data = self.imap.select('Inbox')
            if status != 'OK':
                time.sleep(poll)
                continue
            status, data = self.imap.search(None, 'TO', email_address)
            data = [d for d in data if d is not None]
            if status == 'OK' and data:
                for num in reversed(data[0].split()):
                    status, data = self.imap.fetch(num, '(RFC822)')
                    email_msg = email.message_from_string(data[0][1])
                    return email_msg
            time.sleep(poll)
        raise AssertionError("No email sent to '%s' found in inbox "
             "after polling for %s seconds." % (email_address, timeout))
    def delete_msgs_sent_to(self, email_address):
        self.imap.select('Inbox')
        status, data = self.imap.search(None, 'TO', email_address)
        if status == 'OK':
            for num in reversed(data[0].split()):
                status, data = self.imap.fetch(num, '(RFC822)')
                self.imap.store(num, '+FLAGS', r'\Deleted')
        self.imap.expunge()
def closedoor() :
        gpio.digitalWrite(relay_pin, gpio.HIGH)
        delay(200)
        gpio.digitalWrite(relay_pin, gpio.LOW)
if __name__ == '__main__':
    setup()
    while(1):
        if gpio.digitalRead(sensor_pin) == gpio.LOW  :
             print("Sensor pin is LOW")
             session = smtplib.SMTP(server, port)
             session.ehlo()
             session.starttls()
             session.ehlo
             session.login(sender, password)
             session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
             session.quit()
    delay(10)
        with MailBox(imap_username, imap_password) as mbox:
                 num=mbox.get_count()
                 if num !=0 :
                        if  mbox.print_msgs()  :
                              print 'turn on'
                              closedoor()
                              session = smtplib.SMTP(server, port)
                      session.ehlo()
                      session.starttls()
                              session.ehlo
                              session.login(sender, password)
                              session.sendmail(sender, recipient, replyheaders + "\r\n\r\n" + replybody)
                              session.quit()



We can use the trick in post to get python library for pcDuino, and  let the above python script to load automatically during startup of pcDuino.

Step 4: Final Setup

The following are pictures showing pcDuino installed:

123D Circuits Contest

Participated in the
123D Circuits Contest