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.
Raspberry per Mailbefehl steuern
-
Cupblue -
20. Februar 2014 um 20:57 -
Erledigt
L
I
V
E
Stammtisch ab 20:30 Uhr im Chat
-
-
Raspberry per Mailbefehl steuern? Schau mal ob du hier fündig wirst!
-
Nun habe ich schon einen Thread gefunden, der genau mein Vorhaben auch behandelt. Nur bin ich leider dadurch gar nicht schlau geworden.
Welchen Thread? -
Diesen Thread habe ich gemeint.
-
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. -
... Nur bin ich leider dadurch gar nicht schlau geworden...
Schwer Dir zu helfen wenn Du nicht etwas genauer sagst was Du nicht verstehst -
Schau dir folgende Module an:
threading
imaplib
email (MIMEMultipart, MIMEBase, MIMEText, Utils)Tell
Mach es mit dem imaplib Modul (select, SEARCH, fetch, store ...) -
Ich nehme mal an, mit dem Python Code verbindet man sich auf dem POP-Server der Mailadresse an die man sendet. Aber ich verstehe aus diesem code leider nicht, wo dort der Befehl aus der Mail abgefragt werden soll.
-
[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:
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 ... -
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.
Codepi@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 anGoogle mal nach " Liste mit POP3- und SMTP-Server Einstellungen "
-
So ich bin nun schon einmal einen Schritt weiter.
Nach diesem CodePython
Alles anzeigen#!usr/bin/python import poplib from email import parser import subprocess while True: pop_conn = poplib.POP3_SSL('pop.gmail.com') pop_conn.user('meinusername') pop_conn.pass_('meinpasswort') numMessages = len(pop_conn.list()[1]) #Get messages from server: messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)] # Concat message pieces: messages = ["\n".join(mssg[1]) for mssg in messages] #Parse message intom an email object: messages = [parser.Parser().parsestr(mssg) for mssg in messages] for message in messages: print message['subject'] pop_conn.quit() time.sleep(2)
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:Codeif "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:Codesudo 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 -
Hallo
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.
-
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:
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
Es läuft alles wie geplant und das durch dieses Script nun :
Python
Alles anzeigen#!usr/bin/python import poplib from email import parser import subprocess while True: pop_conn = poplib.POP3_SSL('pop.gmail.com') pop_conn.user('Meinuser') pop_conn.pass_('Meinpasswort') maillist = pop_conn.list()[1] mailcount = len(maillist) #Get messages from server: messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)] # Concat message pieces: messages = ["\n".join(mssg[1]) for mssg in messages] #Parse message intom an email object: messages = [parser.Parser().parsestr(mssg) for mssg in messages] for message in messages: print message['subject'] pop_conn.quit() if mailcount == 1: betreff = message['subject'] if "test" in message['subject']: subprocess.call("mpg123 sirene.mp3", shell=True) else: print " falscher Befehl" time.sleep(2)
-
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?
-
Außerdem bekommen ich in unregelmäßigen Abständen:
Zitatpoplib.error_proto: -ERR [AUTH] Username and password not accepted.
und das Skript bricht ab.Liegt aber nicht am Passwort selber, das funktioniert ja sonst auch.
Kann es sein, dass hier Gmail einer zu häufigen Abfrage einen Riegel vorschiebt?
-
Ich hab's nicht probiert, aber es muesste etwa so gehen:
Diesen Code:
Codeif mailcount == 1: betreff = message['subject'] if "test" in message['subject']: subprocess.call("mpg123 sirene.mp3", shell=True) else: print " falscher Befehl"
So aendern:
Codeif 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.
-
Topp, funktioniert! Danke Tell!
-
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!