Zeitschaltuhr für Relais

  • Hallo Leute,


    ich bin neu hier im Forum. Ich bin 36 Jahre alt und habe hin und wieder mal mit Programmierungen zu tun gehabt.
    Habe es aber leider nie richtig gelernt.


    Nun zu meinem Projekt mit meinem Raspberry. An meinem RPi ist ein Relaisboard mit 8 Relais angeschlossen. Dieses wird derzeit mittels Webinterface angesteuert und kann nur an oder aus. Es dient nachher zur Bewässerung meines Gartens.


    Mein Ziel:
    Für 4 Kanäle eine eigene Zeitschaltuhr zu programmieren und per Webinterface weiterhin die Relais anzusteuern.


    Ich habe die index.php Datei angehängt in der ich die Zeitschaltuhr mit integrieren möchte.


    Die timer.py habe schon mal leicht auf ungefähre Zeiten abgeändert. Leider kommt bei den curr.time usw Zeilen immer ein Fehler.
    Dort weiß ich leider nicht weiter.


    Ja ich habe die Suchfunktion benutzt, aber leider kein passendes Projekt gefunden.


    Vielen dank schon mal im Vorraus.


    Mit freundlichen Grüßen
    Fahne

    Files

    • index.php

      (5.97 kB, downloaded 389 times, last: )
    • timer.py

      (5.42 kB, downloaded 592 times, last: )
  • hmm komisch,


    ich sehe in der PHP Buttons, ich sehe Phyton Code


    Was ich nicht sehe ist eine Fehlermeldung, wenn du die zeigen würdest könnte man evtl. was erahnen obwohl ich Python nicht kenne.

    lasst die PIs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • Hallo Fahne.


    In der Datei fehlen bei der Python datei die Einrückungen.
    Ist das im Originalscript ebenfalls der fall?


    kurzer Auszug:
    [code=php]
    while True:


    # get the current time in hours, minutes and seconds
    currTime = datetime.datetime.now()
    # get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
    currDay = datetime.datetime.now().weekday()
    [/php]


    richtig müsst das so stehen


    [code=php]
    while True:
    # get the current time in hours, minutes and seconds
    currTime = datetime.datetime.now()
    # get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
    currDay = datetime.datetime.now().weekday()
    [/php]


    Gruss Dani

  • es fehlen nicht nur Einrückungen ...
    So abgeändert kommt keine Fehlermeldung bei mir. Das #print "Start"# habe ich nur eingefügt um eine Ausgabe an der Konsole zu haben, kannst wieder rauslöschen.


  • Wenn ich "$val = trim(@shell_exec()" sehe krieg ich jedes mal nen Brechreiz....


    Ich würde dir dazu raten weder PHP noch apache&co zu verwenden sondern direkt alles über Python zu machen: FAQ => Nützliche Links / Linksammlung => [Python] Webserver, Websocket und ein bisschen AJAX
    Dein HTML Code kannst du weiter verwenden, nur der PHP Code muss in Python übersetzt werden.


    Zeitschaltuhr kannst du dann ebenfalls über Python regeln und zB bestimmte URL's aufrufen um ein Relais zu schalten.


    Die timer.py würde ich aber auch anders schreiben - wie zB der Anfang mit den "Mon1 bis Mon3" Einträgen... Da würde sich eine Liste pro Tag anbieten.


    Einrückungen sind für Python extrem wichtig - aber auch in HTML/PHP ist es sinnvoll welche zu haben um die Lesbarkeit zu steigern.

  • Hallo Leute,
    danke für die schnellen Antworten.
    Die komische schreibweise meiner PHP Datei habe ich aus einem Tutorial einer anderen Seite entnommen.
    Habe es dann nur erweitert.


    Das timer.py Script funktioniert jetzt schon mal. :bravo2: :bravo2: :bravo2:
    Zumindest die erste Schaltzeit und dann passiert leider nichts weiter.
    Er zeigt den Schriftzug
    Start an und Schaltet zur besagten 1. Zeit ein und aus. Allerdings schaltet er die 2. Zeit nicht.


    Hatte ich schon erwähnt, dass mein Relaisboard bei Level Low die Relais schaltet. :blush: :blush: :blush: :blush:


    Danke für den Hinweis mit dem Einrücken.



    Vielen dak für Eure Hilfe. :danke_ATDE: :danke_ATDE: :danke_ATDE: :danke_ATDE:

  • Kanns sein, dass in currDay eine 0 steht, weil heute Montag ist? Und du deshalb immer nur den nullten Eintrag in deiner Zeitenliste vergleichst?


    Müsstest du nicht mit ner Schleife durch das ganze Array hecheln und schauen, ob eine der Zeiten übereinstimmt?


    Hab gerade Essen auf dem Herd und nur kurz drüber geflogen... sorry, falls ich totalen Bockmist erzähle. :blush:

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

    Edited once, last by Gnom ().


  • Die komische schreibweise meiner PHP Datei habe ich aus einem Tutorial einer anderen Seite entnommen.


    Wenn du unbedingt bei PHP usw bleiben willst dann mach es lieber so wie hier beschrieben:
    FAQ => Nützliche Links / Linksammlung => PHP: Anleitung zum schalten von GPIO


    Hatte ich schon erwähnt, dass mein Relaisboard bei Level Low die Relais schaltet.


    Das liegt an Pull-Up/Down... Siehe dazu => GPIO mit Pullup- oder Pulldown-Widerstand beschalten?



    Das timer.py Script funktioniert jetzt schon mal.
    Zumindest die erste Schaltzeit und dann passiert leider nichts weiter.
    Er zeigt den Schriftzug
    Start an und Schaltet zur besagten 1. Zeit ein und aus. Allerdings schaltet er die 2. Zeit nicht.


    Bitte poste das korrigierte und aktuelle Script - wo die Einrückungen passen.

  • Hier einmal die geänderte Datei.
    Bei dieser funktioniert die 1. An und Ab Schaltung.

    Files

    • timer.py

      (5.45 kB, downloaded 275 times, last: )
  • Das ist der Code aus Beitrag#5


    Wo hast du das Konstrukt denn her? Was diente dir als Vorlage für die "datetime.time(hour=23,minute=25,second=0)" Zeilen usw?


    Woher sind die ganzen Kommentarzeilen?
    ....die ich by the way ziemlich störend finde.. das reicht völlig: http://codepad.org/OdUQuH1i


    Davon abgesehen wird das wie gesagt So nicht funktionieren, da zum Beispiel "currDay" am heutigen Tage "1" enthält aber OnTime[currDay] somit nur "Mon2On" prüfen würde, nicht aber "Mon1On" oder "Mon3On"

  • Bei der Gelegenheit: Ich hab mich gefragt, ob man nicht eine Art zeitgesteuerten Interrupt definieren kann, der alle Minute (oder auch alle 5 oder 10 Minuten) eine Routine aufruft, die auf Schaltbefehle prüft. Das muss man ja nicht in einer wie irre umlaufenden Schleife machen.
    Google hat mir nicht viel geholfen. Im Python gibts wohl ein threading.timer, mit dem man Routinen zeitversetzt aufrufen kann. Damit könnte man sowas ähnliches machen.
    Ansonsten hab ich ein "Twisted python framework" gefunden, das wohl nicht in Python läuft, sondern auf einer tieferen Systemebene. Wenn ich das richtig verstehe, erlaubt es sogar, dass das System zwischen den "Timer-Interrupts" in den Sleep-Modus geht.
    Auslösung von Routinen in definierbaren Zeitabständen fände ich in vielen Fällen sehr praktisch. Bei der Gartenbewässerung würden 10 Minuten-Abstände ja völlig reichen. Dazwischen kann das System andere Dinge machen oder schlafen...


    meigrafd, du weißt doch bestimmt, was es da für Möglichkeiten gibt.
    Automatisch zusammengefügt:[hr]
    Also, ich seh das so:
    currDay = datetime.datetime.now().weekday() holt dir den heutigen Wochentag - also "0" für Montag (seit ner Stunde "1" für Dienstag.
    if (currTime.hour - OnTime[currDay].hour == 0 and ... vergleicht die aktuelle Stunde mit OnTime[0].hour (bzw. jetzt (Dienstag) mit OnTime[1].hour. Du müsstest aber alle von OnTime[0].hour bis OnTime[99].hour durcharbeiten und schauen, welcher passt. Da fehlt ne Schleife von 1 bis 99 (so viel wie du halt Einträge hast). Und currDay als Index funktioniert nicht.


    Die erste hat zufällig funktioniert, weil Montag = 0. Im Moment müsste die zweite Funktionieren, weil jetzt Dienstag ( = 1 ) ist.


    Oder steh ich auf dem Schlauch?

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

    Edited once, last by Gnom ().


  • Bei der Gelegenheit: Ich hab mich gefragt, ob man nicht eine Art zeitgesteuerten Interrupt definieren kann, der alle Minute (oder auch alle 5 oder 10 Minuten) eine Routine aufruft, die auf Schaltbefehle prüft. Das muss man ja nicht in einer wie irre umlaufenden Schleife machen.
    Google hat mir nicht viel geholfen. Im Python gibts wohl ein threading.timer, mit dem man Routinen zeitversetzt aufrufen kann. Damit könnte man sowas ähnliches machen.


    meigrafd, du weißt doch bestimmt, was es da für Möglichkeiten gibt.


    Ja ;)
    Ich würde hier aber auch eher den Weg über crontab gehen da das zuverlässiger ist und das Python Script somit nicht permanent laufen müsste - denn dafür bräuchte man dann ggf auch noch einen watchdog um sicherzustellen dass das Script wirklich permanent läuft (evtl. crasht es mal und dann passiert nichts mehr)


    threading.Timer() mag ich aktuell nicht mehr so gerne da das bei vielen Timern ein Memory-Leak zur Folge haben kann, also ein anschwellen des verbrauchten RAMs und irgendwann crasht das Script. Hatte es auch mit "apscheduler" usw probiert aber das ist recht umständlich und nicht so wirklich toll. Siehe dazu > hier <


    Also, ich seh das so:
    currDay = datetime.datetime.now().weekday() holt dir den heutigen Wochentag - also "0" für Montag (seit ner Stunde "1" für Dienstag.
    if (currTime.hour - OnTime[currDay].hour == 0 and ... vergleicht die aktuelle Stunde mit OnTime[0].hour (bzw. jetzt (Dienstag) mit OnTime[1].hour. Du müsstest aber alle von OnTime[0].hour bis OnTime[99].hour durcharbeiten und schauen, welcher passt. Da fehlt ne Schleife. Und currDay als Index funktioniert nicht.


    Die erste hat zufällig funktioniert, weil Montag = 0. Im Moment müsste die zweite Funktionieren, weil jetzt Dienstag ( = 1 ) ist.


    Oder steh ich auf dem Schlauch?


    2 Doofe ein Gedanke :fies:


    //EDIT:


    ich würds mit ner verschachtelten Liste probieren, in etwa so:



    Die Zahl am Anfang ist das Index und entspricht currDay:

    Code
    >>> currTime = datetime.datetime.now()
    >>> currDay = currTime.weekday()
    >>> OnTime[currDay]
    [datetime.time(8, 10), datetime.time(12, 10), datetime.time(18, 10)]
    >>>

    :daumendreh2:

  • Interessant. Das werd ich mir mal in Ruhe zu Gemüte führen.
    Und dieses "Twisted python framework" schau ich mir auch mal an. Klingt jedenfalls auch gut.

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

  • Hallo,


    das in einem dauerlaufenden Skript zu machen halte ich auch für Quatsch. Besser ein paar systemd Timer Units schreiben (oder wer bei systemd noch nicht angekommen ist kann's auch per Cron machen ;-) ).


    Fahne: deine Variblen-Bezeichnung sind irreführend. In den Schaltzeiten sind die Wochentage enthalten - der Wert enthält aber nur eine Zeit, keinen Wochentag. Außerdem sind da bergeweise Wiederholungen drin, das ist unschön. Dann lieber jede Zeit, die die brauchst, 1x definieren und für die verschiedenen Tage in Tupeln zusammenfassen.


    Außerdem schreibt man Variablen in Python klein_mit_unterstrich.


    Gnom:

    Quote

    Ansonsten hab ich ein "Twisted python framework" gefunden, das wohl nicht in Python läuft, sondern auf einer tieferen Systemebene.


    Der Satz ist ja auch... unsinnig. Ohne Python läuft Twisted nicht, weil Twisted _für_ Python geschrieben ist. Was nicht ausschließt, dass einige Submodule in C umgesetzt sind, die ggf. direkt auf low-level Funktionen des OS zugreifen.


    Wozu hier Twisted ins Spiel gebracht wird erschließt sich mir hier auch so gar nicht - Twisted ist für die Event-getriebene (Netzwerk-) Programmierung mit Python. Im gegebenen Fall gibt's aber keine Events, auf die man reagieren müsste.


    Gruß, noisefloor

  • Im vorliegenden Fall ist systemd sicher eine eine schlanke Sache. Es mag aber Fälle geben, wo man die Zeitsteuerung innerhalb von Python lösen will, dann ist Fahnes Idee - zumal für einen Einsteiger - ja erstmal ganz ok.
    Um die Vergleiche zu vereinfachen, könnte man die Zeiten auch als selbst definierte Zahlengröße hinterlegen Für Di, 8 Uhr 30 zum Beispiel 10830 also im Format WHHMM - die Vergleichsgröße lässt sich aus der aktuellen Zeitinformation leicht bilden und man muss nicht Tag, Stunde und Minute einzeln vergleichen.


    Twisted python framework hatte ich so verstanden, dass man damit sehr gut Funktionen in regelmäßigen Zeitabständen auslösen kann, ohne das System mit Schleifen zu belasten. Natürlich liegt es irgendwie unter Python. Was ich meinte ist, dass es nicht einfach nur die gleiche ressourcenfressende Schleifenorgie in einer Python oder C-Bibliotheksroutine vor den Augen des Programmierers verbirgt, sondern die Zeitsteuerung effizient von einer tieferen Ebene aus bereitstellt. Dass es ohne Python läuft, hab ich nie gesagt. noisfloor, du magst dich da besser auskennen, aber besonders charmant ist es nicht, wenn du Beiträge von anderen so brüsk als Unsinn und Quatsch bezeichnest. Was ich zu Twisted Python schrieb, war vielleicht nicht exakt ausgedrückt, aber deinem Beitrag entnehme ich, dass du ganz gut verstanden hast, was ich meinte. Da musst du dann bei der Formulierung nicht in den krümeln suchen. Es geht doch mehr um die Sache. Kann man damit sozusagen Timer-Events auslösen? Dann tut es das, was ich mir vorstelle.

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

  • Danke für die vielen Antworten.


    Die Anfänge habe hier her. Webinterface und An / Aus


    Das Timer Script habe ich auch in irgendwelchen Projekten gefunden.
    Ich hatte halt nach Python gesucht da ich dieses bereits installiert hatte.
    Ich habe diese dann so wie ich mir das gedacht habe erweitert. Leider doch wohl mit den falschen gedanken.


    Mir ist es eigentlich egal mit was ich das ganze realisiere.


    Ich möchte:
    Webinteface mit Schaltflächen > Ein / Aus / Programm / vielleicht noch 30 min
    Programm soll eine Zeitschaltuhr für jeden Kanal haben
    30min soll eine Zeitvorgabe sein von 30min Aktiv


    Was für ein Programm ich nehme ist mir denke ich noch egal. Sollte halt nur nicht allzu kompliziert sein.


    Den Crontab werde ich mir heute noch anschauen.


    Danke für die Hilfe.

  • Mit was willst du denn denn die Webanbindung machen? PHP oder direkt in Python?


    Ich denke nicht, dass es egal ist, welches Programm du nimmst. Die Webanbindung lässt sich für Einsteiger eher mit PHP machen, da gibts reichlich Stoff im Internet. Steuerung der Relais würde ich dann eher über Python machen. Die reinen Zeitsteuerungen über systemd/Cron. Wenn du aber die Programmzeiten auch über die Webanwendung verwalten willst, wird es vielleicht etwas komplizierter.

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

  • Ich würde das wie gesagt lieber alles mit Python umsetzen - insbesondere dann wenn Er weder PHP noch Python gut kann und sowieso Python lernen muss, denn warum sollte er jetzt 2 bzw 3 Sprachen lernen?
    Weg über apache2: HTML, PHP, Python und ggf noch JavaScript.
    Weg über Python: HTML, Python und ggf noch JavaScript.


    Ein Web-Interface mithilfe von bottle ist schnell umgesetzt. HTML kann er dort weiter verwenden. Die "button"s lassen sich auch sehr einfach in bottle integrieren und mehr brauch er ja eigentlich erst mal nicht.
    Wenn er dann noch quasi in Echtzeit den Status der GPIOs anzeigen möchte geht das im selben Python Script ebenfalls sehr einfach und wenn man sich sicher ist dass das eine Script gut läuft kann man da sogar auch noch den Scheduler für die Relais integrieren - all in one.
    Über bereits erwähnte Anleitung finden sich mehrere Beispiele mit Codevorlagen.