Aus Flask ausbrechen

Django, Flask, Bottle, WSGI, CGI…
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Hallo zusammen,

ich habe jetzt zwar schon sehr viel gelesen, komme aber nicht weiter.
Folgenden Ablauf habe ich im moment:
Ich lege meine fix-variabeln fest (z.B Anzahl der LEDs apix=300)

Code: Alles auswählen

#Configuration:
#apix = Anzahl der angeschlossenen LEDs (Fächer + Fail LED)
#Bei 'apix' muss die Anzahl der angeschlossenen LEDs angegeben werden.
apix = 300
##############################################################
Dann importiere ich alles was ich brauche.

Code: Alles auswählen

##############################################################
#Imports
import time
import mysql.connector
import itertools
import functools
from flask import Flask, request
from rpi_ws281x import *
Danach starte ich den MySQL Datenbankaufbau und setzte den cursor

Code: Alles auswählen

#Script für Datenbankaufbau
# Versuche...
try:
  #Aufbau einer Verbindung
  db = mysql.connector.connect(
    host='db4free.net', # Servername
    user='benutzer', # Benutzername
    password='passwort', # Passwort
    database='datenbank',
    port='3306'
  )
  # Ausgabe des Hashwertes des initialisierten Objektes
  print(db)
  print("Connected to database")
# Wenn ein Fehler vom Typ "mysql.connector.errors.ProgrammingError" aufgetreten ist...
except mysql.connector.errors.ProgrammingError:
  # Ausgabe einer Fehlermeldung auf der Konsole
  print("Fehler beim Aufbau der DB Verbindung aufgetreten!")

cursor = db.cursor()
cursor.execute("SHOW TABLES")
for tbl in cursor:
  print(tbl)
##############################################################
Nun route ich Flask

Code: Alles auswählen

app = Flask(__name__)

strip = Adafruit_NeoPixel(apix, 18, 800000, 5, False, 255)
strip.begin()

@app.route('/')
def main():
    return 'Hello Mitarbeiter, hier gibt es nichts zu sehen.'



@app.route('/p2lwert', methods=['GET'])
Jetzt beginne ich mit den eigentlichen Script

Code: Alles auswählen

def p2lwert():
    # if key doesn't exist, returns None
    teilnehmer = request.args.get('user', default = 4, type = int)
    nummer = request.args.get('code')

    if (teilnehmer == 1):
        print ("Der teilnehmer 1 (Erfassung) wurde erkannt")
        farbe = "rot"
        rt = 255
        gn = 0
        bl = 0
    elif (teilnehmer == 2):
        print ("Der Teilnehmer 2 (Vorlegen) wurde erkannt")
        farbe = "gruen"
        rt = 0
        gn = 255
        bl = 0
    elif (teilnehmer == 3):
        print ("Der Teilnehmer 3 (Getriebeschrauben) wurde erkannt")
        farbe = "blau"
        rt = 0
        gn = 0
        bl = 255
    elif (teilnehmer == 4):
        print ("Der Teilnehmer wurde nicht angegeben")
        farbe = "pink"
        rt = 255
        gn = 0
        bl = 255
        teilnehmer = "wurde nicht angegeben"
    else:
        print ("Ich kenne den Teilnehmer nicht")
        farbe = "weiß"
        rt = 255
        gn = 255
        bl = 255
        teilnehmer = "Unbekannt!"


    cursor = db.cursor()
    sql = "SELECT fach FROM barcodes WHERE barcode = %s"
    cursor.execute(sql, (nummer,))
    farbeprint = cursor.fetchall()
    string = list(itertools.chain.from_iterable(farbeprint))

    if string:
        led = int(functools.reduce(lambda a, b : a + str(b), string, ""))
    else:
        led = None
    if (led != None):
        strip.setPixelColorRGB(led, rt, gn, bl)
        print ("Barcode: ", nummer)
        print ("Fach: ", led)
        strip.show()
        return     '''
            <h1>Bauteil mit dem Barcode {} liegt im Fach {}</h1>
            <h1>Das Fach {} leuchtet nun {} </h1>
        '''.format(nummer, led, led, farbe)
    else:
        strip.setPixelColorRGB(0, rt, gn, bl)
        print ("Barcode: ", nummer)
        print ("Barcode konnte nicht gefunden werden")

        strip.show()

        return     '''
            <h1>Bauteil mit dem Barcode {} konnte nicht gefunden werden</h1>
            <h1>Die Fail LED leuchtet nun in der Teilnehmerfarbe {} </h1>
        '''.format(nummer, farbe)


if __name__ == "__main__":
    app.run(port=5055, host='0.0.0.0')
Sicherlich ist dieses Script sehr unschön weil ich alles irgendwie zusammen stückel.
Es funktioniert auch mit den LEDs ansteuern, auch wenn der Teilnehmer nicht übertragen wird, der Barcode nicht gefunden wurde usw.

Info: Fach = LED also im echten Leben sind es Fächer die Angesteuert werden, im Demoaufbau sind es LEDs (neopixel LED Stripe mit 60LED/m und 5m = 300 LEDs RGB)
Aber folgende Probleme habe ich noch:
1. Die LEDs werden nach dem setzen nicht mehr gelöscht. Also wenn Teilnehmer 1 erst den Barcode aus Fach 10 liefert, dann leuchtet auch die LED in Fach 10 entsprechend ROT (Teilnehmer 1= Rot, 2= Grün, 3=Blau)
Wenn teilnehmer 1 nun den Barcode aus fach 11 aufruft, leuchtet fach 11 und weiterhin fach 10 rot. Hier müsste aber die 10 ausgehen.
Nur irgendwie bekomme ich es nicht gebacken. Wenn teilnehmer 2 nun fach 10 Aufruft ändert sich die Farbe auf Grün, das passt.

Ich hätte hier 2 Ansätze: 1. Man schreibt in eine Variable je Teilnehmer z.B LED1 und schreibt hier rein welche die letzte LED war ( LED1= led) und löscht beim erneuten Aufruf des Teilnehmers seine letzte LED.
Problem hier wäre aber das wenn Teilnehmer 1 fach 10 aufruft, dann teilnehmer 2 fach 10 aufruft, das dann der teilnehmer 1 bei aufruf von led 20 automatisch ja die LED 10 löschen würde also die vom Teilnehmer 2.
2. Ansatz wäre man schreibt nicht die LEDs direkt sondern beim Flask aufruf wird die LED ermittelt und in eine DB geschrieben. 1 Tabelle mit 3 Zeilen. In Zeile 1 Zelle 1 steht der Wert von Teilnehmer 1, in Zeile 2 Zelle 1 steht die LED von Teilnehmer 2 usw.
Dann könnte ein zweiter Script zyklisch alle 3 Zellen abfragen, den Wert einsetzen und entsprechende LEDs ansteuern.

Aber: Ist das für die DB okay mit dem ständigen geschreibe? Gibt es eine schönere Lösung? Die DB dann local um das netzwerk nicht so zu belasten?

Und wie wäre es wenn die Abfrage der LED (Also nach Übergabe Barcode wird ja in einer DB gesucht welchem Fach dieser Barcode zugeordnert ist, was aber wenn der Barcode dem Fach 10 und dem Fach 20 zugeordnert ist) durch den das die Abfrage eine Liste liefert könnte man ja einfach die Liste als LED setzen und es müssten dann alle LEDs angesteuert werden. Aber in meinen Test schluckt der

Code: Alles auswählen

strip.setPixelColorRGB(led, rt, gn, bl)
für led nur einen int und keine list.

Ich hoffe ihr versteht was ich meine. Schonmal 1000 Dank. Ich versuche es jetzt wirklich schon seit 3 Tagen und jetzt hätte ich einfach gerne die Meinung von den Profis.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Was Du als fix-Variablen beschreibst, sind Konstanten, und die werden nach Konvention komplett gross geschrieben: ANZAHL_PIXEL
Benutze keine kryptischen Abkürzungen.
Deine Fehlerbehandlung beim Datenbankaufbau ist schlecht. Nicht nur, dass Du die vielsagende Fehlermeldung, die Dir die Datenbank liefert durch einen nichtssagenden String ersetzt, sondern auch, dass Du danach so weiter machst, als sei alles OK, und zwei Zeilen später dann in einen NameError hineinläufst.

Man benutzt keine globalen Variablen. Für Datenbanken bietet es sich an SQLAlchemy zu benutzen, das verwaltet im Hintergrund einen Verbindungspool, so dass man nicht bei jeder Abfrage eine neue Verbindung aufbauen muß.

Das was Du da mit itertools.chain.from_iterable ist sehr undurchsichtig. Du möchtest eine Liste mit einelementigen Tupeln in eine Liste ohne Tuple verwandeln, dann schreib das auch so:

Code: Alles auswählen

faecher = [fach for fach, in cursor]
`string` ist ein sehr schlechter Name, für eine Liste, die laut Datenbank Fächer enthält.

Was Du da mit functools.reduce machst, ist sehr undurchsichtig. Du willst die Zahlen, die in Faecher stehen zu einer großen Zahl zusammenpappen? Ist das wirklich das, was Du machen möchtest? Was bedeutet denn die Zahl im fach? Wenn da [12, 3] steht, wie unterscheidet sich das von [1, 23]?

Ich vermute ja mal, die SQL-Abfrage liefert maximal ein Ergebnis zurück, und deine ganze Geschichte mit Schleifen und int sind alle überflüssig.

Erst die Variable `led` auf None zu setzen um gleich danach dieses None abzufragen, ist sehr komplziert, warum packst Du nicht gleich alles in die if-Abfrage davor?
Auf None prüft man übrigens mit `is` bzw. `is not`.

Code: Alles auswählen

    cursor.execute("SELECT fach FROM barcodes WHERE barcode = %s", (nummer,))
    fach = cursor.fetchone()
    if fach is None:
        print("Barcode: ", nummer)
        print("Barcode konnte nicht gefunden werden")
        strip.setPixelColorRGB(0, rt, gn, bl)
        strip.show()
        return f'''
            <h1>Bauteil mit dem Barcode {nummer} konnte nicht gefunden werden</h1>
            <h1>Die Fail LED leuchtet nun in der Teilnehmerfarbe {farbe} </h1>'''
    else:
        print("Barcode: ", nummer)
        print("Fach: ", led)
        strip.setPixelColorRGB(led, rt, gn, bl)
        strip.show()
        return f'''
            <h1>Bauteil mit dem Barcode {nummer} liegt im Fach {led}</h1>
            <h1>Das Fach {led} leuchtet nun {farbe} </h1>'''
Die Frage, ob Du das in einer Datenbank persistieren mußt, hängt davon ab, ob nach Programmneustart die LED-Informationen noch verfügbar sein sollen, oder nicht.

Das einfachst wäre, die LEDs abzufragen und die passende Farbe einfach zu löschen:

Code: Alles auswählen

def clear_color(strip, red, green, blue):
    color_to_clear = Color(red, green, blue, white)
    for index, color in strip.getPixels():
        if color_to_clear == color:
            strip.setPixelColorRGB(index, 0, 0, 0)
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Was Du als fix-Variablen beschreibst, sind Konstanten, und die werden nach Konvention komplett gross geschrieben: ANZAHL_PIXEL
Benutze keine kryptischen Abkürzungen.
Alles klar, nehm ich mit. Danke
Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Deine Fehlerbehandlung beim Datenbankaufbau ist schlecht. Nicht nur, dass Du die vielsagende Fehlermeldung, die Dir die Datenbank liefert durch einen nichtssagenden String ersetzt, sondern auch, dass Du danach so weiter machst, als sei alles OK, und zwei Zeilen später dann in einen NameError hineinläufst.
Das habe ich von irgendwo kopiert aus einen MySQL Python Tutorial

Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Man benutzt keine globalen Variablen. Für Datenbanken bietet es sich an SQLAlchemy zu benutzen, das verwaltet im Hintergrund einen Verbindungspool, so dass man nicht bei jeder Abfrage eine neue Verbindung aufbauen muß.
Das schau ich mir mal an.

Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Das was Du da mit itertools.chain.from_iterable ist sehr undurchsichtig. Du möchtest eine Liste mit einelementigen Tupeln in eine Liste ohne Tuple verwandeln, dann schreib das auch so:

Code: Alles auswählen

faecher = [fach for fach, in cursor]
`string` ist ein sehr schlechter Name, für eine Liste, die laut Datenbank Fächer enthält.

Was Du da mit functools.reduce machst, ist sehr undurchsichtig. Du willst die Zahlen, die in Faecher stehen zu einer großen Zahl zusammenpappen? Ist das wirklich das, was Du machen möchtest? Was bedeutet denn die Zahl im fach? Wenn da [12, 3] steht, wie unterscheidet sich das von [1, 23]?

Ich vermute ja mal, die SQL-Abfrage liefert maximal ein Ergebnis zurück, und deine ganze Geschichte mit Schleifen und int sind alle überflüssig.
Also die Idee ist es das es eine Datenbank gibt in der folgende Spalten existieren:
Fach, Barcode, Name, Info
z.B
1; 100100100; Bauteil 1; Sehr schwer
2; 200200200; Bauteil 2; Groß
3; 300300300; Bauteil 3; Versilberte Variante von Bauteil 2
4; 100100100; Bauteil 1; Sehr schwer

Nun sollen wenn der Barcode "100100100" übermittelt wird und das von Teilnehmer 3 (blau) die LEDs 1 und 4 angehen.
http://p2l:5055/p2lwert?user=3&code=100100100
Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Erst die Variable `led` auf None zu setzen um gleich danach dieses None abzufragen, ist sehr komplziert, warum packst Du nicht gleich alles in die if-Abfrage davor?
Natürlich, war nur so leichter beim Testen unabhänig ganze Teile auszutauschen wenn etwas nicht funktioniert hat.
Hat es irgendwelche Nachteile es so zu machen? Als SPS Programmierer denke ich halt oft in Schrittketten.
Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Auf None prüft man übrigens mit `is` bzw. `is not`.
Das wenn ich mache, sagt Flask dass das so schon geht aber schöner == und != wären
Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Die Frage, ob Du das in einer Datenbank persistieren mußt, hängt davon ab, ob nach Programmneustart die LED-Informationen noch verfügbar sein sollen, oder nicht.
Nach Programmneustart, also Reboot dürfen alle Informationen weg sein die nicht in der MySQL stehen. (Also die Fächerzuweisung zu den Barcodes) Aber welche LED vor dem Reboot geleuchtet hat darf vergessen werden.
Sirius3 hat geschrieben: Dienstag 8. März 2022, 11:54 Das einfachst wäre, die LEDs abzufragen und die passende Farbe einfach zu löschen:

Code: Alles auswählen

def clear_color(strip, red, green, blue):
    color_to_clear = Color(red, green, blue, white)
    for index, color in strip.getPixels():
        if color_to_clear == color:
            strip.setPixelColorRGB(index, 0, 0, 0)
Aber lösche ich dann nicht jedesmal alle?

Also zum besseren Verständniss:

Teilnehmer 1 ist ein Barcodescanner direkt am Regal mit den Fächern. Hier werden Barcodes gescannt und je nach Barcode soll die rote LED anzeigen in welches Fach der gescannte Barcode eingeräumt werden muss.
Wenn der Barcode nicht gefunden wurde, kann dieser an diesen Arbeitsplatz direkt angelegt und einem Fach zugewiesen werden.

Teilnehmer 2 ist der Arbeitsplatz "Vorlegen". Dieser hat einen Monitor auf den er seinen Auftrag sieht. Hier sieht er die einzelnen Bauteile die er benötigt.
Tippt er nun auf eines dieser Bauteile, z.B dem Bauteil 2 mit dem Barcode 200200200 wird folgender "Link" aufgerufen:
http://p2l:5055/p2lwert?user=2&code=200200200
Es soll nun das Fach aus der MySQL DB also in diesem Fall das Fach 2 und somit die LED (neopixel) Nr. 2 in Grün also 0, 255, 0 leuchten.

Teilnehmer 3 ist der Arbeitsplatz "Getriebeschrauben". Dieser ist wie Teilnehmer 2 nur das bei seiner Auswahl entsprechendes Fach blau leuchten soll.

Also leuchten an diesem Regal immer mindestens 1 Fach pro Farbe.
Wenn z.B der Teilnehmer 1 den Code 200200200 überträgt geht die rote LED an fach 2 an. Irgendwann überträgt Teilnehmer 3 den Code 100100100 dann soll an Fach 1 und 4 die blaue LED angehen und weiterhin aber an Fach 2 die rote LED Leuchten. Wenn nun der Teilnehmer 2 den Code 545234234 überträgt, leuchtet die LED 0 (Ein Leuchtschild auf den Fail steht) eben in Grün (Teilnehmerfarbe von 2)
Wenn nun Teilnehmer 3 den Code 200200200 schickt, muss die LED an fach 2 von Rot auf blau wechseln (wird überschrieben) und zeitgleich müssen aber die LEDs 1 und 4 aus gehen.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn mehrere Fächer gleichzeitig leuchten können, dann brauchst Du halt eine Schleife, die alle Fächer-LEDs anschaltet.
Hatte Dein Programm ja nicht, kann ich also nicht wissen.
Und bis auf diesen Punkt passt ja meine Lösung.

Wo sagt Flask dass == schöner ist?
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Sirius3 hat geschrieben: Dienstag 8. März 2022, 13:46 Wenn mehrere Fächer gleichzeitig leuchten können, dann brauchst Du halt eine Schleife, die alle Fächer-LEDs anschaltet.
Hatte Dein Programm ja nicht, kann ich also nicht wissen.
Und bis auf diesen Punkt passt ja meine Lösung.

Wo sagt Flask dass == schöner ist?
pi@p2l:~/pickbylight $ sudo python3 p2lget.py
/home/pi/pickbylight/p2lget.py:67: SyntaxWarning: "is" with a literal. Did you mean "=="?
if (teilnehmer is 1):
wenn ich es so eingebe:

Code: Alles auswählen

    if (teilnehmer is 1):
        print ("Der teilnehmer 1 (Erfassung) wurde erkannt")
        farbe = "rot"
        rt = 255
        gn = 0
        bl = 0
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Sirius3 hat geschrieben: Dienstag 8. März 2022, 13:46 Wenn mehrere Fächer gleichzeitig leuchten können, dann brauchst Du halt eine Schleife, die alle Fächer-LEDs anschaltet.
Hatte Dein Programm ja nicht, kann ich also nicht wissen.
Und bis auf diesen Punkt passt ja meine Lösung.

Wo sagt Flask dass == schöner ist?
In meinen Programm ist es aber so das ich mehrere LEDs von unterschiedlichen Teilnehmern anschalten lassen kann.
Nur eben das diese nicht wieder ausgeschalten werden wenn dieser Teilnehmer eine neue Anfrage schickt.

Außerdem bin ich ja offensichtlich in Python nicht so fit. Also wie genau wäre dein Lösungsvorschlag nun damit mehre Teilnehmer die LEDs in unterschiedlichen Farben schalten können aber bei einer neuenn Anfrage des Teilnehmers die LEDs der vorherigen Anfrage des selben Teilnehmers gelöscht werden?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

`teilnehmer is 1` ist ja auch falsch. Ich schrieb, dass man None mit is vergleicht, Zahlen vergleicht man mit ==.
`clear_color` vergleicht alle LEDs und schaltet nur die aus, deren Farbe mit der vorgegebenen Farbe übereinstimmt.
Was konkret verstehst Du daran nicht? Es hilft ja nichts, wenn ich Dir jetzt die Musterlösung schreibe und Du verstehst sie nicht.
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Sirius3 hat geschrieben: Dienstag 8. März 2022, 15:40 `teilnehmer is 1` ist ja auch falsch. Ich schrieb, dass man None mit is vergleicht, Zahlen vergleicht man mit ==.
`clear_color` vergleicht alle LEDs und schaltet nur die aus, deren Farbe mit der vorgegebenen Farbe übereinstimmt.
Was konkret verstehst Du daran nicht? Es hilft ja nichts, wenn ich Dir jetzt die Musterlösung schreibe und Du verstehst sie nicht.
Hast du doch schon :D Danke, das war das fehlende Puzzleteil.
Also merke lieber rehgum: == bei Zahlen und is bei Worten. Sorry das hatte ich nicht so überrissen.
Also merke lieber rehgum: clear_color löscht nur die LEDs welche diese Farbe haben.

1000 Dank, damit kann ich dann erstmal weiter machen.
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Verstehe die Funktion immernoch nicht.
Mein Versuch:

Code: Alles auswählen

>>> ANZAHL_PIXEL = 300
>>> strip = Adafruit_NeoPixel(ANZAHL_PIXEL, 18, 800000, 5, False, 255)
>>> strip.begin()
strip.setPixelColorRGB(2, 255, 0, 0)
strip.setPixelColorRGB(3, 255, 0, 0)
strip.setPixelColorRGB(4, 0, 255, 0)
strip.setPixelColorRGB(5, 0, 255, 0)
strip.setPixelColorRGB(6, 0, 255, 0)
strip.setPixelColorRGB(7, 0, 0, 255)
strip.setPixelColorRGB(8, 0, 0, 255)
strip.setPixelColorRGB(9, 0, 0, 255)
strip.show()
strip.getPixelColor(1)
strip.getPixelColor(2)
strip.getPixelColor(3)
strip.getPixelColor(4)
strip.getPixelColor(5)
strip.getPixelColor(6)
strip.getPixelColor(7)
strip.getPixelColor(8)
strip.getPixelColor(9)
color_to_clear = Color(red, green, blue, white)
print(color_to_clear)
color_to_clear = Color(255, 0, 0)
print(color_to_clear)
color_to_clear = Color(0, 255, 0)
print(color_to_clear)
color_to_clear = Color(0, 0, 255)
print(color_to_clear)
def clear_color(strip, red, green, blue):
    color_to_clear = Color(255, 0, 0)
    for index, color in strip.getPixels():
        if color_to_clear == color:
            strip.setPixelColorRGB(index, 0, 0, 0)
>>> strip.setPixelColorRGB(1, 255, 0, 0)
>>> strip.setPixelColorRGB(2, 255, 0, 0)
>>> strip.setPixelColorRGB(3, 255, 0, 0)
>>> strip.setPixelColorRGB(4, 0, 255, 0)
>>> strip.setPixelColorRGB(5, 0, 255, 0)
>>> strip.setPixelColorRGB(6, 0, 255, 0)
>>> strip.setPixelColorRGB(7, 0, 0, 255)
>>> strip.setPixelColorRGB(8, 0, 0, 255)
>>> strip.setPixelColorRGB(9, 0, 0, 255)
>>> strip.show()
>>> strip.getPixelColor(1)
16711680
>>> strip.getPixelColor(2)
16711680
>>> strip.getPixelColor(3)
16711680
>>> strip.getPixelColor(4)
65280
>>> strip.getPixelColor(5)
65280
>>> strip.getPixelColor(6)
65280
>>> strip.getPixelColor(7)
255
>>> strip.getPixelColor(8)
255
>>> strip.getPixelColor(9)
255
>>> color_to_clear = Color(red, green, blue, white)
>>> print(color_to_clear)
65280
>>> color_to_clear = Color(255, 0, 0)
>>> print(color_to_clear)
16711680
>>> color_to_clear = Color(0, 255, 0)
>>> print(color_to_clear)
65280
>>> color_to_clear = Color(0, 0, 255)
>>> print(color_to_clear)
255
>>> def clear_color(strip, red, green, blue):
...     color_to_clear = Color(255, 0, 0)
...     for index, color in strip.getPixels():
...         if color_to_clear == color:
...             strip.setPixelColorRGB(index, 0, 0, 0)
...
>>>
>>>
Was tut sich an den LEDs?
Naja die LEDs schalten sich wie gefordert an (Die ersten 3 Rot, die nächsten 3 grün, die nächsten 3 blau)

Aber keine LED wird ausgeschalten (Also eigentlich sollten doch jetzt die ersten 3 LEDs ausgehen), oder?
Auch ein nachfoldenes "strip.show()" bewirkt nichts.

Danke
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Du rufst `clear_color` nie auf.
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rehgum: „``is`` bei Worten“ ist falsch. ``is`` verwendet man, wenn man wissen will ob es sich um das selbe Objekt handelt. ``==`` wenn man wissen will ob die Operanden den gleichen Wert haben aber nicht zwangsläufig das selbe Objekt sind. ``None`` ist ein Singleton, das heisst es gibt diesen Wert garantiert nur ein einziges mal. Darum kann man dafür ``is`` nehmen. Das ist bei Zahlen nicht garantiert, deshalb darf man da gar nicht ``is`` nehmen, weil das zu Fehlern führen kann.

Code: Alles auswählen

In [12]: a                                                                      
Out[12]: 4711

In [13]: b                                                                      
Out[13]: 4711

In [14]: a == b                                                                 
Out[14]: True

In [15]: a is b                                                                 
Out[15]: False
Es kann aber auch sein, dass zwei Namen auch tatsächlich zum gleichen Objekt aufgelöst werden:

Code: Alles auswählen

In [19]: a                                                                      
Out[19]: 42

In [20]: b                                                                      
Out[20]: 42

In [21]: a == b                                                                 
Out[21]: True

In [22]: a is b                                                                 
Out[22]: True
Darum funktioniert das mit ``is 1`` bei Dir zufällig. Es ist ganz allgemein aber nicht garantiert.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Sirius3 hat geschrieben: Dienstag 8. März 2022, 19:35 Du rufst `clear_color` nie auf.
Sorry, das habe ich natürlich ausgeführt, nur nicht mit kopiert.

Es tut sich trotzdem nichts. Jetzt hab ich das mal Zeile für Zeile eingegeben und erhalte

Code: Alles auswählen

>>> def clear_color(red, green, blue):
...     color_to_clear = Color(red, green, blue)
...     for index, color in strip.getPixels():
...         if color_to_clear == color:
...             strip.setPixelColorRGB(index, 0, 0, 0)
...
>>> clear_color(rt, gn, bl)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in clear_color
TypeError: cannot unpack non-iterable int object
Verstehe ich das richtig das er von dem strip.getPixels() einen anderen Datentyp erwartet?

Code: Alles auswählen

>>> a = strip.getPixels()
>>> print(a)
<rpi_ws281x.rpi_ws281x._LED_Data object at 0xb6750b80>
>>> print(type(a))
<class 'rpi_ws281x.rpi_ws281x._LED_Data'>
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

__blackjack__ hat geschrieben: Dienstag 8. März 2022, 21:29 @rehgum: „``is`` bei Worten“ ist falsch. ``is`` verwendet man, wenn man wissen will ob es sich um das selbe Objekt handelt. ``==`` wenn man wissen will ob die Operanden den gleichen Wert haben aber nicht zwangsläufig das selbe Objekt sind. ``None`` ist ein Singleton, das heisst es gibt diesen Wert garantiert nur ein einziges mal. Darum kann man dafür ``is`` nehmen. Das ist bei Zahlen nicht garantiert, deshalb darf man da gar nicht ``is`` nehmen, weil das zu Fehlern führen kann.

Code: Alles auswählen

In [12]: a                                                                      
Out[12]: 4711

In [13]: b                                                                      
Out[13]: 4711

In [14]: a == b                                                                 
Out[14]: True

In [15]: a is b                                                                 
Out[15]: False
Es kann aber auch sein, dass zwei Namen auch tatsächlich zum gleichen Objekt aufgelöst werden:

Code: Alles auswählen

In [19]: a                                                                      
Out[19]: 42

In [20]: b                                                                      
Out[20]: 42

In [21]: a == b                                                                 
Out[21]: True

In [22]: a is b                                                                 
Out[22]: True
Darum funktioniert das mit ``is 1`` bei Dir zufällig. Es ist ganz allgemein aber nicht garantiert.

Danke aber verstehen tu ich es noch nicht.
Wieso ist bei
a=42
b=42
a==b true
und
a is b true
nicht aber wenn a und b 4711 sind?
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rehgum: Weil in einem Fall zwei verschiedene Objekte sind, die den gleichen Wert haben, und im anderen Fall das selbe Objekt, was natürlich gleich sich selbst ist. Und die tatsächlichen Zahlenwerte sind im Grunde egal, das kann Dir theoretisch mit jedem Zahlwert passieren. Weshalb es halt wirklich *falsch* ist, Zahlen mit ``is`` zu vergleichen, weil man nicht sagen kann, was dabei heraus kommt. Gilt auch für Zeichenketten, und eben alles was kein Singleton ist, oder wo man genau weiss gegen welches Objekt man dort testet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Da fehlt in `enumerate`:

Code: Alles auswählen

def clear_color(strip, red, green, blue):
    color_to_clear = Color(red, green, blue)
    for index, color in enumerate(strip.getPixels()):
        if color_to_clear == color:
            strip.setPixelColorRGB(index, 0, 0, 0)
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Sirius3 hat geschrieben: Mittwoch 9. März 2022, 08:30 Da fehlt in `enumerate`:

Code: Alles auswählen

def clear_color(strip, red, green, blue):
    color_to_clear = Color(red, green, blue)
    for index, color in enumerate(strip.getPixels()):
        if color_to_clear == color:
            strip.setPixelColorRGB(index, 0, 0, 0)
        
Danke, aber dann tut sich wieder gar nichts mehr :/

Code: Alles auswählen

Python 3.9.2 (default, Mar 12 2021, 04:06:34)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from rpi_ws281x import *
strip.setPixelColorRGB(2, 255, 0, 0)
strip.setPixelColorRGB(3, 255, 0, 0)
strip.setPixelColorRGB(4, 0, 255, 0)
strip.setPixelColorRGB(5, 0, 255, 0)
strip.setPixelColorRGB(6, 0, 255, 0)
strip.setPixelColorRGB(7, 0, 0, 255)
strip.setPixelColorRGB(8, 0, 0, 255)
strip.setPixelColorRGB(9, 0, 0, 255)>>>
>>> ANZAHL_PIXEL = 300
>>> strip = Adafruit_NeoPixel(ANZAHL_PIXEL, 18, 800000, 5, False, 255)
>>> strip.begin()
>>> strip.setPixelColorRGB(1, 255, 0, 0)
>>> strip.setPixelColorRGB(2, 255, 0, 0)
>>> strip.setPixelColorRGB(3, 255, 0, 0)
>>> strip.setPixelColorRGB(4, 0, 255, 0)
>>> strip.setPixelColorRGB(5, 0, 255, 0)
>>> strip.setPixelColorRGB(6, 0, 255, 0)
>>> strip.setPixelColorRGB(7, 0, 0, 255)
>>> strip.setPixelColorRGB(8, 0, 0, 255)
>>> strip.setPixelColorRGB(9, 0, 0, 255)
>>> strip.show()
>>> def clear_color(strip, red, green, blue):
...     color_to_clear = Color(red, green, blue)
...     for index, color in enumerate(strip.getPixels()):
...         if color_to_clear == color:
...             strip.setPixelColorRGB(index, 0, 0, 0)
...
>>> clear_color(strip, 255, 0, 0)



Egal wie oft ich Enter drücke, springt er nur eine leere Zeile weiter runter.
Wenn ich ein else eingebe explodiert die Rückmeldung.

Code: Alles auswählen

def clear_color(strip, red, green, blue):
    color_to_clear = Color(red, green, blue)
    for index, color in enumerate(strip.getPixels()):
        if color_to_clear == color:
            strip.setPixelColorRGB(index, 0, 0, 0)
        else:
            print("nein leider nicht")
Ergebniss:
nein leider nicht
....unendlich oft "nein leider nicht"....
nein leider nicht
nein leider nicht
nein leider nicht
^Cnein leider nicht
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in clear_color
KeyboardInterrupt
>>>
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum gibst Du ständig "nein leider nicht" aus? Bei jeder LED die nicht ausgeschaltet wird? Das ist nicht unendlich mal, sondern 297mal.

Und Du rufst zum Schluß kein `strip.show()` auf, nachdem Du die LEDs wieder ausgeschaltet hast.
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

ich kann ja gar nichts mehr eingeben :(
Nach den
>>> clear_color(strip, 255, 0, 0)
ENTER
kommen nur noch leere Zeilen ohne die >>> also ich kann nichts mehr eingeben. bzw. ich kann schon was eingeben aber es passiert halt nichts.


Code: Alles auswählen

Python 3.9.2 (default, Mar 12 2021, 04:06:34)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from rpi_ws281x import *
strip.setPixelColorRGB(16, 0, 255, 0)
strip.setPixelColorRGB(17, 0, 0, 255)
strip.setPixelColorRGB(18, 0, 0, 255)
strip.setPixelColorRGB(19, 0, 0, 255)
strip.show()>>>
>>> ANZAHL_PIXEL = 300
>>> strip = Adafruit_NeoPixel(ANZAHL_PIXEL, 18, 800000, 5, False, 255)
>>> strip.begin()
>>> strip.setPixelColorRGB(11, 255, 0, 0)
>>> strip.setPixelColorRGB(12, 255, 0, 0)
>>> strip.setPixelColorRGB(13, 255, 0, 0)
>>> strip.setPixelColorRGB(14, 0, 255, 0)
>>> strip.setPixelColorRGB(15, 0, 255, 0)
>>> strip.setPixelColorRGB(16, 0, 255, 0)
>>> strip.setPixelColorRGB(17, 0, 0, 255)
>>> strip.setPixelColorRGB(18, 0, 0, 255)
>>> strip.setPixelColorRGB(19, 0, 0, 255)
>>> strip.show()
>>> def clear_color(strip, red, green, blue):
...     color_to_clear = Color(red, green, blue)
...     for index, color in enumerate(strip.getPixels()):
...         if color_to_clear == color:
...             strip.setPixelColorRGB(index, 0, 0, 0)
...
>>> clear_color(strip, 255, 0, 0)




strip.show()

ich kann hier schreiben was ich will
und es passiert nichts
Das ändert sich auch nicht wenn ich das strip.begin() nach dem vorherigen strip.show() einfüge.


Bild
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Okay also nach 10 Minuten ohne eingabe kommt:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in clear_color
OverflowError: iter index too large

Immerhin sind die betroffenen LEDs nun ausgegangen :D
rehgum
User
Beiträge: 22
Registriert: Montag 28. Februar 2022, 16:45

Niemand eine Idee wie ich den OverflowError weg bekomme? Neues Thmea öffnen?
Antworten