2 programme verbinden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Ich habe 2 Programme
Programm 1:

Code: Alles auswählen

import RPi.GPIO as GPIO
import lcddriver
import time
import os

# Use the Broadcom SOC Pin numbers
GPIO.setmode(GPIO.BCM)

# Import LCD driver (lcddriver.py file)
lcd = lcddriver.lcd()

# Setup the pins with internal pullups enabled and pin in reading mode.

GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #Shutdown button GPIO 21
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #Reboot button   GPIO 18 

# Our functions on what to do when the button is pressed
def Shutdown(channel):                              
    print("Shutting Down")                         #Show text in terminal 
    lcd.lcd_display_string("Shutting Down",1)      #Display text in LCD 
    time.sleep(3)                                  #Sleep 3 seconds
    os.system("sudo shutdown now")                 #Write command

def Reboot(channel):
    print("Rebooting")
    lcd.lcd_display_string("Rebooting",1)
    time.sleep(3)
    os.system("sudo reboot")

# Add our function to execute when the button pressed event happens
GPIO.add_event_detect(21, GPIO.FALLING, callback=Shutdown, bouncetime=2000)
GPIO.add_event_detect(18, GPIO.FALLING, callback=Reboot,   bouncetime=2000)
 
#Wait!
while 1:
   time.sleep(1)
Programm 2:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
import lcddriver
import signal, sys
import datetime
import time
import mysql
import mysql.connector
import os

#import lcddriver
#from time import*

lcd = lcddriver.lcd()
lcd.lcd_clear()

mydb = mysql.connector.connect(
  host="localhost",
  user="pi",
  password="raspberry",
  database="rfid"
)

GPIO.setmode(GPIO.BCM)

LED_BLUE = 12
LED_GREEN = 16
LED_YELLOW = 20
LED_RED = 21

GPIO.setup(LED_BLUE, GPIO.OUT)
GPIO.setup(LED_GREEN, GPIO.OUT)
GPIO.setup(LED_YELLOW, GPIO.OUT)
GPIO.setup(LED_RED, GPIO.OUT)

GPIO.output(LED_BLUE, GPIO.LOW)
GPIO.output(LED_GREEN, GPIO.LOW)
GPIO.output(LED_YELLOW, GPIO.LOW)
GPIO.output(LED_RED, GPIO.LOW)


#Parameter fuer Eintragung
evsb06 = "Training"
evsb08 = "Weisweil"

def abbruch(signal, frame):
    lcd.lcd_display_string("               ",1)
    lcd.lcd_display_string("               ",2)
    GPIO.cleanup()
    sys.exit(0)

GPIO.output(LED_BLUE, GPIO.HIGH)
signal.signal(signal.SIGINT, abbruch)

reader=SimpleMFRC522()

print ("Programm gestartet zum Karten scannen!")
lcd.lcd_display_string(" OK Los geht es ",1)

while True:
    GPIO.output(LED_GREEN, GPIO.HIGH)

    now = datetime.datetime.today()
    evsb05 = now.strftime('%Y-%m-%d')
    evsb09 = now.strftime('%Y')
    evsb10 = time.strftime('%H:%M:%S', time.localtime())
    evsb11 = ""

    cid, text=reader.read()
    lcd.lcd_display_string(" Karte erkannt  ",1)
    time.sleep(1)
    lcd.lcd_display_string(" Daten werden   ",1)
    lcd.lcd_display_string(" verarbeitet    ",2)
    GPIO.output(LED_GREEN, GPIO.LOW)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.HIGH)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.LOW)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.HIGH)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.LOW)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.HIGH)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.LOW)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.HIGH)
    time.sleep(0.2)
    GPIO.output(LED_GREEN, GPIO.LOW)
    GPIO.output(LED_YELLOW, GPIO.HIGH)
    time.sleep(0.2)
    lcd.lcd_display_string("Daten wurden in ",1)
    lcd.lcd_display_string(" DB eingetragen ",2)
    ivsb07 = cid
    mycursor = mydb.cursor()
    sql = f"SELECT * FROM db where db04 = {cid}"
    mycursor.execute(sql)
    myresult = mycursor.fetchone()
    if myresult is not None:
        mycursor = mydb.cursor()
        sql = f"SELECT * FROM db WHERE db04 = {cid}"
        mycursor.execute(sql)
        myresult = mycursor.fetchall()
        for row in myresult:
            ivsb01 = row[1]
            ivsb02 = row[2]
            ivsb03 = row[3]
            ivsb04 = row[4]
            ivsb05 = evsb05 
            ivsb06 = evsb06
            ivsb07 = cid 
            ivsb08 = evsb08 
            ivsb09 = evsb09 
            ivsb10 = evsb10 
            ivsb11 = evsb11
            ivsb12 = ""  
            
        mycursor = mydb.cursor()
        sql = "INSERT INTO iss (vsb01, vsb02, vsb03, vsb04, vsb05, vsb06, vsb07, vsb08, vsb09, vsb10, vsb11, vsb12) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
        val = (ivsb01, ivsb02, ivsb03, ivsb04, ivsb05, ivsb06, ivsb07, ivsb08, ivsb09, ivsb10, ivsb11, ivsb12)
        mycursor.execute(sql, val)
        mydb.commit()
        time.sleep(1)
        #gogo = str(cid)
        print (cid)
        print("Nächste Karte.")
        GPIO.output(LED_YELLOW, GPIO.LOW)
        lcd.lcd_display_string("OK, weitere C/K ",1)
        lcd.lcd_display_string("                ",2)
    else:
        mycursor = mydb.cursor()
        sql = f"SELECT * FROM cd where cd01 = {cid}"
        mycursor.execute(sql)
        myresult = mycursor.fetchone()
        if myresult is not None:
            lcd.lcd_display_string("C/K ist  in DB ",1)
            lcd.lcd_display_string("vorhanden      ",2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_RED, GPIO.LOW)
            print("Karte ist schon vorhanden.")
            print("Nächste Karte.")
            time.sleep(2)
            lcd.lcd_display_string("OK, weitere C/K ",1)
            lcd.lcd_display_string("                ",2)
        else:
            lcd.lcd_display_string("C/K wurde in DB",1)
            lcd.lcd_display_string("eingetragen    ",2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            GPIO.output(LED_YELLOW, GPIO.LOW)
            time.sleep(0.2)
            icd01 = cid
            icd02 = "f"
            icd03 = "n"
            mycursor = mydb.cursor()
            sql = "INSERT INTO cd (cd01, cd02, cd03) VALUES (%s, %s, %s)"
            val = (icd01, icd02, icd03)
            mycursor.execute(sql, val)
            mydb.commit()
            print (cid)
            print (" wurde eingetragen")
            print("Nächste Karte.")
            time.sleep(2)
            lcd.lcd_display_string("OK, weitere C/K ",1)
            lcd.lcd_display_string("                ",2)
Ich selber habe gesehen das ich LED_RED von PIN 21 auf einen aneren verlegen muß dazu habe ich mir noch keine gedanken gemacht auf welchen
auch die Teile wo mitgeladen werden sollen ( lcddriver usw sind nicht mein problem )
in beiden habe ich "def " und " xxx ", was ich soweit verstanden habe

Kann ich alles von Programm 1 über nehmen und bei Programm 2 einfügen bis auf das was schon wäre ?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo ist Dein konkretes Problem dabei? Hast Du die Programme verstanden?

Beide Programme müssen erst einmal sauber umgeschrieben werden, dass sie keine globalen Variablen benutzen, eine main-Funktion haben und eine saubere Finalisierung.

Das `signal.signal` im zweiten Programm muß auf jeden Fall durch try-finally ersetzt werden (Zeilen 49-56).
Man kopiert keinen Code vielfach, sondern nutzt Schleifen und Funktionen (Zeilen 77-93, 142-162, 172,192).
Die Variablennamen sind zum Teil sehr kryptisch (evsb05, ivsb03). Und warum sind die Spalten in der Datenbank genauso kryptisch. Das muß angepasst werden.
Man formatiert niemals Parameter direkt in SQL-Queries hinein, sondern benutzt Platzhalter! Wenn man nur ein Ergebnis erwartet, benutzt man fetchone und nicht fetchall und eine for-Schleife! Was passiert, wenn gar kein Datensatz gefunden wird? Bei Dir wird im günstigsten Fall ein NameError ausgelöst, im ungünstigsten die Daten der vorherigen Karte einfach als neuer Datensatz genommen. Ach nein, das wird ja mit einer identischen Abfrage davor abgefangen, sehr verwirrend.
Man benutzt keine *-SELECTs sondern gibt die Feldnamen explizit an, die man benötigt.
Warum ermittelst Du das Datum per datetime.today, die Uhrzeit aber nachträglich mit time.time? Damit kann es sein, dass Tag und Uhrzeit nicht zusammenpassen, weil die eine Abfrage vor und die andere nach Mitternacht stattfanden.
Warum werden Datum und Uhrzeit in DREI! Felder eingetragen? Das sollte nur ein TIMESTAMP-Feld sein.
Warum wird als Zeit überhaupt die Zeit genommen, wenn die vorhergehende Karte aufgelegt worden war, und nicht die Zeit der aktuellen Karte?

Wenn man am Ende jedes if/else-Blocks den selben Code hat, kann man den auch einmal danach schreiben.

Hier mal eine angepasste Version:

Code: Alles auswählen

#!/usr/bin/env python3
from RPi import GPIO
from mfrc522 import SimpleMFRC522
import lcddriver
import datetime
import mysql.connector
from contextlib import closing

LED_BLUE = 12
LED_GREEN = 16
LED_YELLOW = 20
LED_RED = 21

def initialize():
    lcd = lcddriver.lcd()
    lcd.lcd_clear()

    mydb = mysql.connector.connect(
      host="localhost",
      user="pi",
      password="raspberry",
      database="rfid"
    )
    reader = SimpleMFRC522()

    GPIO.setmode(GPIO.BCM)
    GPIO.setup([LED_BLUE, LED_GREEN, LED_YELLOW, LED_RED], GPIO.OUT, initial=GPIO.LOW)
    return lcd, mydb, reader

def blink(pin, count):
    for _ in range(count):
        GPIO.output(pin, GPIO.LOW)
        time.sleep(0.2)
        GPIO.output(pin, GPIO.HIGH)
        time.sleep(0.2)
    GPIO.output(pin, GPIO.LOW)


def update_database(mydb, timestamp):
    with closing(mydb.cursor()) as cursor:
        cursor.execute("SELECT * FROM db where db04 = %s", [cid])
        result = cursor.fetchone()
        if result is not None:
            cursor.execute("INSERT INTO iss (vsb01, vsb02, vsb03, vsb04, vsb05, vsb06, vsb07, vsb08, vsb09, vsb10, vsb11, vsb12) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",[
                row[1], row[2], row[3], row[4],
                now.strftime('%Y-%m-%d'), # TODO: use now
                "Training",
                cid,
                "Weisweil",
                now.strftime('%Y'), # TODO: remove extra year field
                now.strftime('%H:%M:%S'), # TODO: remove extra time field"
                "",
                "",
            ])
            mydb.commit()
            print(cid)
            return "iss-Eintrag"
        else:
            cursor.execute("SELECT * FROM cd where cd01 = %s", [cid])
            result = cursor.fetchone()
            if result is not None:
                print("Karte ist schon vorhanden.")
                return "schon da"
            else:
                cursor.execute("INSERT INTO cd (cd01, cd02, cd03) VALUES (%s, %s, %s)", [
                    cid, "f", "n",
                ])
                mydb.commit()
                print(f"{cid} wurde eingetragen")
                return "cd-Eintrag"


def main():
    lcd, mydb, reader = initialize()
    try:
        GPIO.output(LED_BLUE, GPIO.HIGH)
        print ("Programm gestartet zum Karten scannen!")
        lcd.lcd_display_string(" OK Los geht es ", 1)

        while True:
            GPIO.output(LED_GREEN, GPIO.HIGH)

            # Use time of previous usage, not the current card usage
            previous_now = datetime.datetime.now()

            cid, text = reader.read()
            lcd.lcd_display_string(" Karte erkannt  ",1)
            time.sleep(1)
            lcd.lcd_display_string(" Daten werden   ",1)
            lcd.lcd_display_string(" verarbeitet    ",2)
            blink(LED_GREEN, count=4)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            lcd.lcd_display_string("Daten wurden in ",1)
            lcd.lcd_display_string(" DB eingetragen ",2)

            result = update_database(mydb, previous_now)
            if result == "iss-Eintrag":
                pass
            elif result == "schon da":
                lcd.lcd_display_string("C/K ist  in DB ",1)
                lcd.lcd_display_string("vorhanden      ",2)
                blink(LED_RED, count=5)
            elif result == "iss-Eintrag":
                lcd.lcd_display_string("C/K wurde in DB",1)
                lcd.lcd_display_string("eingetragen    ",2)
                blink(LED_YELLOW, count=5)
            else:
                assert False
            
            GPIO.output(LED_YELLOW, GPIO.LOW)
            print("Nächste Karte.")
            time.sleep(2)
            lcd.lcd_display_string("OK, weitere C/K ",1)
            lcd.lcd_display_string("                ",2)

    finally:
        lcd.lcd_display_string("               ",1)
        lcd.lcd_display_string("               ",2)
        GPIO.cleanup()


if __name__ == "__main__":
    main()
Was fehlt ist die Klärung mit dem Zeitpunkt, und das anpassen der Datenbank-Tabellen und Feld-Namen.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Das `signal.signal` im zweiten Programm muß auf jeden Fall durch try-finally ersetzt werden (Zeilen 49-56).
wie schon erwähnt aus Buch oder Internet gefunden
Man kopiert keinen Code vielfach, sondern nutzt Schleifen und Funktionen (Zeilen 77-93, 142-162, 172,192).
Die Variablennamen sind zum Teil sehr kryptisch (evsb05, ivsb03). Und warum sind die Spalten in der Datenbank genauso kryptisch. Das muß angepasst werden.
Man formatiert niemals Parameter direkt in SQL-Queries hinein, sondern benutzt Platzhalter! Wenn man nur ein Ergebnis erwartet, benutzt man fetchone und nicht fetchall und eine for-Schleife! Was passiert, wenn gar kein Datensatz gefunden wird? Bei Dir wird im günstigsten Fall ein NameError ausgelöst, im ungünstigsten die Daten der vorherigen Karte einfach als neuer Datensatz genommen. Ach nein, das wird ja mit einer identischen Abfrage davor abgefangen, sehr verwirrend.
Man benutzt keine *-SELECTs sondern gibt die Feldnamen explizit an, die man benötigt.
Warum ermittelst Du das Datum per datetime.today, die Uhrzeit aber nachträglich mit time.time? Damit kann es sein, dass Tag und Uhrzeit nicht zusammenpassen, weil die eine Abfrage vor und die andere nach Mitternacht stattfanden.
Warum werden Datum und Uhrzeit in DREI! Felder eingetragen? Das sollte nur ein TIMESTAMP-Feld sein.
Warum wird als Zeit überhaupt die Zeit genommen, wenn die vorhergehende Karte aufgelegt worden war, und nicht die Zeit der aktuellen Karte?
Wie erkläre ich deine Fragen .......
Programm1 ist ein fund im Internet ( wo ich einen Taster als Reset bzw Schutdown nutzen kann ).
Programm2 ist von mir was ich viel mühe mir zusammen gestellt habe und auch sofort sehe was wo passiert.
Programm2 läuft so wie ich möchte
Ich besitze einige RFID Chips und Karten, derzeit ist nur 1 Chip aktiv (in Tabelle2 vorhanden und auch mit weiteren infos hinterlegt
Ablauf:
Tabelle1 = Liste alle Chips oder Karten
Tabelle2 = Liste aller Chips oder Karten wo zugeordnet sind ( Türöffner oder oder )
Tabelle3 = Wann , wo der Chip genutzt wurde
Tabelle4 = Hier nicht im gebrauch
1. Wenn ich mein Chip anhalte soll die ID vom Chip gelesen werden
2. LED Grün blink damit soll mitgeteilt werden Chip erkannt und gelesen
3.Vergleiche mit Tabelle2 ob Chip Vorhanden ist.
4.
A. Ist der Chip in der Tabelle2 dann lese Infos aus Tabelle2 und speichere mit weiteren Infos in anderen Tabelle3
LED_Gelb leuchtet
B. Ist der Chip nicht in der Tabelle2 dann vergleiche mit Tabelle1
B1. Ist der Chip nicht in Tabelle1, dann speichere seine ID in Tabelle1
LED_Gelb blinkt
B2. Ist der Chip in Tabelle1 ( und nicht in Tabelle3 ) zeige Fehler an
LED_rot blinkt
Bevor ich das 16x2 Display in Betrieb hatte, habe ich die LED's für mich als Info benutzet um zu wissen was Sache ist ( weil kein Bildschirm oder dergleichen genutzt wird )
Da sich meine programierung auf Bücher beschränken wo ich nur 10% verstehe ist alles aus Erfolg und Misserfolg zusammen gesetzt worden bei mir
drum auch soweit was ich an Code verstehe

wie bei Dir sehe hast Du "def" genommen was wiederum mit "if __name__ == "__main__":" zusammen hängt
in Programm fehlte "____main___" was für mich ein stolperer ist

Code: Alles auswählen

GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #Shutdown button GPIO 21
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #Reboot button   GPIO 18 

# Our functions on what to do when the button is pressed
def Shutdown(channel):                              
    print("Shutting Down")                         #Show text in terminal 
    lcd.lcd_display_string("Shutting Down",1)      #Display text in LCD 
    time.sleep(3)                                  #Sleep 3 seconds
    os.system("sudo shutdown now")                 #Write command

def Reboot(channel):
    print("Rebooting")
    lcd.lcd_display_string("Rebooting",1)
    time.sleep(3)
    os.system("sudo reboot")

# Add our function to execute when the button pressed event happens
GPIO.add_event_detect(21, GPIO.FALLING, callback=Shutdown, bouncetime=2000)
GPIO.add_event_detect(18, GPIO.FALLING, callback=Reboot,   bouncetime=2000)
Wenn ich diese Code in Programm2 über "while True:"
funzt es dann auch noch , bzw läuft Programm2 dann auch mit den 2 Taster ?
Das `signal.signal` im zweiten Programm muß auf jeden Fall durch try-finally ersetzt werden (Zeilen 49-56).
wie schon erwähnt aus Buch oder Internet gefunden
Man kopiert keinen Code vielfach, sondern nutzt Schleifen und Funktionen (Zeilen 77-93, 142-162, 172,192).
Die Variablennamen sind zum Teil sehr kryptisch (evsb05, ivsb03). Und warum sind die Spalten in der Datenbank genauso kryptisch. Das muß angepasst werden.
Man formatiert niemals Parameter direkt in SQL-Queries hinein, sondern benutzt Platzhalter! Wenn man nur ein Ergebnis erwartet, benutzt man fetchone und nicht fetchall und eine for-Schleife! Was passiert, wenn gar kein Datensatz gefunden wird? Bei Dir wird im günstigsten Fall ein NameError ausgelöst, im ungünstigsten die Daten der vorherigen Karte einfach als neuer Datensatz genommen. Ach nein, das wird ja mit einer identischen Abfrage davor abgefangen, sehr verwirrend.
Man benutzt keine *-SELECTs sondern gibt die Feldnamen explizit an, die man benötigt.
Warum ermittelst Du das Datum per datetime.today, die Uhrzeit aber nachträglich mit time.time? Damit kann es sein, dass Tag und Uhrzeit nicht zusammenpassen, weil die eine Abfrage vor und die andere nach Mitternacht stattfanden.
Warum werden Datum und Uhrzeit in DREI! Felder eingetragen? Das sollte nur ein TIMESTAMP-Feld sein.
Warum wird als Zeit überhaupt die Zeit genommen, wenn die vorhergehende Karte aufgelegt worden war, und nicht die Zeit der aktuellen Karte?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Du bekommst hier zum ersten Mal für Dein Programm Rückmeldung, und niemand erwartet, dass das perfekt ist, aber es gibt eben noch viel zu tun. Ich habe Dir viele Stichworte geliefert, jetzt mußt Du halt das Nachlesen, was Du an Python-Konstrukten noch nicht kennst und versuchen, das aufgeräumte Programm zu verstehen, um dann auf ein Niveau zu kommen, dass Du auch Dein zweites Programm mit einbauen kannst.

Es ist ungefähr so, wie wenn Du zu einem Architekten gehst und sagst, ich habe hier einen Bungalow zusammengezimmert und da möchte ich jetzt noch ein zweites Stockwerk draufsetzen. Da wirst Du auch als Antwort bekommen, dass die Statik nicht ausreichend ist, und Dir beim Versuch das ganze Haus zusammenbricht.

Die grundsätzlichen Fragen, die ganz unabhängig von der Programmierung sind, hast Du nicht beantwortet.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Wo ist Dein konkretes Problem dabei? Hast Du die Programme verstanden?
Versteanden habe ich nur 1/4 von wo ich habe
Beide Programme müssen erst einmal sauber umgeschrieben werden, dass sie keine globalen Variablen benutzen, eine main-Funktion haben und eine saubere Finalisierung.
globale Variablen = ist für mich wieder fremd
Das `signal.signal` im zweiten Programm muß auf jeden Fall durch try-finally ersetzt werden (Zeilen 49-56).
Wie schon gesagt so habe ich den Code vorgefunden
Man kopiert keinen Code vielfach, sondern nutzt Schleifen und Funktionen (Zeilen 77-93, 142-162, 172,192).
while und for sind schleifen, anfangs hatte ich mal genutzt aber bin davon weg weil ich den überblick verloren hatte
Die Variablennamen sind zum Teil sehr kryptisch (evsb05, ivsb03). Und warum sind die Spalten in der Datenbank genauso kryptisch. Das muß angepasst werden.
ich habe damit ein besseren einblick und gleichzeitig sehe ich darin eine art schutz
Man formatiert niemals Parameter direkt in SQL-Queries hinein, sondern benutzt Platzhalter! Wenn man nur ein Ergebnis erwartet, benutzt man fetchone und nicht fetchall und eine for-Schleife! Was passiert, wenn gar kein Datensatz gefunden wird? Bei Dir wird im günstigsten Fall ein NameError ausgelöst, im ungünstigsten die Daten der vorherigen Karte einfach als neuer Datensatz genommen. Ach nein, das wird ja mit einer identischen Abfrage davor abgefangen, sehr verwirrend.
Man benutzt keine *-SELECTs sondern gibt die Feldnamen explizit an, die man benötigt.
In meiner programm erklärung habe ich es erklärt wenn kein CID wert in tabelle gefunden wurde
das programm läuft so und mach das so wie ich es will und beschrieben habe
ich habe so ein überblick über das wo was abläuft
Warum ermittelst Du das Datum per datetime.today, die Uhrzeit aber nachträglich mit time.time? Damit kann es sein, dass Tag und Uhrzeit nicht zusammenpassen, weil die eine Abfrage vor und die andere nach Mitternacht stattfanden.
Warum werden Datum und Uhrzeit in DREI! Felder eingetragen? Das sollte nur ein TIMESTAMP-Feld sein.
Warum wird als Zeit überhaupt die Zeit genommen, wenn die vorhergehende Karte aufgelegt worden war, und nicht die Zeit der aktuellen Karte?
Mir ist klar das ich Datum und Zeit zusammen schreiben kann, aber dann ich es nicht vergleichen
das programm hier ist nur ein Teil aus vielen Dingen, von einer anderen stelle wird mit php zB einträge in der iss bzw ess später in eine andere SQL Datenbank übertragen
Jede Einheit soll für sich abgeschlosssen sein und später dann zusammen ins große über tragen
Wenn man am Ende jedes if/else-Blocks den selben Code hat, kann man den auch einmal danach schreiben.
Wie schon gesagt ich brauche de überblick

Beispiel
Vor vielen Jahren fing ich an mit Delphi2 was zu machen ( Delphi 2 in 21 Tagen ) bis ich endelich eine DB hatte und mein frontdazu zum einträgen, verändern und löschen mit abfragen und drucken waren es 3 Monate.
Ein begriff aus der Zeit Objektorentierte Programierung, was das auch immer heißen soll.
dann bekam ich ein Buch für C++, ich fing an zu lesen es kam der Begriff Bibliotheken ( keine erklärung dazu ) heute weiß ich etwas mehr
es sind zusätze oder funktionen mit mit geladen werden können ohne sie neu schreiben zu müßen ( was mich wieder vor fragen stellt, woher weiß ich was und wofür ist )

meine ersten versuche waren auch mit TRY aber mein programm wiederholte sich nicht so kam ich auf while
das mit DEF ist ja auch so eine sache, die müßen ja irgend wo aufgerufen werden ( ____main___) wie von Dir geschrieben oder mit () war da was
ich gehe nach erfolg und misserfolg vor wenn ich ein Code finde wo für mich passt versuche ich ihn einzubinden

Hurra ich hatte Erfolg der Code mit Taster hat geklappt aber ich verstehe nicht warum und wieso.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Du kannst gerne Deine eigenen Rechtfertigungen haben, warum Dein Code so aussieht, wie er aussieht. Aber erwarte nicht, dass den irgendwer anderer versteht, oder überhaupt Lust hat, den sich anzuschauen.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Habe versucht den Code von Dir umzusetzen, aber ohne erfolg.
Nun bin ich dran alles neu zu machen
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Nach dem Code von Dir ?

Traceback (most recent call last):
File "r.py", line 125, in <module>
main()
File "r.py", line 75, in main
lcd, mydb, reader = initialize()
File "r.py", line 27, in initialize
GPIO.setmode(GPIO.BCM)
ValueError: A different mode has already been set!
Benutzeravatar
sparrow
User
Beiträge: 4185
Registriert: Freitag 17. April 2009, 10:28

Du musst schon den ganzen Code zeigen. Alleine an der Fehlermeldung kann man nur sagen was die dir auch sagt: du kannst den Mode nicht ändern, nachdem er schon gesetzt ist.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Code: Alles auswählen

#!/usr/bin/env python3
from RPi import GPIO
from mfrc522 import SimpleMFRC522
import lcddriver
import datetime
import mysql.connector
from contextlib import closing

LED_BLUE = 12
LED_GREEN = 13   
LED_YELLOW = 19
LED_RED = 20
TON = 26

def initialize():
    lcd = lcddriver.lcd()
    lcd.lcd_clear()

    mydb = mysql.connector.connect(
      host="localhost",
      user="pi",
      password="raspberry",
      database="rfid"
    )
    reader = SimpleMFRC522()

    GPIO.setmode(GPIO.BCM)
    GPIO.setup([LED_BLUE, LED_GREEN, LED_YELLOW, LED_RED], GPIO.OUT, initial=GPIO.LOW)
    return lcd, mydb, reader

def blink(pin, count):
    for _ in range(count):
        GPIO.output(pin, GPIO.LOW)
        time.sleep(0.2)
        GPIO.output(pin, GPIO.HIGH)
        time.sleep(0.2)
    GPIO.output(pin, GPIO.LOW)


def update_database(mydb, timestamp):
    with closing(mydb.cursor()) as cursor:
        cursor.execute("SELECT * FROM db where db04 = %s", [cid])
        result = cursor.fetchone()
        if result is not None:
            cursor.execute("INSERT INTO iss (vsb01, vsb02, vsb03, vsb04, vsb05, vsb06, vsb07, vsb08, vsb09, vsb10, vsb11, vsb12) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",[
                row[1], row[2], row[3], row[4],
                now.strftime('%Y-%m-%d'), # TODO: use now
                "Training",
                cid,
                "Weisweil",
                now.strftime('%Y'), # TODO: remove extra year field
                now.strftime('%H:%M:%S'), # TODO: remove extra time field"
                "",
                "",
            ])
            mydb.commit()
            print(cid)
            return "iss-Eintrag"
        else:
            cursor.execute("SELECT * FROM cd where cd01 = %s", [cid])
            result = cursor.fetchone()
            if result is not None:
                print("Karte ist schon vorhanden.")
                return "schon da"
            else:
                cursor.execute("INSERT INTO cd (cd01, cd02, cd03) VALUES (%s, %s, %s)", [
                    cid, "f", "n",
                ])
                mydb.commit()
                print(f"{cid} wurde eingetragen")
                return "cd-Eintrag"


def main():
    lcd, mydb, reader = initialize()
    try:
        GPIO.output(LED_BLUE, GPIO.HIGH)
        print ("Programm gestartet zum Karten scannen!")
        lcd.lcd_display_string(" OK Los geht es ", 1)

        while True:
            GPIO.output(LED_GREEN, GPIO.HIGH)

            # Use time of previous usage, not the current card usage
            previous_now = datetime.datetime.now()

            cid, text = reader.read()
            lcd.lcd_display_string(" Karte erkannt  ",1)
            time.sleep(1)
            lcd.lcd_display_string(" Daten werden   ",1)
            lcd.lcd_display_string(" verarbeitet    ",2)
            blink(LED_GREEN, count=4)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            lcd.lcd_display_string("Daten wurden in ",1)
            lcd.lcd_display_string(" DB eingetragen ",2)

            result = update_database(mydb, previous_now)
            if result == "iss-Eintrag":
                pass
            elif result == "schon da":
                lcd.lcd_display_string("C/K ist  in DB ",1)
                lcd.lcd_display_string("vorhanden      ",2)
                blink(LED_RED, count=5)
            elif result == "iss-Eintrag":
                lcd.lcd_display_string("C/K wurde in DB",1)
                lcd.lcd_display_string("eingetragen    ",2)
                blink(LED_YELLOW, count=5)
            else:
                assert False
            
            GPIO.output(LED_YELLOW, GPIO.LOW)
            print("Nächste Karte.")
            time.sleep(2)
            lcd.lcd_display_string("OK, weitere C/K ",1)
            lcd.lcd_display_string("                ",2)

    finally:
        lcd.lcd_display_string("               ",1)
        lcd.lcd_display_string("               ",2)
        GPIO.cleanup()


if __name__ == "__main__":
    main()
Wie zu sehe ich habe nur 3 GPIO's geändert und 1 hinzugefügt, wegen änderungen
now.strftime('%Y'), # TODO: remove extra year field
now.strftime('%H:%M:%S'), # TODO: remove extra time field"
Das brauche ich wegen abfragen später weil ich das gesammte nicht trennen ( nicht weis wie trennen ) kann
print("") fliegt nach und nach raus wird mit lcd.lcd_display_string("") ersetzt
ich denke die von mit gemachten änderungen sollten kein einfluß auf den fehler haben
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Da kommt es wohl auf die richtige Reihenfolge an:

Code: Alles auswählen

    GPIO.setmode(GPIO.BCM)
    GPIO.setup([LED_BLUE, LED_GREEN, LED_YELLOW, LED_RED], GPIO.OUT, initial=GPIO.LOW)
    reader = SimpleMFRC522()
Warum solltest Du nicht an der Stelle, an der Du das Jahr brauchst, nicht das Jahr aus dem TIMESTAMP extrahieren können. Das macht keinen Sinn.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

ich lerne langsam py und php
vieles was ich habe ist zusammen gesetzt
unter php habe ich einen eventcalender
z.B.
30.01.2021
$start_day = intval(strtotime(htmlspecialchars($_POST["start_day"])));
$end_day = intval(strtotime(htmlspecialchars($_POST["start_day"])));
$start_day wird dan so gesichert

weil ich es nicht auslesen kann eine weiteres feld wo es drin steht für mich zum abfragen

ich habe einiges schon umsetzen können aus deinem code, bzw habe versucht meinen zu ändern

das mit dem blink funktion habe ich für mich umsetzen können und sogar auch noch weitere sachen damit machen können
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo ist denn deine Datenbankabfrage?
Wie Daten gespeichert werden, ist eine wichtige Frage. Ein wichtiger Grundsatz ist, keine Redundanz zu haben.
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

es ist nur ein auszug aus php gewesen
ich kann mit der art daten speichern nichts anfangen und wieder auslesen
aber was anderes
an anfang kam try zu nehmen
dazu habe ich eine frage

Code: Alles auswählen

def initialize():
    lcd = lcddriver.lcd()
    lcd.lcd_clear()

    mydb = mysql.connector.connect(
      host="localhost",
      user="pi",
      password="raspberry",
      database="rfid"
    )
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup([LED_BLUE, LED_GREEN, LED_YELLOW, LED_RED], GPIO.OUT, initial=GPIO.LOW)
    reader = SimpleMFRC522()
    
    return lcd, mydb, reader

was ich wenn mehrer datenbanken abfragen will ob sie vorhanden sind
weil
wenn nicht 1 dann nutze 2 zum speichern bzw arbeiten
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

genervternewbie hat geschrieben: Sonntag 30. Januar 2022, 14:21 ich kann mit der art daten speichern nichts anfangen und wieder auslesen
ich kann mit Deiner Art Daten zu speichern auch nichts anfangen. Da sind wir ja dann zu zweit. Deshalb schreibe ich ja die ganze Zeit, dass man das ändern muß. Aber ohne, dass Du zeigst, wo Du Probleme mit der Datenabfrage hast, kann man Dir da auch nicht helfen.

Was meinst Du damit, dass Du zwei Datenbanken hast?
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

das habe ich aus einen php script
$start_day = intval(strtotime(htmlspecialchars($_POST["start_day"])));
$end_day = intval(strtotime(htmlspecialchars($_POST["start_day"])));
$start_day diesen inhalt wird in db gespeichert
ich sehe das in db
1613084400
ich hoffe du verstehst jetzt warum ich doppelt speichere
aber das ist nicht mehr mein problem

ich lernen als noch mit dem Code von dir
je mehr ich das lese je mehr fragen kommen auf

wechsele mal eben computer
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

Code: Alles auswählen

#!/usr/bin/env python3
from RPi import GPIO
from mfrc522 import SimpleMFRC522
import lcddriver
import time
import datetime
import mysql.connector
from contextlib import closing

LED_BLUE = 13
LED_GREEN = 16
LED_YELLOW = 19
LED_RED = 20
TON = 26

def initialize():
    lcd = lcddriver.lcd()
    lcd.lcd_clear()

    mydb = mysql.connector.connect(
      host="localhost",
      user="pi",
      password="raspberry",
      database="rfid"
    )
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup([LED_BLUE, LED_GREEN, LED_YELLOW, LED_RED, TON], GPIO.OUT, initial=GPIO.LOW)
    reader = SimpleMFRC522()
    
    return lcd, mydb, reader

def blink(pin, count):
    for _ in range(count):
        GPIO.output(pin, GPIO.LOW)
        time.sleep(0.2)
        GPIO.output(pin, GPIO.HIGH)
        time.sleep(0.2)
    GPIO.output(pin, GPIO.LOW)


def update_database(mydb, timestamp):
    with closing(mydb.cursor()) as cursor:
        cursor.execute("SELECT * FROM db where db04 = %s", [cid])
        result = cursor.fetchall()
        if result is not None:
            cursor.execute("INSERT INTO iss (vsb01, vsb02, vsb03, vsb04, vsb05, vsb06, vsb07, vsb08, vsb09, vsb10, vsb11, vsb12) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",[
                row[1], row[2], row[3], row[4],
                now.strftime('%Y-%m-%d'), # TODO: use now
                "Training",
                cid,
                "Weisweil",
                now.strftime('%Y'), # TODO: remove extra year field
                now.strftime('%H:%M:%S'), # TODO: remove extra time field"
                "",
                "",
            ])
            mydb.commit()
            print(cid)
            return "iss-Eintrag"
        else:
            cursor.execute("SELECT * FROM cd where cd01 = %s", [cid])
            result = cursor.fetchall()
            if result is not None:
                print("Karte ist schon vorhanden.")
                return "schon da"
            else:
                cursor.execute("INSERT INTO cd (cd01, cd02, cd03) VALUES (%s, %s, %s)", [
                    cid, "f", "n",
                ])
                mydb.commit()
                print(f"{cid} wurde eingetragen")
                return "cd-Eintrag"


def main():
    lcd, mydb, reader = initialize()
    try:
        GPIO.output(LED_BLUE, GPIO.HIGH)
        print ("Programm gestartet zum Karten scannen!")
        lcd.lcd_display_string(" OK Los geht es ", 1)

        while True:
            GPIO.output(LED_GREEN, GPIO.HIGH)

            # Use time of previous usage, not the current card usage
            previous_now = datetime.datetime.now()

            cid, text = reader.read()
            print(cid)
            lcd.lcd_display_string(" Karte erkannt  ",1)
            time.sleep(1)
            lcd.lcd_display_string(" Daten werden   ",1)
            lcd.lcd_display_string(" verarbeitet    ",2)
            blink(LED_GREEN, count=4)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            lcd.lcd_display_string("Daten wurden in ",1)
            lcd.lcd_display_string(" DB eingetragen ",2)

            result = update_database(mydb, previous_now)
            if result == "iss-Eintrag":
                pass
            elif result == "schon da":
                lcd.lcd_display_string("C/K ist  in DB ",1)
                lcd.lcd_display_string("vorhanden      ",2)
                blink(LED_RED, count=5)
            elif result == "iss-Eintrag":
                lcd.lcd_display_string("C/K wurde in DB",1)
                lcd.lcd_display_string("eingetragen    ",2)
                blink(LED_YELLOW, count=5)
            else:
                assert False
            
            GPIO.output(LED_YELLOW, GPIO.LOW)
            print("Nächste Karte.")
            time.sleep(2)
            lcd.lcd_display_string("OK, weitere C/K ",1)
            lcd.lcd_display_string("                ",2)

    finally:
        lcd.lcd_display_string("               ",1)
        lcd.lcd_display_string("               ",2)
        GPIO.cleanup()


if __name__ == "__main__":
    main()

Ergebnis


Code: Alles auswählen

Programm gestartet zum Karten scannen!
226825939761
Traceback (most recent call last):
  File "r.py", line 128, in <module>
    main()
  File "r.py", line 101, in main
    result = update_database(mydb, previous_now)
  File "r.py", line 44, in update_database
    cursor.execute("SELECT * FROM db where db04 = %s", [cid])
NameError: name 'cid' is not defined
Muß ich cid nicht mit übergeben nach def ?
zumindest habe ich es so verstanden was globale und locale variablen angeht
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast in PHP einen Unix-Timestamp, sagst Du ja auch explizit, dass Du das haben willst (strtotime).
Und deshalb nochmal der dringende Rat, dein Datenbankschema anzupassen. MySQL kann wunderbar mit Zeiten rechnen, wenn man ihm nur die Chance gibt, indem man auch wirklich Datumsfelder anlegt.
Das macht Dein Programmiererleben an so vielen Stellen so viel einfacher und fehlerfreier.
Wenn Du Spalten aus einer Tabelle `db` (sehr schlechter Name) in eine Tabelle `iss` (genauso schlechter Name) kopierst, dann verletzt Du ein wichtiges Datenbankprinzip: Normalisierung.

Ja, da waren noch ein paar Fehler drin:

Code: Alles auswählen

#!/usr/bin/env python3
from RPi import GPIO
from mfrc522 import SimpleMFRC522
import lcddriver
import time
import datetime
import mysql.connector
from contextlib import closing

LED_BLUE = 13
LED_GREEN = 16
LED_YELLOW = 19
LED_RED = 20
TON = 26

def initialize():
    lcd = lcddriver.lcd()
    lcd.lcd_clear()

    mydb = mysql.connector.connect(
      host="localhost",
      user="pi",
      password="raspberry",
      database="rfid"
    )
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup([LED_BLUE, LED_GREEN, LED_YELLOW, LED_RED, TON], GPIO.OUT, initial=GPIO.LOW)
    reader = SimpleMFRC522()
    
    return lcd, mydb, reader

def blink(pin, count):
    for _ in range(count):
        GPIO.output(pin, GPIO.LOW)
        time.sleep(0.2)
        GPIO.output(pin, GPIO.HIGH)
        time.sleep(0.2)
    GPIO.output(pin, GPIO.LOW)


def update_database(mydb, timestamp, card_id):
    with closing(mydb.cursor()) as cursor:
        cursor.execute("SELECT * FROM db where db04 = %s", [card_id])
        # TODO: explicitly name the fields to query
        result = cursor.fetchone()
        if result is not None:
            # TODO: find readable names for the fields and table.
            # TODO: Remove result, due to normalization
            cursor.execute("INSERT INTO iss (vsb01, vsb02, vsb03, vsb04, vsb05, vsb06, vsb07, vsb08, vsb09, vsb10, vsb11, vsb12) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",[
                result[1], result[2], result[3], result[4],
                now.strftime('%Y-%m-%d'), # TODO: use now
                "Training",
                card_id,
                "Weisweil",
                now.strftime('%Y'), # TODO: remove extra year field
                now.strftime('%H:%M:%S'), # TODO: remove extra time field"
                "",
                "",
            ])
            mydb.commit()
            print(card_id)
            return "iss-Eintrag"
        else:
            cursor.execute("SELECT cd01 FROM cd where cd01 = %s", [card_id])
            result = cursor.fetchone()
            if result is not None:
                print("Karte ist schon vorhanden.")
                return "schon da"
            else:
                # TODO: find readable names for the fields and table.
                cursor.execute("INSERT INTO cd (cd01, cd02, cd03) VALUES (%s, %s, %s)", [
                    card_id, "f", "n",
                ])
                mydb.commit()
                print(f"{card_id} wurde eingetragen")
                return "cd-Eintrag"


def main():
    lcd, mydb, reader = initialize()
    try:
        GPIO.output(LED_BLUE, GPIO.HIGH)
        print("Programm gestartet zum Karten scannen!")
        lcd.lcd_display_string(" OK Los geht es ", 1)

        while True:
            GPIO.output(LED_GREEN, GPIO.HIGH)

            card_id, text = reader.read()
            print(card_id)
            lcd.lcd_display_string(" Karte erkannt  ",1)
            time.sleep(1)
            lcd.lcd_display_string(" Daten werden   ",1)
            lcd.lcd_display_string(" verarbeitet    ",2)
            blink(LED_GREEN, count=4)
            GPIO.output(LED_YELLOW, GPIO.HIGH)
            time.sleep(0.2)
            lcd.lcd_display_string("Daten wurden in ",1)
            lcd.lcd_display_string(" DB eingetragen ",2)

            # Correctly, use the current time!
            now = datetime.datetime.now()
            result = update_database(mydb, now, card_id)
            if result == "iss-Eintrag":
                pass
            elif result == "schon da":
                lcd.lcd_display_string("C/K ist  in DB ",1)
                lcd.lcd_display_string("vorhanden      ",2)
                blink(LED_RED, count=5)
            elif result == "cd-Eintrag":
                lcd.lcd_display_string("C/K wurde in DB",1)
                lcd.lcd_display_string("eingetragen    ",2)
                blink(LED_YELLOW, count=5)
            else:
                assert False
            
            GPIO.output(LED_YELLOW, GPIO.LOW)
            print("Nächste Karte.")
            time.sleep(2)
            lcd.lcd_display_string("OK, weitere C/K ",1)
            lcd.lcd_display_string("                ",2)

    finally:
        lcd.lcd_display_string("               ",1)
        lcd.lcd_display_string("               ",2)
        GPIO.cleanup()


if __name__ == "__main__":
    main()
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

import time #für time.sleep(0.2) nötig
import datetime #für Zeitstempel
soweit mir klar
now.strftime('%Y-%m-%d'), # TODO: use now
"Training",
card_id,
"Weisweil",
now.strftime('%Y'), # TODO: remove extra year field
now.strftime('%H:%M:%S'), # TODO: remove extra time field"
aber
now is not defined
muß now noch wo an gegeben werden ?
wei es zu dem fehler kommt
genervternewbie
User
Beiträge: 25
Registriert: Samstag 17. November 2018, 18:42

now.datetime.datetime.today()
das hatte gefehlt
Antworten