Zyklische und Azyklischen Programmteil Parallel

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

Hi,

Ich habe Daten von einem Event die ich mittels evdev und read_loop abfrage. Jetzt möchte ich nach einem Event Laufblinker aktivieren oder deaktivieren.

Hier der Code:

Code: Alles auswählen

#import evdev
from evdev import InputDevice, categorize, ecodes, KeyEvent
from time import sleep

#creates object 'gamepad' to store the data

gamepad = InputDevice('/dev/input/event0')

		
		
def main():
		
#prints out device info at start
		print(gamepad)

#evdev takes care of polling the controller in a loop
		for event in gamepad.read_loop():
			global Blinker_links_aktiv
			if event.code == 102 and categorize(event).keystate == 1:
				if Blinker_links_aktiv:#toggle bit
					Blinker_links_aktiv=false
				else
					Blinker_links_aktiv=true
			
''' Blinklicht Code
led_leiste=[Links,mitte,rechts]
for led in led_leiste:
	led =false

while Blinker_links_aktiv:
	#Blinker aus
	for led in led_leiste:
		led =false
	# Blicker durchlaufen
	for led in led_leiste:
		sleep(0.5)
		led =true
		for status in led_leiste:
			print (led_leiste.index(status),status)
	else:# alle LEDS an
		sleep(0.6)
'''

				
	finally:
		for led in led_leiste:
		led =false

if __name__ == "__main__":
	main()

 
Wie Ihr seht habe ich den die Blinkeransteuerung noch als Kommentar, da ich vermute das der Code nur bei Unterbrechung von read_loop ausgeführt wird.

Wie wird sowas normalerweise Realisiert?
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rob87: Eingerückt wird mit vier Leerzeichen pro Ebene. Keine Tabs.

`gamepad` sollte nicht auf Modulebene existieren, das wäre dort globaler Zustand.

Kommentare sollten auch der Einrückung folgen. Das schöne an der Einrückung ist ja, dass man die Struktur des Codes daran sehen kann. Wenn die Kommentarzeilen da ”ausbrechen” macht man sich diese Eigenschaft kaputt.

Literale Zeichenketten sind keine Kommentare. Kommentarzeichen ist ``#`` und nichts anderes.

Der Code kommt nicht am Compiler vorbei, da fehlt ein Doppelpunkt beim ``else:``.

``global`` hat da nichts zu suchen. Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen, als Argument(e) übergeben.

Die Vergleiche mit den magischen Zahlen bei `evdev` sind nicht gut. Was soll 102 bedeuten? Dafür stellt `evdev.ecodes` Konstanten bereit.

Das wird da auch falsch gemacht: Du weisst vom Code her nicht zwingend, dass der zu einem Ereignistyp gehört der ein `keystate`-Attribut hat. Es können ja mehrere Ereignistypen den Code 102 haben. Man muss also immer erst einmal prüfen ob der Ereignistyp stimmt.

Wo kommen `true` und `false` her? Mal angenommen das sind eigentlich `True` und `False`, dann ist das negieren mit ``not`` einfacher als da ein ``if``/``else`` für zu schreiben.

`Blinker_links_aktiv` entspricht nicht der Namenskonvention.

Der auskommentierte Blinkercode scheint komplette Fiktion zu sein, weil das Zuweisen an die Laufvariable natürlich nichts an dem Wert in der Liste ändert. Das ``else`` zum ``for`` macht keinen Sinn und verwirrt den Leser einfach nur.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

__blackjack__ hat geschrieben: Montag 22. März 2021, 11:35 @rob87: Eingerückt wird mit vier Leerzeichen pro Ebene. Keine Tabs.
Da sowohl das eine als auch das andere funktioniert, nehme ich das praktischere. Aber danke für den Hinweis.

`gamepad` sollte nicht auf Modulebene existieren, das wäre dort globaler Zustand.
Sprich es sollte in die Main.

Kommentare sollten auch der Einrückung folgen. Das schöne an der Einrückung ist ja, dass man die Struktur des Codes daran sehen kann. Wenn die Kommentarzeilen da ”ausbrechen” macht man sich diese Eigenschaft kaputt.
Da geh ich voll mit. Da das eine gekürzte Version ist habe ich dort nicht so Richtig drauf geachtet.
Literale Zeichenketten sind keine Kommentare. Kommentarzeichen ist ``#`` und nichts anderes.
Ach du meinst die drei Hochkomma... Sag das doch. Komisch die Art habe ich schon bei mehreren Programmbespielen gesehen um ganze Textblöcke auszukommentieren.

Der Code kommt nicht am Compiler vorbei, da fehlt ein Doppelpunkt beim ``else:``.
Danke.
``global`` hat da nichts zu suchen. Funktionen und Methoden bekommen alles was sie außer Konstanten benötigen, als Argument(e) übergeben.
Stimmt die for-Schleife ist weder Funktion noch Methode und somit ist die Variable im kompletten Main verfügbar.
Die Vergleiche mit den magischen Zahlen bei `evdev` sind nicht gut. Was soll 102 bedeuten? Dafür stellt `evdev.ecodes` Konstanten bereit.

Das wird da auch falsch gemacht: Du weißt vom Code her nicht zwingend, dass der zu einem Ereignistyp gehört der ein `keystate`-Attribut hat. Es können ja mehrere Ereignistypen den Code 102 haben. Man muss also immer erst einmal prüfen ob der Ereignistyp stimmt.
Der Xbox-Controller übergibt nur einmal die ID 102. im Originalcode sortiere ich entsprechend sprechenden Variablen zu und ja frage vorher den Ereignistyp ab.
Wo kommen `true` und `false` her? Mal angenommen das sind eigentlich `True` und `False`, dann ist das negieren mit ``not`` einfacher als da ein ``if``/``else`` für zu schreiben.
Gute Idee den Code zu optimieren.
`Blinker_links_aktiv` entspricht nicht der Namenskonvention.
Korrekt. Müsste klein geschrieben werden.

Der auskommentierte Blinkercode scheint komplette Fiktion zu sein, weil das Zuweisen an die Laufvariable natürlich nichts an dem Wert in der Liste ändert. Das ``else`` zum ``for`` macht keinen Sinn und verwirrt den Leser einfach nur.
Mit der Laufvariable magst du recht haben hier sollte man mit "enumerate" direkt in die Liste schreiben. Wie der Kommentar schon sagt ist das die Zeit die alle LED's an sind. Man könnte die sleep auch als erstes in die while schreiben.

=> Kannst du vielleicht noch zum eigentlichen Thema was sagen?
=> Müsste sowieso noch optimiert werden damit beim verlassen der while alle LED aus sind.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rob87: Statt sich mit `enumerate()` einen zusätzlichen Index zu generieren würde man einfach eine neue Liste mit den geänderten Werten erzeugen.

Das `sleep()` könnte auch am Ende des ``while``-Blocks stehen, nur halt nicht in einem ``else`` zu einem ``for``, welches gar kein ``break`` enthält. Das macht keinen Sinn, denn so ein Zweig wird dann *immer* ausgeführt.

Beim eigentlichen Thema ist die Frage was da konkret passieren soll. Wenn das Blinken nebenläufig zum auswerten der Eingabeereignisse passieren soll, dann brauchst Du irgendeine Form der Nebenläufigkeit. Beispielsweise Threads.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

__blackjack__ hat geschrieben: Montag 22. März 2021, 14:34 @rob87: Statt sich mit `enumerate()` einen zusätzlichen Index zu generieren würde man einfach eine neue Liste mit den geänderten Werten erzeugen.
OK Ja, und die geändert Liste dann an die PIN-Ansteuerungsfunktion Übergeben. Hmm, oder man macht einen Zähler..

Das `sleep()` könnte auch am Ende des ``while``-Blocks stehen, nur halt nicht in einem ``else`` zu einem ``for``, welches gar kein ``break`` enthält. Das macht keinen Sinn, denn so ein Zweig wird dann *immer* ausgeführt.
Ja auch das ist möglich.
Beim eigentlichen Thema ist die Frage was da konkret passieren soll. Wenn das Blinken nebenläufig zum auswerten der Eingabeereignisse passieren soll, dann brauchst Du irgendeine Form der Nebenläufigkeit. Beispielsweise Threads.
-> Naja eine Event (Button wird gedrückt) schaltet die Blinker Funktion frei. Ein weiteres Event(Button wird erneut gedrückt) nimmt die Freigabe wieder weg. Thread habe ich mir _KURZ_ angeschaut, erste frage die bei mir kommt ist, kann ich zwischen zwei Threads Variablen austauschen? Muss ich heute Abend mal genauer schauen.
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

Hi, also ich bin jetzt immer noch nicht wirklich weiter. Prinzipiell habe ich ja 3 Programm-Teile.
- Eingang(azyklisch): Verändert Controllerzustandsvariablen
- Verarbeitung(zyklisch): Verändert anhand der Controllerzustandsvariablen die pin_sollzustands_variablen
-Ausgabe( ??? ): veränder GPIO-Spannung entsprechend pin_sollzustands_variablen

Nur wie mache ich die Wertüber- bzw. -rückgabe und das auch noch so, das mir die Programmteile sich nicht gegenseitig stören?

Theoretisch könnte man auch die Controllerzustände zyklisch abfragen nur wie?

Danke Rob
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

Hi,
ich hole den Thread nochmals hoch, da ich noch keine Lösung habe. Könnten man alternativ die Hardwarezustände auch Zyklisch abfragen? Es ist ein Bluetooth Controller. Legt der Bluetooth-Treiber die letzten Werte Irgendwo Systemseitig ab?

Danke und Gruß
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich würde asyncio benutzen, https://python-evdev.readthedocs.io/en/ ... ng-asyncio - damit kann man problemlos pseudo-parallel arbeiten, und einen Blink und einen Abfrage-Task machen. Und dich zb über ein Event synchronisieren https://docs.python.org/3/library/async ... ncio.Event
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

Hi,

also wenn ich das richtig verstehe würde ich 2 Tasks erstellen mit
asyncio.create_task(???)
.
- Ein Task würde den Code gamepad.readloop beinhalten und als endlosschleife im Dauerlauf laufen( bis das hauptprogramm gestoppt wird).
- Der 2. Task würde ebenfalls eine Endlosschleife enthalten nur das die 500ms schläft (-> in festen Zeitabständen aufgerufen wird)

=> das mit dem Event habe ich noch nicht verstanden
Ich würde ein EVENT erzeugen (wie?) und dort die alle Zustände des Controllers reinpacken. Und wenn dann Task 2 erwacht Schaut er was für zustände in dem EVENT stehen und arbeite dementsprechend meine Logik ab?

Was steh eigentlich in
'/dev/input/event0'
drin?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@rob87,
Ich würde ein EVENT erzeugen (wie?) und dort die alle Zustände des Controllers reinpacken. Und wenn dann Task 2 erwacht Schaut er was für zustände in dem EVENT stehen und arbeite dementsprechend meine Logik ab?

das mit den beiden endlos laufenden Routinen ist schon mal gut.
Die Events dienen der Kommunication zwischen den beiden:

Kleines Beispiel: Der Blinker reagiert auf das Setzen und Rücksetzen des Events und kann so vom "controller" gesteuert werden.

Code: Alles auswählen

import asyncio


async def controller(event):
    """ simuliert gamepad events im Abstand von 5 Sekunden """
    while True:
        await asyncio.sleep(5)
        event.set()
        await asyncio.sleep(5)
        event.clear()


async def blinker(event):
    """ 
    Der Blinker wechselt von "Aus" nach "Ein", wenn das Event gesetzt wurde
    und schaltet von "Ein" nach "Aus", wenn das Event zurückgesetzt wurde
    """
    while True:
        while not event.is_set():
            print("Wait")
            await asyncio.sleep(1)

        print("Start Blinking")

        while event.is_set():
            print("Blink")
            await asyncio.sleep(1)

        print("Stop Blinking")


async def manager():
    event = asyncio.Event()
    await asyncio.gather(controller(event), blinker(event))


asyncio.run(manager())

"""
Ausgabe:
Wait
Wait
Wait
Wait
Wait
Start Blinking
Blink
Blink
Blink
Blink
Blink
Stop Blinking
Wait
Wait
Wait
"""
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das event ist ein Objekt. Wie jedes andere auch. Das hat eine Reihe von Methoden. Man erzeugt es, und reicht es an beide tasks als Argument rein. Der Blinker wartet darauf, dass es gesetzt wird, in seiner endlos-Schleife. Und prüft dann periodisch beim blinken, ob das noch der Fall ist. Der andere setzt und ent-setzt es, abhängig von den Eingaben.

In der Geräte-Datei kommt der Strom von Ereignissen an. So wie auch Daten über ein Netzwerk kämen, etc.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@__deets__, Das passt :D Du hast zeitgleich die Erklärung zu meinem Beispiel gepostet
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

rogerb hat geschrieben: Donnerstag 2. September 2021, 14:07 @__deets__, Das passt :D Du hast zeitgleich die Erklärung zu meinem Beispiel gepostet
👍🏻😬
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

Hi,

grundlegend habe ich es verstanden, nur für die Umsetzung fehl mir noch was.

So wie ich dein Beispiel verstehe:
rogerb hat geschrieben: Donnerstag 2. September 2021, 14:01

Code: Alles auswählen

import asyncio


async def controller(event):
    """ simuliert gamepad events im Abstand von 5 Sekunden """
    while True:
        await asyncio.sleep(5)
        event.set()# <-- Im Objekt 'event' gibt es eine Funktion die in einem Speicher eine 1 schreibt


async def blinker(event):
    """ 
    Der Blinker wechselt von "Aus" nach "Ein", wenn das Event gesetzt wurde
    und schaltet von "Ein" nach "Aus", wenn das Event zurückgesetzt wurde
    """
    while True:
        while not event.is_set(): # <-- Im Objekt 'event' gibt es eine Funktion die den Standartspeicher auf 1(True) abfragt und das ergebnis zurückgibt
            print("Wait")
            await asyncio.sleep(1) # 1Sekunde Pause


async def manager():
    event = asyncio.Event()# hier wird mittels der Funktion '.Event()'ein globales Objekt 'event' definiert, das verschiedene Funktionen und Eigenschaften beinhaltet
    await asyncio.gather(controller(event), blinker(event)) # hier werden mittels asyncio die Programmteile in eine Reihe geschaltet und den Programmteilen wird das globale Objekt 'event' übergeben.


asyncio.run(manager()) # Abarbeitungsstart

Jetzt stellensich mir die Fragen:
wo kann ich heraufsinden was für Funktionen und Eigenschaften ".Event()" definiert?
Wie kann ich Analoge Variablen übergeben?
Kann ich auch eigene Objekte innerhalb von asycio nutzen?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@rob87,
wo kann ich heraufsinden was für Funktionen und Eigenschaften ".Event()" definiert?
Events haben nicht viele Funktionen. Es sind eigentlich nur gegenseitig gesetzte Wartepunkte.
https://docs.python.org/3/library/async ... ncio.Event

Wie kann ich Analoge Variablen übergeben?
Das geht mit Hilfer einer Queue:
https://docs.python.org/3/library/async ... html#queue

Code: Alles auswählen

import asyncio
import random


async def sender(queue):
    """ simuliert senden von daten via queue """
    while True:
        await asyncio.sleep(1)
        await queue.put(random.randint(1, 10))


async def receiver(queue):
    """ simuliert empfang von daten """
    while True:
        data = await queue.get()
        print(data)


async def manager():
    queue = asyncio.Queue()
    await asyncio.gather(sender(queue), receiver(queue))


asyncio.run(manager())
Kann ich auch eigene Objekte innerhalb von asycio nutzen?
Ich bin nicht ganz sicher was du meinst. Aber grundsätzlich gibt es keine Einschränkungen, solange du dich an die asynchrone Programmierweise hältst.
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

rogerb hat geschrieben: Mittwoch 8. September 2021, 19:31
Ich bin nicht ganz sicher was du meinst. Aber grundsätzlich gibt es keine Einschränkungen, solange du dich an die asynchrone Programmierweise hältst.
Hi,

ich meinte sowas in der Art:

Code: Alles auswählen

#Controllerobjekt 

A=0.0
B=0.0

def InputKEY(id,val): #input kann 0.0 oder 1.0 sein
	global A,B,Y,X,LB,RB,MENU,ANSICHT,XBOX,RSTICK,LSTICK
	if id==304:
		A=val
	elif id==305:
		B=val

Code: Alles auswählen

import asyncio
import random
import xbox as cont_state

async def read_cont(Controller):
    """ simuliert senden von daten via queue """
	from evdev import InputDevice, categorize, ecodes, KeyEvent
	for event in InputDevice('/dev/input/event0')read_loop():
		#Binaer input
		if event.type == ecodes.EV_KEY:
				state=categorize(event).keystate
				Controller.InputKEY(event.code,state)


async def blinker_write(Controller):
	SpOn=true #Speicher letzter Zyklus
    while True:
        if Controller.A == 1.0:
			if SpOn:
				print("On")
				SpOn=false
			else
				print("Off")
				SpOn=true
			await asyncio.sleep(1) # 1Sekunde Pause
			

async def manager():
	await asyncio.gather(read_cont(cont_state), blinker_write(cont_state))


asyncio.run(manager())
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@rob87,

Das sollte so ähnlich gehen. (Du müsstest das natürlich noch etwas aufräumen)
Hier ist ja so ein Beispiel:
https://python-evdev.readthedocs.io/en/ ... ng-asyncio

Geänderter Beipspiel Code:

Code: Alles auswählen

async def helper(dev, queue):
    async for ev in dev.async_read_loop():
    await queue.put(ev.value) # Zum Beispiel "value" an die Queue übergeben

Das müsste ich aber auch ausprobieren um mehr zu sagen.
rob87
User
Beiträge: 45
Registriert: Donnerstag 17. Oktober 2019, 14:24

rogerb hat geschrieben: Mittwoch 8. September 2021, 21:21 @rob87,
(Du müsstest das natürlich noch etwas aufräumen)

Code: Alles auswählen

async def helper(dev, queue):
    async for ev in dev.async_read_loop():
    await queue.put(ev.value) # Zum Beispiel "value" an die Queue übergeben

Hast Recht:

Code: Alles auswählen

import asyncio
import xbox 
from evdev import InputDevice, categorize, ecodes, KeyEvent


async def read_cont(dev,eventspeicher_queue):
	async for ev in dev.async_read_loop():
		#Binaer input
		if ev.type == ecodes.EV_KEY:
			#Input Type , ID und Wert verketten
			queuestring = "K "+ev.code+" "+categorize(ev).keystate
		eventspeicher_queue.put(queuestring)


async def blinker_write(eventspeicher_queue):

	Controller = Xbox
	SpOn=true
	
	while True:
		#Inputs auslesen
		while NOT eventspeicher_queue.empty():
			input =eventspeicher_queue.get_nowait().split()
			if input[0] == "K": ##Taste gedrückt?
				# ID und Wert an Controllerspeichr übergeben
				Controller.InputKEY(input[1],input[2])
	
	
        	if Controller.A == 1.0: #Status Button A gedrückt abfragen
			if SpOn:
				print("On")
				SpOn=false
			else
				print("Off")
				SpOn=true
			await asyncio.sleep(1) # 1Sekunde Pause
			

async def manager():
	inputspeicher = asyncio.Queue()
	await asyncio.gather(blinker_write(inputspeicher))

# Eventlistener auf Bluetoothcontoller anlagen und definieren.
dev = InputDevice('/dev/input/event1')

loop = asyncio.get_event_loop()
loop.run_until_complete(read_cont(dev,inputspeicher ))

asyncio.run(manager())
Hier kommt die Frage wieder ob gather und loop miteinander Harmonieren...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die beiden tasks müssen schon parallel laufen. Nicht erst einen laufen lassen, und dann den nächsten…. Dafür muss dein read_cont (steht cont für Kontinuierlich oder Kontinenz? Weiß man bei so Abkürzungen nie) schon kontinuierlich laufen, also mit einer while Schleife drumrum.

NOT gibt es nicht. Und auf eine Queue muss man garantiert awaiten, wie soll die sonst vom anderen Task befüllt werden?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@rob87,

das sieht aus als würde es nicht funktionieren.

Code: Alles auswählen

loop = asyncio.get_event_loop()
loop.run_until_complete(read_cont(dev,inputspeicher ))
inputspeicher wird in der Funktion "manager" definiert. Daher dürfte es auf Modul - Ebene gar nicht bekannt sein.

Einge weitere Probleme die Python nicht ausführen kann:
"false" und "true" werden in Python "False" und "True" geschrieben.
"NOT" wird "not" geschrieben.
Nach "else" fehlt ein Doppelpunkt
"input" ist ein Schlüsselwort und sollte nicht alse Variablenname verwendet werden
Du importierst xbox, verwendest später aber Xbox
Warum die Zuweisung Controller = Xbox ?
"SpOn" ist eine einfache Variable und sollte klein geschrieben werden. Außerdem ist unklar was der Name bedeutet.

Ich kenne die xbox und evdev Libraries nicht, daher weiß ich auch nicht, ob der Rest Sinn macht.

asyncio.gather() führt die Coroutines "read_count" und "blinker_write" quasi paralellel aus und wartet bis beide abgeschlossen sind. Man verwendet gather() nur wenn mehrere Couroutines von der Eventloop ausgeführt werden sollte. Dasist hier der Fall.
Bei dir wurden die Coroutines nacheinander ausgeführt, was natürlich keine Kommunikation über die Queue erlaubt.

Ich habe nur die offensichtlichen Syntaxfehler entfernt und die Einrückung korrigiert. Ob das schon das gewünschte Ergebnis liefert kann ich nicht sagen.

Code: Alles auswählen

import asyncio
import xbox
from evdev import InputDevice, categorize, ecodes, KeyEvent


async def read_cont(dev, eventspeicher_queue):
    async for ev in dev.async_read_loop():
        # Binaer input
        if ev.type == ecodes.EV_KEY:
            # Input Type , ID und Wert verketten
            queuestring = "K " + ev.code + " " + categorize(ev).keystate
            eventspeicher_queue.put(queuestring)


async def blinker_write(eventspeicher_queue):

    Controller = xbox
    spon = True

    while True:
        # Inputs auslesen
        while not eventspeicher_queue.empty():
            queue_input = eventspeicher_queue.get_nowait().split()
            if queue_input[0] == "K":  ##Taste gedrückt?
                # ID und Wert an Controllerspeichr übergeben
                Controller.InputKEY(queue_input[1], queue_input[2])
        if Controller.A == 1.0:  # Status Button A gedrückt abfragen
            if spon:
                print("On")
                spon = False
            else:
                print("Off")
                spon = True
            await asyncio.sleep(1)  # 1Sekunde Pause


async def manager(dev):
    inputspeicher = asyncio.Queue()
    await asyncio.gather(blinker_write(inputspeicher), read_cont(dev, inputspeicher))


# Eventlistener auf Bluetoothcontoller anlagen und definieren.
dev = InputDevice("/dev/input/event1")

asyncio.run(manager(dev))
Antworten