Python Script im Hintergrund und mit Cronjob

  • Hallo,

    ich habe z.B. dieses Python Script:

    Ich würde dieses Script gerne im Hintergrund ausführen. Mit Screen funktioniert das wunderbar, nur da kommt schon das nächste Problem:

    Ich will das Script mit einem Cronjob um z.B. 14:00 Uhr stoppen und um 15:00 Uhr mit einem Cronjob wieder starten. Was verwende ich für einen Befehl zum starten und stoppen des Scripts?
    init.d Dateien geben da ja auch keinen Sinn oder?

    Mfg

  • Ich habe das schon in deinem anderen Thread gesagt: das ist keine gute herangehensweise. Du solltest die Funktionalitaet so bauen, dass zwischen 14 und 15 uhr eben nichts gemacht wird, statt von aussen irgendwie auf das Programm einwirken zu wollen.

    Python hat ein tolles datetime-Modul, mit dem du Datums-Arithmetik leicht betreiben kannst.


  • Danke für deine Antwort, und sorry ich habe es auch grad gesehen. Habe seit gestern nicht mehr in den Thread gekuckt.

    Danke für dein Script ich werde es gleich ausprobieren und probieren es zu kapieren.

    Ich hatte gedacht das es mit Cronjob einfacher wäre, da ich ein absoluter Programmier noob bin und gerade mal so die Basics verstehe.

  • ich halte es - wie in dem anderen Beitrag schon erwaehnt - fuer weniger robust. Wenn du eine *gute* Loesung willst, dann musst du etwas bauen, dass sicherstellt, dass dein Skript *IMMER* laeuft - das ist ja sicherheitskritisch.

    Aber das widerspricht dann eben dem Ansatz, es "umzubringen", um den Uebungszeitraum abzudecken.

    Ausserdem ist es mit umbringen nicht getan - du musst auch noch sicherstellen, dass die GPIOs dann definierte Zustaende haben. Soll ja nicht an sein, und dann ploetztlich in der Uebung statt aus daueran.

    Damit wird das dann alles schoeeen kompliziert.

  • Ja die Zeitabfrage geht eig von der Komplexität her.

    Als Beispiel hier mein C++ Code für den Arduino:

    Zumindestens der Teil der die Torsperre steuert.

    Und wenn das Script läuft wie führe ich es dann im Hintergrund aus, ohne die SSH Konsole offen zu haben?

    Einmal editiert, zuletzt von maddig (22. März 2016 um 18:59)

  • Dazu kannst du hier im Forum eine *Menge* suchen und finden - Stichworte sind zB rc.local oder startup skripte.

  • Ja stimmt ich hab gerade nicht überlegt...

    Eine Anfänger Frage hab ich noch. Ich versuch gerade Time zu verstehen.

    Warum gibt er mir bei diesem Code bei einer Uhrzeit von 20:19 Uhr:

    Das hier aus :

    Code
    20
    20
    LAEUFT NICHT

    ich verstehe es einfach nicht. Ich lasse mir vorher die Variable ausgeben und die ist 20. In der IF Frage ich dann ob die Variable 20 ist und er sagt nein?

    Ich hoffe ihr könnt meinen Denkfehler beseitigen :D

  • Gibt es einen Grund, warum du das von mir gezeigte datetime Modul ignorierst? Das ist deutlich besser als das time-Modul, welches ich nur noch zum "schlafen" benutze - wie auch in meinem Skript. Denn es erlaubt einfaches rechnen mit Daten.

    Und unter anderem bekommst du die Daten auch so, wie du sie erwartest:

    Code
    beer:opencv deets$ python
    Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54)
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import datetime
    >>> datetime.datetime.now().hour == 20
    True

    Dein Problem ist letztlich, dass mit time.strftime einen STRING zurueckbekommst (STRingFormatTIME). Wenn du den mit 20 vergleichen willst, musst du die '20' in eine 20 umwandeln, zb mit int('20').


  • Dein Problem ist letztlich, dass mit time.strftime einen STRING zurueckbekommst (STRingFormatTIME). Wenn du den mit 20 vergleichen willst, musst du die '20' in eine 20 umwandeln, zb mit int('20').

    Andersherum oder nicht?

    time.strftime("%H") == str(20)

    oder

    int(time.strftime("%H")) == 20

  • Ok danke,
    Das datetime dass du benutzt ist irgendwie für mich als kompletter Noob sehr kompliziert und unübersichtlich.

    Habe den Link benutzt nur es gibt tausend verschiedene Möglichkeiten:

    https://docs.python.org/2/library/datetime.html
    Automatisch zusammengefügt:
    Ok hab das Prinzip mit Datum und Uhrzeit verstanden. Einfach das .hour durch z.b. .minute oder .day ersetzten.

    Wie kriege ich den Wochentag raus?

    Habe es schon mit datetime.weekday() probiert funktioniert aber nicht.

    Einmal editiert, zuletzt von maddig (22. März 2016 um 20:50)

  • weekday ist schon richtig. Was geht denn nicht?

    Code
    >>> datetime.datetime.now().weekday() == 1
    True

    0 = Montag, 1 = Dienstag etc....

    Einen bestimmten Tag einer Woche zu berechnen ist zuzugebendermassen aber ein bisschen fummelig - allerdings auch nicht weniger als mit time! Im Gegenteil.

    Wenn du fuer ein gegebenen Zeitpunkt das Datum eines bestimmten Tages berechnen willst, geht das so:

    Code
    >>> zeitpunkt = datetime.datetime.now() # halt jetzt
    >>> SAMSTAG = 5
    >>> (zeitpunkt + datetime.timedelta(days=SAMSTAG - zeitpunkt.weekday())).date()
    datetime.date(2016, 3, 26)

    Das funktioniert sogar fuer Tage, die *vor* heute sind, der Montag dieser Woche war der 21te, und das geht genauso:

    Code
    >>> MONTAG = 0
    >>> (zeitpunkt + datetime.timedelta(days=MONTAG - zeitpunkt.weekday())).date()
    datetime.date(2016, 3, 21)
  • Das ist aber nicht immer Sinnvoll. Wie zum Beispiel prüft man ob das Script in der Screensession noch läuft? Also ein Watchdog via crontab um sicherzustellen dass das Script noch läuft.

    Klar, es gibt immer mehrere Wege, aber screen ist auch nicht unbedingt immer notwendig, oft reicht es das Script mit dem Prefix " nohup " zu starten damit es im Hintergrund läuft und Ausgaben sollte man allgemein besser in Logdateien schreiben.

  • screne ist ein tolles Tool, aber in meiner Wahrnehmung ungeeignet fuer ein System wie dieses, bei dem es um Robustheit auch nach Neustart geht.

  • Ok also das mit dem im Hintergrund ausführen funktioniert mit rc.local ganz gut.

    Ich habe jetzt ein wenig mein Programm gebastelt.. Nur will es noch nicht so wie ich und ich brauche nochmal eure Hilfe.
    Die Zeitabfrage funktioniert wunderbar (danke nochmal an deets). Jedoch scheitert jetzt das Programm selber.

    Zur Situation: Bei einem Alarm geht der Eingang FME auf 1. Dann wird gecheckt ob der Masterschalter (in dem Fall ein Schlüsselschalter außen an der Steuerung) eingeschaltet ist und ob die Torsperre nicht aktiv ist. Wenn diese drei Kriterien erfüllt sind soll er die Funktion alarm ausführen.
    Die Testfunktion ist einfach nur dazu, dass man den Schalter betätigt und beide Tore zusammen hochfahren.

    Bei beiden Funktionen zieht das Relais und lässt nach einer Sekunde wieder los um den Impuls fürs Tor auszulösen. Bei der alarm ist einfach noch für das optische das Umschalten der LEDs dabei.

    Und noch was: Diese Steuerung ist nicht lebenswichtig. Man kann die Tore immer noch mit Schlüssel aufsperren, sowie es die Jahre davor auch gemacht hat. Die Arduino Steuerung ist jetzt seit ca. 1 1/2 Jahren im Einsatz und ist ein "nettes Gimmick" mit der man ein paar Sekunden spart. Wobei der Erste bei einem Einsatz sowie sehr schnell da ist und die Tore aufmacht.

    Hier mein bisheriger Code:

  • Was heisst denn "scheitert"? Wirft es einen Fehler? Und bitte formatier das richtig. Ich weiss nicht genau, was das Forum falsch macht - mein Verdacht waere Tabs nicht darzustellen - aber so ist der Code unlesbar.

  • Ok, bevor ich mich da an ein detaillierteres Debugging begebe, wuerde ich dich bitten, ein paar Dinge zu korriegieren - denn so ist das unlesbar.

    - bitte definiere und benutze Konstanten fuer die Pins. Das erhoeht die Uebersichtlichkeit massiv, und erst dann kann man logischen Fehleren auf die Spur kommen. Also ein simples

    Code
    TORSCHALTER = 15
    GPIO.setup(TORSCHALTER, GPIO.OUT)
    ...
    GPIO.output(TORSCHALTER, True)

    oder was auch immer. Denn so ist es absolut unmoeglich nachzuvollziehen, was da wann wie passieren soll

    - es gibt einen offensichlichen Fehler bei der Bestimmung von "now". Du machst das zu Beginn des Skriptes genau einmal. Womit das Skript auf ewig denkt, es lebt zum Startzeitpunkt. Das kann nicht richtig sein. Die Zeile gehoert in die Schleife, direkt vor die Bedingung die sie benutzt zB.

    - ich weiss nicht, was master_switch ist, aber er wirkt schon sehr komisch, dass etwas, das geschaltet werden soll, nur *einmal* abgefragt wird.
    - was auch immer master_switch ist, master ist immer gleich dem, was master_switch ist. master sollte also rausfliegen, und stattdessen master_switch benutzt werden. Merke: jede boolsche Variable *verdoppelt* die Menge der Programmzustaende, die du im Kopf nachvollziehen musst, um zu verstehen, was dein Programm macht. Darum so wenige davon wie moeglich - jede weniger heisst halb so viele Probleme. So grob jedenfalls :D
    - if (bedingung) ist Unsinn, bitte entferne die Klammern - and anderer Stelle machst du das nicht. Mag sich kleinkariert anhoeren, aber Code muss beim lesen gut verstaendlich sein (das probiere ich ja gerade hier - zu verstehen) - und da ist konsistenz wichtig.

  • Ok danke erstmal, oben bei #16 hab ich die Funktion mal grob beschrieben der Masterswitch ist ein Schlüsselschalter der die Steuerung deaktiviert oder aktiviert.

    Ich habe jetzt alle Pin mit Konstanten versehen.

    Bei dem tor_gros und tor_klein zieht das Relais an und lässt nach 1 Sekunde wieder los. Und als erstes kommt False weil es konvertiert ist.

    Hier nochmal die hoffentlich übersichtlichere Version
    Automatisch zusammengefügt:
    Sorry die setup sind jetzt auch noch richtig.

Jetzt mitmachen!

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