Schulprojekt ohne Kentnisse

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Matty
User
Beiträge: 2
Registriert: Mittwoch 8. Juni 2016, 15:18

Hallo Leute, ich in neu in der Python Welt und habe folgendes Problem.
Ich habe mir diesen Quelltext zusammengeschustert indem mir ein Bewegungsmelder und ein Reed Schalter ein Foto mit der PiCamera erstellen und ein kleines Video automatisch aufzeichnen soll, hinzu kam noch eine Benachrichtigung per Mail.
Jetzt wollte ich für das ganze noch eine enutzeroberfläche erstellen.
Leider bin ich absoluter Neuling und habe mir in diversen Videos hilfe geholt. (Etwas habe ich in der Schule schon mit Java in Eclipse Programmiert) Nur mit dem IDLE ist es leider nicht so kompfortabel. (Mehrere Klassen, MainApp und GUI)

Folgendes Problem:
Ein Button auf der Benutzeroberfläche soll mir die while Schleife zuschalten, ein anderer wieder abschalten. Zudem möchte ich noch in verschiedenen labels verschiedene Textausgaben zu den beiden if-Strukturen (Bewegungsmelder & Reedschalter) machen.
Leider Macht mein Fesnter nach dem Start der while Schleife nichts mehr. woran liegt das????

Code: Alles auswählen

#importieren der genutzten Bibliotheken & Dateien
from Tkinter import *
import time
import datetime
import RPi.GPIO as GPIO
import picamera
import subprocess
import smtplib
import socket
import sys
from email.mime.text import MIMEText

#------------------------grafisches Fenster----------------------------

#Erzeugung des Fensters
fenster = Tk()

#Titel des Fensters
fenster.title("Alarmanlage")

#Groeße des Fensters
fenster.geometry("300x300")

def close_app_win():
    print 'Alarmanlage abgeschaltet!'
    app_win.destroy

label1 = Label(text = "Alarmanlage scharf schalten")
label1.pack()

#-------------------------Info per Mail--------------------------------

#-------------------------Info per Mail--------------------------------

# Accountinformationen zum Senden der E-Mail
Empfaenger = 'stablo@gmx.net'
Absender = 'raspberryos@gmx.de'
Passwort = 'ElektroPort1305'
smtpserver = smtplib.SMTP('mail.gmx.net', 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo

# In Account einloggen
smtpserver.login(Absender, Passwort)

#Aktuelles Datum holen
Datum = datetime.date.today()

# Text
msg_1 = MIMEText('Alarm!!! Bewegungsmelder ausgeloest')
msg_2 = MIMEText('Alarm!!! Fenster Kueche geoeffnet')

# Betreff + Datum
msg_1['Subject'] = 'Alarm von Raspberry Pi - %s' % Datum.strftime('%b %d %Y')
msg_2['Subject'] = 'Alarm von Raspberry Pi - %s' % Datum.strftime('%b %d %Y')

# Absender
msg_1['From'] = Absender
msg_2['From'] = Absender

# In Account einloggen
smtpserver.login(Absender, Passwort)

#Aktuelles Datum holen
Datum = datetime.date.today()

# Text
msg_1 = MIMEText('Alarm!!! Bewegungsmelder ausgeloest')
msg_2 = MIMEText('Alarm!!! Fenster Kueche geoeffnet')

# Betreff + Datum
msg_1['Subject'] = 'Alarm von Raspberry Pi - %s' % Datum.strftime('%b %d %Y')
msg_2['Subject'] = 'Alarm von Raspberry Pi - %s' % Datum.strftime('%b %d %Y')

# Absender
msg_1['From'] = Absender
msg_2['From'] = Absender

# Empfaenger
msg_1['To'] = Empfaenger
msg_2['To'] = Empfaenger


# MESSUNG GPIO & AUSGABE Bewegungsmelder/Reed-Schalter:

GPIO.setmode(GPIO.BOARD)

GPIO.setwarnings(False)
GPIO.setup(7, GPIO.IN)
GPIO.setup(12, GPIO.IN)
GPIO.setup(33, GPIO.OUT)


camera = picamera.PiCamera()

def scharf():

    while True:
        if GPIO.input(7):
            a = datetime.datetime.now()
            a = str(a)
            a = a[0:19]
            alert_1 = ("Bewegungsmelder ausgeloest "+str(a))
            print(alert_1)
            pic = (a)+(".jpg")
            vid = (a)+(".h264")
            message = (alert_1),(pic),(vid)

            label1.configure(text = (alert_1))

            #Groeße der Bildaufnahme:
            camera.resolution = (1024, 768)

            #Aufnahme des Bildes:
            camera.capture(pic)
            time.sleep(2)

            #Groeße der Videoaufnahme:
            camera.resolution = (640, 480)

            #Aufnahme des Videos:
            camera.start_recording(vid)
            camera.wait_recording(10)
            camera.stop_recording()

            #E-Mail abschicken:
            smtpserver.sendmail(Absender, [Empfaenger], msg_1.as_string())
            smtpserver.quit()

            time.sleep(30)              #Pausieren fuer 30 sekunden

         if GPIO.input(12):
            b = datetime.datetime.now()
            b = str(b)
            b = b[0:19]
            alert_2 = ("Fenster Kueche geoeffnet "+str(b))
            print(alert_2)
            pic = (b)+(".jpg")
            vid = (b)+(".h264")
            message = (alert_2),(pic),(vid)

            #Groeße der Bildaufnahme:
            camera.resolution = (1024, 768)

            #Aufnahme des Bildes:
            camera.capture(pic)
            time.sleep(2)

            #Groeße der Videoaufnahme:
            camera.resolution = (640, 480)

            #Aufnahme des Videos:
            camera.start_recording(vid)
            camera.wait_recording(10)
            camera.stop_recording()

#E-Mail abschicken:
            smtpserver.sendmail(Absender, [Empfaenger], msg_2.as_string())
            smtpserver.quit()

            #Pausieren fuer 30 sekunden:
            time.sleep(3)



unscharf = Button(fenster, text="unscharf", command = exit)
#Positionierung des Buttons (scharf)
unscharf.pack()


#Laden des Buttons (scharf)
scharf = Button(fenster, text="Anlage Scharf stellen", command=scharf)
#Positionierung des Buttons (scharf)
scharf.pack()


mainloop() #Ende mainloop grafik!
BlackJack

@Matty: Das liegt daran das wenn Deine ``while``-Schleife nicht läuft, die Tk-Hauptschleife nicht laufen kann. Die läuft erst weiter wenn Deine Funktion zuende ist und die Kontrolle wieder zurück gibt. Wenn Du das lösen willst, brauchst Du nebenläufige Programmierung. Eventuell geht das noch mit der `after()`-Methode auf Tk-Widgets, oder mit dem `threading`-Modul. Und für die GUI brauchst Du eigentlich objektorientierte Programmierung (OOP). Das sind beides zwei umfangreichere Themen und zusammen nochmal etwas komplexer. Du machst in dem Code aber nicht einmal sinnvollen Gebrauch von Funktionen, also ist so eine GUI im Grunde noch zwei Stufen zu hoch für deinen jetzigen Kenntnisstand, den Du ja selbst als „ohne Kentnisse“ beschreibst.

Eventuell wäre es besser wenn Du das erst einmal ordentlich ohne GUI schreibst. Keine Sternchen-Importe. Auf Modulebene nur Definitionen von Konstanten, Funktionen, und Klassen. Das Hauptprogramm auch in einer eigenen Funktion. Die einzelnen Teilaufgaben die gelöst werden sinnvoll auf Funktionen aufteilen…

Das Login zum SMTP-Server wird zweimal gemacht. Und an der falschen Stelle. Denn wenn keiner das Fenster öffnet, und sich nichts bewegt, dann bleibt die ganze Zeit die Verbindung offen. Oder eben auch nicht, weil normale SMTP-Server die Verbindung schliessen wenn sich eine bestimmte Zeit lang nichts tut. Das wäre beispielsweise ein guter Kandidat für eine Funktion: Eine E-Mail verschicken. Mit Verbindungsauf- und abbau.
Matty
User
Beiträge: 2
Registriert: Mittwoch 8. Juni 2016, 15:18

Vielen Dank für die Antwort!
Gibt es irgendwelche empfehlenswerte Crashkurse für Python, da ich ja schon ein wenig Objektorientiert mit Java und Eclipse geschrieben habe.
Benutzeravatar
Pywolf
User
Beiträge: 5
Registriert: Dienstag 10. Mai 2016, 08:49

Matty hat geschrieben: Gibt es irgendwelche empfehlenswerte Crashkurse für Python, da ich ja schon ein wenig Objektorientiert mit Java und Eclipse geschrieben habe.
Schau Dir mal die Kurse auf SoloLearn an. Ich habe letztens so einen durchgearbeitet. Macht Spaß und kostet nichts!
http://www.sololearn.com/Courses/
This is the end.
BlackJack

@Matty: Es gibt in der Python-Dokumentation ein Tutorial das einen kleinen Rundgang durch die Sprache macht. Und Style Guide for Python Code sollte man mal durchgehen.

Ansonsten sind GUI-Programmierung (ereignisorientiert) und nebenläufige Programmierung letztendlich keine reinen Python-Themen. Die Problematiken die sich dabei ergeben, gibt es mit jeder Sprache die Tk für die GUI oder Threads für nebenläufige Ausführung verwendet. Vieles ist auch nicht auf Tk beschränkt — auch in Java blockiert eine Swing-GUI wenn man die Kontrolle nicht an die GUI-Hauptschleife zurück gibt. Und da die `threading`-API der von Java nachempfunden ist, sieht es dort auch recht ähnlich aus. `concurrent.futures` gibt es in Python auch. Ist auch dem Konzept in Java sehr ähnlich.

Zur GUI: Zwei Schaltflächen sind hier IMHO zuviel, denn wenn man Start gedrückt hat, macht der Start-Button keinen Sinn mehr bis man Stop gedrückt hat, und der Button ist wiederum sinnlos solange man nicht Start gedrückt hat. Eine Schaltfläche, die die Beschriftung entsprechend verändert oder ”einrastet”, wäre ausreichend.
Antworten