Seite 1 von 2

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 15:11
von __deets__
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?

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 15:22
von MaierA
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.

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import smtplib
from time import sleep
from datetime import datetime as DateTime
from email.mime.text import MIMEText

import RPi.GPIO as GPIO

AL1 = 5 
AL2 = 6
AL3 = 13
AL4 = 19
AL5 = 26
AT1 = 'Heizung'
AT2 = 'Pumpe1'
AT3 = 'Pumpe2'
AT4 = 'Pumpe3'
AT5 = 'Hebeanlage'
FROM_EMAIL = ********@gmail.com'
TO_EMAIL = '*****@hotmail.com; *******@googlemail.com'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_USERNAME = FROM_EMAIL
SMTP_PASSWORD = '**************'


def main():
    GPIO.cleanup()
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(AL1, GPIO.IN)
    GPIO.setup(AL2, GPIO.IN)
    GPIO.setup(AL3, GPIO.IN)
    GPIO.setup(AL4, GPIO.IN)
    GPIO.setup(AL5, GPIO.IN)

    print('Überwachung der Störungen')
    # 
    # TODO Remove busy waiting!! Urgent!!!
    # 
    while True:
        if GPIO.input(AL1):
            AT1 = 'Störung Gasheizung\n'
        else:
            AT1 = 'Gasheizung in Ordnung\n'
        if GPIO.input(AL2):
            AT2 = 'Störung Pufferladepumpe\n'
        else:
            AT2 = 'Pufferladepumpe in Ordnung\n'
        if GPIO.input(AL3):
            AT3 =  'Störung Heizungspumpe\n'
        else:
            AT3 = 'Heizungspumpe in Ordnung\n'
        if GPIO.input(AL4):
            AT4 = 'Störung Pufferzirkulationspumpe\n'
        else:
            AT4 = 'Pufferzirkulationspumpe in Ordnung\n'
        if GPIO.input(AL5):
            AT5 = 'Störung Regenwasserhebeanlage'
        else:
            AT5 = 'Regenwasserhebeanlage in Ordnung'
        if GPIO.input(AL1) or GPIO.input(AL2) or GPIO.input(AL3) or GPIO.input(AL4) or GPIO.input(AL5):
            now = DateTime.now()
            text  = 'Störung an der Heizungsanlage \n \n \n'+AT1+AT2+AT3+AT4+AT5
            message = MIMEText(text)
            message['Subject'] = (
                'Störung Heizungsanlage - {0:%a %d %b %Y, %H:%M:%S}'.format(
                    now
                )
            )
            message['From'] = FROM_EMAIL
            message['To'] = TO_EMAIL
            message['Date'] = format(now, '%a, %d %b %Y %H:%M:%S %z')
            smtp = smtplib.SMTP(SMTP_SERVER)
            smtp.starttls()
            smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
            smtp.sendmail(message['From'], message['To'], message.as_string())
            smtp.quit()
            print('Email sent')
            sleep(2)

        while GPIO.input(AL1) or GPIO.input(AL2) or GPIO.input(AL3) or GPIO.input(AL4) or GPIO.input(AL5):
            sleep(0.1)
        sleep(0.1)


if __name__ == '__main__':
    main()

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 15:55
von __deets__
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?

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 16:21
von __deets__
Oh, jetzt sehe ich erst das du die zweite Bedingung schon geupdatet hast! Das sieht doch gut aus. Tut es immer noch nicht?

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 21:40
von MaierA
__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.

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 22:07
von __deets__
Das ist dann etwas komplizierter, ja. Mein Ansatz: schreib eine Funktion "alarme", die sieht so aus

Code: Alles auswählen

def alarme():
     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:

Code: Alles auswählen

KEIN_ALARM = (0, 0, 0, 0, 0)

while True:
      aktuelle_alarme = alarme()
      if aktuelle_alarme != KEIN_ALARM:
          # email schreiben
          if aktuelle_alarme[0]: # text fuer ersten Alarm dazutun, etc.
               ...
          while aktuelle_alarme == alarme():
               sleep(.1)

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 22:22
von MaierA

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import smtplib
from time import sleep
from datetime import datetime as DateTime
from email.mime.text import MIMEText

import RPi.GPIO as GPIO

AL1 = 5  # TODO Find a more descriptive name.
AL2 = 6
AL3 = 13
AL4 = 19
AL5 = 26
AT1 = 'Heizung'
AT2 = 'Pumpe1'
AT3 = 'Pumpe2'
AT4 = 'Pumpe3'
AT5 = 'Hebeanlage'
FROM_EMAIL = '*******@gmail.com'
TO_EMAIL = '******@hotmail.com'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_USERNAME = FROM_EMAIL
SMTP_PASSWORD = '*******'


def main():
    GPIO.cleanup()
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(AL1, GPIO.IN)
    GPIO.setup(AL2, GPIO.IN)
    GPIO.setup(AL3, GPIO.IN)
    GPIO.setup(AL4, GPIO.IN)
    GPIO.setup(AL5, GPIO.IN)
	
	def alarme()
		return GPIO.input(AL1), GPIO.input(AL2), GPIO.input(AL3), GPIO.input(AL4), GPIO.input(AL5)
    print('Überwachung der Störungen')
    # 
    # TODO Remove busy waiting!! Urgent!!!
    # 
	KEIN_ALARM = (0, 0, 0, 0, 0)
	
    while True:
        if GPIO.input(AL1):
            AT1 = 'Störung Gasheizung\n'
        else:
            AT1 = 'Gasheizung in Ordnung\n'
        if GPIO.input(AL2):
            AT2 = 'Störung Pufferladepumpe\n'
        else:
            AT2 = 'Pufferladepumpe in Ordnung\n'
        if GPIO.input(AL3):
            AT3 =  'Störung Heizungspumpe\n'
        else:
            AT3 = 'Heizungspumpe in Ordnung\n'
        if GPIO.input(AL4):
            AT4 = 'Störung Pufferzirkulationspumpe\n'
        else:
            AT4 = 'Pufferzirkulationspumpe in Ordnung\n'
        if GPIO.input(AL5):
            AT5 = 'Störung Regenwasserhebeanlage'
        else:
            AT5 = 'Regenwasserhebeanlage in Ordnung'
		aktuelle_alarme = alarme()
        if aktuelle_alarme != KEIN_ALARM:
            now = DateTime.now()
            text  = 'Störung an der Heizungsanlage \n \n \n'+AT1+AT2+AT3+AT4+AT5
            message = MIMEText(text)
            message['Subject'] = (
                'Störung Heizungsanlage - {0:%a %d %b %Y, %H:%M:%S}'.format(
                    now
                )
            )
            message['From'] = FROM_EMAIL
            message['To'] = TO_EMAIL
            message['Date'] = format(now, '%a, %d %b %Y %H:%M:%S %z')
            smtp = smtplib.SMTP(SMTP_SERVER)
            smtp.starttls()
            smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
            smtp.sendmail(message['From'], message['To'], message.as_string())
            smtp.quit()
            print('Email sent')
            sleep(2)

        while aktuelle_alarme == alarme():
            sleep(0.1)
        sleep(0.1)


if __name__ == '__main__':
    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

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 22:25
von __deets__
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.

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 22:36
von Sirius3
@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.

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 23:13
von MaierA
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.

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
import smtplib
import RPi.GPIO as GPIO
from __future__ import absolute_import, division, print_function
from time import sleep
from datetime import datetime as DateTime
from email.mime.text import MIMEText

AL1 = 5 
AL2 = 6
AL3 = 13
AL4 = 19
AL5 = 26

AT1 = 'Heizung'
AT2 = 'Pumpe1'
AT3 = 'Pumpe2'
AT4 = 'Pumpe3'
AT5 = 'Hebeanlage'

FROM_EMAIL = '*********@gmail.com'
TO_EMAIL = '********@hotmail.com'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_USERNAME = FROM_EMAIL
SMTP_PASSWORD = '************'

KEIN_ALARM = (0, 0, 0, 0, 0)

def determins_alarme():
    return GPIO.input(AL1), GPIO.input(AL2), GPIO.input(AL3), GPIO.input(AL4), GPIO.input(AL5)

def main():
    GPIO.cleanup()
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(AL1, GPIO.IN)
    GPIO.setup(AL2, GPIO.IN)
    GPIO.setup(AL3, GPIO.IN)
    GPIO.setup(AL4, GPIO.IN)
    GPIO.setup(AL5, GPIO.IN)
	
    print('Überwachung der Störungen')
    
    while True:
        aktuelle_alarme = determins_alarme()
        if aktuelle_alarme != KEIN_ALARM:
            now = DateTime.now()
            if aktuelle_alarme[0]:
                AT1 = 'Störung Gasheizung\n'
            else :
                AT1 = 'Gasheizung in Ordnung\n'
            if aktuelle_alarme[1]:
                AT2 = 'Störung Pufferladepumpe\n'
            else:
                AT2 = 'Pufferladepumpe in Ordnung\n'
            if aktuelle_alarme[2]:
                AT3 =  'Störung Heizungspumpe\n'
            else:
                AT3 = 'Heizungspumpe in Ordnung\n'
            if aktuelle_alarme[3]:
                AT4 = 'Störung Pufferzirkulationspumpe\n'
            else:
                AT4 = 'Pufferzirkulationspumpe in Ordnung\n'
            if aktuelle_alarme[4]:
                AT5 = 'Störung Regenwasserhebeanlage'
            else:
                AT5 = 'Regenwasserhebeanlage in Ordnung'
				
            text  = 'Störung an der Heizungsanlage \n \n \n'+AT1+AT2+AT3+AT4+AT5
            message = MIMEText(text)
            message['Subject'] = ('Störung Heizungsanlage - {0:%a %d %b %Y, %H:%M:%S}'.format(now))
            message['From'] = FROM_EMAIL
            message['To'] = TO_EMAIL
            message['Date'] = format(now, '%a, %d %b %Y %H:%M:%S %z')
            smtp = smtplib.SMTP(SMTP_SERVER)
            smtp.starttls()
            smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
            smtp.sendmail(message['From'], message['To'], message.as_string())
            smtp.quit()
            print('Email sent')
            sleep(2)

        while aktuelle_alarme == determins_alarme():
            sleep(0.1)
        sleep(0.1)


if __name__ == '__main__':
    main()

Re: E-Mail senden bei GPIO Input

Verfasst: Sonntag 3. Dezember 2017, 23:18
von __deets__
Schön das es geklappt hat.

Re: E-Mail senden bei GPIO Input

Verfasst: Dienstag 5. Dezember 2017, 20:31
von harryberlin
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.

Code: Alles auswählen

    # device (name, gpio)
    devices = [('Gasheizung', AL1),
               ('Pufferladepumpe', AL2),
               ('Heizungspumpe', AL3),
               ('Pufferzirkulationspumpe', AL4),
               ('Regenwasserhebeanlage', AL5)]

    states = ['Störung',
              'in Ordnung']

    email_text = 'Störung an der Heizungsanlage \n \n \n'

    for device, gpio in devices:
        email_text += '%s: %s\n' % (device, states[GPIO.input(gpio)])

    print email_text

Re: E-Mail senden bei GPIO Input

Verfasst: Dienstag 5. Dezember 2017, 20:59
von Sirius3
Nochmal komplett:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from time import sleep
import email.utils
from email.mime.text import MIMEText
import smtplib
import RPi.GPIO as gpio

INPUTS = {
    5: "Gasheizung",
    6: "Pufferladepumpe",
    13: "Heizungspumpe",
    19: "Pufferzirkulationspumpe",
    26: "Regenwasserhebeanlage",
}
 
FROM_EMAIL = '*********@gmail.com'
TO_EMAIL = '********@hotmail.com'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_USERNAME = FROM_EMAIL
SMTP_PASSWORD = '************'
 
def determins_alarme():
    return [(gpio.input(k), n) for k, n in INPUTS.items()]

def send_mail(aktuelle_alarme):
    now = email.utils.formatdate(localtime=True)
    messages = ['Störung an der Heizungsanlage \n \n \n']
    for status, name in aktuelle_alarme:
        messages.append('{}: {}\n'.format(name, "Störung" if status else "in Ordnung"))
    message = MIMEText(''.join(messages))
    message['Subject'] = 'Störung Heizungsanlage - {}'.format(now)
    message['From'] = FROM_EMAIL
    message['To'] = TO_EMAIL
    message['Date'] = now
    smtp = smtplib.SMTP(SMTP_SERVER)
    smtp.starttls()
    smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
    smtp.sendmail(message['From'], message['To'], message.as_string())
    smtp.quit()

def main():
    gpio.cleanup()
    gpio.setmode(gpio.BCM)
    gpio.setup(INPUT.keys(), gpio.IN)
   
    print('Überwachung der Störungen')
    aktuelle_alarme = determins_alarme()
    while True:
        neue_alarme = determins_alarme()
        if aktuelle_alarme != neue_alarme:
            aktuelle_alarme = neue_alarme
            send_mail(aktuelle_alarme)
            print('Email sent')
        sleep(0.1)
 
if __name__ == '__main__':
    main()

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 20. Oktober 2018, 00:15
von CrazyRM
Hi, sorry das ich das alte Thema noch einmal hervor hole aber im Störungsfall sendet Python im Sekundentakt eine E-Mail da bei mir das Signal stetig anliegt.

Ich quäle google schon einige Stunden komme aber auf keine lösung das nur ein einiges mal eine Meldung abgesetzt werden soll.
Nach dem versenden der Mail kann das Script ruhig beendet werden.

ich danke schonmal

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 20. Oktober 2018, 10:05
von Sirius3
Dann beende die Schleife doch mittels »break«, nachdem Du einmal eine Mail gesendet hast.

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 20. Oktober 2018, 11:46
von CrazyRM
:lol:
So simpel wie einfach und das haut auch noch hin.

Vielen Dank

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 10. November 2018, 12:13
von peko
Hallo zusammen,

ich habe mir ein Script - auf der Basis des Threaterstellers - geschrieben,
es läuft auch stabil.
Nur möchte ich die email an mehrere Adressaten senden, aus mir unerfindlichen Gründen
wird aber immer nur der erste Adresssat per email benachrichtigt.
Ich habe die Zeile

Code: Alles auswählen

TO_EMAIL = '********@hotmail.com'
auf

Code: Alles auswählen

TO_EMAIL = '********@gmx.de;****@t-online.de;****@vodafone.de'
abgeändert (Sowohl mit ";" als auch mit "," Trennung)

Beim ersten Empfänger werden auch alle drei emailadressen angezeigt, aber bei den anderen kommt nichts an.
Der Versuch, dann (vom ersten Empfänger) allen zu Antworten, klappt problemlos,
nur das Python programm sendet eben nur an den ersten Eintrag der Liste eine email weg.

Habt ihr irgendwelche Tipps ?

Gruß
peko

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 10. November 2018, 12:32
von __deets__

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 10. November 2018, 13:21
von peko
Hallo __deets__,

immer wieder Hilfreich, DANKE !

email.message ist der Schlüssel

Anbei der Codeschnipsel als Hilfe für Suchende:

Code: Alles auswählen

import smtplib
from email.message import EmailMessage

...
...
...

recipients = ['info@eins.de','mobil@zwei.de','drei@gmx.de']
FROM_EMAIL = 'info@eins.de'
SMTP_SERVER = 'smtp.provider.de:587'
SMTP_USERNAME = FROM_EMAIL
SMTP_PASSWORD = 'geheimes PW'

def send_mail(aktuelle_alarme, email1, email2):
    now = email.utils.formatdate(localtime=True)
    if aktuelle_alarme == 1:
        text  = '''xyz,\n
yzx\n\n Automatische E-Mail - nicht antworten'''
    if aktuelle_alarme == 2:
        text  = '''abcd.\n\n
 Automatische E-Mail - nicht antworten'''

    message = EmailMessage()
    message.set_content(text)
    message['Subject'] = 'Abwasserstand'
    message['From'] = FROM_EMAIL
    message['To'] = recipients
    message['Date'] = now

    smtp = smtplib.SMTP(SMTP_SERVER)
    smtp.starttls()
    smtp.login(SMTP_USERNAME, SMTP_PASSWORD)
    smtp.send_message(message)
    smtp.quit()

    ...
    ...

Re: E-Mail senden bei GPIO Input

Verfasst: Samstag 10. November 2018, 15:28
von ThomasL
peko hat geschrieben: Samstag 10. November 2018, 12:13 ich habe mir ein Script - auf der Basis des Threaterstellers - geschrieben,
Hallo peko,
sei mir nicht böse aber ich musste gerade so herzhaft über diesen Typo lachen...
Threat - An expression of an intention to inflict pain, harm, or punishment.