scripts parallel ausführen

  • Hallo Experten,

    habe mit einem RPiZero, einem Photosensor TSL2561 und 3 Relais eine Lichtsteuerung für 3 Leuchtkörper für wenn abwesend gebaut.

    Die Steuerung bzw. das Script wird durch Einschalten des RPi initiiert mittels Eintrag in </etc/rc.local> . Das folgen Script schaltet

    2 der 3 Leuchtkörper zu variablen Zeiten nachdem der Lichtwert (Visible) unter einen gesetzten Wert (75) gefallen ist:

    https://github.com/luemar/lights_…b/main/licht.py

    Den 3. Leuchtkörper wollte ich zu festen Zeiten mit einem Eintrag unter </etc/crontab> schalten, das passiert aber nicht.

    Ich nehme an, dass dieser Eintrag ignoriert wird währen das obige Script läuft.

    Frage: Kann ich das Problem lösen indem ein Script im Hintergrund läuft ? Wie ginge das ?

    Abgesehn davon könnte ich die Steuerung des 3 Leuchtkörpers ins obige Script einbauen, aber mich interessiert primär ob der
    RPi mit mehreren Scripten parallel umgehen kann.

  • * Wenn der Raspi unter Linux laeuft kann er problemlos mit mehreren parallelen Scripten umgehen.

    * cron ist ein unabhängiger Prozess der ebenfalls parallel laeuft.

    => Ein Problem koennte gpiozero sein. Wenn das die Schnittstelle exklusiv belegt kommen andere Prozesse nicht dran.

    Wenn das der Fall ist muesste der zweite Prozess einen Fehler produzieren.

    Das Problem koennte mit einem Prozess geloest werden der die Schnittstelle unter sich hat und von den anderen

    Prozessen gesteuert wird. Moeglich waere eine Kommunikation ueber Sockets und Message Queues, eventuell auch

    eine Named Pipe.

  • Beitrag von SteepBrook64153 (30. April 2021 um 20:44)

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • Hallo,

    ich denke auch, dass gpiozero mit dem Standardbackend (RPi.GPIO) nicht mehrere Instanzen zulässt. Lt. diesem Thread sollte / könnte es funktionieren, wenn du gpiozero mit der pigpio Pin Factory nutzt. Ist in der Doku von gpiozero erklärt.

    Oder du nutzt halt den von Tell vorgeschlagenen Ansatz.

    BTW:

    * /etc/rc.local ist veraltet, Stand der Dinge zum Starten ist eine systemd Service Unit

    * statt eines Cronjobs kannst du auch eine systemd Timer Unit verwenden. Hat den Vorteile, dass a) die Timer flexibler sind und b) du das Logging nach journald von systemd "gratis" dazu bekommst

    Gruß, noisefloor

  • Beitrag von SteepBrook64153 (1. Mai 2021 um 20:20)

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • Hallo Kai :wink:

    Mr. Selbstdarsteller hier :shy:

    Von oben nach unten:

    Eine Funktionsname soll beschreiben was eine Funktion macht und nicht welcher Datentyp von der Funktion zurück gegeben wird.

    Der Name 'jetzt_zeit' ist auch unnötig, du kannst sofort die Zeit zurückgeben.

    Zu was die default-Werte in 'check_zeit'? Kommt es vor, das keine Start- bzw. Stopzeit übergeben wird? Wenn wir schon dabei sind, eine einheitliche Sprache wäre auch angenehmer zu lesen.

    Die Überprüfung ob nach dem Typ String ist auch überflüssig, da du ja Strings übergibst. Auf dem Weg vom Aufruf bis in die Funktion ändert sich der Datentyp nicht.

    'zw_start' und 'zw_stop' sind auch nichts-sagende Namen, das sollte man ändern.

    'if'-Abfragen benötigen keine Klammern.

    'wert' sagt gar nichts über den Sinn der Variable aus.

    Auf Modulebene steht nur Code, der Konstanten, Funktionen oder Klassen beschreibt.

    Da du gerne Texte liest, habe ich auf den Beispielcode verzichtet.


    Puh, das tat mir und meiner Selbstdarstellung richtig gut. Man bin ich toll 8)

    Edit: Sorry an den TE, aber keine Sorge ich werde hier nicht weiter antworten.

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Beitrag von SteepBrook64153 (1. Mai 2021 um 21:00)

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • @Kai_aus_der Kiste Ergänzend zur Antwort von Dennis89:

    Bei `str_time` kann man nicht nur die lokale Variable weg lassen, sondern mit `functools.partial()` auch gleich noch die Funktionsdefinition:

    Python
    str_time = partial(strftime, "%H:%M:%S")

    Ich weiss nicht was Du hier mit „unterschiedlichen Weisheiten“ sagen willst, aber man prüft in einer Programmiersprache mit „duck typing“ keine Typen, und schon mal gar nicht mit `type()` und ``==``. Damit verbaust Du Dir hier völlig ohne Not das jemand etwas übergibt was kein `str` ist, sich aber passend verhält, und sogar von `str` abgeleitete Typen die sich ziemlich sicher passend verhalten, sind aussen vor.

    Und wenn man schon Wert auf Prüfung der Argumente legt ist es komisch dass dann einfach so zu schlucken das der Aufrufer keine Chance bekommt das auch zu erkennen. Denn an einem `False` als Rückgabewert sieht man ja nicht ob das nun wegen eines Arguments ist, dass unpassend ist, oder ob die Argumente okay sind, aber die aktuelle Zeit nicht dazwischen liegt. Man würde da bei Typprüfung einen `TypeError` und bei ungültigen Werten einen `ValueError` erwarten.

    Wenn man dieses erste ``if`` heraus nimmt, wird man bei unpassenden Werten aber sowieso eine Ausnahme bekommen. Andererseits ist es auch komisch das Du den Typ unbedingt auf `str` festnageln willst und die Länge unbedingt 5 Zeichen sein muss, aber auf der anderen Seite Werte wie "99:99", "9:999", "999:9", oder gar "-99:9" oder "-9:-9" von der Funktion verarbeitet werden als wären die nicht ausserhalb des Wertebereichs.

    Ohne Klammern kommt keine andere Logik heraus. Die sind hier redundant. ``and`` bindet stärker als ``or``:

    Die ganzen ``and``\s sind aber sowieso besser lesbar und kompakter durch verkettete Vergleiche ausgedrückt:

    Python
            if jetzt >= 0 and jetzt <= zw_stop or jetzt >= zw_start and jetzt <= t_max:
            
            # =>
            
            if 0 <= jetzt <= zw_stop or zw_start <= jetzt <= t_max:

    Wobei 0 und `t_max` eigentlich nicht notwendig sind wenn die Werte innerhalb des erwarteten Wertebereichs sind.

    Apropos Wertebereich: Wenn übergebene Start- und Endzeit *gleich* sind, löst die Funktion einen `NameError` beziehungsweise `UnboundLocalError` aus, weil in dem Fall `wert` nicht definiert wird.

    Zum Thema Kommentare: Kommentarzeichen ist # und nur das. Ausdrücke die nur aus literalen Zeichenketten bestehen sind keine Kommentare. An bestimmten Stellen haben sie laut Python-Syntax die Bedeutung von Docstrings. An anderen Stellen sind sie für Python selbst nur sinnlose Ausdrücke, allerdings haben sie für andere Werkzeuge auch die Bedeutung von Dokumentation. Beispielsweise für Sphinx, dem offiziellen Werkzeug für die Python-Dokumentation, das auch von vielen anderen Projekten genutzt wird. Das was man bei readthedocs findet ist in der Regel damit erstellt.

    Letztlich ist dieses Herumgehampel mit Zeichenketten die Zeiten repräsentieren sollen und rechnen mit Sekunden hier aber auch ziemlich viel Arbeit die man sich eigentlich nicht geben würde. Es gibt das `datetime`-Modul in der Standardbibliothek.

    Bleibt (ungetestet):

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • darf ich als Initiators dieses threads/Themas in aller Bescheidenheit

    melde, dass ich die Steuerung meiner 3. LED in mein nun einzige

    Script integriert habe.

    Bin noch nicht ganz fertig, werde es in Github veröffentlichen und

    den Link hier dann abschliessend mitteilen.

  • muss leider nochmals von vorne anfangen, mein Rpi Zero W hat aus

    unerfindlichen Gründen den Geist aufgegeben. Zudem werde ich die

    sich als untauglich erwiesenen Songle Relais durch solid state Relais

    ersetzen und einen Power-Controller für Raspberry Pi (RPi-PC)

    hinzufügen und damit die Funk-Steckdose ersetzen. Das alles wird

    noch ein bisschen dauern und ich schliesse diesen thread.
    Mein Script werde ich aber auf Github posten.

Jetzt mitmachen!

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