programing

RFID 카드가 로그아웃을 위해 두 번째로 읽히는 것을 시스템이 인식하도록 하려면 어떻게 해야 합니까?

kingscode 2022. 9. 20. 23:16
반응형

RFID 카드가 로그아웃을 위해 두 번째로 읽히는 것을 시스템이 인식하도록 하려면 어떻게 해야 합니까?

저는 초보라서 도움/지도가 필요해요!그래서 기본적으로 라즈베리 파이 4와 RFID 리더와 라이터를 사용하여 출석 시스템을 만들려고 합니다.현재까지는 모든 것이 잘 되고 있지만, sign_out을 위한 데이터 송부에 어려움을 겪고 있습니다.지금은 데이터베이스에서도 sign_in에 있는 타임스탬프와 같은 타임스탬프가 sign_out에 표시되지만, 여기서는 RFID 카드를 두 번째로 읽을 때 sign_out 열에 데이터가 입력되도록 하고 싶습니다.다른 제안이 있으면 기꺼이 듣고 배우겠습니다. 감사합니다.편집: "이 질문에서 코드 전체가 삭제되었습니다."

사인/사인아웃을 스위치로 취급하는 것을 고려해 본 적이 있습니까?기본 상태는 다음과 같습니다.sign-in0 또는 false로 설정합니다.sign-out1 또는 true로 설정합니다.그런 다음 카드를 읽으면 로그인 값을 확인합니다.0/false일 경우 1/true로 플립되고 로그아웃에는 반대로 플립됩니다.카드를 두 번째로 읽으면 로그아웃이 읽히고 0/false일 경우 1/true로 설정되며 사인인과는 반대됩니다.

알기 쉽게 하기 위해:

current state: 
    sign-in = 0
    sign-out = 1

---> card is read for the first time
sign-in = (sign-in + 1) % 2 
sign-out = (sign-out + 1) %2

state now:
    sign-in = 1
    sign-out = 0

---> card is read for the second time, consider previous state
sign-in = (sign-i + 1) % 2
sign-out = (sign-out + 1) % 2

state:
    sign-in = 0
    sign-out = 1

이 모든 것은 2개의 상태를 1개의 상태로 줄임으로써 더욱 심플화할 수 있습니다.signed-in.

initial state:
    signed-in = 0

---> card is read for entry
signed-in = (signed-in + 1) % 2

state:
    signed-in = 1

---> card is read for exit
signed-out = (signed-in + 1) % 2

state:
    signed-in = 0

간단히 말하면, 이 머신은, 다음의 2개의 이행이 있는 심플한 스테이트 머신이라고 생각할 수 있습니다.In로.Out및 에서Out로.In여기에 이미지 설명 입력

이것이 올바른 방향으로 안내하는 데 도움이 됩니까?

타임스탬프 질문

따라서 루프에 들어가기 전에 타임스탬프를 1회 초기화합니다.이동해 보다

ts = time.time()
timestamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d     %H:%M:%S'

다음 행 뒤에 표시됩니다.

id, text = reader.read()

이것으로 당신의 문제는 해결되었습니까?

일반적인 스타일의 코멘트

다음을 단순화할 수 있습니다.

if sign_in == 0:
    sign_in = (sign_in + 1) % 2
    sign_out = (sign_out + 1) % 2
    #id, text = reader.read()
    cursor.execute("INSERT INTO attendance (user_id, clock_in) VALUES (%s, %s)", (result[0], timestamp,) )
    lcd.lcd_display_string("Sign in " + result[1])

  elif sign_in == 1:
    sign_out = (sign_out + 1) % 2
    sign_in = (sign_in + 1) % 2
    #id, text = reader.read()
    cursor.execute("INSERT INTO attendance (user_id, clock_out) VALUES (%s, %s)", (result[0], timestamp,) )

    lcd.lcd_display_string("Sign out " + result[1])

더 비슷한 것으로

sign_in = (sign_in + 1) % 2
sign_out = (sign_out + 1) % 2
#id, text = reader.read()
field_in_or_out = 'in' if sign_in == 1 else 'out'
cursor.execute(f"INSERT INTO attendance (user_id, clock_{field_in_or_out}) VALUES (%s, %s)", (result[0], timestamp,) )
lcd.lcd_display_string(f"Sign {field_in_or_out} " + result[1])

로직을 더 단순화하는 방법

#!/usr/bin/env python
import time
import datetime
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
import mysql.connector
import I2C_LCD_driver

db = mysql.connector.connect(
    host="localhost",
    user="admin",
    passwd="*******",
    database="attendancesystem"
)

cursor = db.cursor()
reader = SimpleMFRC522()
lcd = I2C_LCD_driver.lcd()
#redLED = 4
#yellowLED = 17
#greenLED = 27
#GPIO.setmode(GPIO.BCM)
signed_in = 0
try:
    while True:
        lcd.lcd_clear()
        lcd.lcd_display_string('Place Card to')
        lcd.lcd_display_string('record attendance', 2)
        id, text = reader.read()

        ts = time.time()
        timestamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d     %H:%M:%S')

        cursor.execute("Select id, name FROM users WHERE rfid_uid="+str(id))
        result = cursor.fetchone()

        lcd.lcd_clear()

        if cursor.rowcount >= 1:
            lcd.lcd_display_string("Welcome")
            lcd.lcd_display_string(""+ result[1], 2)
            #GPIO.output(greenLED,GPIO.HIGH)
            #time.sleep(3)
            #GPIO.output(greenLED,GPIO.LOW)
            cursor.execute("INSERT INTO attendance (user_id) VALUES (%s)", (result[0],) )

            signed_in = (signed_in + 1) % 2
            #id, text = reader.read()
            cursor.execute(f"INSERT INTO attendance (user_id, read_at) VALUES (%s, %s)", (result[0], timestamp,) )
            lcd.lcd_display_string(f"Card read " + result[1])
            db.commit()

        else:
            lcd.lcd_display_string("User does not")
            lcd.lcd_display_string("exist !!", 2)
            #GPIO.output(yellowLED,GPIO.HIGH)
            #time.sleep(3)
            #GPIO.output(yellowLED,GPIO.LOW)
        time.sleep(2)
finally:
    GPIO.cleanup()

데이터베이스 스키마를 업데이트하여user_id및 aread_at시간 컬럼을 표시합니다.변경하다sign_in/sign_out을 가질 수 있는 것signed_in두 개의 상태를 모두 나타내는 필드(사용자가 로그인한 경우 1, 로그인하지 않은 경우 0)입니다.

코드의 다른 변경은 타임스탬프 로직을 끌어당기는 것입니다.while고리.

그러면 예상 데이터베이스에는 카드가 리더에 터치될 때마다 이벤트 시간과 함께 행이 표시되므로 기존 엔트리를 업데이트할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/61428664/how-to-make-the-system-realize-that-the-rfid-card-is-read-for-2nd-time-for-sign

반응형