Programm zeitabhängig machen

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo

    Ich möchte eine Steuerung machen, die abhängig ist von der aktuellen Tageszeit. Ich will dass z.B. genau nach 3h ein Ausgang geschaltet wird. Oder dass das Programm die Tageszeit erkennt und so am Tag andere Parameter verwendet als in der Nacht.

    Wie kriege ich das am besten hin? Bietet das Raspberry so eine Funktion an? oder brauche ich da externe Zeitinformationen?

    Danke für die Hilfe und Gruss
    Ruben

  • Hallo Ruben,

    wenn es sich immer um die gleichen Zeiten handelt, dann kommst Du mit

    Code
    cron

    weiter.

    Dies hilft Dir aber nur dann, wenn der Raspberry Pi die ganze Zeit läuft - oder Internet-Zugang hat, um seine interne Zeit abzugleichen.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Forumsuche nach: crontab
    1.Treffer

    Dies hilft Dir aber nur dann, wenn der Raspberry Pi die ganze Zeit läuft - oder Internet-Zugang hat, um seine interne Zeit abzugleichen.

    Solange der PI dann läuft wann es ausgeführt werden soll, muss er nicht 24/7 laufen :fies:
    Könnte er zB durch eine Steckdosen-Zeitschaltuhr erreichen indem der Pi 5 Minuten vorher gestartet wird, nach seiner Aktion heruntergefahren und wieder abgeschaltet wird..

  • crontab führt nur etwas aus. Was das Script letztlich macht ist crontab egal.

    Das was du nun fragst hat also etwas mit dem Script selbst zu tun. Man kann die Zeit speichern, ja. Man kann auch im Script eine Art Stopuhr einbauen. Man kann auch eine Art Timer programmieren um einen GPIO erst nach einer gewissen Zeit auszuführen. Man kann so vieles....

    Der PI soll die ganze Zeit laufen?
    Soll das Script auch die ganze Zeit laufen? Oder soll crontab einfach nur zu einer bestimmten Uhrzeit etwas ausführen? Ein Script, oder mehrere Scripte, oder ein Script mit entsprechendem Parameter aufrufen?

  • Ja das Raspberry soll dauernd laufen. Ich möchte eine erkennung der Bewegung in einem Raum machen mit sensoren.
    Wenn lange keine Bewegung erkannt wird, soll eine mail an mich verschickt werden. Ich könnte so z.B. erkennen wenn eine ältere Person im Raum gestürzt ist und Hilfe braucht..

    Deshalb glaube ich ist es am besten wenn ich die Zeit speichere, in der das letzte Signal am GPIO pin auftritt. Wenn dann lange genug nichts passiert, soll die Mail verschickt werden.
    Ich weiss nicht genau wie ich das am besten aufbauen kann. kannst du mir ein paar tipps dazu geben?

  • Dann mach einen Crontabeintrag der ein Script jede Minute ausführt

    Code
    * * * * * /usr/bin/python /path/to/script.py

    Und im Script lässt du dann eine Zeit in eine temporäre Datei schreiben, welche aber auch ausgelesen und mit der aktuellen verglichen wird. Am einfachsten geht das imho mit der UNIXTIME, das ist eine standardisierte Zeitmessung, die Sekunden die seit dem 1.1.1970 vergangen sind. Anhand dessen kannst du einfach ausrechnen wie viel Zeit vergangen ist.

    [code=php]
    import time, os

    timeFile = "/tmp/lastimestamp"
    maxDiff = 90 #in sekunden

    def getLastTime():
    with open(timeFile, 'r') as file:
    timestamp = file.readline()
    return timestamp

    def writeLastTime(zeit):
    with open(timeFile, 'w') as file:
    file.write(zeit)

    if os.path.isfile(timeFile):
    lastTime = float(getLastTime())
    if time.time() - lastTime >= maxDiff:
    print "Letzter Zugriff ist zu lange her {}".format( time.asctime( time.localtime( lastTime ) ) )

    # nur ausfuehren wenn Bewegung....
    writeLastTime( str(time.time()) )

    [/php]

  • Ich habe versucht einen crontab eintrag zu machen genau wie du beschrieben hast mit crontab -e

    Danach die Zeilen dort zuletzt eingefügt:

    * * * * * /home/pi/helloworld.py
    #------------------------------

    und abgespeichert. Jetzt sollte doch das helloworld.py jede Minute ausgeführt werden oder?
    Hat aber leider nicht funktioniert.. :s
    Auch nicht mit
    [i]* * * * * /usr/bin/python /home/pi/helloworld.py

    Die Angabe die du gemacht hast mit /usr/bin/python wird doch nur gebraucht bei einer System Crontab oder?

    Oder muss ich noch irgendwas installieren vorher?

    • Offizieller Beitrag

    Woher weisst du das es nicht funktioniert?
    hast du schonmal in

    Code
    /tmp/lastimestamp

    reingeschaut? oder wird die Datei gar nicht erst erstellt?

    Code
    * * * * * /usr/bin/python /home/pi/helloworld.py


    Diese Version ist notwendig, da dein Script keine Shebang enthällt und du ihm somit den Interpreter manuell übergeben musst.

    Die Erstere Variante erwartet eine ausführbare Datei + Shebang.

  • Hallo dbv, ich wollte zuerst das helloworld.py file zum testen ausführen.
    Da wird einfach "hello world" in die konsole ausgegeben.
    Erst danach wollte ich das mit dem lasttimesramp machen.
    Aber ist nichts passiert in der Konsole..? das file funktioniert sonst aber

    • Offizieller Beitrag

    Es funktioniert auch, nur gibt er das "Hello World" nicht deiner aktuellen Console aus, sondern irgendwo in einer virtuellen. Cron ist auch nicht dazu da um Bildschirmausgaben zu machen.
    Wenn du deinen cron so umschreibst

    Code
    * * * * * /usr/bin/python /home/pi/helloworld.py >> /home/pi/crontest.log


    Wirst du sehen das in /home/pi plötzlich eine Datei namens crontest.log enhällt. Und wenn du diese per

    Code
    cat /home/pi/crontest.log

    anschaust, wirst du sehen das jede Minute ein "Hello Word" mehr drin steht ;)

  • Ach soo, ja jetzt hats geklappt, vielen dank :)

    Ich hab jetzt den GPIO Input welcher vom Sensor kommt auch in dieses File eingefügt mit einer if abfrage:

    Code
    # nur ausfuehren wenn Bewegung....
    if (GPIO.input(sensor) == True):
    	writeLastTime( str(time.time()) )

    Somit wird aber leider nur exakt zu jede vollen Minute einmal überprüft, ob ein Signal da ist.

    Wie mache ich das am besten, wenn ich will das sie Signale jederzeit registriert werden und nicht nur wenn sie genau zur vollen minute da sind?
    Mache ich da am besten ein eigenes file mit dem GPIO status drin der letzten minute, welches dann auch ausgelesen werden kann von diesem Skript zu jeder vollen minute? oder geht das einfacher?

    Danke für eure Hilfe
    Gruss Ruben

  • hier das skript test.py


    Hmm was gäbe es denn für alternativen?

    Es müsste jetzt nur noch der Sensor zu jeder Zeit erkannt werden, da es sein kann dass das Signal nur einige Sekunden auftritt. Es reicht dann aus, wenn sein Zustand nur jede Minute mit diesem Skript ausgewertet wird.

    sorry, sollte wohl nächstes mal "php und /php" verwenden :wallbash: :)

    Einmal editiert, zuletzt von Ruben89 (16. März 2015 um 11:53)

    • Offizieller Beitrag

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

    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(22,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    sensor = 22

    timeFile = "/tmp/lasttimestamp"
    maxDiff = 90 #in sekunden

    def getLastTime():
    with open(timeFile, 'r') as file:
    timestamp = file.readline()
    return timestamp

    def writeLastTime(zeit):
    with open(timeFile, 'w') as file: # with open, weil schliesst so automatisch
    file.write(str(time.time()))


    # nur ausfuehren wenn Bewegung....
    GPIO.add_event_detect(22, GPIO.RISING, callback=writeLastTime)
    while True:
    if os.path.isfile(timeFile):
    lastTime = float(getLastTime())
    if time.time() - lastTime >= maxDiff:
    print "Letzter Zugriff ist zu lange her {}".format( time.asctime( time.localtime( lastTime ) ) )
    time.sleep(60)[/php]

    Das könnte so klappen. Ich würde das Teil in nem Screen starten. Dann kannst du dich immer wieder hinconnecten und siehst auch deine Printausgabe

  • Da war wohl jemand nicht so aufmerksam :D

    2x das Module 'time' importieren :-/ 'signal' wird in diesem Fall auch nicht mehr gebraucht.
    Es wird zwar eine Variable sensor = 22 gesetzt aber nicht verwendet :s
    Die Übergabe des callback's ist keine 'zeit' sondern der pin des events, also def writeLastTime(zeit): ändern in def writeLastTime(pin):
    Und eine paar Einrückungen sind etwas anders als die anderen ;) Ich nutze gerne 2 Leerzeichen, aber der Übersichtshalber wären TABs besser und entsprechen 8 Leerzeichen. Ich änder das mal ;)

    Die Schleife wird jede Minute ausgeführt, was Oke ist, aber wenn man das ändern will wärs schöner nur im oberen "setup"-Bereich etwas verändern zu müssen :fies:

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

    sensor = 22
    timeFile = "/tmp/lasttimestamp"
    maxDiff = 90 #in Sekunden
    checkEvery = 60 #in Sekunden

    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(sensor, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

    def getLastTime():
    with open(timeFile, 'r') as file:
    timestamp = file.readline()
    return timestamp

    # nur ausfuehren wenn Bewegung....
    def writeLastTime(pin):
    with open(timeFile, 'w') as file: # with open, weil schliesst so automatisch
    file.write(str(time.time()))
    GPIO.add_event_detect(sensor, GPIO.RISING, callback=writeLastTime)

    while True:
    if os.path.isfile(timeFile):
    lastTime = float(getLastTime())
    if time.time() - lastTime >= maxDiff:
    print "Letzter Zugriff ist zu lange her {}".format( time.asctime( time.localtime( lastTime ) ) )
    time.sleep(checkEvery)
    [/php]

    Also durch den Interrupt (add_event_detect) wird die callback jedes mal ausgeführt sobald ein RISING erkannt wurde, also eine Zustandsänderung des angegeben GPIO's von LOW auf HIGH. Das schreibt dann jedesmal den neuen Timestamp in die Datei.
    Die while Schleife ist davon unabhängig - der Interrupt wird in einem separaten Thread ausgeführt, das Script selbst ist ebenfalls ein Thread - und prüft 'checkEvery' Sekunden ob 'lastTime' länger her ist als 'maxDeff', falls ja wird die print Zeile ausgeführt. Das könnte man dann noch mit einer Funktion zum EMail Versand kombinieren.

    Was noch fehlen würde wären ein paar try und except's sowie ein GPIO.cleanup() am Ende des Scripts.

  • Ihr seid super!! :)

    Sehe ich das richtig, dass jetzt dieses Skript nicht mehr in Verbindung steht mir der crontab?
    Jetzt macht das checkEvery dass die Abfrage jede Minute passiert oder?

    Ich hab da noch ein paar grundlegende Fragen zum ganzen: :s

    Wenn ich mit der crontab das skript jede minute aufrufe und in dem skript eine enlosschleife wie "while True" drin habe, wird dann jede minute ein neuer Thread eröffnet, weil die alten ja noch in der while schleife hängen und nicht beendet werden?

    Und sehe ich das richtig, dass der Interrupt nur erkannt werden kann, wenn das Skript (Thread) gerade ausgeführt wird?

    Danke nochmals für eure Unterstützung!

Jetzt mitmachen!

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