0

I have been working on a self-watering plant and I want it to send me emails when the water tank is empty and when it is full. Everything works but, I need to be able to set a condition that triggers the email function only ONCE when the condition is met. Instead, it goes infinitely and sends emails every second as long as the condition is met.

For ex: Water tank is full according to sensor, send email "Water tank full"

Water tank is empty according to sensor, send email "Water tank empty"

That should only happen once unless the water level changes.

And do not do anything until a different condition is met. So the loop goes on forever without triggering any condition as long as there is water.

Once there is no more water, then the condition will trigger. The same when there is no water and then I refill it

Here is the code:

import RPi.GPIO as GPIO, feedparser 
from time import sleep
import smtplib, os, sys 
from email.mime.text import MIMEText 
from email.MIMEMultipart import MIMEMultipart

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

#Set up GPIO Inputs
# Yellow Input
GPIO.setup(2, GPIO.IN)

def send_email(msg):
    USERNAME = "[email protected]"
    PASSWORD = "my_email_password"
    MAILTO "recipient email"

    msg['From'] = USERNAME
    msg['To'] = MAILTO

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo_or_helo_if_needed()
    server.starttls()
    server.ehlo_or_helo_if_needed()
    server.login(USERNAME, PASSWORD)
    server.sendmail(USERNAME, MAILTO, msg.as_string())
    server.quit()

    print "Email sent to: "+ MAILTO 
    return

def Send_nowater_email():
  print"No water"
  msg = MIMEMultipart()
  msg.attach(MIMEText('Water tank empty'))
  msg['Subject'] = 'Plant notification'
  send_email(msg)
  return

def Send_watered_email():
  msg = MIMEMultipart()
  msg.attach(MIMEText('Water tank full'))
  msg['Subject'] = 'Plant notification'
  send_email(msg)
  return 

while True: 
  Input_yellow = GPIO.input(2)
  print Input_yellow

  if Input_yellow == False:
    Send_watered_email()

  if Input_yellow == True:
    Send_nowater_email()
2
  • It's becuase your email() functions are inside a while(True) loop Commented Dec 29, 2016 at 19:08
  • If you do not track some kind of state that indicates if an email has/should be sent, it will obviously keep sending since you are constantly calling the function. You will need to add some sort of flag to determine if an email should be sent, and then decide when and if you want to clear it so that an email can again be sent. The question is a bit broad since there are many ways you could choose to do this, so you will probably get different ideas but you should think about what actually works best for your situation. Commented Dec 29, 2016 at 19:14

2 Answers 2

2

Instead of continuously looking at Input_yellow, try to look for changes in Input_yellow. Something like this will help you,

current = False
while True: 
  Input_yellow = GPIO.input(2)
  print Input_yellow

  if Input_yellow == False and current == True:
    Send_watered_email()
    current = False

  if Input_yellow == True and current == False:
    Send_nowater_email()
    current = True
Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! Thank you so much! I did something like this with basic LED on off by reading a photo-resistor. I did not know how to incorporate such a code into my script. Thank you!
2

just lock it to the last seen state and only act if its different

current_state = None
while True: 
  is_empty = GPIO.input(2)
  if current_state != is_empty:
      current_state = is_empty
      if is_empty == False:
         Send_watered_email()
      if is_empty == True:
         Send_nowater_email()

also use meaningful names

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.