gpt4 book ai didi

python - 如何让系统实现RFID卡二次读取退出?

转载 作者:行者123 更新时间:2023-12-04 04:12:48 25 4
gpt4 key购买 nike

我是初学者,我需要一些帮助/指导!所以基本上我正在尝试使用 Raspberry Pi 4 和 RFID 读写器制作考勤系统。到目前为止,一切都运行良好,但我正在为 sign_out 发送数据而苦苦挣扎。现在,sign_in 中的相同时间戳也被标记在数据库中的 signed_out 中,但在这里我想在第二次读取 RFID 卡时将数据填充到 sign_out 列中。如果您有任何其他建议,我很乐意听到/学习,谢谢。编辑:“整个代码已从此问题中删除”

最佳答案

您是否考虑过将登录/注销视为一个开关?默认状态是 sign-in 设置为 0 或 false,sign-out 设置为 1 或 true。然后,当读取卡时,它会检查登录值。如果它是 0/false,它会翻转为 1/true,并进行相反的翻转以注销。第二次读卡时,读取 sign-out,如果为 0/false,则设置为 1/true,与 sign-in 相反。

为清楚起见:

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 种状态减少为一种状态,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

简单地说,您想将其视为具有两个转换的简单状态机:从 InOut 以及从 Out enter image description here

这是否有助于为您指明正确的方向?

时间戳问题

因此,您似乎在进入循环之前初始化了一次时间戳。尝试移动

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 和一个 read_at 时间列,用于读取卡片的时间。将您的 sign_in/sign_out 逻辑更改为只有一个表示两种状态的 signed_in 字段,1 表示用户已登录,0 表示何时不是。

代码中的另一个变化是将时间戳逻辑拉入 while 循环。

然后,您的预期数据库将有一行记录读卡器每次接触卡片时的事件时间,您不必更新现有条目。

关于python - 如何让系统实现RFID卡二次读取退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61428664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com