首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的工作时间跟踪系统

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

Stack Overflow用户
提问于 2022-11-27 15:07:34
回答 1查看 63关注 0票数 0

我是一个完全的初学者,我认为我低估了我的小项目。

我正在尝试实施一个简单的考勤系统,它将给我每天和每月晚些时候工作的时间。我正在使用一个覆盆子π3 b+和RC522射频识别阅读器加上16x2液晶显示器。使用MariaDB存储在数据库中的数据列表。

这样做的目的是让餐厅的学生工作人员在他们的时间里计时。员工们仍然会写下他们的工作时间,但是如果它能代替文书工作的话,我们就会看到了。我知道会有一些关于合法性的担忧,但一旦我做完了,律师们就该这么做了。

然而,我的问题是,现在我无法时钟和时钟的多个用户。它确实适用于一个用户。如果我在用户1时钟,它等待直到有一个新的时钟输出信息,不重要的用户是谁。因此,用户1时钟进来,用户2想时钟,但他是登记出时钟,只有这样,数据库条目才会被转移。我认为它需要立即更新条目。

我想你可以从图片phpMyAdminScreenshot得到这个想法

我想我需要从数据库中获得更多的信息,并将其与我所拥有的进行比较。但我现在碰壁了,我找不到解决问题的办法。

我现在的密码是:

代码语言:javascript
复制
'#!/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并检查这个id -- signed_in行的最后一个状态,如果是1,时间戳将将clock_out行和signed_in更新为0。如果是0,而clock_out不是NULL,那么它将使用clock_in时间戳启动一个新行,并将signed_in切换到1。

我在更新任何数据库值方面没有任何运气,所以我返回到INSERT。

EN

回答 1

Stack Overflow用户

发布于 2022-11-27 17:38:44

我希望数据库只存储事件。这些事件将从他们接触RFID时开始。该卡将有身份证/雇员号码。

处理数据库信息将允许计算谁在轮班和轮班的工作时间等。

如果员工有奇数的条目,那么您可以假设他们在轮班。即使是条目的数量,也意味着他们已经完成了转换。

我没有您的硬件或数据库,所以我创建了随机的RFID读取事件,并使用sqlite3。

代码语言:javascript
复制
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()

这给了我以下的成绩单

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74591121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档