PIR-Sensor/ Pushbullet/ GPIO/ Raspicam mit Python kombinierbar?

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo!
    Ich habe einen Pi, jede Menge Ideen und leider keine Ahnung von Programmierung, jetzt würde ich mich auch nicht davor scheuen etwas neues zu lernen, nur sollte es dann doch zielführend sein. Sprich, ist Python das richtige für meine Idee/Ideen.
    Stand z.z. ist das ich am
    - Raspberry eine Fernsteuerung für Steckdosen laufen habe,
    - ausserdem ist eine Raspicam angebaut.
    - Zugang über SSH ist eingerichtet, auch via NoIP, also aus der ferne,
    - des weiteren habe ich einen Pushbulletdienst eingerichtet, Bei Anmeldung auf SSH bekomme ich eine Pushnachricht auf mein Handy.

    Funktioniert soweit alles gut.
    - Ausserdem habe ich das ganze auf einen Roboter/Rover montiert. War ein Projekt mit meinem Sohn, Steuerung ist da aber via Scratch.

    Step 1:
    Was ich jetzt gerne machen möchte wäre eine Pushbullet-Info erhalten wenn der Bewegungsmelder in einem bestimmten Zeitfenster Bewegung erkennt.

    Meinem Verständnis nach wäre es so das ein Gpio-pin vom Bewegungsmelder von low auf high geschaltet wird, das löst das pushbullet-script aus das mir eine Bewegung meldet.

    Step 2:
    Die Steckdosen werden auf 1 geschaltet als eingeschaltet.

    Step 3:
    Die Gpio-Schaltung löst dann aus das die Kamera eingeschaltet wird und Bilder macht und per email versendet oder in der dropbox ablegt.

    Das wäre mein Wunsch, wie kann ich so etwas umsetzen?
    Ist da python das richtige?
    Wo kann ich da brauchbare info finden?
    Einsteigertutorials?

    Für tipps und Anregungen wäre ich sehr dankbar.
    Gruß

    Tim

  • PIR-Sensor/ Pushbullet/ GPIO/ Raspicam mit Python kombinierbar?? Schau mal ob du hier fündig wirst!

  • Generell wird gerade auf dem PI sehr viel in Python entwickelt da es eine eigentlich recht einfache Programmiersprache ist. Wenn du also Fragen hast findest du im Internet sehr schnell Beispiele die in Python geschrieben sind.

    Für dein Vorhaben würde ich ebenfalls Python verwenden, da es für alles von dir erwähnte bereits Lösungswege gibt.

    Google zum Beispiel mal nach: PIR python
    Gleich der erste Treffer zeigt dir eine Möglichkeit den PIR zu verwenden

    Allerdings würde Ich lieber mit einem Interrupt arbeiten. Also die Suche erweitern: PIR python interrupt
    Ebenfalls gleich der erste Treffer zeigt dir ein entsprechendes Script. (aber auch hier würde ich die while ersetzen, aber dazu später gerne mehr)

    Für die RaspiCam gibt es ebenfalls ein Python Module womit der Umgang erheblich vereinfacht wird: picamera
    Die Bilder via EMail zu verschicken oder auf Dropbox hochzuladen ist auch kein Problem.

    Steckdosen über python zu schalten ist auch kein Problem..

  • Tach'schen,

    Anleitung für den PIR sensor gibt es auf diesem Blog:

    Wenn Dein Python script auch noch was anderes machen soll als den PIR-Sensor abfragen, dann würde das Grundgerüst mit Interrupt für den PIR-Sensor, etwa so aussehen (auf die Schnelle ...):

    Im Netz findest Du da sicher noch mehr Code-Beispiele.

  • Hallo,
    danke für die vielen Antworten, es schein also so das python da ein richtiger weg ist.
    Wie kann ich da jetzt loslegen? gibt es da ein empfehlenswertes buch als standartwerk? für anfänger?
    Soweit erstmal danke

  • Es gibt für fast jedes Modul Dokumentationen. Für Buchtipps gibt es ein paar Themen hier im Forum.

    ProfDrFisch
    17. September 2014 um 09:50

    PS:
    Eine Frage die du dir noch stellen muss ist: Python2 oder Python3 ;)

  • luetzel: Der von dir angegebene Blog ist der von mir beschriebene erste Treffer, allerdings ist der ohne Interrupt.
    Dein Grundgerüst ist aber leider auch leicht fehlerhaft da dort Einrückungen fehlen.

    Richtiger wäre:

    Spoiler anzeigen

    [code=php]
    #!/usr/bin/python
    import RPi.GPIO as GPIO
    import picamera

    PIR_PIN = 24
    GPIO.setup(PIR_PIN, GPIO.IN)

    def MOTION(PIR_PIN):
    # hier kann man dann z.B. mit dem picamera modul ein Bild schiessen ...
    return

    def main():
    try:
    GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=MOTION)
    while(1):
    # Endlossschleife für andere Befehle
    except KeyboardInterrupt: # does not work if it runs in background.
    print "Quit"
    GPIO.cleanup()

    if __name__ == '__main__':
    main()
    [/php]

    Allerdings würde ICH das so auch noch nicht nutzen :fies:
    Zum einen gefällt mir das while nicht (wobei es natürlich darauf an kommt was in dem Script sonst noch passieren soll, aber die meisten greifen hier zu einem sleep aber genau das wäre schlecht), zum andern macht das "return" im callback eigentlich kein Sinn und die Variable die dem Callback übergeben wird ist der Pin auf dem der Interrupt ausgelöst wurde, was nicht zwangsläufig PIR_PIN sein muss wenn man zB mehrere Interrupts mit nur einem Callback nutzt.

    Also ich würde das lieber so schreiben:

    Spoiler anzeigen

    [code=php]#!/usr/bin/python
    import time
    import RPi.GPIO as GPIO
    import signal

    PIR_PIN = 24
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(PIR_PIN, GPIO.IN)

    def interrupt_event(pin):
    Time = time.asctime()
    print("{} -> GPIO {} ausgeloest!".format(Time, pin))
    # hier kann man dann z.B. mit dem picamera modul ein Bild schiessen ...

    def main():
    try:
    GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=interrupt_event, bouncetime=100)
    #keep script running
    signal.pause()
    except KeyboardInterrupt: # does not work if it runs in background.
    print("Quit")

    if __name__ == '__main__':
    main()

    GPIO.cleanup()
    [/php]

    Da seht ich auch gleich ein paar mehr Veränderungen:

    * Wird ein Interrupt ausgelöst (also eine Änderung des GPIO-pins) wird der jeweilig betroffene Pin und die Zeit der Auslösung angezeigt.

    * Dem add_event_detect hab ich eine weitere Einstellung hinzugefügt um mögliches prellen zu ignorieren, ein erneutes triggern innerhalb von 100ms wird also vom Interrupt ignoriert.

    * Anstatt einer while nutze ich lieber signal um das Script daran zu hindern sich zu beenden, was folgenden Hintergrund hat:
    Scripts/Programme werden von oben nach unten abgearbeitet. Das Script selbst ist ein Thread, der Interrupt ist ein weiterer Thread. Wird aber der Haupt-Thread also das Script beendet, wird auch der Interrupt-Thread beendet. Deshalb muss man das Script daran hindern sich zu beenden, was die meisten mit einer " while " Schleife erreichen. Wenn man aber eine while-Schleife und time.sleep(1) o.ä. verwendet dann wird das Script für diese Zeit blockiert, es kann nichts anderes aus dem Script ausgeführt werden - der Interrupt-Thread läuft zwar im Hintergrund weiter aber wenn der dann in genau diesem Moment eine Anweisung vom Script ausführen will funktioniert das nicht. Mit signal.pause() kann das nicht passieren.

    * Da das Script von oben nach unten abgearbeitet wird, und ein KeyboardInterrupt das signal.pause() unterbrechen würde, kann man die GPIO.cleanup() ans Ende setzen - natürlich nur wenn vorher nicht noch ein Fehler das vorzeitige beenden des Scripts auslösen würde, aber dann würde Deine Schreibweise daran auch nichts ändern... ;)


    Bezüglich Anleitungen kann ich dir kein Buch empfehlen - ich ergoogle mir alles, mit den entsprechenden Suchbegriffen findet man etliche Beispiele. Finde ich auch für Sinnvoller als irgendein Buch zu lesen in dem vielleicht nur 10% für das jeweilige Vorhaben nützlich wäre ;)
    Du hast ja schon klare Vorstellungen was du erreichen möchtest - such einfach nach " python Pushbullet " oder " python raspicam " usw dann wirst du schnell fündig. Für weitere Fragen einfach nen Post machen :)

  • meigrafd

    Was muss passieren bei deinem Code, dass ``GPIO.cleanup() `` ausgeführt wird?

    Edit:
    Wäre es nicht schlauer, es in die except KeyboardInterrupt zu packen, damit die GPIOs beim Beenden auch sauber auf 0 gesetzt werden?

    Edit II:
    so würde ich es auch machen ;)

    Edit III:
    Das von meigfrad ist fast ein perfektes Grundgerüst für Python3 mit ein paar Schönheitsfehler. Eine Variable zu benennen wie ein Modul wird sehr gefährlich und kann sogar zum Absturz führen. Des Weiteren ist ``print`` eine Anweisung und keine Funktion, deshalb sind die Klammern deplaziert.

    Spoiler anzeigen
  • bootsmann: Das fragst Du mich? Du bist hier doch unser Python Experte...

    //EDIT:


    Edit:
    Wäre es nicht schlauer, es in die except KeyboardInterrupt zu packen, damit die GPIOs beim Beenden auch sauber auf 0 gesetzt werden?

    Edit II:
    so würde ich es auch machen ;)

    Ob man es ins if __name__ == '__main__': mit einfüge, oder separat darunter, spielt keine Rolle.

    Also egal ob man:
    [code=php]
    if __name__ == '__main__':
    main()
    GPIO.cleanup()
    print("Ende des Scripts")
    [/php]

    Oder ob man:
    [code=php]
    if __name__ == '__main__':
    main()

    GPIO.cleanup()
    print("Ende des Scripts")
    [/php]

    verwendet. Beides bewirkt das selbe: Das Script wird generell von oben nach unten abgearbeitet. Wird main() beendet werden die nächsten Zeilen des Script abgearbeitet.
    Bevor deshalb nun hier wieder eine Diskussion entsteht: Selbstversuch macht Klug.


    //EDIT2: oh my god - nun geht das wieder los :wallbash:
    Time ist kein Modul und wegen der print's sehe ich bei Deinem Code zu meinem keinen Unterschied?!?

    ..ich klink mich nun hier auch aus - das wird mir langsam zu doof mit dir..

  • Hallo,........Der Syntax Fehler hat sich erledigt. Habe das komplette Script von meigrafd nochmals in meine pir.py kopiert und jetzt geht es. Jetzt bleibt nur noch der untere Teil, wie ich das versenden einbauen kann.

    Ok, das hat sich auch erledigt.

    Funktioniert mit:
    import subprocess
    _
    _
    subrocess.call(" /.sendmail.py")

    bin gerade dabei das Script von meigrafd, bzw. bootsmann von oben in mein System zu integrieren.
    Jetzt bekomme ich allerdings einen Syntax error in Line 15.
    aktuelle_zeit = time.asctime()
    Nach Überprüfung bei der Python Software Foundation sollte der Befehl aber korrekt sein.
    Ich komme da im Moment nicht weiter und vielleicht sieht jemand wo der Fehler liegen kann.


    Ich bin auch noch auf der Suche, wo und wie ich in dem Script einen Aufruf eines zweiten Scripts einfügen kann um eine email bzw. einen pushbullet push zu senden.

    Das manuelle senden mit Aufruf im Terminal pushbullet.sh bzw. sendmail.py funktioniert bereits einwandfrei.

    Einmal editiert, zuletzt von rmjspa (30. März 2015 um 01:30)

Jetzt mitmachen!

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