我是一个初学者,我需要一些帮助/指导!因此,基本上我正在尝试使用树莓派4和RFID读写器来制作一个考勤系统。到目前为止,一切都运行得很好,但我正在为sign_out发送数据而苦苦挣扎。现在,在sign_in中的相同时间戳也在数据库中的signed_out中标记,但在这里,我想在第二次读取RFID卡时将数据填充到sign_out列中。如果你有任何其他建议,我很乐意倾听/学习,谢谢。编辑:“从这个问题中删除了整个代码”
发布于 2020-04-26 00:26:27
您是否考虑过将登录/注销视为切换?默认状态是sign-in设置为0或false,sign-out设置为1或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这可以通过将两个状态减少到一个单独的状态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简单地说,您希望将其视为具有两个转换的简单状态机:从In到Out和从Out到In

这能帮助你找到正确的方向吗?
时间戳问题
因此,在进入循环之前,您似乎只初始化了一次时间戳。试着移动
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循环。
然后,您期望的数据库将在每次卡被触摸到读卡器时都有一行记录事件发生的时间,这样您就不必更新已经存在的条目。
https://stackoverflow.com/questions/61428664
复制相似问题