#!/usr/bin/env python
# coding: utf8
 
# Import der Python libraries
import RPi.GPIO as GPIO
import time
import datetime
import picamera
import smtplib

from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
 
# Wir verwenden den Board Mode, Angabe der PIN Nummern anstelle der GPIO BCM Nummer
GPIO.setmode(GPIO.BOARD)
# GPIO definieren
GPIO_PIR = 7
# GPIO als "Input" definieren
GPIO.setup(GPIO_PIR, GPIO.IN)

# Speicherort definieren 
STORAGE_LOCATION = '/home/pi/Desktop/'

# Timeouts definieren
TIMEOUT_AFTER_CAPTURE = 10
TIMEOUT_BETWEEN_CAPTURE = 1

# Anzahl der Bilder die durch eine Bewegung aufgezeichnet werden
CAPTURE_COUNT = 5

# Größe der Bilder definieren
PIC_WIDTH = 1280
PIC_HEIGHT = 1024

# Soll eine Mail gesendet werden?
SEND_EMAIL = 1

# SMTP Einstellungen definieren
smtp_host = 'smtp.server.de'
smtp_port = 587
smtp_user = 'username'
smtp_pass = 'password'

# Absender und Empfänger für Mail definieren
subject = 'Bewegungsmelder ausgelöst'
addr_from = 'from@mail.de'
addr_to = 'to@mail.de'

# Kamera initialisieren
camera = picamera.PiCamera()
#camera.vflip = False
#camera.hflip = False
#camera.brightness = 60
#camera.sharpness = 0
#camera.contrast = 0
#camera.saturation = 0
#camera.ISO = 0
#camera.video_stabilization = False
#camera.exposure_compensation = 0
#camera.exposure_mode = 'auto'
#camera.meter_mode = 'average'
#camera.awb_mode = 'auto'
#camera.image_effect = 'none'
#camera.color_effects = None
#camera.rotation = 0
#camera.crop = (0.0, 0.0, 1.0, 1.0)

state_current = 0
state_previous = 0

def get_attachment(file):
    fp = open(file, 'rb')
    attachment = MIMEApplication(
        fp.read(),
        Name=basename(file)
    )
    attachment['Content-Disposition'] = 'attachment; filename="{basename}"' . format(basename=basename(file))
    fp.close()
    return attachment

def sendmail(files):
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = addr_from
    msg['To'] = addr_to
    msg.preamble = subject
    for file in files:
        msg.attach(get_attachment(file))
    try:
        s = smtplib.SMTP(smtp_host, smtp_port)
        s.ehlo()
        s.starttls()
        s.ehlo()
        s.login(user = smtp_user, password = smtp_pass)
        #s.send_message(msg)
        s.sendmail(addr_from, addr_to, msg.as_string())
        s.quit()
    except smtplib.SMTPException as error:
        print "{date}: Error: unable to send email : {err}" . format(date=datetime.datetime.now(), err=error)

def capture():
    print "{date}: Bewegung erkannt! Nehme Foto auf..." . format(date=datetime.datetime.now())
    files = []
    
    for i, filename in enumerate(camera.capture_continuous(STORAGE_LOCATION + 'image_{timestamp:%H-%M-%S-%f}_{counter:03d}.jpg')):
        print "{date}: {cycle}. Foto aufgenommen..." . format(date=datetime.datetime.now(), cycle=i + 1)
        files.append(filename)
        if i + 1 == CAPTURE_COUNT:
            break;
        time.sleep(TIMEOUT_BETWEEN_CAPTURE)
    
    if(SEND_EMAIL):
        print "{date}: Fertig! Sende Mail..." . format(date=datetime.datetime.now())
        sendmail(files)

print "Bewegungsmelder (CTRL-C zum Beenden)"
print "========================================="

try:
    print "{date}: Sensor initialisieren ..." . format(date=datetime.datetime.now())

    # Warten bis Sensor sich meldet
    while GPIO.input(GPIO_PIR)==1:
        state_current  = 0

    print "{date}: Fertig! Warte auf Bewegung..." . format(date=datetime.datetime.now())

    # Schleife bis CTRL+C
    while True :
        # Status von Sensor auslesen
        state_current = GPIO.input(GPIO_PIR)

        if state_current==1 and state_previous==0:
            capture()
            state_previous=1
            time.sleep(TIMEOUT_AFTER_CAPTURE)
            print "{date}: Fertig! Warte auf Bewegung..." . format(date=datetime.datetime.now())
        elif state_current==0 and state_previous==1:
            state_previous=0

        time.sleep(0.01)
except KeyboardInterrupt:
    print "{date}: Exit" . format(date=datetime.datetime.now())
    GPIO.cleanup()