Raspberry per Mailbefehl steuern

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo liebe Freunde.
    Mein System zur Überwachung und Hausautomation läuft.
    Aber nun möchte ich nicht immer nur über das webbasierte Interface den Alarm aktivieren.
    Ich möchte nun dem Pi per Mail Befehle senden nach denen er eine bestimmt Aktion durchführt.
    Ein wenig Erfahrung mit der Mail habe ich schon, da ich es hinbekomme mir eine Mail mit Anhang eines "Einbrecherfotos" auf meine zweite Mailadresse zukommen zu lassen.
    Nun habe ich schon einen Thread gefunden, der genau mein Vorhaben auch behandelt. Nur bin ich leider dadurch gar nicht schlau geworden.
    Ich hoffe ihr könnt mir dazu einige Anregungen geben.

    :helpnew:

  • Ich hab auch einen Mail-Empfaenger fuer POP3 gebaut: POP mit Python auf dem Raspberry

    Das Mail wird empfangen, mit allen Headern und dem Body-Text auf die Konsole ausgegeben
    und dann vom Mailserver geloescht.

    Was noch fehlt: Header oder Body auswerten und eine Aktion starten. Das ist nicht allzu
    schwer wenn keine exotische Codierung verwendet wird.

    Viele Mailer checken, was geschickt wird und wenn reines ASCII drin ist schicken sie es
    ohne Codierung. Also erst mal checken, was der vorgesehene Mail-Client so schickt.

  • [font="Tahoma, Verdana, Arial, sans-serif"]> Ich nehme mal an, mit dem Python Code verbindet man sich auf dem POP-Server der[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]> Mailadresse an die man sendet.[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Genau. Die IP-Adresse, Username und Password im Script muessen angepasst werden.[/font]

    [font="Tahoma, Verdana, Arial, sans-serif"] > Aber ich verstehe aus diesem code leider nicht, wo dort der Befehl aus der Mail[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]> abgefragt werden soll.[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Dann waere es vielleicht schlau gewesen, den Code mal laufen zu lassen ?[/font]
    [font="Tahoma, Verdana, Arial, sans-serif"]Man kann das Script naemlich einfach rauskopieren und auf dem Raspberry speichern.[/font]

    [font="Tahoma, Verdana, Arial, sans-serif"]Man sieht eine ganze Menge wenn er lauft ![/font]

    Aber gut, hier ist ein ganz klarer Hinweis:

    Code
    for line in text:
           print( line )

    Diese Schleife holt Zeile fuer Zeile des Mails und zeigt sie an. Wenn der Befehl in der
    Zeile (line) steht, kann man zum Beispiel eine Funktion aufrufen.

    Zu beachten ist, dass zuerst die Headerzeilen ausgegeben werden. Nach der ersten
    Leerzeile kommt der Text der Mail.

    Bei MIME-Mails kann es sein, dass der Text der Mail aus verschiedenen Parts zusammen-
    gesetzt ist und die koennen zusaetzlich noch codiert sein. Als Codierung ist Quoted-Printable
    ueblich, aber auch Base64 kommt oft vor. Ich wuerde mich nicht wundern, wenn es noch andere
    Codierungen gibt ...

    Einmal editiert, zuletzt von Tell (22. Februar 2014 um 00:21)

  • Wenn ich das Script mit meiner IP des Pi's ausführe, dazu den Nutzername meines Empfänger Accounts sowie dessen Passwort eingebe, dann erscheint bei mir folgender Fehler.

    Code
    pi@raspberrypi ~ $ sudo python befehl.py
    Traceback (most recent call last):
      File "befehl.py", line 4, in <module>
        pop    = poplib.POP3( "Meine Pi IP" )
      File "/usr/lib/python2.7/poplib.py", line 83, in __init__
        self.sock = socket.create_connection((host, port), timeout)
      File "/usr/lib/python2.7/socket.py", line 571, in create_connection
        raise err
    socket.error: [Errno 111] Connection refused


    Was kann das bedeuten ?

    ich ahbe auch mal probiert, statt der IP den POP3 Server meines Mailaccounts einzutragen. Dann erscheint dieser Fehler nicht, aber es tut sich weiterhin auch nichts, bis ich per Keyboardinterrupt das Programm beende.

  • > Was kann das bedeuten ?
    Das ist sogar sehr klar: die angegebene Maschine will keine Verbindung zu diesem Port.

    > Dann erscheint dieser Fehler nicht, aber es tut sich weiterhin auch nichts, bis ich per
    > Keyboardinterrupt das Programm beende.
    Das wiederum ist nicht normal. Nach spaetestens 60 Sekunden muesste ein Timeout
    kommen.

    Also nochmal die Einstellungen des POP3-Accounts ueberpruefen:
    * Welche IP soll benutzt werden
    * Welches Port ist eingestellt ?
    (Das Script benutzt den Default: 110)
    * Passwort und Username stimmen vermutlich
    (Da sind doch nicht etwa Zeichen mit Umlauten drin ?)

    Und nochmals das Verhalten des Scripts im Fall 2 pruefen, denn das Script fragt genau
    einmal den Mailserver ab. Falls dort eine lange Schleife auftritt, gibt es eine Verbindung
    zum Mailserver aber es gibt Probleme beim Abfragen der Mails.

  • Was denk ich auch wichtig wäre ist ob der EMail Anbieter den du nutzt, nur verschlüsselte Verbindungen erlaubt - das machen mittlerweile nämlich eigentlich alle..
    Und dann wäre das nicht mehr der Port 110 sondern zB 25 oder 465 oder 587 oder 995 oder 993 usw ... Könnte auch sein das der Anbieter nicht SSL sondern TLS verlangt ... Das kommt auf den Anbieter an


    Google mal nach " Liste mit POP3- und SMTP-Server Einstellungen "

  • So ich bin nun schon einmal einen Schritt weiter.
    Nach diesem Code


    werden mir alle 2 Sekunden bei einem Maileingang der Betreff im Terminal angezeigt.
    Wie kann ich diesen jedoch weiter auswerten ?
    Ich habe es einmal damit probiert:

    Code
    if "test" in message['subject']:
            subprocess.call("mpg123 sirene.mp3", shell=True)
        else:
            print "Keine Nachricht"
        time.sleep(3)


    Lasse ich das so laufen und es liegt eine Mail mit dem Betreff 'test' vor, so führt er alles wunderbar aus.
    Lasse ich das Laufen und es leigt eine Mail mit einem anderen Betreff vor, so schreibt er 'Keine Nachricht', also es klappt bis dahin alles gut.
    Ist jedoch keine Mail vorhanden, so komm diese Fehlermeldung:

    Code
    sudo python Emailbefehle.py
    Traceback (most recent call last):
      File "Emailbefehle.py", line 25, in <module>
        if "test" in message['subject']:
    NameError: name 'message' is not defined


    Das verstehe ich leider noch nicht, ich kann ja nicht andauern eine mail losschicken, nur damit es läuft :D

  • Hallo

    Code
    betreff = message['subject']
    if betreff == "test":
        #mach was damit
    else:
        #--"--

    EDIT:

    Ups, da habe ich vergessen den letzten Absatz zu lesen

    Zitat


    [font="Tahoma, Verdana, Arial, sans-serif"]Ist jedoch keine Mail vorhanden, so komm diese Fehlermeldung:[/font]

    Dann musst du davor eine weitere if-Abfrage machen. Wenn Mail vorhanden, dann das obige, sonst tue nichts. Ich würde es mal mit dem imaplib versuchen und so einstellen, dass nur eine vordefinierte Mailadresse mittels SEARCH(None, 'FROM', 'deine@mail.com') verarbeitet wird.

    http://docs.python.org/2/library/imaplib.html

  • Mit imaplib habe ich schon probiert, es aber nicht mal so weit wie jetzt mit poplib geschafft.

    Ich nehme mal an in dieser Zeile hier:

    Code
    messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]

    ersehe ich, dass eine Mail auf dem Server anliegt.
    Aber wie baue ich dann eine weitere If-Abfrage auf ?

  • Wenn man sich am Abend nach dem lernen nochmal konzerntriert dann bekommt mana uch was hin :bravo2:

    Es läuft alles wie geplant und das durch dieses Script nun :

  • Wenn ich diesen älteren Thread nochmal aufwärmen darf: Ich bastle gerade an einer Steuerungskontrolle über Geofencing und da kommt mir dieses Script mehr als gelegen!

    Allerdings würde ich gerne noch eine Sicherheitsstufe einbauen und nur zwei verschiedene Email Adressen zulassen, bei denen der "Befehl auf Email" akzeptiert wird. Bin kein großer Python Kenner und frage mich, wo und wie ich diese Prüfung einbauen müßte?

  • Ich hab's nicht probiert, aber es muesste etwa so gehen:

    Diesen Code:

    Code
    if mailcount == 1:
            betreff = message['subject']
            if "test" in message['subject']:
                subprocess.call("mpg123 sirene.mp3", shell=True)
            else:
                print " falscher Befehl"

    So aendern:

    Code
    if mailcount == 1:
            betreff = message['subject']
            if ("test" in message['subject']) and ("mailadresse" in message["From"]):
                subprocess.call("mpg123 sirene.mp3", shell=True)
            else:
                print " falscher Befehl"

    "mailadresse" durch eine sinnvolle Adresse ersetzen !

    - - - - -

    Und ja, die meisten Mailserver moegen keine Abragen alle 2 Sekunden. Das wird als Attacke angesehen.

    Einmal editiert, zuletzt von Tell (28. Dezember 2014 um 19:30)

  • Hallo,
    ich habe dieses Script nachgebaut und es läuft auch eigentlich gut. Versuche so was schon länger. Nur manchmal bricht es ab mit einer Fehlermeldung (traceback call at last.....)und mein Passwort erscheint auch in der Fehlermeldung. Als würde mir der Zugriff auf das Mailkonto verweigert.Was könnte das sein? Passiert ja nicht immer. Wer kann mir helfen?

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!