E-Mail senden bei GPIO Input

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Benutzeravatar
__deets__
User
Beiträge: 2157
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: E-Mail senden bei GPIO Input

Beitragvon __deets__ » Sonntag 3. Dezember 2017, 15:11

Ja, geht richtig los. Aber warum genau verzögert sie das? Bzw wie steht sie im Verhältnis zu der Bedingung im if-Statement vorher, durch die überhaupt erst eine Mail Versand wird?
MaierA
User
Beiträge: 10
Registriert: Sonntag 3. Dezember 2017, 10:32

Re: E-Mail senden bei GPIO Input

Beitragvon MaierA » Sonntag 3. Dezember 2017, 15:22

Leider komme ich aktuell nicht weiter wie, ich es umprogrammieren müsste.
Mein Ziel wäre es so umzuprogrammieren, dass nur bei bei änderung von Wert false / 0 auf Wert true / 1 eine Mail gesendet wird. Bei jeder Flankenänderung die steigend ist soll also eine Mail kommen.

Genau hier liegt mein Problem begraben, an dem ich leider ohne eure hilfe nicht mehr weiter komme.
Aktuell wird jede 2 Sek. eine Mail gesendet, außerdem wäre busy waiting noch so eine kleinigkeit, die ich mit meinem Wissen nicht umgehen kann.

Danke für jeden Tipp der mir helfen kann.

  1. #!/usr/bin/env python
  2. # coding: utf8
  3. from __future__ import absolute_import, division, print_function
  4. import smtplib
  5. from time import sleep
  6. from datetime import datetime as DateTime
  7. from email.mime.text import MIMEText
  8.  
  9. import RPi.GPIO as GPIO
  10.  
  11. AL1 = 5
  12. AL2 = 6
  13. AL3 = 13
  14. AL4 = 19
  15. AL5 = 26
  16. AT1 = 'Heizung'
  17. AT2 = 'Pumpe1'
  18. AT3 = 'Pumpe2'
  19. AT4 = 'Pumpe3'
  20. AT5 = 'Hebeanlage'
  21. FROM_EMAIL = ********@gmail.com'
  22. TO_EMAIL = '*****@hotmail.com; *******@googlemail.com'
  23. SMTP_SERVER = 'smtp.gmail.com'
  24. SMTP_USERNAME = FROM_EMAIL
  25. SMTP_PASSWORD = '**************'
  26.  
  27.  
  28. def main():
  29.    GPIO.cleanup()
  30.    GPIO.setmode(GPIO.BCM)
  31.    GPIO.setup(AL1, GPIO.IN)
  32.    GPIO.setup(AL2, GPIO.IN)
  33.    GPIO.setup(AL3, GPIO.IN)
  34.    GPIO.setup(AL4, GPIO.IN)
  35.    GPIO.setup(AL5, GPIO.IN)
  36.  
  37.    print('Überwachung der Störungen')
  38.    #
  39.    # TODO Remove busy waiting!! Urgent!!!
  40.    #
  41.    while True:
  42.        if GPIO.input(AL1):
  43.            AT1 = 'Störung Gasheizung\n'
  44.        else:
  45.            AT1 = 'Gasheizung in Ordnung\n'
  46.        if GPIO.input(AL2):
  47.            AT2 = 'Störung Pufferladepumpe\n'
  48.        else:
  49.            AT2 = 'Pufferladepumpe in Ordnung\n'
  50.        if GPIO.input(AL3):
  51.            AT3 =  'Störung Heizungspumpe\n'
  52.        else:
  53.            AT3 = 'Heizungspumpe in Ordnung\n'
  54.        if GPIO.input(AL4):
  55.            AT4 = 'Störung Pufferzirkulationspumpe\n'
  56.        else:
  57.            AT4 = 'Pufferzirkulationspumpe in Ordnung\n'
  58.        if GPIO.input(AL5):
  59.            AT5 = 'Störung Regenwasserhebeanlage'
  60.        else:
  61.            AT5 = 'Regenwasserhebeanlage in Ordnung'
  62.        if GPIO.input(AL1) or GPIO.input(AL2) or GPIO.input(AL3) or GPIO.input(AL4) or GPIO.input(AL5):
  63.            now = DateTime.now()
  64.            text  = 'Störung an der Heizungsanlage \n \n \n'+AT1+AT2+AT3+AT4+AT5
  65.            message = MIMEText(text)
  66.            message['Subject'] = (
  67.                'Störung Heizungsanlage - {0:%a %d %b %Y, %H:%M:%S}'.format(
  68.                    now
  69.                )
  70.            )
  71.            message['From'] = FROM_EMAIL
  72.            message['To'] = TO_EMAIL
  73.            message['Date'] = format(now, '%a, %d %b %Y %H:%M:%S %z')
  74.            smtp = smtplib.SMTP(SMTP_SERVER)
  75.            smtp.starttls()
  76.            smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
  77.            smtp.sendmail(message['From'], message['To'], message.as_string())
  78.            smtp.quit()
  79.            print('Email sent')
  80.            sleep(2)
  81.  
  82.        while GPIO.input(AL1) or GPIO.input(AL2) or GPIO.input(AL3) or GPIO.input(AL4) or GPIO.input(AL5):
  83.            sleep(0.1)
  84.        sleep(0.1)
  85.  
  86.  
  87. if __name__ == '__main__':
  88.    main()
Benutzeravatar
__deets__
User
Beiträge: 2157
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: E-Mail senden bei GPIO Input

Beitragvon __deets__ » Sonntag 3. Dezember 2017, 15:55

Ich verstehe schon was du willst. Nur bringt es in meinen Augen nix dir einfach eine Lösung hinzuknallen. Dann ist das Problem bei der nächsten Kleinigkeit schon wieder meines, und du kannst es immer noch nicht lösen.

Es ist doch ganz simpel: die grundlogik läuft so:

Code: Alles auswählen

In einer Schleife
    wenn ein Fehler vorliegt
           schicke eine Mail
           Solange der Fehler immer noch vorliegt
                 warte



Wird es dir jetzt klarer, was der Zweck des zweiten while ist, und warum es bei dir noch hakt?
Benutzeravatar
__deets__
User
Beiträge: 2157
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: E-Mail senden bei GPIO Input

Beitragvon __deets__ » Sonntag 3. Dezember 2017, 16:21

Oh, jetzt sehe ich erst das du die zweite Bedingung schon geupdatet hast! Das sieht doch gut aus. Tut es immer noch nicht?
MaierA
User
Beiträge: 10
Registriert: Sonntag 3. Dezember 2017, 10:32

Re: E-Mail senden bei GPIO Input

Beitragvon MaierA » Sonntag 3. Dezember 2017, 21:40

__deets__
Entschuldige das ich jetzt erst Antworte.
Also ich bin soweit, dass es fast so funktioniert wie es soll.
Sobald ein flanke Steigt bekomme ich eine Mail und solange diese Flanke ansteht, wird keine weitere Mail gesendet. Leider wird keine Mail gesendet wenn sich eine weitere Flanke steigt.
Da hab ich noch keine Lösung für gefunden.
Benutzeravatar
__deets__
User
Beiträge: 2157
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: E-Mail senden bei GPIO Input

Beitragvon __deets__ » Sonntag 3. Dezember 2017, 22:07

Das ist dann etwas komplizierter, ja. Mein Ansatz: schreib eine Funktion "alarme", die sieht so aus

  1. def alarme():
  2.      return GPIO.input(AL1), GPIO.input(AL2), GPIO.input(AL3),  GPIO.input(AL4), GPIO.input(AL5)


Damit bestimmst du, was die aktuellen Alarme sind. Und dann kann man so vorgehen:

  1. KEIN_ALARM = (0, 0, 0, 0, 0)
  2.  
  3. while True:
  4.       aktuelle_alarme = alarme()
  5.       if aktuelle_alarme != KEIN_ALARM:
  6.           # email schreiben
  7.           if aktuelle_alarme[0]: # text fuer ersten Alarm dazutun, etc.
  8.                ...
  9.           while aktuelle_alarme == alarme():
  10.                sleep(.1)
MaierA
User
Beiträge: 10
Registriert: Sonntag 3. Dezember 2017, 10:32

Re: E-Mail senden bei GPIO Input

Beitragvon MaierA » Sonntag 3. Dezember 2017, 22:22

  1. #!/usr/bin/env python
  2. # coding: utf8
  3. from __future__ import absolute_import, division, print_function
  4. import smtplib
  5. from time import sleep
  6. from datetime import datetime as DateTime
  7. from email.mime.text import MIMEText
  8.  
  9. import RPi.GPIO as GPIO
  10.  
  11. AL1 = 5  # TODO Find a more descriptive name.
  12. AL2 = 6
  13. AL3 = 13
  14. AL4 = 19
  15. AL5 = 26
  16. AT1 = 'Heizung'
  17. AT2 = 'Pumpe1'
  18. AT3 = 'Pumpe2'
  19. AT4 = 'Pumpe3'
  20. AT5 = 'Hebeanlage'
  21. FROM_EMAIL = '*******@gmail.com'
  22. TO_EMAIL = '******@hotmail.com'
  23. SMTP_SERVER = 'smtp.gmail.com'
  24. SMTP_USERNAME = FROM_EMAIL
  25. SMTP_PASSWORD = '*******'
  26.  
  27.  
  28. def main():
  29.     GPIO.cleanup()
  30.     GPIO.setmode(GPIO.BCM)
  31.     GPIO.setup(AL1, GPIO.IN)
  32.     GPIO.setup(AL2, GPIO.IN)
  33.     GPIO.setup(AL3, GPIO.IN)
  34.     GPIO.setup(AL4, GPIO.IN)
  35.     GPIO.setup(AL5, GPIO.IN)
  36.    
  37.     def alarme()
  38.         return GPIO.input(AL1), GPIO.input(AL2), GPIO.input(AL3), GPIO.input(AL4), GPIO.input(AL5)
  39.     print('Überwachung der Störungen')
  40.     #
  41.     # TODO Remove busy waiting!! Urgent!!!
  42.     #
  43.     KEIN_ALARM = (0, 0, 0, 0, 0)
  44.    
  45.     while True:
  46.         if GPIO.input(AL1):
  47.             AT1 = 'Störung Gasheizung\n'
  48.         else:
  49.             AT1 = 'Gasheizung in Ordnung\n'
  50.         if GPIO.input(AL2):
  51.             AT2 = 'Störung Pufferladepumpe\n'
  52.         else:
  53.             AT2 = 'Pufferladepumpe in Ordnung\n'
  54.         if GPIO.input(AL3):
  55.             AT3 =  'Störung Heizungspumpe\n'
  56.         else:
  57.             AT3 = 'Heizungspumpe in Ordnung\n'
  58.         if GPIO.input(AL4):
  59.             AT4 = 'Störung Pufferzirkulationspumpe\n'
  60.         else:
  61.             AT4 = 'Pufferzirkulationspumpe in Ordnung\n'
  62.         if GPIO.input(AL5):
  63.             AT5 = 'Störung Regenwasserhebeanlage'
  64.         else:
  65.             AT5 = 'Regenwasserhebeanlage in Ordnung'
  66.         aktuelle_alarme = alarme()
  67.         if aktuelle_alarme != KEIN_ALARM:
  68.             now = DateTime.now()
  69.             text  = 'Störung an der Heizungsanlage \n \n \n'+AT1+AT2+AT3+AT4+AT5
  70.             message = MIMEText(text)
  71.             message['Subject'] = (
  72.                 'Störung Heizungsanlage - {0:%a %d %b %Y, %H:%M:%S}'.format(
  73.                     now
  74.                 )
  75.             )
  76.             message['From'] = FROM_EMAIL
  77.             message['To'] = TO_EMAIL
  78.             message['Date'] = format(now, '%a, %d %b %Y %H:%M:%S %z')
  79.             smtp = smtplib.SMTP(SMTP_SERVER)
  80.             smtp.starttls()
  81.             smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
  82.             smtp.sendmail(message['From'], message['To'], message.as_string())
  83.             smtp.quit()
  84.             print('Email sent')
  85.             sleep(2)
  86.  
  87.         while aktuelle_alarme == alarme():
  88.             sleep(0.1)
  89.         sleep(0.1)
  90.  
  91.  
  92. if __name__ == '__main__':
  93.     main()


Das sollte bis jetzt stimmen wenn ich kein Denkfehler drin habe.
Wo ich aktuell hänge ist an Zeile 7 bei deinem Lösungsvorschlag
Benutzeravatar
__deets__
User
Beiträge: 2157
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: E-Mail senden bei GPIO Input

Beitragvon __deets__ » Sonntag 3. Dezember 2017, 22:25

Du machst das fasch herum. Du baust schon Text zusammen (bzw pruefst darauf) ohne zu wissen, ob du eine Email verschickst.

Das ganze ATx-Geraffel muss *in* die if-Anweisung, und dann kannst du eben statt auf input(AL5) auf "aktuelle_alarme[4]" zugreifen, da steht ja der aktuelle Wert drin.
Sirius3
User
Beiträge: 7052
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: E-Mail senden bei GPIO Input

Beitragvon Sirius3 » Sonntag 3. Dezember 2017, 22:36

@MaierA: man definiert keine Funktion innerhalb einer Funktion. `alarme` sollte `determine_alarms` heißen und vor `main` stehen. Statt Konstanten durchzunummerieren, will man normalerweise eine Liste verwenden und die vielen Statusmeldungen packt man am besten auch in eine Datenstruktur. Dass der GPIO-Port an mehreren Stellen im Programm abgefragt wird, ist eine Fehler, denn dadurch können inkonsistente Ergebnisse entstehen.
MaierA
User
Beiträge: 10
Registriert: Sonntag 3. Dezember 2017, 10:32

Re: E-Mail senden bei GPIO Input

Beitragvon MaierA » Sonntag 3. Dezember 2017, 23:13

Einen sehr großen Dank an __deets__ und auch Danke an Sirius3
Ohne die Hilfe von euch wäre es nichts geworden.
Anbei der fertige Skript der schon getestet ist, falls es noch Fehler gibt und Schönheitsfehler könnt Ihr mir gerne noch schreiben.

  1. #!/usr/bin/env python
  2. # coding: utf8
  3. import smtplib
  4. import RPi.GPIO as GPIO
  5. from __future__ import absolute_import, division, print_function
  6. from time import sleep
  7. from datetime import datetime as DateTime
  8. from email.mime.text import MIMEText
  9.  
  10. AL1 = 5
  11. AL2 = 6
  12. AL3 = 13
  13. AL4 = 19
  14. AL5 = 26
  15.  
  16. AT1 = 'Heizung'
  17. AT2 = 'Pumpe1'
  18. AT3 = 'Pumpe2'
  19. AT4 = 'Pumpe3'
  20. AT5 = 'Hebeanlage'
  21.  
  22. FROM_EMAIL = '*********@gmail.com'
  23. TO_EMAIL = '********@hotmail.com'
  24. SMTP_SERVER = 'smtp.gmail.com'
  25. SMTP_USERNAME = FROM_EMAIL
  26. SMTP_PASSWORD = '************'
  27.  
  28. KEIN_ALARM = (0, 0, 0, 0, 0)
  29.  
  30. def determins_alarme():
  31.     return GPIO.input(AL1), GPIO.input(AL2), GPIO.input(AL3), GPIO.input(AL4), GPIO.input(AL5)
  32.  
  33. def main():
  34.     GPIO.cleanup()
  35.     GPIO.setmode(GPIO.BCM)
  36.     GPIO.setup(AL1, GPIO.IN)
  37.     GPIO.setup(AL2, GPIO.IN)
  38.     GPIO.setup(AL3, GPIO.IN)
  39.     GPIO.setup(AL4, GPIO.IN)
  40.     GPIO.setup(AL5, GPIO.IN)
  41.    
  42.     print('Überwachung der Störungen')
  43.    
  44.     while True:
  45.         aktuelle_alarme = determins_alarme()
  46.         if aktuelle_alarme != KEIN_ALARM:
  47.             now = DateTime.now()
  48.             if aktuelle_alarme[0]:
  49.                 AT1 = 'Störung Gasheizung\n'
  50.             else :
  51.                 AT1 = 'Gasheizung in Ordnung\n'
  52.             if aktuelle_alarme[1]:
  53.                 AT2 = 'Störung Pufferladepumpe\n'
  54.             else:
  55.                 AT2 = 'Pufferladepumpe in Ordnung\n'
  56.             if aktuelle_alarme[2]:
  57.                 AT3 =  'Störung Heizungspumpe\n'
  58.             else:
  59.                 AT3 = 'Heizungspumpe in Ordnung\n'
  60.             if aktuelle_alarme[3]:
  61.                 AT4 = 'Störung Pufferzirkulationspumpe\n'
  62.             else:
  63.                 AT4 = 'Pufferzirkulationspumpe in Ordnung\n'
  64.             if aktuelle_alarme[4]:
  65.                 AT5 = 'Störung Regenwasserhebeanlage'
  66.             else:
  67.                 AT5 = 'Regenwasserhebeanlage in Ordnung'
  68.                
  69.             text  = 'Störung an der Heizungsanlage \n \n \n'+AT1+AT2+AT3+AT4+AT5
  70.             message = MIMEText(text)
  71.             message['Subject'] = ('Störung Heizungsanlage - {0:%a %d %b %Y, %H:%M:%S}'.format(now))
  72.             message['From'] = FROM_EMAIL
  73.             message['To'] = TO_EMAIL
  74.             message['Date'] = format(now, '%a, %d %b %Y %H:%M:%S %z')
  75.             smtp = smtplib.SMTP(SMTP_SERVER)
  76.             smtp.starttls()
  77.             smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
  78.             smtp.sendmail(message['From'], message['To'], message.as_string())
  79.             smtp.quit()
  80.             print('Email sent')
  81.             sleep(2)
  82.  
  83.         while aktuelle_alarme == determins_alarme():
  84.             sleep(0.1)
  85.         sleep(0.1)
  86.  
  87.  
  88. if __name__ == '__main__':
  89.     main()
Benutzeravatar
__deets__
User
Beiträge: 2157
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: E-Mail senden bei GPIO Input

Beitragvon __deets__ » Sonntag 3. Dezember 2017, 23:18

Schön das es geklappt hat.
harryberlin
User
Beiträge: 187
Registriert: Donnerstag 17. Dezember 2015, 12:17

Re: E-Mail senden bei GPIO Input

Beitragvon harryberlin » Dienstag 5. Dezember 2017, 20:31

Ich würde versuchen die ganzen if abfragen raus zu bringen, z.B. mit einer schleife.
Wenn man es noch weiterspinnt, könnte man sogar ein dict draus machen, um individuelle gut oder schlecht Texte zu definieren.

  1.     # device (name, gpio)
  2.     devices = [('Gasheizung', AL1),
  3.                ('Pufferladepumpe', AL2),
  4.                ('Heizungspumpe', AL3),
  5.                ('Pufferzirkulationspumpe', AL4),
  6.                ('Regenwasserhebeanlage', AL5)]
  7.  
  8.     states = ['Störung',
  9.               'in Ordnung']
  10.  
  11.     email_text = 'Störung an der Heizungsanlage \n \n \n'
  12.  
  13.     for device, gpio in devices:
  14.         email_text += '%s: %s\n' % (device, states[GPIO.input(gpio)])
  15.  
  16.     print email_text
empty Sig
Sirius3
User
Beiträge: 7052
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: E-Mail senden bei GPIO Input

Beitragvon Sirius3 » Dienstag 5. Dezember 2017, 20:59

Nochmal komplett:
  1. #!/usr/bin/env python
  2. # coding: utf8
  3. from __future__ import absolute_import, division, print_function
  4. from time import sleep
  5. import email.utils
  6. from email.mime.text import MIMEText
  7. import smtplib
  8. import RPi.GPIO as gpio
  9.  
  10. INPUTS = {
  11.     5: "Gasheizung",
  12.     6: "Pufferladepumpe",
  13.     13: "Heizungspumpe",
  14.     19: "Pufferzirkulationspumpe",
  15.     26: "Regenwasserhebeanlage",
  16. }
  17.  
  18. FROM_EMAIL = '*********@gmail.com'
  19. TO_EMAIL = '********@hotmail.com'
  20. SMTP_SERVER = 'smtp.gmail.com'
  21. SMTP_USERNAME = FROM_EMAIL
  22. SMTP_PASSWORD = '************'
  23.  
  24. def determins_alarme():
  25.     return [(gpio.input(k), n) for k, n in INPUTS.items()]
  26.  
  27. def send_mail(aktuelle_alarme):
  28.     now = email.utils.formatdate(localtime=True)
  29.     messages = ['Störung an der Heizungsanlage \n \n \n']
  30.     for status, name in aktuelle_alarme:
  31.         messages.append('{}: {}\n'.format(name, "Störung" if status else "in Ordnung"))
  32.     message = MIMEText(''.join(messages))
  33.     message['Subject'] = 'Störung Heizungsanlage - {}'.format(now)
  34.     message['From'] = FROM_EMAIL
  35.     message['To'] = TO_EMAIL
  36.     message['Date'] = now
  37.     smtp = smtplib.SMTP(SMTP_SERVER)
  38.     smtp.starttls()
  39.     smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
  40.     smtp.sendmail(message['From'], message['To'], message.as_string())
  41.     smtp.quit()
  42.  
  43. def main():
  44.     gpio.cleanup()
  45.     gpio.setmode(gpio.BCM)
  46.     gpio.setup(INPUT.keys(), gpio.IN)
  47.    
  48.     print('Überwachung der Störungen')
  49.     aktuelle_alarme = determins_alarme()
  50.     while True:
  51.         neue_alarme = determins_alarme()
  52.         if aktuelle_alarme != neue_alarme:
  53.             aktuelle_alarme = neue_alarme
  54.             send_mail(aktuelle_alarme)
  55.             print('Email sent')
  56.         sleep(0.1)
  57.  
  58. if __name__ == '__main__':
  59.     main()

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder