Programm beenden, wenn neues Programm gestartet wird

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Niklas1508
User
Beiträge: 1
Registriert: Donnerstag 14. Juli 2022, 09:38

Hallo zusammen,
ich möchte mich ebenfalls als absoluten Neuling auf diesem Gebiet outen und hoffe jetzt schon für diese Frage und meinen Code nicht virtuell verkloppt zu werden ;)
Grundsätzlich geht es um eine LED Steuerung, die ich im Raspberry Pi Programmiert habe. Ich habe um nicht bei 0 zu starten mir das Strandtest Skript runtergeladen und es dann zu meinen Zwecken angepasst.
Mein Ziel ist es verschiedene Licht Szenen per URL Befehle auszulösen, weshalb ich die Flask App importiert habe und am Ende hat es funktioniert ohne, dass ich genau wusste warum :P

Nun mein Problem. Die URL Befehle werden mit Hilfe des Stream Decks ausgelöst und dauern 30-60 Sekunden. Sollte nun aber ein weiterer Knopf gedrückt werden bevor das Skript durchgelaufen ist, dann schickt das neue Programm Befehle an die LEDs aber auch das alte Programm schickt noch alles rüber, was in der Pipeline ist. Aus diesem Grund wäre es super, wenn ich eine Funktion einfügen könnte, die beim Start einer neuen Funktion erstmal alle Befehle, die noch in der Pipeline sind löscht, sodass das neue Programm sauber startet und das alte Programm abrupt beendet wird.
Vielen Dank für euren Input und solltet ihr weitere Vorschläge haben, wie ich mein Skript etwas schlanker gestalten kann, bin ich gerne für Vorschläge offen.

Code: Alles auswählen

import time
from rpi_ws281x import PixelStrip, Color
import argparse
from flask import Flask
app = Flask(__name__)
from app import app
# LED strip configuration:

LED_COUNT = 600 
LED_PIN = 18 


LED_FREQ_HZ = 800000 

LED_DMA = 10 

LED_BRIGHTNESS = 255

LED_INVERT = False 

LED_CHANNEL = 0 





def onoff1(strip, color, bpm = float, rep = int):
        for k in range(round(rep/2)):
                for i in range(596):
                        strip.setPixelColor(i, color)
                strip.show()
                time.sleep(60/bpm)
                for j in range(596):
                        strip.setPixelColor(j, 0)
                strip.show()
                time.sleep(60/bpm)

def onoff2(strip, u = int, v = int, w = int, x = int, y = int, z = int, bpm = float, rep = int):
        for k in range(round(rep/2)):
                for i in range(596):
                        strip.setPixelColor(i, Color(u, v, w))
                strip.show()
                time.sleep(60/bpm)
                for j in range(596):
                        strip.setPixelColor(j, Color(x, y, z))
                strip.show()
                time.sleep(60/bpm)

def onoff3(strip, r = int, s = int, t = int, u = int, v = int, w = int, x = int, y = int, z = int, bpm = float, re>
        for k in range(round(rep/3)):
                for i in range(596):
                        strip.setPixelColor(i, Color(r, s, t))
                strip.show()
                time.sleep(60/bpm)
                for j in range(596):
                        strip.setPixelColor(j, Color(u, v, w))
                strip.show()
                time.sleep(60/bpm)
                for l in range(596):
                        strip.setPixelColor(l, Color(x, y, z))
                strip.show()
                time.sleep(60/bpm)

def onoffrainbow(strip, bpm = float, rep = int):
        for k in range(round(rep/6)):
                for i in range(596):
                        strip.setPixelColor(i, Color(255, 0, 0))
                strip.show()
                time.sleep(60/bpm)
                for j in range(596):
                        strip.setPixelColor(j, Color(246, 138, 30))
                strip.show()
                time.sleep(60/bpm)
                for l in range(596):
                        strip.setPixelColor(l, Color(253, 224, 26))
                strip.show()
                time.sleep(60/bpm)
                for m in range(596):
                        strip.setPixelColor(m, Color(0, 121, 64))
                strip.show()
                time.sleep(60/bpm)
                for n in range(596):
                        strip.setPixelColor(n, Color(36, 64, 142))
                strip.show()
                time.sleep(60/bpm)
                for o in range(596):
                        strip.setPixelColor(o, Color(115, 41, 130))
                strip.show()
                time.sleep(60/bpm)

def onoffindia(strip, bpm = float, rep = int):
        for k in range(rep):
                for i in range(192):
                        strip.setPixelColor(i, Color(255, 153, 51))
                for j in range(192, 384):
                        strip.setPixelColor(j, Color(255, 255, 255))
                for l in range(384, 576):
                        strip.setPixelColor(l, Color(19, 136, 8))
                for m in range(576, 596):
                        strip.setPixelColor(m, Color(0, 0, 255))
                strip.show()
                time.sleep(60/bpm)
                for n in range(596):
                        strip.setPixelColor(n, 0)
                strip.show()
                time.sleep(60/bpm)


def move2color1(strip, u = int, v = int, w = int, x = int, y = int, z = int, bpm = float, rep = int):
        for k in range(round(rep/6)):
                for l in range (6):
                        for i in range(596):
                                strip.setPixelColor(i, Color(u, v, w))
                        for m in range(l*96,l*96+95):
                                strip.setPixelColor(m, Color(x, y, z))
                        strip.show()
                        time.sleep(60/bpm)

def move2color2(strip, u = int, v = int, w = int, x = int, y = int, z = int, bpm = float, rep = int):
        for k in range(round(rep/8)):
                for l in range (8):
                        for i in range(596):
                                strip.setPixelColor(i, Color(u, v, w))
                        for n in range(12):
                                for m in range(n*48+l*6,n*48+l*6+6):
                                        strip.setPixelColor(m, Color(x, y, z))
                        strip.show()
                        time.sleep(60/bpm)


if __name__ == '__main__':


        parser = argparse.ArgumentParser()

        parser.add_argument('-c', '--clear', action='store_true', help='clear the display on exit')

        args = parser.parse_args()



        strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)


        strip.begin()



        print('Press Ctrl-C to quit.')

        if not args.clear:

                print('Use "-c" argument to clear LEDs on exit')



        try:

                  @app.route('/s1')
                        def s1():
                                onoff1(strip, Color(255, 0, 0), 136, 45)
                                onoff1(strip, Color(255, 0, 0), 600, 50)
                                onoff1(strip, Color(255, 0, 0), 136, 68)
                                return "s1"

                        @app.route('/s2')
                        def s2():
                                time.sleep(2)
                                onoff3(strip, 255, 255, 255, 0, 71, 160, 205, 46, 58, 132, 64)
                                return "s2"

                        @app.route('/s3')
                        def s3():
                                time.sleep(1)
                                onoff1(strip, Color(255, 0, 0), 140, 64)
                                return "s3"

                        @app.route('/s4')
                        def s4():
                                time.sleep(1)
                                onoff2(strip, 137, 207, 240, 255, 68, 204, 132, 64)
                                return "s4"
                        
                        @app.route('/s5')
                        def s5():
                                time.sleep(2.5)
                                onoffindia(strip, 98, 34)
                                move2color1(strip, 255, 153, 51, 19, 136, 8, 98, 17)
                                move2color2(strip, 19, 136, 8, 255, 153, 51, 98, 17)
                                onoffindia(strip, 98, 17)
                                return "s5"

                        @app.route('/s6')
                        def s6():
                                time.sleep(2)
                                onoff2(strip, 210, 183, 115, 40, 116, 178, 125, 36)
                                return "s6"

                        @app.route('/s7')
                        def s7():
                                time.sleep(2.5)
                                move2color1(strip, 135, 179, 60, 44, 195, 112, 123, 12)
                                move2color2(strip, 44, 195, 112, 135, 179, 60, 123, 32)
                                onoff2(strip, 135, 179, 60, 44, 195, 112, 123, 10)
                                onoff2(strip, 135, 179, 60, 44, 195, 112, 600, 20)
                                onoff2(strip, 135, 179, 60, 44, 195, 112, 123, 8)
                                return "s7"

                        @app.route('/s8')
                        def s8():
                                onoff3(strip, 245, 255, 0, 255, 0, 127, 136, 0, 255, 128, 33)
                                move2color2(strip, 255, 0, 127, 136, 0, 255, 128, 32)   
                                onoff3(strip, 245, 255, 0, 255, 0, 127, 136, 0, 255, 128, 33)
                                return "s8"

                        @app.route('/s9')
                        def s9():
                                move2color2(strip, 206, 17, 38, 252, 209, 22, 100, 8) 
                                move2color2(strip, 206, 17, 38, 0, 56, 147, 100, 8)
                                onoff3(strip, 206, 17, 38, 0, 56, 147, 252, 209, 22, 100, 27)
                                onoff3(strip, 206, 17, 38, 0, 56, 147, 252, 209, 22, 600, 30)
                                onoff3(strip, 206, 17, 38, 0, 56, 147, 252, 209, 22, 100, 15)
                                return "s9"

                        @app.route('/s10')
                        def s10():
                                onoff2(strip, 226, 6, 19, 255, 255, 255, 114, 30)
                                move2color2(strip, 226, 6, 19, 255, 255, 225, 114, 32)
                                onoff2(strip, 226, 6, 19, 255, 255, 255, 600, 20)
                                onoff2(strip, 226, 6, 19, 255, 255, 255, 114, 30)
                                return "s10"  

                        @app.route('/s11')
                        def s11():
                                onoff3(strip, 0, 51, 153, 30, 127, 203, 116, 208, 241, 128, 99)
                                return "s11"
 
                        @app.route('/s12')
                        def s12():
                                move2color2(strip, 255, 0, 0, 246, 138, 30, 164, 8)
                                move2color2(strip, 246, 138, 30, 253, 224, 26, 164, 8)
                                move2color2(strip, 253, 224, 26, 0, 121, 64, 164, 8)
                                move2color2(strip, 0, 121, 64, 36, 64, 142, 164, 8)
                                move2color2(strip, 36, 64, 142, 246, 138, 30, 164, 8)
                                move2color2(strip, 115, 41, 130, 255, 0, 0, 164, 8)
                                move2color1(strip, 255, 0, 0, 246, 138, 30, 164, 6)
                                move2color1(strip, 246, 138, 30, 253, 224, 26, 164, 6)
                                move2color1(strip, 253, 224, 26, 0, 121, 64, 164, 6)
                                move2color1(strip, 0, 121, 64, 36, 64, 142, 164, 6)
                                move2color1(strip, 36, 64, 142, 246, 138, 30, 164, 6)
                                move2color1(strip, 115, 41, 130, 255, 0, 0, 164, 6)
                                move2color1(strip, 255, 0, 0, 246, 138, 30, 164, 6)
                                move2color1(strip, 246, 138, 30, 253, 224, 26, 164, 6)
                                time.sleep(2)
                                onoffrainbow(strip, 164, 60)
                                return "s12"


                        @app.route('/s13')
                        def s13():
                                time.sleep(2)
                                move2color1(strip, 170, 21, 27, 241, 191, 0, 89, 6)
                                move2color2(strip, 241, 191, 0, 170, 21, 27, 89, 8)
                                onoff3(strip, 170, 21, 27, 241, 191, 0, 170, 21, 27, 89, 3)
                                move2color1(strip, 170, 21, 27, 241, 191, 0, 89, 6)
                                move2color2(strip, 241, 191, 0, 170, 21, 27, 89, 8) 
                                onoff2(strip, 170, 21, 27, 241, 191, 0, 89, 30)
                                return "s13"


                        app.run(host='0.0.0.0',port=5500)

        except KeyboardInterrupt:
                if args.clear:
                        colorWipe(strip, Color(0, 0, 0), 10)
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Niklas1508: Der Quelltext ist unvollständig und hat Syntaxfehler.

Eingerückt wird mit vier Leerzeichen pro Ebene.

Grunddatentypen als Defaultargumente irgendwie in der Hoffnung das wäre vielleicht eine Typdeklaration sind falsch. Alphabetisch fortlaufende einbuchstabige Namen als Argumente sind auch wenig hilfreich und im Grund durchnummerieren von Namen halt mit etwas anderen Mitteln. Das macht man nicht. Namen sollen dem Leser vermitteln was der Wert hinter dem Namen bedeuten. Funktionen die Argumente `r`, `s`, `t`, `u`, … bekommen werfen beim Leser mehr Fragen auf als sie beantworten.

ZwischenWortensolltemanLeerzeichensetzenbeziehunsgweiseinNamendannUnterstricheweildassonstschwerzulesenist.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Der Code in dem ``if __name__ == …``-Guard definiert ja trotzdem viele globale Variablen.

Die Definition von Funktionen/Flask-Routen gehört nicht in das ``try``/``except`` für den Abbruch per Strg+C.

Das Aufräumen gehört nicht in diese Ausnahmebehandlung, denn dann passiert das ja *nur* wenn das Programm per Strg+C abgebrochen wird, aber beispielsweise *nicht* wenn es durch einen Fehler abgebrochen wird. Aufräumen gehört deshalb in der Regel in einen ``finally``-Zweig, der *immer* ausgeführt wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dazu muss das bestehende Programm so umstrukturiert werden, dass es statt die Auftraege in einem der HTTP-Threads abzuarbeiten einen Hintergrund-Thread startet, der die Instruktionen abarbeitet, und dessen Anweisungs-queue auch geleert werden kann.

Das Beispiel hier illustriert das vorgehen:

Code: Alles auswählen

import time
import threading
import queue


class LEDWorker:

    def __init__(self):
        self._q = queue.Queue()
        t = threading.Thread(target=self._work)
        t.daemon = True
        t.start()

    def _work(self):
        while True:
            instruction = self._q.get()
            instruction()

    def sleep(self, timeout):
        self._q.put(lambda: time.sleep(timeout))

    def color(self, color):
        self._q.put(lambda: print(color))

    def clear(self):
        while not self._q.empty():
            try:
                self._q.get_nowait()
            except queue.Empty:
                pass


def main():
    worker = LEDWorker()
    # Legt 20 Instruction mit etwa 10 sekunden Dauer an.
    for i in range(10):
        worker.sleep(1)
        worker.color(f"color {i}")
    time.sleep(5) # Anweisungen laufen noch.
    # Neue Anweisungen erzeugen
    worker.clear()
    for i in range(10):
        worker.sleep(1)
        worker.color(f"new color {i}")

    time.sleep(15)


if __name__ == '__main__':
    main()
Aber das alles einzubauen ist Arbeit. Ich haette gedacht, dass sich fuer sowas schon fertige Pakete finden, da wuerde ich eher reininvestieren.
Antworten