1-Wire Sensor: Alarm sendet mail / email
Anbei ein Python Programm, um einen 1-Wire Sensor zu lesen und
bei Überschreitung der Alarmgrenzen eine Mail zu versenden.
Das script kann man über cronjob regelmäßig starten.
Bei Sender- und Empfänger-adressen ist folgendes zu beachten:
– Die Mail-Adressen müssen ein gültiges Format ausweisen: name@domain.de
– Weder Sender- noch Empfänger-Adresse müssen existieren
– ABER …. Wenn ein Adresse verwendet, die auf dem verwendeten Mail-Server liegt, MUSS die existieren
Es geht: Mail-Server = smtp.web.de & Empfänger/Sender diegibtesnicht@gmx.de | denauchnicht@gmx.de
Geht nicht Mail-Server = smtp.gmx.de & Empfänger/Sender diegibtesnicht@gmx.de | denauchnicht@gmx.de
Edit: Die neue Version gibt eine bessere Fehlermeldung aus.
[codesyntax lang=”python”]
#!/usr/bin/python # -*- coding: utf-8 -*- # # read 1-wire sensor # in case of value exceeding alarm limit # send email via smtp # 2013-06-06 V0.2 by Thomas Hoeser # import sys import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText mail_server = 'smtp.web.de' # Mail Server mail_account = 'xxx.yyy@web.de' # name of mail account mail_password = 'secretpassword' # password addr_sender = 'bill.gates@microsoft.de' # sender email addr_receiver = 'bill.gates@microsoft.de' # receiver email verbose_level = 2 debug_level = 0 error_temp = -999 # dictionary with for 1-wire sensors: [sensor name] [1-Wire device] sensor_dict = { "Wohnzimmer": "28-00000487bb70", "Balkon" : "28-00000487bb70", "Speicher" : "28-000004be39a5" } #--------------------------------------------------------------------------------------------- def read_sensor(Sensor): if verbose_level > 2: print "1++++ read_sensor()" print "sensor:" , Sensor if debug_level == 0: # get 1-Wire id from dictionary sensor_slave = str(sensor_dict.get(Sensor)) # Open 1-wire slave file sensor_device = '/sys/bus/w1/devices/' + str(sensor_slave) + '/w1_slave' if verbose_level > 2: print "open: ", sensor_device try: file = open(sensor_device) filecontent = file.read() # Read content from 1-wire slave file file.close() # Close 1-wire slave file stringvalue = filecontent.split("\n")[1].split(" ")[9] # Extract temperature string if stringvalue[0].find("YES") > 0: temp = error_temp else: temp = float(stringvalue[2:]) / 1000 # Convert temperature value # temp=str(temp) except IOError: print "PANIC read_sensor - Cannot find file >" + sensor_slave + "< in /sys/bus/w1/devices/" print "No sensor attached" print "check with > cat /sys/devices/w1_bus_master1/w1_master_slaves" temp=("Sensor not attached") else: # this is dummy function generating a random number # ony used for testing purposes temp = random.randrange(-10, 30, 2) + 0.3 # temp = Sensor + " " + str(temp) return(temp) # exit function read_sensor # -------------------------------------------------------------------------------- def send_mail(title,message): debug_level = 0 # set to 1 to get more messages # Create message container - the correct MIME type is multipart/alternative. msg = MIMEMultipart('alternative') msg['Subject'] = title msg['From'] = addr_sender msg['To'] = addr_receiver # Create the body of the message (a plain-text and an HTML version). text = message html = """\ """ html += message html += """\
This is a service provided by raspberry
""" # print html # Record the MIME types of both parts - text/plain and text/html. part1 = MIMEText(text, 'plain') part2 = MIMEText(html, 'html') # Attach parts into message container. msg.attach(part1) msg.attach(part2) #mailsrv = smtplib.SMTP(mail_server) #mailsrv.login(mail_account,mail_password) #mailsrv.sendmail(addr_sender, addr_receiver, msg.as_string()) #mailsrv.quit() #return() try: if debug_level > 0: print "smtplib.SMTP:", mail_server mailsrv = smtplib.SMTP(mail_server) # Send the message via local SMTP server. except: print "Error: unable to send email - smtp server" print "Server on ", mail_server, " cannot be reached or service is down" return() try: if debug_level > 0: print "mailsrv.login:", mail_account, mail_password mailsrv.login(mail_account,mail_password) except: print "Error: unable to send email - login failed" print "login is not valid - check name and password:",mail_account,mail_password return() try: # sendmail function takes 3 arguments: sender's address, recipient's address and message to send - here it is sent as one string. if debug_level > 0: print "mailsrv.sendmail:", addr_sender, addr_receiver mailsrv.sendmail(addr_sender, addr_receiver, msg.as_string()) mailsrv.quit() print "Successfully sent email" except: print "Error: unable to send email - wrong address" print "mail address for sender or receiver invalid:",addr_sender,addr_receiver #--------------------------------------------------------------------------------------------- if __name__ == "__main__": alarm_hi = 20.5 # upper alarm level alarm_lo = -10.5 # lowe alarm level cur_temp = read_sensor("Speicher") print cur_temp, alarm_hi, alarm_lo if cur_temp == error_temp: print "read error - CRC = NO" else: if (cur_temp > alarm_hi) or (cur_temp < alarm_lo): subject = "Alarm" message = "Die Temperatur betraegt: " + str(cur_temp) print subject, message send_mail(subject,message) else: print "o.k." sys.exit(0)
[/codesyntax]
Hallo,
Durch Stöbern im Netz bin ich auf dieses Programm aufmerksam geworden.
Es ist genau das, was ich gesucht habe.
Leider funktioniert es bei mir nicht.
Das Auslesen der Sensoren klappt nicht;
e-Mail schon.
Die Fehlermeldung lautet:PANIC read_sensor – Cannot find file >None< in /sys/bus/w1/devices…
Der Sensor ist vorhanden und ist auch im Pfad eingetragen. Die Datei w1_slave beinhaltet auch die Temperatur.
geändert wurde nur der e-Mail Zugang und die Sensor Seriennummer.
Hier läuft ein Raspberry mit Debian Wheezy Version B
Gibt es evtl. ein Tip, was hier falsch läuft?
Gruss Helmut
Hallo Helmut,
Der Fehler >None< deutet darauf hin, dass der Sensor nicht im Dictionary eingetragen ist. Das python Programm geht den Umweg über ein Dictionary. In sensor_dict werden die Sensoren eingetragen: Sensor Name. : Device ID Somit kann man im Programm mit sprechenden Bezeichnungen arbeiten. Mir hat es auch geholfen, nach der Planung die Sensoren auszuwechseln, ohne mit IDs durcheinander zu kommen. Also trage den Sensor in sensor_dict ein und vergebe einen Namen. Dieser Namen wird in Main beim Aufruf eingetragen Cur_temp = read_sensor ("sensorname") Alternativ kann man in der Funktion read_sensor die Suche im Dictionary entfernen. sensor_slave = str(sensor_dict.get(Sensor)) Aendern in sensor_slave = Sensor Ich hoffe dies hilft. Wenn nicht bitte melden. Gruß,Thomas
Hallo Thomas,
Vielen Dank für das Programm, Es läuft auch soweit bei mir, aber es verschickt keine Mails obwohl ich die Mail-Zugangsdaten eingetragen habe.
Ich habe exim4 installiert. Muss ich da noch etwas konfiguriern ? Soweit ich mich erinnern kann, habe ich exim nur für lokalen Mailversand konfiguriert …
Hier die Prog.-Ausgabe:
pi@raspberrypi ~ $ python /home/pi/scripte/py/alarmsendmail.py
1.187 30.0 3.0
Alarm Die Temperatur betraegt: 1.187
Error: unable to send email
Hallo Torsten,
ich habe das Programm leicht geändert (V0.2).
Es werden jetzt bessere Fehlermeldungen angezeigt, wenn das Versenden der mail nicht funktioniert.
Gruß,
Thomas
hoi
habst du eine neue version für die sendmail.py auch?
cheers
cr