SuppahHacka
SuppahHacka

Reputation: 11

How to trigger function when certain condition is met in Python

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()

Upvotes: 0

Views: 2052

Answers (2)

martianwars
martianwars

Reputation: 6500

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

Upvotes: 2

Joran Beasley
Joran Beasley

Reputation: 113978

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

Upvotes: 2

Related Questions