Initial test
This commit is contained in:
502
attendanceManager.py
Normal file
502
attendanceManager.py
Normal file
@@ -0,0 +1,502 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import sys
|
||||
import csv
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from zk.finger import Finger
|
||||
import codecs
|
||||
|
||||
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||
ROOT_DIR = os.path.dirname(CWD)
|
||||
sys.path.append(ROOT_DIR)
|
||||
|
||||
from zk import ZK, const
|
||||
import zk
|
||||
print (zk.__file__)
|
||||
|
||||
mesin_absen = [
|
||||
{ "lokasi":"Painting In", "ip":"10.35.14.14", "id":"1" },
|
||||
{ "lokasi":"Painting Out" , "ip":"10.35.14.13", "id":"2"},
|
||||
{ "lokasi":"Injection In", "ip":"10.35.7.10", "id":"3"},
|
||||
{ "lokasi":"Injection Out", "ip":"10.35.7.11", "id":"4"},
|
||||
{ "lokasi":"Office", "ip":"10.35.14.10", "id":"5"},
|
||||
{ "lokasi":"Hotpress in", "ip":"10.35.14.15", "id":"7"},
|
||||
{ "lokasi":"Hotpress out", "ip":"10.35.14.16", "id":"6"},
|
||||
{ "lokasi":"KIIC", "ip":"10.45.7.2", "id":"8"},
|
||||
{ "lokasi":"Injection 2 out", "ip":"10.35.7.12", "id":"9"},
|
||||
{ "lokasi":"Injection 2 in", "ip":"10.35.7.13", "id":"10"},
|
||||
{ "lokasi":"Test Machine", "ip":"10.35.7.14", "id":"11"},
|
||||
{ "lokasi":"ZK Gate1", "ip":"10.35.7.3", "id":"12"},
|
||||
|
||||
]
|
||||
|
||||
#print(mesin_absen[0]['lokasi'])
|
||||
|
||||
def pilih_mesin():
|
||||
print("Daftar mesin attendance : ")
|
||||
for i, mesin in enumerate(mesin_absen, start=1):
|
||||
print(f"{i}: {mesin['lokasi']} (IP: {mesin['ip']})")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = int(input("Pilih nomor mesin (1-12): "))
|
||||
if 1 <= choice <= 12:
|
||||
mesin_dipilih = mesin_absen[choice - 1]
|
||||
ipaddress = mesin_dipilih["ip"]
|
||||
lokasi = mesin_dipilih["lokasi"]
|
||||
idmesin = mesin_dipilih["id"]
|
||||
print(f"Dipilih mesin {idmesin}, lokasi: {lokasi}, IP Address mesin absen: {ipaddress}")
|
||||
return ipaddress, idmesin
|
||||
else:
|
||||
print("Masukan angka 1-12")
|
||||
except ValueError:
|
||||
print("Invalid input. Masukan angka.")
|
||||
|
||||
def koneksi_mesin(ipaddress):
|
||||
conn = None
|
||||
zk = ZK(ipaddress, port=4370, verbose=True, timeout=5, password=0, force_udp=True)
|
||||
# connect to device
|
||||
conn = zk.connect()
|
||||
device_info = conn.get_network_params()
|
||||
#device_id = device_info.get('MachineNumber', 'ID Tidak ditemukan')
|
||||
print(f"Device ID: {device_info}")
|
||||
# disable device, this method ensures no activity on the device while the process is run
|
||||
conn.disable_device()
|
||||
print("Koneksi tersambung dengan mesin ", ipaddress)
|
||||
return conn
|
||||
|
||||
def menu():
|
||||
operasi = [
|
||||
"Input karyawan baru",
|
||||
"Import data karyawan",
|
||||
"Import data finger",
|
||||
"Tampilkan data karyawan",
|
||||
"Tampilkan data kehadiran",
|
||||
"Ekspor data karyawan",
|
||||
"Ekspor data kehadiran",
|
||||
"Ekspor data kehadiran per tanggal",
|
||||
'Ekspor data finger',
|
||||
"Eksport data finger satuan",
|
||||
"Hapus data karyawan",
|
||||
"Hapus data finger",
|
||||
"Keluar"
|
||||
]
|
||||
|
||||
print("Operasi yang tersedia : ")
|
||||
for i, ops in enumerate(operasi, start=1):
|
||||
print(f"{i}: {ops}")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = int(input("Pilih operasi: "))
|
||||
if 1 <= choice <= 12:
|
||||
operasi_dipilih = operasi[choice - 1]
|
||||
print(f"{operasi_dipilih} dipilih")
|
||||
return operasi_dipilih
|
||||
else:
|
||||
print("Masukan angka")
|
||||
except ValueError:
|
||||
print("Invalid input. Masukan angka.")
|
||||
|
||||
def input_karyawan(conn):
|
||||
last_uid = get_latest_uid(conn)
|
||||
try:
|
||||
name = input("Masukkan nama karyawan: ")
|
||||
user_id = input("Masukkan user ID karyawan: ")
|
||||
privilege_input = int(input("Privilege, admin=0, user=1: "))
|
||||
print(privilege_input)
|
||||
type(privilege_input)
|
||||
if privilege_input == 0:
|
||||
privilege = const.USER_ADMIN
|
||||
else:
|
||||
privilege = const.USER_DEFAULT
|
||||
password = input("Masukkan password (kosongkan jika tidak ada): ")
|
||||
|
||||
conn.set_user(uid = last_uid + 1, name=name, privilege=privilege, password=password, user_id=user_id)
|
||||
print("Karyawan baru berhasil ditambahkan!")
|
||||
except Exception as e:
|
||||
print(f"Terjadi kesalahan: {e}")
|
||||
finally:
|
||||
if conn:
|
||||
conn.disconnect()
|
||||
|
||||
def delete_karyawan(conn):
|
||||
uid = int(input("Masukkan UID: "))
|
||||
conn.delete_user(uid=uid)
|
||||
print("Karyawan berhasil dihapus")
|
||||
if conn:
|
||||
conn.disconnect()
|
||||
|
||||
def delete_finger(conn):
|
||||
uid = int(input("Masukkan UID: "))
|
||||
temp_id = int(input("Masukkan Finger ID: "))
|
||||
try:
|
||||
conn.delete_user_template(uid=uid, temp_id=temp_id, user_id='')
|
||||
print("Finger berhasil dihapus")
|
||||
except Exception as e:
|
||||
print(f"Terjadi kesalahan: {e}")
|
||||
if conn:
|
||||
conn.disconnect()
|
||||
|
||||
|
||||
def import_data_karyawan(conn):
|
||||
try:
|
||||
with open('karyawan_data/import_m10.csv', mode='r') as file:
|
||||
reader = csv.reader(file, delimiter=';')
|
||||
next(reader)
|
||||
column_index = [1, 4] # 1: nama, 4: user_id
|
||||
last_uid = get_latest_uid(conn) #Ambil UID terakhir
|
||||
for index, row in enumerate(reader):
|
||||
if not row or len(row) < max(column_index) + 1:
|
||||
print(f"Baris {index} kosong atau tidak valid, dilewati")
|
||||
continue
|
||||
selected_columns = [row[i] for i in column_index]
|
||||
print(selected_columns)
|
||||
#uid = row[0]
|
||||
#name = row[1]
|
||||
#user_id = row[4]
|
||||
|
||||
#for row in reader:
|
||||
# Check if the row has enough columns
|
||||
# if all(i < len(row) for i in column_indices):
|
||||
# selected_columns = [row[i] for i in column_indices]
|
||||
# print(selected_columns)
|
||||
# else:
|
||||
# print(f"Skipping row with missing columns: {row}")
|
||||
|
||||
try:
|
||||
name = row[column_index[0]]
|
||||
user_id = row[column_index[1]]
|
||||
print(f"Importing: {name} (User ID: {user_id})")
|
||||
conn.set_user(uid = last_uid + 1, name=name, privilege=const.USER_DEFAULT, password='', user_id=user_id)#(uid=uid, name=name, privilege=const.USER_DEFAULT, password='', user_id=user_id)
|
||||
#conn.test_voice(index=0)
|
||||
last_uid += 1
|
||||
except Exception as e:
|
||||
#print ("Terjadi kesalahan : {}".format(e))
|
||||
print(f"Error di baris {index} saat memproses {name}: {e}")
|
||||
except FileNotFoundError:
|
||||
print("File CSV tidak ditemukan")
|
||||
except Exception as e:
|
||||
print(f"Terjadi kesalahan: {e}")
|
||||
finally:
|
||||
if conn:
|
||||
conn.enable_device()
|
||||
conn.disconnect()
|
||||
|
||||
def import_data_finger(conn):
|
||||
conn.disable_device()
|
||||
conn.free_data()
|
||||
conn.refresh_data()
|
||||
users = conn.get_users()
|
||||
try: #file csv harus encoding UTF-8, template finger jangan diquote
|
||||
with open('karyawan_data/finger_data/import_finger_data_m9_m10_huda.csv', mode='r', encoding='latin-1') as file:
|
||||
reader = csv.reader(file, delimiter=';', quotechar='â')
|
||||
next(reader)
|
||||
column_index = [1, 2, 4] # 1: uid, 2: fid, 4: template
|
||||
for index, row in enumerate(reader):
|
||||
if not row or len(row) < max(column_index) + 1:
|
||||
print(f"Baris {index} kosong atau tidak valid, dilewati")
|
||||
continue
|
||||
selected_columns = [row[i] for i in column_index]
|
||||
print("Data csv: ", selected_columns)
|
||||
|
||||
try:
|
||||
#template = codecs.decode(row[4].encode('latin-1'), 'unicode_escape') #akhirnya ketemu caranya T_T
|
||||
#template = bytes(row[4])
|
||||
#template = bytes(template, 'latin-1')
|
||||
template_str = row[4].replace('""', '"') # Replace double quotes with a single quote
|
||||
template = eval(template_str)
|
||||
if not isinstance(template, bytes):
|
||||
raise ValueError(f"Data in row[4] is not in bytes format: {row[4]}")
|
||||
print('Data template:', template)
|
||||
|
||||
uid = int(row[1])
|
||||
fid = int(row[2])
|
||||
fingerdata = Finger(uid=uid, fid=fid, valid=1, template=template)
|
||||
user1 = next((u for u in users if u.uid == uid), None)
|
||||
|
||||
try:
|
||||
conn.save_user_template(user=user1, fingers=[fingerdata])
|
||||
print('menyimpan data sidik jari:')
|
||||
print(user1)
|
||||
print(fingerdata)
|
||||
print('data berhasil disimpan')
|
||||
except:
|
||||
print(fingerdata.__dict__)
|
||||
print('data gagal disimpan')
|
||||
except:
|
||||
print('cannot encode fingerprint')
|
||||
|
||||
|
||||
except FileNotFoundError:
|
||||
print("File CSV tidak ditemukan")
|
||||
except Exception as e:
|
||||
print(f"Terjadi kesalahan: {e}")
|
||||
finally:
|
||||
if conn:
|
||||
conn.enable_device()
|
||||
conn.disconnect()
|
||||
|
||||
def get_latest_uid(conn):
|
||||
users = conn.get_users()
|
||||
if users:
|
||||
return max(user.uid for user in users)
|
||||
print("Gara2 get users")
|
||||
return 0
|
||||
|
||||
def tampilkan_data_karyawan():
|
||||
userdata = []
|
||||
users = conn.get_users()
|
||||
last_uid = get_latest_uid(conn)
|
||||
for user in users:
|
||||
userdataset = OrderedDict() #pakai ordered dict supaya datanya berurutan
|
||||
privilege = 'User'
|
||||
if user.privilege == const.USER_ADMIN:
|
||||
privilege = 'Admin'
|
||||
'''print ('+ UID #{}'.format(user.uid))
|
||||
print (' Name : {}'.format(user.name))
|
||||
print (' Privilege : {}'.format(privilege))
|
||||
print (' Password : {}'.format(user.password))
|
||||
print (' Group ID : {}'.format(user.group_id))
|
||||
print (' User ID : {}'.format(user.user_id))'''
|
||||
#print ('+ UID #{}'.format(user.uid))
|
||||
userdataset["uid"] = user.uid
|
||||
userdataset["privilege"] = user.privilege
|
||||
#print (' Name : {}'.format(user.name))
|
||||
userdataset["name"] = user.uid
|
||||
#print (' Name : {}'.format(user.name))
|
||||
userdataset["name"] = user.name
|
||||
#print (' Password : {}'.format(user.password))
|
||||
userdataset["password"] = user.password
|
||||
#print (' Group ID : {}'.format(user.group_id))
|
||||
userdataset["group_id"] = user.group_id
|
||||
#print (' User ID : {}'.format(user.user_id))
|
||||
userdataset["user_id"] = user.user_id
|
||||
userdata.append(userdataset)
|
||||
#print(userdata)
|
||||
|
||||
for u in userdata:
|
||||
# print(u)
|
||||
for key, value in u.items():
|
||||
print(f"{key.capitalize()}: {value}")
|
||||
#print("*" * 30) # 30 asterisks
|
||||
print("=" * 50) # 50 equal signs
|
||||
|
||||
print("UID Terakhir: ", last_uid)
|
||||
|
||||
if conn:
|
||||
conn.enable_device()
|
||||
conn.disconnect()
|
||||
|
||||
def ekspor_data_karyawan():
|
||||
userdata = []
|
||||
users = conn.get_users()
|
||||
|
||||
for user in users:
|
||||
userdataset = OrderedDict() #pakai ordered dict supaya datanya berurutan
|
||||
userdataset["uid"] = user.uid
|
||||
userdataset["name"] = user.name
|
||||
userdataset["password"] = user.password
|
||||
userdataset["group_id"] = user.group_id
|
||||
userdataset["user_id"] = user.user_id
|
||||
userdata.append(userdataset)
|
||||
|
||||
fieldnames = ["uid", "name", "password", "group_id", "user_id"]
|
||||
current_time = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
directory = "karyawan_data"
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
filename = os.path.join(directory,f"karyawan_m{idmesin}_{current_time}.csv")
|
||||
with open(filename, 'w', newline='', encoding='utf-8') as csv_file:
|
||||
writer = csv.DictWriter(csv_file, delimiter=';', fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
for u in userdata:
|
||||
writer.writerow(u)
|
||||
print("Data berhasil disimpan sebagai ", filename)
|
||||
if conn:
|
||||
conn.enable_device()
|
||||
conn.disconnect()
|
||||
|
||||
def ekspor_data_finger(conn):
|
||||
#template = conn.get_user_template(uid=1, temp_id=0)
|
||||
fingers = conn.get_templates()
|
||||
#print(fingers)
|
||||
#print(type(fingers))
|
||||
for finger in fingers:
|
||||
print(finger.__dict__)
|
||||
|
||||
fieldnames = ["size", "uid", "fid", "valid", "template", "mark"]
|
||||
current_time = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
directory = "karyawan_data/finger_data"
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
filename = os.path.join(directory,f"finger_m{idmesin}_{current_time}.csv")
|
||||
with open(filename, 'w', newline='', encoding='utf-8') as csv_file:
|
||||
writer = csv.DictWriter(csv_file, delimiter=';', fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
for f in fingers:
|
||||
writer.writerow(f.__dict__)
|
||||
print("Data finger berhasil disimpan sebagai ", filename)
|
||||
|
||||
if conn:
|
||||
conn.enable_device()
|
||||
conn.disconnect()
|
||||
|
||||
def ekspor_data_finger_satuan(conn):
|
||||
uid = int(input("Masukkan UID : "))
|
||||
fingers = []
|
||||
for i in range(10):
|
||||
fingers.append(conn.get_user_template(uid=uid, temp_id=i))
|
||||
print(fingers)
|
||||
#fingers = conn.get_templates()
|
||||
#print(fingers)
|
||||
#print(type(fingers))
|
||||
#for finger in fingers:
|
||||
# print(finger.__dict__)
|
||||
|
||||
fieldnames = ["size", "uid", "fid", "valid", "template", "mark"]
|
||||
current_time = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
directory = "karyawan_data/finger_data"
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
filename = os.path.join(directory,f"finger_m{idmesin}_{uid}.csv")
|
||||
with open(filename, 'w', newline='', encoding='utf-8') as csv_file:
|
||||
writer = csv.DictWriter(csv_file, delimiter=';', fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
for f in fingers:
|
||||
writer.writerow(f.__dict__)
|
||||
print("User data written to ", filename)
|
||||
|
||||
if conn:
|
||||
conn.enable_device()
|
||||
conn.disconnect()
|
||||
|
||||
def tampilkan_data_kehadiran():
|
||||
attendances = conn.get_attendance()
|
||||
print(type(attendances))
|
||||
for attendance in attendances:
|
||||
print(attendance)
|
||||
if conn:
|
||||
conn.disconnect()
|
||||
|
||||
def ekspor_data_kehadiran(conn, idmesin):
|
||||
print(conn)
|
||||
attendances = conn.get_attendance()
|
||||
idmesin = str(idmesin).zfill(3)
|
||||
fieldnames = ["machineid", "uid", "datestamp", "timestamp", "type", "inout"]
|
||||
#current_time = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
current_time = datetime.now().strftime("%Y%m%d")
|
||||
|
||||
# Ensure the directory exists
|
||||
directory = "attendance_data"
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
filename = os.path.join(directory,f"attendances_{current_time}.txt")
|
||||
#filename = os.path.join(directory,f"att_m{idmesin}_{current_time}.txt")
|
||||
#filename = input("Masukan nama file untuk menyimpan data kehadiran: ") + ".csv" #nama file disimpan
|
||||
|
||||
#with open(filename, 'w', newline='', encoding='utf-8') as csv_file:
|
||||
with open(filename, 'a', newline='', encoding='utf-8') as csv_file:
|
||||
writer = csv.DictWriter(csv_file, delimiter=';', fieldnames=fieldnames)
|
||||
#writer.writeheader()
|
||||
|
||||
for attendance in attendances:
|
||||
datestamp = attendance.timestamp.strftime("%d-%m-%Y")
|
||||
timestamp = attendance.timestamp.strftime("%H:%M")
|
||||
writer.writerow({
|
||||
"machineid": idmesin,
|
||||
"uid": str(attendance.user_id).zfill(16), # biar 16 digit, diisi 0 di depan
|
||||
"datestamp": datestamp,
|
||||
"timestamp": timestamp,
|
||||
"type": str(attendance.punch).zfill(2),
|
||||
"inout": str(attendance.status).zfill(2),
|
||||
})
|
||||
print("Data kehadiran berhasil disimpan di", filename)
|
||||
'''try:
|
||||
conn.clear_attendance()
|
||||
print("Data attendance berhasil dihapus dari mesin")
|
||||
except Exception as e:
|
||||
print(f"Gagal menghapus data attendance dari mesin {e}")
|
||||
'''
|
||||
if conn:
|
||||
conn.disconnect()
|
||||
|
||||
def ekspor_data_kehadiran_per_tanggal(conn, idmesin, fromdate, todate):
|
||||
print(conn)
|
||||
attendances = conn.get_attendance()
|
||||
idmesin = str(idmesin).zfill(3)
|
||||
fieldnames = ["machineid", "uid", "datestamp", "timestamp", "type", "inout"]
|
||||
current_time = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
fromdate = datetime.strptime(fromdate, "%d-%m-%Y").date()
|
||||
todate = datetime.strptime(todate, "%d-%m-%Y").date()
|
||||
|
||||
|
||||
# Ensure the directory exists
|
||||
directory = "attendance_data"
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
filename = os.path.join(directory,f"att_m{idmesin}_{current_time}.txt")
|
||||
#filename = input("Masukan nama file untuk menyimpan data kehadiran: ") + ".csv" #nama file disimpan
|
||||
with open(filename, 'w', newline='', encoding='utf-8') as csv_file:
|
||||
writer = csv.DictWriter(csv_file, delimiter=';', fieldnames=fieldnames)
|
||||
#writer.writeheader()
|
||||
print("From Date: ", fromdate, type(fromdate))
|
||||
print("To Date: ", todate, type(todate))
|
||||
for attendance in attendances:
|
||||
datestamp = attendance.timestamp.strftime("%d-%m-%Y")
|
||||
datestamp = datetime.strptime(datestamp, "%d-%m-%Y").date() #konversi ke date
|
||||
timestamp = attendance.timestamp.strftime("%H:%M")
|
||||
if fromdate <= datestamp <= todate:
|
||||
datestamp = attendance.timestamp.strftime("%d-%m-%Y") #kembalikan ke bentuk string untuk ditulis ke file
|
||||
writer.writerow({
|
||||
"machineid": idmesin,
|
||||
"uid": str(attendance.user_id).zfill(16), # biar 16 digit, diisi 0 di depan
|
||||
"datestamp": datestamp,
|
||||
"timestamp": timestamp,
|
||||
"type": str(attendance.punch).zfill(2),
|
||||
"inout": str(attendance.status).zfill(2),
|
||||
})
|
||||
print("Data kehadiran berhasil disimpan di", filename)
|
||||
if conn:
|
||||
conn.disconnect()
|
||||
|
||||
def operasi(dipilih, conn, idmesin):
|
||||
if dipilih == "Input karyawan baru":
|
||||
input_karyawan(conn)
|
||||
elif dipilih == "Import data karyawan":
|
||||
import_data_karyawan(conn)
|
||||
elif dipilih == "Import data finger":
|
||||
import_data_finger(conn)
|
||||
elif dipilih == "Tampilkan data karyawan":
|
||||
tampilkan_data_karyawan()
|
||||
elif dipilih == "Ekspor data karyawan":
|
||||
ekspor_data_karyawan()
|
||||
elif dipilih == "Tampilkan data kehadiran":
|
||||
tampilkan_data_kehadiran()
|
||||
elif dipilih == "Ekspor data kehadiran":
|
||||
ekspor_data_kehadiran(conn, idmesin)
|
||||
elif dipilih == "Ekspor data kehadiran per tanggal":
|
||||
fromdate = input("Masukkan tanggal awal (dd-mm-yyyy): ")
|
||||
todate = input("Masukkan tanggal akhir (dd-mm-yyyy): ")
|
||||
ekspor_data_kehadiran_per_tanggal(conn, idmesin, fromdate, todate)
|
||||
elif dipilih == "Ekspor data finger":
|
||||
ekspor_data_finger(conn)
|
||||
elif dipilih == "Eksport data finger satuan":
|
||||
ekspor_data_finger_satuan(conn)
|
||||
elif dipilih == "Hapus data karyawan":
|
||||
delete_karyawan(conn)
|
||||
elif dipilih == "Hapus data finger":
|
||||
delete_finger(conn)
|
||||
elif dipilih == "Keluar":
|
||||
print("Keluar dari program")
|
||||
conn.disconnect()
|
||||
sys.exit()
|
||||
|
||||
while True:
|
||||
ipaddress, idmesin = pilih_mesin()
|
||||
conn = koneksi_mesin(ipaddress)
|
||||
dipilih = menu()
|
||||
operasi(dipilih, conn, idmesin)
|
||||
Reference in New Issue
Block a user