Relaistimer in python

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Liebes Forum,

    ich habe eines dieser 8-Channel-Relay Boards am Raspi, mit python kann ich jedes Relais natürlich einfach ein- und ausschalten.

    Jetzt aber folgendes Problem: An diese Relais kommen Magnetventile zur Bewässerungssteuerung. Da möchte ich die Relais für eine bestimmte Zeit einschalten, sagen wir mal 30min. Mir fällt da kein guter Ansatz ein, wenn ich in python einfach eine 30min Warteschleife einlege, kann ich in der Zeit ja keine anderen Relais anwerfen. Mehrfachaufruf des gleichen Skipts wäre ja auch blöd, da dann u.U. ein vorheriger Skripttimer das Relais vorzeitig abschaltet. Eigentlich bräuchte ich 8 Timer, die sekündlich bis auf 0 runterzählen. Wenn sie bei 0 sind, geht das Relais aus. Extern müsste man dann diese Timer irgendwie setzen können - z.B. auf 1800 für 30s.

    Habt ihr da einen Ansatz für mich ?

    Alle Suchen nach Timer laufen eher auf Zeitschaltuhren wie z.B. für Aquarien...

  • Speichre die Uhrzeit, zu der ein geöffnetes Ventil wieder geschlossen werden soll in einer Variablen und schau alle Minute mal nach, ob diese Uhrzeit bereits erreicht ist.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Danke für die Beiträge - apscheduler sieht sehr vielversprechend aus. Hab "nur" noch nicht verstanden, wie man das quasi als daemon einrichten kann - derzeit begreife ich das als Interpreter, also setzen und abarbeiten der queue in einem einzigen Skript.

    Ich bräuchte aber quasi 1 Script, das die Queue abarbeitet und ein anderes, mit dem ich jobs absetze.

  • Tja, dann hast du was falsch gemacht bzw, nicht verstanden, wie man es ein- und umsetzt.
    Ich kenne ein paar, welche eine komplette Hausautomation (Beleuchtung, Bewässerung, Schalosienen etc.) mittels APscheduler realisiert haben (professionell bzw. kommerziell). APscheduler ist meiner Meinung nach das Beste, was es in Sachen Zeitschaltung gibt.

    Edit:
    Vor allem mittels einem Mikrorahmenwerk wie Bottle oder Flask lässt sich so eine Zeitschaltung hervorragend ralisieren. Gibt sicherlich ein paar Tuts im www.

  • The Message meines Beitrags war nicht dass APscheduler schlecht wäre oder nicht funktioniert, sondern nicht ganz so trivial und einfach zu verstehen.

    //EDIT:

    Da lese ich nicht raus dass er eine UI zum einstellen der Zeiten haben will/braucht :huh:

    Sein letzter Satz sagt aus dass er zB um 18 Uhr ein Relais einschalten und 30 Sekunden später wieder ausschalten möchte.

    Man könnte das so umsetzen dass ein permanent laufendes Python-Script das jeweilige ein und ausschalten regelt und Sekündlich prüft ob es etwas zu tun gibt. Das jeweilige schalten der GPIO's blockiert ja keine Abläufe also sehe ich da eigentlich kein Problem drin mithilfe 'datetime' in einer while Schleife zu arbeiten (Beitrag#5) :s Einzig die Zeittabelle wo die Schaltzeiten drin stehen müsste man bei jedem Durchlauf der while neu einlesen - zum Beispiel aus einer SQLite Datenbank oder einer json Konfigurationsdatei - oder vorher prüfen ob sich die Datei geändert hat bevor man alles neu ausliest.

  • Bei dem Projekt scheint es ja nicht auf ein oder zwei Minuten anzukommen. Ich habe ein ähnliches Projekt mit Cronjob und Python erledigt. In einem Pythonscript kann ich in einer grafischen Oberfläche Zeiten und Aktionen eingeben. Anfangs hatte ich das in eine Datenbank schreiben lassen, nun ist es eine einfache Textdatei. Die Textdatei wird dann über Cron durch ein weiteres Pythonscript alle 2 Minuten ausgewertet und die Relais führen dann entsprechende Aktionen aus. Vorteil ist kaum Prozessorlast, Nachteil sekundengenaue Abläufe sind damit nicht drin. Wichtig ist, dass das Script am Ende wieder den Speicherplatz freigibt, aber die GPIOs nicht zurücksetzt.


  • Bei dem Projekt scheint es ja nicht auf ein oder zwei Minuten anzukommen. Ich habe ein ähnliches Projekt mit Cronjob und Python erledigt. In einem Pythonscript kann ich in einer grafischen Oberfläche Zeiten und Aktionen eingeben. Anfangs hatte ich das in eine Datenbank schreiben lassen, nun ist es eine einfache Textdatei. Die Textdatei wird dann über Cron durch ein weiteres Pythonscript alle 2 Minuten ausgewertet und die Relais führen dann entsprechende Aktionen aus. Vorteil ist kaum Prozessorlast, Nachteil sekundengenaue Abläufe sind damit nicht drin. Wichtig ist, dass das Script am Ende wieder den Speicherplatz freigibt, aber die GPIOs nicht zurücksetzt.

    Richtig, eine UI brauche ich nicht. Der Raspi mit dem Skipt soll nur diese Timer hosten.
    Eigentlich hätte ich am liebsten einfach ein Skript, dem ich per Parameter das gewünschte Relais und die gewünschte Einschaltdauer mitteilen kann, also in der Form:

    "script.py r1 180" - schaltet dann relais 1 für 180s ein. Analog soll dann "script.py r3 300" eben r3 für 5min einschalten, wobei der Timer von r1 so bleiben soll, wie er war.

    Ich versuche das gerade mit APScheduler zu daemonisieren, es ist aber tatsächlich für mich sehr komplex.


  • Eigentlich hätte ich am liebsten einfach ein Skript, dem ich per Parameter das gewünschte Relais und die gewünschte Einschaltdauer mitteilen kann, also in der Form:

    "script.py r1 180" - schaltet dann relais 1 für 180s ein. Analog soll dann "script.py r3 300" eben r3 für 5min einschalten, wobei der Timer von r1 so bleiben soll, wie er war.

    Dann mach das doch so? ;)

    Ich würde bei der Übergabe aber einfach nur den GPIO angeben, somit bliebe das Script selbst flexibel. Also in etwa so:

    Code
    /path/to/script.py <GPIO#> <sec>
    Code
    /path/to/script.py 17 180

    [code=php]
    from __future__ import print_function
    import time
    import sys
    from RPi import GPIO

    try:
    gpio_pin = int(sys.argv[1])
    runtime = float(sys.argv[2])
    except IndexError:
    print("Error... Usage: {0} <GPIO#> <sec>" . format(sys.argv[0]))
    sys.exit(1)

    print("OK. Switching GPIO-%s HIGH for %s sec" % (sys.argv[1], sys.argv[2]))

    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(gpio_pin, GPIO.OUT)
    GPIO.output(gpio_pin, True)
    time.sleep(runtime)
    GPIO.output(gpio_pin, False)
    [/php]

  • Ja, aber dann habe ich ja das Problem der Überlappung. Mal angenommen, es kommt "script.py 17 180"

    der GPIO zieht an und wartet.

    Jetzt kommt nach 120s ein neuer Aufruf "script.py 17 180" - dann sollte #17 ja angezogen bleiben, würde dann aber aufgrund des ersten Aufrufs nach 1min abfallen.


  • Ja, aber dann habe ich ja das Problem der Überlappung. Mal angenommen, es kommt "script.py 17 180"

    der GPIO zieht an und wartet.

    Jetzt kommt nach 120s ein neuer Aufruf "script.py 17 180" - dann sollte #17 ja angezogen bleiben, würde dann aber aufgrund des ersten Aufrufs nach 1min abfallen.

    Aber warum sollte das passieren? Du stellst doch den Crontab ein und somit sind die Aufrufe nicht willkürlich :s


    PS: Bitte nicht Beiträge vollständig quoten/zitieren, vor allem wenn diese genau da drüber stehen.

  • Ja, aber nicht manuell - sondern über andere Skripte. Die messen z.B. alle 15min die Bodenfeuchtigkeit. Ist diese zu gering, wird für 180s gepieselt. Leider ist die Verbindung per Funk - d.h. es kommen auch mal für Stunden keine Werte. Das macht aber nix, denn die Funkverbindung ist zumindest so gut, dass ich ein paar mal am Tag Werte bekomme, das reicht.

    Darüberhinaus kann man aber auch manuell die Beregnung starten, mit Knöppchen.

    Startest du manuell die Beregnung und kommt dann zufällig in der nächsten Minute das entprechende Signal von der Automatik, hast du quasi die Willkürlichkit.

  • Dann brauchst du 2 Scripts

    - "Main.py" => permanent laufendes, welches entsprechend Beitrag#5 die GPIO's schaltet und einen SocketServer beinhaltet.
    - "action.py" => was du beliebig aufrufen kannst und sich dann via Socket zum Main.py verbindet.

    Wenn action.py so wie du beschrieben hast 2x den selben GPIO schalten möchte prüft Main.py ob der GPIO bereits aktiv ist und verwirft in solch einem Fall die Anfrage dann.
    Alternativ ginge statt Socket auch ein Queue-Server wie Beanstalkd

Jetzt mitmachen!

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