1

I have a program to control lots of the things about my hen house including opening and closing the door at set times. Occasionally something happens and the door doesn't open or close and I have now got it to send an email when this happens. The problem is it will send 6 or more emails and I have been trying to work out how to limit it to send only one which is possible using while or if - but then I need to re-set it so that if happens again on another day it will send another email. This is the loop that I have

def loop():
# retrieve current datetime
now = datetime.time(datetime.datetime.now().hour, datetime.datetime.now().minute)

# Open door on all days at the correct time
if ((now.hour == HOUR_ON.hour) and (now.minute == HOUR_ON.minute)):
  if (gpio.digitalRead(17) == 0):
    openplay()

# Close door on all days at the correct time
if ((now.hour == HOUR_OFF.hour) and (now.minute == HOUR_OFF.minute)):
  if (gpio.digitalRead(22) == 1):
    closeplay()

# check if door is open, 2 minutes after set time
if ((now.hour == HOUR_ON.hour) and (now.minute == HOUR_ON.minute + 120) and (now.second == 0) and (gpio.digitalRead(25) == 0)):
  # send email
  sendemail()

# check if door is closed, 2 minutes after set time
if ((now.hour == HOUR_OFF.hour) and (now.minute == HOUR_OFF.minute + 120) and (now.second == 0) and (gpio.digitalRead(25) == 1)):
  # send email
  sendemail()

# gives CPU some time before looping again
webiopi.sleep(1)

This is just a hobby and I put together things from mostly searching but can't crack this so would appreciate any help with it

tamus
  • 53
  • 1
  • 1
  • 9
  • Consider adding a basic delay function. See: http://stackoverflow.com/questions/510348/how-can-i-make-a-time-delay-in-python – J.P.M. Sep 15 '16 at 23:05
  • I have webiopi.sleep(1) in the loop and also included webiopi.sleep(5) in the sendemail() function - this reduced the amount of emails. I can't understand why these don't work as I am checking the time down to the second. I could have tried 60 seconds but I don't want the program paused for this length of time – tamus Sep 15 '16 at 23:28
  • You can use crontabs for scheduling, its easier on the cpu. :) – Caramiriel Sep 17 '16 at 20:19

2 Answers2

0

Assuming sendemail() is a function you defined, you could rewrite it to store the time it last sent an email, and if it hasn't been long enough, don't send it.

The now.minute == HOUR_ON.minute + 120 doesn't make sense to me—it looks like you're saying 2 hours, not 2 minutes, unless now.minute returns a value in seconds?

Another possibility: do you have multiple instances of this python program running at the same time? pgrep python3 to see how many instances of python are running.

csstudent
  • 77
  • 2
  • 5
  • `sendemail()` is a function I have put together but if I store the time as you say and the door doesn't close at night time or open the next morning, I have no idea how to reset it. – tamus Sep 15 '16 at 23:46
  • I am trying to add 2 minutes to `HOUR_ON.minute`, I thought I had to add in seconds or hours. I ran `pgrep python3` and got 2141 – tamus Sep 15 '16 at 23:57
  • added a few print () and see my error of adding 120 - thanks – tamus Sep 16 '16 at 00:11
0

This seems to do it.

def loop():
  global emailsent1
  global emailsent2

  # retrieve current datetime
  now = datetime.time(datetime.datetime.now().hour, datetime.datetime.now().minute)

  # Open door on all days at the correct time
  if ((now.hour == HOUR_ON.hour) and (now.minute == HOUR_ON.minute)):
    if (gpio.digitalRead(17) == 0):
      openplay()

  # Close door on all days at the correct time
  if ((now.hour == HOUR_OFF.hour) and (now.minute == HOUR_OFF.minute)):
    if (gpio.digitalRead(22) == 1):
      closeplay()

  # check if door is open, 10 minutes after set time and send email if not already sent
  if ((now.hour == HOUR_ON.hour) and (now.minute == HOUR_ON.minute + 10) and (now.second == 0) and (gpio.digitalRead(25) == 1) and not emailsent1):
    # send email
    a = 'opened'
    sendemail(a)
    emailsent1 = True

  if ((now.hour == HOUR_ON.hour) and (now.minute == HOUR_ON.minute + 11) and emailsent1): # reset if email has been sent
emailsent1 = False

  # check if door is closed, 10 minutes after set time and send email if not already sent
  if ((now.hour == HOUR_OFF.hour) and (now.minute == HOUR_OFF.minute + 10) and (now.second == 0) and (gpio.digitalRead(25) == 0) and not emailsent2):
    # send email
    a = 'closed'
    sendemail(a)
    emailsent2 = True

    if ((now.hour == HOUR_OFF.hour) and (now.minute == HOUR_OFF.minute + 11) and emailsent2): # resset if email has been sent
    emailsent2 = False

    # gives CPU some time before looping again
    webiopi.sleep(1)

10 minutes after closing time it checks if door closed and sendmail(a) is called and emailsent1 is set to True - after a minute it is set to false again.

Do I need emailsent1 and emailsent2 as global?

tamus
  • 53
  • 1
  • 1
  • 9