mariadb 跟踪工作时间的简单系统

7cwmlq89  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(122)

我是一个完全的初学者,我想我低估了我的小项目。
我正在尝试实现一个简单的考勤系统,它将给我每天和以后每个月的工作时间。我正在使用树莓pi 3 b+和RC522 RFID阅读器加上16x2液晶显示器。数据是存储在一个数据库使用MariaDB。
我们的想法是让学生员工在餐馆里用它来记录他们的工作时间。员工们仍然会写下他们的工作时间,但如果它起作用,它可能会取代文书工作,我们将拭目以待。我知道会有一些关于合法性的担忧,但一旦我完成了,那就取决于律师们了。
然而,我的问题是,现在我无法为多个用户打卡。它只对一个用户有效。如果我为用户1打卡,它会一直等到有新的打卡信息,不管是哪个用户。因此,用户1打卡,用户2想要打卡上班,但是他被注册为打卡下班,并且只有在那时才传送数据库条目。我认为它需要立即更新条目。
我想你可以从图片phpMyAdminScreenshot中得到这个想法
我想我需要从数据库中获得更多的信息,并将其与我所拥有的进行比较。但是我现在碰壁了,我无法找到解决我的问题的方法。
我现在拥有的代码:

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

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

cursor = db.cursor()
reader = SimpleMFRC522()
display = drivers.Lcd()

sign_in = 0
sign_out= 1

try:
  while True:
    display.lcd_clear()
    display.lcd_display_string("Transponder", 1)
    display.lcd_display_string("platzieren", 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()

    display.lcd_clear()

    #if cursor.rowcount >= 1:
      #display.lcd_display_string("Willkommen " + result[1], 2)
      #cursor.execute("INSERT INTO attendance (user_id) VALUES (%s)", (result[0],) )

    if sign_in == 0:
      sign_in = (sign_in +1) % 2
      sign_out = (sign_out +1) % 2
      cursor.execute(f"INSERT INTO attendance (user_id, clock_in, signed_in) VALUES (%s, %s, %s)", (result[0], timestamp, sign_in) )
      display.lcd_display_string(f"Angemeldet " + result[1], 1)

    elif sign_in == 1:
      sign_out = (sign_out +1) % 2
      sign_in = (sign_in +1) % 2
      cursor.execute(f"INSERT INTO attendance (user_id, clock_out, signed_in) VALUES (%s, %s, %s)", (result[0], timestamp, sign_in) )
      display.lcd_display_string (f"Abgemeldet " + result[1], 1)
      db.commit()

    else:
      display.lcd_display_string("Existiert nicht.", 1)
    time.sleep(2)
finally:
  GPIO.cleanup()'

我的想法是再获取一个名为signed_in的数据库条目,并将其设置为0或1。signed_in状态确实会按照我希望的方式进行更新,但我不知道如何从此处继续。
我的想法是获取user_id并检查signed_in行的最后状态是否有此id,如果是1,则时间戳将更新clock_out行并将signed_in更新为0。如果是0且clock_out不为NULL,则将使用clock_in时间戳开始一个新行并将signed_in切换为1。
我没有更新任何数据库值,所以我恢复到INSERT。

roejwanj

roejwanj1#

我希望数据库只存储事件。这些事件将来自他们接触RFID的时候。卡将有一个ID/员工编号。
处理数据库信息将允许计算谁在轮班以及轮班工作的长度等。

如果某个员工的录入数为奇数,则您可以假定他们正在轮班。录入数为偶数则表示他们已完成轮班。
我没有你的硬件或数据库,所以我创建了随机RFID读取事件,并使用sqlite3。

import datetime
import random
import sqlite3
import time

class SimpleMFRC522:
    @staticmethod
    def read():
        while random.randint(0, 30) != 10:  # Create some delay/blocking
            time.sleep(1)
        employee_id = random.randint(0, 5)
        return employee_id, f'employee_{employee_id}'

class MyDatabase:
    def __init__(self):
        self.db = sqlite3.connect('/tmp/my-test.db')
        with self.db:
            self.db.execute("""
            CREATE TABLE IF NOT EXISTS workers (
                        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                        empl_no INTEGER,
                        name TEXT,
                        tap_event timestamp);
            """)
            self.db.commit()

    def insert_event(self, empl_no, name, timestamp):
        sqlite_insert_with_param = """INSERT INTO 'workers'
                                  ('empl_no', 'name', 'tap_event') 
                                  VALUES (?, ?, ?);"""
        self.db.cursor()
        self.db.execute(sqlite_insert_with_param, (empl_no, name, timestamp))
        self.db.commit()

    def worker_in(self, empl_no):
        sql_cmd = f"SELECT COUNT(*) FROM workers WHERE empl_no = {empl_no};"
        cursor = self.db.execute(sql_cmd)
        event_count, = cursor.fetchone()
        return event_count % 2 == 1 and event_count > 0

    def last_shift(self, empl_no):
        sql_cmd = f"""SELECT tap_event FROM 
                        (SELECT * FROM workers WHERE empl_no = {empl_no} ORDER BY tap_event DESC LIMiT 2) 
                        ORDER BY tap_event ASC ;"""
        cursor = self.db.execute(sql_cmd)
        tap_in, tap_out = cursor.fetchall()
        start = datetime.datetime.fromtimestamp(tap_in[0])
        end = datetime.datetime.fromtimestamp(tap_out[0])
        return end - start

def main():
    db = MyDatabase()
    reader = SimpleMFRC522()
    while True:
        empl_no, name = reader.read()
        print(f"adding tap event for {name}")
        db.insert_event(empl_no, name, datetime.datetime.timestamp(datetime.datetime.now()))
        if db.worker_in(empl_no):
            print(f"\t{name} has started their shift")
        else:
            time_worked = db.last_shift(empl_no)
            print(f"\t{name} has left the building after {time_worked}")

if __name__ == '__main__':
    main()

这给了我一份成绩单如下

adding tap event for employee_5
    employee_5 has started their shift
adding tap event for employee_0
    employee_0 has left the building after 0:02:10.154697
adding tap event for employee_3
    employee_3 has left the building after 0:07:02.465903
adding tap event for employee_3
    employee_3 has started their shift
adding tap event for employee_2
    employee_2 has left the building after 0:06:27.403874
adding tap event for employee_2
    employee_2 has started their shift

相关问题