Teodora BuleaFloris-Diana Vornicu
Published © GPL3+

Cool My Room

Automated gmail based temperature control system for any room

BeginnerFull instructions provided3 hours3,636
Cool My Room

Things used in this project

Hardware components

Raspberry Pi Zero
Raspberry Pi Zero
×1
Temperature Sensor
Temperature Sensor
×1
Axial Fan, 12 VDC
Axial Fan, 12 VDC
×1
General Purpose Transistor NPN
General Purpose Transistor NPN
×1
Resistor 220 ohm
Resistor 220 ohm
×4
Male/Female Jumper Wires
Male/Female Jumper Wires
×8
Breadboard (generic)
Breadboard (generic)
×1
9V 1A Switching Wall Power Supply
9V 1A Switching Wall Power Supply
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian
PuTTY
Python 3.8
Python Module for GPIO

Story

Read more

Schematics

CoolMyRoom Circuit Diagram

Code

CoolMyRoom Code

Python
import os
import time
import signal
import sys
import RPi.GPIO as GPIO
import datetime
from w1thermsensor import W1ThermSensor
import imaplib
import email
import smtplib
 
# Refresh period
sleepTime = 5
# Write information into log file
fileLog = open('/home/pi/fan_control.log', 'w+', 0)
 
#########################
# Log messages should be time stamped
 
def timeStamp():
    t = time.time()
    s = datetime.datetime.fromtimestamp(t).strftime('%Y/%m/%d %H:%M:%S - ')
    return s
 
# Write messages in a standard format
 
def printMsg(s):
    fileLog.write(timeStamp() + s + "\n")
 
# Create a class to easily control a pin given the pin's ID
 
 
class Pin(object):
    def __init__(self, id):
        try:
            self.pin = id
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(self.pin, GPIO.OUT)
            GPIO.setwarnings(False)
            printMsg("Initialized: run-fan using GPIO pin: " + str(self.pin))
        except:
            printMsg("If method setup doesn't work, need to run script as sudo")
            exit
 
    # resets all GPIO ports used by this program
    def exitPin(self):
        GPIO.cleanup()
 
    def set(self, state):
        GPIO.output(self.pin, state)
 
# Fan class to control fan's functionality
 
 
class Fan(object):
    fanOff = True
 
    def __init__(self):
        self.fanOff = True
 
    # Turn the fan on or off
    def setFan(self, temp, on, myPin):
        if on:
            printMsg("Turning fan on " + str(temp))
        else:
            printMsg("Turning fan off " + str(temp))
        myPin.set(on)
        self.fanOff = not on
 
 
# Temperature class helps getting the temperature
class Temperature(object):
 
    def __init__(self):
        self.sensor = W1ThermSensor()
 
    def getTemperature(self):
        print("Temperature is " + str(self.sensor.get_temperature()))
        return self.sensor.get_temperature()
 
 
# used to prevent sending multiple emails
lastEmailDetails = ""
 
# Email communication combines both sending and reading emails  into one class
# given the credentials of the account to be used to send notifications
 
 
class MyEmail(object):
    emaill = email
    emailAddr = ""
    password = ""
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    server = smtplib.SMTP('smtp.gmail.com', 587)
    data = ""
 
    def __init__(self, emailAddrs, password):
        self.emailAddr = emailAddrs
        self.password = password
        self.mail.login(emailAddrs, password)
        self.mail.list()
        self.mail.select('inbox')
        self.server.starttls()
        self.server.login(self.emailAddr, self.password)
        print("Init myEmail")
 
# Returns last email's subject
    def getLastEmail(self):
        self.mail.list()
        self.mail.select('inbox')
        typ, data = self.mail.search(None, 'ALL')
        ids = data[0]
        id_list = ids.split()
        latest_email_id = int(id_list[-1])
 
        i = latest_email_id
        typ, data = self.mail.fetch(i, '(RFC822)')
 
        for response_part in data:
            if isinstance(response_part, tuple):
                msg = self.emaill.message_from_string(response_part[1])
                self.data = str(msg['date'])
                print(self.data)
                varSubject = msg['subject']
                varFrom = msg['from']
 
        varFrom = varFrom.replace('<', '')
        varFrom = varFrom.replace('>', '')
 
        if len(varSubject) > 35:
            varSubject = varSubject[0:32] + '...'
 
        print('[' + varFrom.split()[-1] + '] ' + varSubject)
        return varSubject
 
# Sends an email with no subject but with a given text, to a give email address
    def sendEmail(self, dest, text):
        self.server.sendmail(self.emailAddr, dest, text)
 
    def closeMail(self):
        self.mail.close()
        self.server.quit()
 
    def getDetails(self):
        return self.data
 
# Gmail notification sender, sends and processes information to and from given gmail addresses
 
 
class Notifier(object):
    sendData = ""
 
    def __init__(self, emailAddr, password, dest):
        self.email = MyEmail(emailAddr, password)
        self.dest = dest
 
    def sendTemp(self, text):
        self.email.sendEmail(self.dest, text)
 
    def readEmail(self):
        response = self.email.getLastEmail().lower()
        self.sendData = self.email.getDetails()
        print(self.sendData)
        if(response.find("fan") != -1):
            if(response.find("on") != -1):
                return "on"
            if(response.find("off") != -1):
                return "off"
        if(response.find("temperature") != -1 or response.find("temp") != -1):
            return "temp"
        return ""
 
 
#########################
printMsg("Starting: run-fan")
 
if __name__ == ('__main__'):
    try:
        myPin = Pin(22)
        myFan = Fan()
        myTemp = Temperature()
        emailSrc = "username@gmail.com"
        emailPass = "password"
        emailDest = "dest@gmail.com"
        notifier = Notifier(emailSrc, emailPass, emailDest)
        while True:
            temp = myTemp.getTemperature()
            if(temp > 26):
                print(temp)
                notifier.sendTemp("Warning! Temperature is : "+str(temp))
            elif(temp < 20):
                notifier.sendTemp("Temperature is : " +
                                     str(temp) + ". Fan has been turned off.")
                if(not myFan.fanOff):
                    myFan.setFan(temp, False, myPin)
            message = notifier.readEmail()
            print(notifier.sendData)
            print(lastEmailDetails)
            if(notifier.sendData != lastEmailDetails):
                if(message == "on" and myFan.fanOff is True):
                    myFan.setFan(temp, True, myPin)
                elif(message == "off" and not myFan.fanOff):
                    myFan.setFan(temp, False, myPin)
                elif(message == "temp"):
                    temp = myTemp.getTemperature()
                    print(temp)
                    notifier.sendTemp("Temperature is " + str(temp))
            lastEmailDetails = notifier.sendData
            time.sleep(sleepTime)
    except KeyboardInterrupt:  # trap a CTRL+C keyboard interrupt
        printMsg("keyboard exception occurred")
        myPin.exitPin()
        fileLog.close()

Credits

Teodora Bulea

Teodora Bulea

1 project • 3 followers
Floris-Diana Vornicu

Floris-Diana Vornicu

1 project • 2 followers

Comments