Search This Blog

Wednesday, 30 March 2016

Make sure your plants don't die with Raspberry Pi and a moisture sensor


Credit goes to all the articles on this topic, that I came across and from which I learnt.

#!/usr/bin/python
# Script for sending email notifications when the earth moisure changes
#
# Moisture sensor   Raspberry Pi
#      VCC        3V3  
#      GND        GND
#      DO         G12      
#  
# If you attach an LED to G12 as well, the LED will light up when there is not enough moisture;
# ie when the pin state is HIGH/True   
#---------------------------------------------------

import RPi.GPIO as GPIO                    # To get access to GPIO pins on the Raspberry Pi
from smtplib import SMTP_SSL               # For sending email notifications
import time                                # For the sleep function

# Configuration
#---------------------------------------------------
# GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

# GPIO pin to connect the digital output from the moisture sensor to
PIN = 12
# Set the GPIO pin to receive input from the moisture sensor
GPIO.setup(PIN, GPIO.IN)
# GPIO will ignore changes withing BOUNCETIME ms, ie will check roughly every BOUNCETIME ms
#      ie acts as a timer - reduces the chances of the callback being run multiple times
BOUNCETIME = 500

# email
smtp_host = "mail.btinternet.com"          # SMTP provider host
smtp_port = 465                            # SMTP provider port (corresponds either to SMTP_SSL or to SMTP)
smtp_username = "john.doe@btinternet.com"  # Login for the SMTP provider
smtp_password = "BIGSECRET"                # Password to login to the SMTP provider

smtp_sender    = "john.doe@btinternet.com" # This is the FROM email addresssmtp_receivers = ['john.doe@btinternet.com','jane.doe@btinternet.com']  # This is the TO email address
# Prepare email messages
#  Triple quotes preserve line breaks in the string. 
# There MUST be an extra empty line after the subject line, otherwise the received email body is empty 
#---------------------------------------------------

# No moisture is detected
alert_message = """From: <Your friendly Raspberry Pi>
To: """ + ', '.join(smtp_receivers)
alert_message = alert_message + "\n"
alert_message = alert_message + """Subject: Moisture Sensor Notification - ALERT

Warning, no moisture detected! Plant is on its death bed !!!
"""

# Moisture is detected
thanks_message = """From: <Your friendly Raspberry Pi>
To: """ + ', '.join(smtp_receivers)
thanks_message = thanks_message + """Subject: Moisture Sensor Notification - THANK YOU

Thank you! Your care is much appreciated. The plant will live :)
"""

# This is our sendEmail function
#---------------------------------------------------

def sendEmail(smtp_message):
 print("Trying to send a message with %s, %s...\n" % (smtp_host, smtp_port))
 try:
  smtp_ssl = SMTP_SSL(smtp_host, smtp_port)
  smtp_ssl.login(smtp_username, smtp_password)
  smtp_ssl.sendmail(smtp_sender, smtp_receivers, smtp_message)         
  print "Successfully sent email"

 except smtplib.SMTPException:
  print "Error: unable to send email"
 
 print("-----------------------------------------")

# Logic for sending an email
#---------------------------------------------------
# Callback function to be called every time when there is a change in input on the specified GPIO PIN
#---------------------------------------------------

def alertThem(PIN):
 pin_state = GPIO.input(PIN)
 print("Pin %d state = %d (%s)" % (PIN, pin_state, time.asctime(time.localtime(time.time()))))

 if pin_state:
  print "LED off => near death experience"
  sendEmail(alert_message)
 else:
  print "LED on => all well and moist"
  #sendEmail(thanks_message)

# Watch the GPIO pin for state change
# The pin state is checked and the callback is triggered 
# changes within BOUNCETIME period are ignored (ie checks roughly every BOUNCETIME ms)
#---------------------------------------------------
GPIO.add_event_detect(PIN, 
                      GPIO.RISING, 
                      bouncetime=BOUNCETIME, 
                      callback=alertThem)

def loop():
# Waiting for 0.5s makes sure running the script will not make the CPU 100% busy
 time.sleep(0.5)

# ==================================================
# Now run forever
#---------------------------------------------------
if __name__ == '__main__':
    try:
        print('Press Ctrl-C to quit.')
        print("Local current time : %s" % time.asctime(time.localtime(time.time())))

        alertThem(PIN)

        while True:
            loop()
    finally:
        GPIO.cleanup()

No comments:

Post a Comment

Note: only a member of this blog may post a comment.