diff --git a/.gitignore b/.gitignore index 971a4a7..70e6997 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build/ dist/ *.egg-info/ +*.test \ No newline at end of file diff --git a/test_machine.py b/test_machine.py old mode 100644 new mode 100755 index 2101d0d..34986f6 --- a/test_machine.py +++ b/test_machine.py @@ -1,11 +1,19 @@ -# -*- coding: utf-8 -*- +#!/usr/bin/env python2 +# # -*- coding: utf-8 -*- import sys +import traceback import argparse - -from zk import ZK, const +import time +import datetime sys.path.append("zk") +from zk import ZK, const +from zk.attendance import Attendance +from zk.exception import ZKErrorResponse, ZKNetworkError +from zk.user import User +from zk.finger import Finger + conn = None @@ -15,19 +23,27 @@ parser.add_argument('-a', '--address', parser.add_argument('-p', '--port', type=int, help='device port', default=4370) parser.add_argument('-T', '--timeout', type=int, - help='timeout', default=60) + help='timeout', default=10) parser.add_argument('-P', '--password', type=int, help='Device code/password', default=0) -#parser.add_argument('-f', '--firmware', type=int, -# help='test firmware', default=8) +parser.add_argument('-f', '--force-udp', action="store_true", + help='Force UDP communication') parser.add_argument('-t', '--templates', action="store_true", help='get templates') parser.add_argument('-r', '--records', action="store_true", help='get records') +parser.add_argument('-u', '--updatetime', action="store_true", + help='Update Date / Time') +parser.add_argument('-D', '--deleteuser', type=int, + help='Delete a User', default=0) +parser.add_argument('-A', '--adduser', type=int, + help='Add a User', default=0) +parser.add_argument('-F', '--finger', type=int, + help='Finger for register', default=0) args = parser.parse_args() -zk = ZK(args.address, port=args.port, timeout=args.timeout, password=args.password) # , firmware=args.firmware +zk = ZK(args.address, port=args.port, timeout=args.timeout, password=args.password, force_udp=args.force_udp) # , firmware=args.firmware try: print 'Connecting to device ...' conn = zk.connect() @@ -35,14 +51,15 @@ try: conn.disable_device() fmt = conn.get_extend_fmt() print 'ExtendFmt : {}'.format(fmt) - if fmt == 1: - print "Firmware 6" - conn.firmware = 6 - else: - print "Firmware 8" - conn.firmware = 8 - - print 'Time : {}'.format(conn.get_time()) + now = datetime.datetime.today().replace(microsecond=0) + if args.updatetime: + print '--- Updating Time---' + conn.set_time(now) + zk_time = conn.get_time() + dif = abs(zk_time - now).total_seconds() + print 'Time : {}'.format(zk_time) + if dif > 120: + print("WRN: TIME IS NOT SYNC!!!!!! (local: %s)" % now) print 'Firmware Version : {}'.format(conn.get_firmware_version()) print 'Platform : %s' % conn.get_platform() print 'DeviceName : %s' % conn.get_device_name() @@ -50,20 +67,73 @@ try: print 'Serial Number : %s' % conn.get_serialnumber() print 'MAC: %s' % conn.get_mac() print '' - conn.read_sizes() - print conn - print '' print '--- Get User ---' users = conn.get_users() - for user in users: - privilege = 'User' - if user.privilege == const.USER_ADMIN: - privilege = 'Admin' + max_uid = 0 + prev = None + if not args.deleteuser: + for user in users: + privilege = 'User' + if user.uid > max_uid: + max_uid = user.uid + privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege + print '-> UID #{:<5} Name : {:<27} Privilege : {}'.format(user.uid, user.name, privilege) + print ' Group ID : {:<8} User ID : {:<8} Password : {:<8} Card : {}'.format(user.group_id, user.user_id, user.password, user.card) + #print len (user.repack73()), user.repack73().encode('hex') + #print '' + if args.adduser and user.uid == args.adduser: + prev = user + if args.deleteuser: + print '' + print '-- Delete User UID#%s ---' % args.deleteuser + #TODO implementar luego + conn.delete_user(args.deleteuser) + users = conn.get_users() #update + for user in users: + if user.uid > max_uid: + max_uid = user.uid + privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege + print '-> UID #{:<5} Name : {:<27} Privilege : {}'.format(user.uid, user.name, privilege) + print ' Group ID : {:<8} User ID : {:<8} Password : {:<8} Card : {}'.format(user.group_id, user.user_id, user.password, user.card) + #print len (user.repack73()), user.repack73().encode('hex') + #print '' + if args.adduser and user.uid == args.adduser: + prev = user - print '-> UID #{:<5} Name : {:<27} Privilege : {}'.format(user.uid, user.name, privilege) - print ' Group ID : {:<8} User ID : {:<8} Password : {:<8} Card : {}'.format(user.group_id, user.user_id, user.password, user.card) - #print len (user.repack73()), user.repack73().encode('hex') - #print '' + if args.adduser: + uid = int(args.adduser) + if prev: + user = prev + privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege + print '' + print '--- Modify User %i ---' % user.uid + print '-> UID #{:<5} Name : {:<27} Privilege : {}'.format(user.uid, user.name, privilege) + print ' Group ID : {:<8} User ID : {:<8} Password : {:<8} Card : {}'.format(user.group_id, user.user_id, user.password, user.card) + #discard prev + else: + print '--- Add new User %i ---' % uid + name = raw_input('Name :') + admin = raw_input('Admin (y/n):') + privilege = 14 if admin == 'y' else 0 + password = raw_input('Password :') + user_id = raw_input('User ID2 :') + card = int(raw_input('Card :')) + if prev: + conn.delete_user(uid) #borrado previo + try: + conn.set_user(uid, name, privilege, password, '', user_id, card) + except ZKErrorResponse, e: + print "error: ", e + #try new format + zk_user = User(uid, name, privilege, password, '', user_id, card) + conn.save_user_template(zk_user) + conn.delete_user_template(uid, args.finger) + conn.reg_event(0xFFFF) # + if conn.enroll_user(uid, args.finger): + conn.test_voice(18) # register ok + else: + conn.test_voice(23) # not registered + conn.refresh_data() print "Voice Test ..." conn.test_voice(10) if args.templates: @@ -74,13 +144,24 @@ try: if args.records: print "Read Records..." attendance = conn.get_attendance() + i = 0 for att in attendance: - print "ATT: uid:{:>3}, t: {}".format(att.uid, att.timestamp) - print 'Enabling device ...' - conn.enable_device() + i +=1 + print "ATT {:>6}: uid:{:>3}, t: {}".format(i, att.uid, att.timestamp) + print '' + print '--- sizes & capacity ---' + conn.read_sizes() + print conn + print '' except Exception, e: print "Process terminate : {}".format(e) print "Error: %s" % sys.exc_info()[0] + print '-'*60 + traceback.print_exc(file=sys.stdout) + print '-'*60 finally: if conn: + print 'Enabling device ...' + conn.enable_device() conn.disconnect() + print '' diff --git a/test_voice.py b/test_voice.py old mode 100644 new mode 100755 index f7a6cc5..106ba73 --- a/test_voice.py +++ b/test_voice.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python2 # -*- coding: utf-8 -*- import sys import argparse diff --git a/zk/base.py b/zk/base.py index fbd5f51..ddd7d02 100644 --- a/zk/base.py +++ b/zk/base.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import sys from datetime import datetime -from socket import AF_INET, SOCK_DGRAM, socket +from socket import AF_INET, SOCK_DGRAM, SOCK_STREAM, socket from struct import pack, unpack from zk import const @@ -44,17 +44,55 @@ def make_commkey(key, session_id, ticks=50): B, k[3] ^ B) return k +class ZK_helper(object): + """ helper class """ + def __init__(self, ip, port=4370): + self.address = (ip, port) + self.ip = ip + self.port = port + #self.timeout = timeout + #self.password = password # passint + #self.firmware = int(firmware) #TODO check minor version? + #self.tcp = tcp + def test_ping(self): + """ + Returns True if host responds to a ping request + """ + import subprocess, platform + # Ping parameters as function of OS + ping_str = "-n 1" if platform.system().lower()=="windows" else "-c 1" + args = "ping " + " " + ping_str + " " + self.ip + need_sh = False if platform.system().lower()=="windows" else True + # Ping + return subprocess.call(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=need_sh) == 0 + def test_tcp(self): + self.client = socket(AF_INET, SOCK_STREAM) + self.client.settimeout(10) # fixed test + res = self.client.connect_ex(self.address) + self.client.close() + return res + def test_udp(self): + self.client = socket(AF_INET, SOCK_DGRAM) + self.client.settimeout(10) # fixed test class ZK(object): """ Clase ZK """ - def __init__(self, ip, port=4370, timeout=60, password=0, firmware=8): + def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False): """ initialize instance """ self.is_connect = False + self.helper = ZK_helper(ip, port) self.__address = (ip, port) self.__sock = socket(AF_INET, SOCK_DGRAM) self.__sock.settimeout(timeout) + self.__timeout = timeout self.__password = password # passint - self.firmware = int(firmware) #TODO check minor version? + #self.firmware = int(firmware) #dummy + self.force_udp = force_udp + self.ommit_ping = ommit_ping + self.tcp = False self.users = 0 self.fingers = 0 self.records = 0 @@ -68,9 +106,24 @@ class ZK(object): self.fingers_av = 0 self.users_av = 0 self.rec_av = 0 + self.user_packet_size = 28 # default zk6 self.__session_id = 0 self.__reply_id = const.USHRT_MAX-1 self.__data_recv = None + def __create_socket(self): + """ based on self.tcp""" + if self.tcp: + self.__sock = socket(AF_INET, SOCK_STREAM) + self.__sock.connect_ex(self.__address) + else: + self.__sock = socket(AF_INET, SOCK_DGRAM) + + + def __create_tcp_top(self, packet): + """ witch the complete packet set top header """ + length = len(packet) + top = pack(' 20: self.faces = fields[20] self.faces_cap = fields[22] - #TODO: get faces size... - return True else: raise ZKErrorResponse("can't read sizes") def __str__(self): """ for debug""" - return "ZK%i adr:%s:%s users:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%i" % ( - self.firmware, self.__address[0], self.__address[1], - self.users, self.users_cap, self.fingers, self.fingers_cap, - self.records, self.rec_cap, self.faces, self.faces_cap + return "ZK %s://%s:%s users[%i]:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%i" % ( + "tcp" if self.tcp else "udp", self.__address[0], self.__address[1], + self.user_packet_size, self.users, self.users_cap, + self.fingers, self.fingers_cap, + self.records, self.rec_cap, + self.faces, self.faces_cap ) def restart(self): @@ -549,18 +626,12 @@ class ZK(object): #uid = chr(uid % 256) + chr(uid >> 8) if privilege not in [const.USER_DEFAULT, const.USER_ADMIN]: privilege = const.USER_DEFAULT - privilege = chr(privilege) - if self.firmware == 6: - print "uid : %i" % uid - print "pri : %c" % privilege - print "pass: %s" % str(password) - print "name: %s" % str(name) - print type(name) - print "group %i" % int(group_id) - print "uid2: %i" % int(user_id) + privilege = int(privilege) + if self.user_packet_size == 28: #self.firmware == 6: + if not group_id: + group_id = 0 try: - command_string = pack('Hc5s8s5sBHI', uid, privilege, str(password), str(name), chr(0), int(group_id), 0, int(user_id)) - print "cmd : %s" % command_string + command_string = pack('HB5s8s5sBHI', uid, privilege, str(password), str(name), chr(0), int(group_id), 0, int(user_id)) except Exception, e: print "s_h Error pack: %s" % e print "Error pack: %s" % sys.exc_info()[0] @@ -568,14 +639,13 @@ class ZK(object): else: name_pad = name.ljust(24, '\x00')[:24] card_str = pack('i', int(card))[:4] - command_string = pack('Hc8s24s4sc7sx24s', uid, privilege, password, name_pad, card_str, chr(0), group_id, user_id) - response_size = 1024 + command_string = pack('HB8s24s4sc7sx24s', uid, privilege, password, name_pad, card_str, chr(0), group_id, str(user_id)) + response_size = 1024 #TODO check response? cmd_response = self.__send_command(command, command_string, response_size) - if cmd_response.get('status'): - return True - else: + if not cmd_response.get('status'): raise ZKErrorResponse("Cant set user") - + self.refresh_data() + def save_user_template(self, user, fingers=[]): """ save user and template """ #TODO: grabado global @@ -591,9 +661,9 @@ class ZK(object): table += pack("> 8) - #command_string = pack('2s', uid) command_string = pack('h', uid) cmd_response = self.__send_command(command, command_string) - if cmd_response.get('status'): - return True - else: + if not cmd_response.get('status'): raise ZKErrorResponse("can't delete user") + self.refresh_data() def get_user_template(self, uid, temp_id): + """ ZKFinger VX10.0 """ command = 88 # comando secreto!!! command_string = pack('hb', uid, temp_id) response_size = 1024 @@ -698,36 +778,34 @@ class ZK(object): return [] total_size = unpack('i', templatedata[0:4])[0] templatedata = templatedata[4:] #total size not used - if self.firmware == 6: #tested! - while total_size: - size, uid, fid, valid = unpack('HHbb',templatedata[:6]) - template = unpack("%is" % (size-6), templatedata[6:size])[0] - finger = Finger(size, uid, fid, valid, template) - #print finger # test - templates.append(finger) - templatedata = templatedata[size:] - total_size -= size - else: # tested with ZEM800_TFT - iFace402/ID - while total_size: - size, uid, fid, valid = unpack('HHbb',templatedata[:6]) - template = unpack("%is" % (size-6), templatedata[6:size])[0] - finger = Finger(size - 6, uid, fid, valid, template) - #print finger # test - templates.append(finger) - templatedata = templatedata[(size):] - total_size -= size + # ZKFinger VX10.0 the only finger firmware tested + while total_size: + size, uid, fid, valid = unpack('HHbb',templatedata[:6]) + template = unpack("%is" % (size-6), templatedata[6:size])[0] + finger = Finger(size, uid, fid, valid, template) + #print finger # test + templates.append(finger) + templatedata = templatedata[size:] + total_size -= size return templates - def get_users(self): + def get_users(self): #ALWAYS CALL TO GET correct user_packet_size """ return all user """ + self.read_sizes() # last update + if self.users == 0: #lazy + return [] users = [] userdata, size = self.read_with_buffer(const.CMD_USERTEMP_RRQ, const.FCT_USER) #print "user size %i" % size - if size < 4: + if size <= 4: print "WRN: no user data" # debug return [] - userdata = userdata[4:] #total size not used - if self.firmware == 6: + total_size = unpack("I",userdata[:4])[0] + self.user_packet_size = total_size / self.users + if not self.user_packet_size in [28, 72]: + print "WRN packet size would be ", self.user_packet_size + userdata = userdata[4:] + if self.user_packet_size == 28: while len(userdata) >= 28: uid, privilege, password, name, card, group_id, timezone, user_id = unpack('HB5s8s5sBhI',userdata.ljust(28)[:28]) password = unicode(password.split('\x00')[0], errors='ignore') @@ -796,58 +874,95 @@ class ZK(object): cmd_response = self.__send_command(command, command_string) if not cmd_response.get('status'): raise ZKErrorResponse("can't set sdk build ") - def enroll_user(self, uid, temp_id=0): + def enroll_user(self, uid=0, temp_id=0, user_id=''): ''' start enroll user ''' command = const.CMD_STARTENROLL - command_string = pack('hhb', uid, 0, temp_id) # el 0 es misterio + done = False + if self.tcp: + if not user_id: + #we need user_id (uid2) + users = self.get_users() + users = filter(lambda x: x.uid==uid, users) + if len(users) == 1: + user_id = users[0].user_id + else: #double? posibly empty + return False #can't enrool + command_string = pack('<24sbb',str(user_id), temp_id, 1) # el 1 es misterio + else: + command_string = pack('hhb', int(uid), 0, temp_id) # el 0 es misterio + self.cancel_capture() cmd_response = self.__send_command(command, command_string) if not cmd_response.get('status'): raise ZKErrorResponse("Cant Enroll user #%i [%i]" %(uid, temp_id)) - print "enroll", cmd_response #retorna rapido toca esperar un reg event + self.__sock.settimeout(60)# default 1min for finger attempts = 3 while attempts: print "A:%i esperando primer regevent" % attempts data_recv = self.__sock.recv(1032) # timeout? tarda bastante... self.__ack_ok() print (data_recv).encode('hex') - if len(data_recv) > 8: #not empty - res = unpack("H", data_recv.ljust(16,"\x00")[8:10])[0] - print "res", res - if res == 6: - print ("posible timeout") - return False + if self.tcp: + if len(data_recv) > 16: #not empty + res = unpack("H", data_recv.ljust(24,"\x00")[16:18])[0] + print "res", res + if res == 0 or res == 6 or res == 4: + # 6 timeout, 4 mismatch error, 0 can't start(why?) + print ("posible timeout o reg Fallido") + break + else: + if len(data_recv) > 8: #not empty + res = unpack("H", data_recv.ljust(16,"\x00")[8:10])[0] + print "res", res + if res == 6 or res == 4: + print ("posible timeout o reg Fallido") + break print "A:%i esperando 2do regevent" % attempts data_recv = self.__sock.recv(1032) # timeout? tarda bastante... self.__ack_ok() print (data_recv).encode('hex') - if len(data_recv) > 8: #not empty + if self.tcp: + if len(data_recv) > 8: #not empty + res = unpack("H", data_recv.ljust(24,"\x00")[16:18])[0] + print "res", res + if res == 6 or res == 4: + print ("posible timeout o reg Fallido") + break + elif res == 0x64: + print ("ok, continue?") + attempts -= 1 + else: + if len(data_recv) > 8: #not empty + res = unpack("H", data_recv.ljust(16,"\x00")[8:10])[0] + print "res", res + if res == 6 or res == 4: + print ("posible timeout o reg Fallido") + break + elif res == 0x64: + print ("ok, continue?") + attempts -= 1 + if attempts == 0: + print "esperando 3er regevent" + data_recv = self.__sock.recv(1032) # timeout? tarda bastante... + self.__ack_ok() + print (data_recv).encode('hex') + if self.tcp: + res = unpack("H", data_recv.ljust(24,"\x00")[16:18])[0] + else: res = unpack("H", data_recv.ljust(16,"\x00")[8:10])[0] - print "res", res - if res == 6: - print ("posible timeout") - return False - elif res == 0x64: - print ("ok, continue?") - attempts -= 1 - - print "esperando 3er regevent" - data_recv = self.__sock.recv(1032) # timeout? tarda bastante... - self.__ack_ok() - print (data_recv).encode('hex') - res = unpack("H", data_recv.ljust(16,"\x00")[8:10])[0] - if res == 4: - print "registro Fallido" - self.cancel_capture() - return False - if res == 0: - size = unpack("H", data_recv.ljust(16,"\x00")[10:12])[0] - pos = unpack("H", data_recv.ljust(16,"\x00")[12:14])[0] - print "enroll ok", size, pos - return True - + if res == 6 or res == 4: + print ("posible timeout o reg Fallido") + if res == 0: + size = unpack("H", data_recv.ljust(16,"\x00")[10:12])[0] + pos = unpack("H", data_recv.ljust(16,"\x00")[12:14])[0] + print "enroll ok", size, pos + done = True + self.__sock.settimeout(self.__timeout) + self.cancel_capture() + self.verify_user() + return done def clear_data(self, clear_type=5): # FCT_USER ''' clear all data (include: user, attendance report, finger database ) @@ -871,29 +986,68 @@ class ZK(object): raise ZKErrorResponse("can't read chunk %i:[%i]" % (start, size)) #else if cmd_response.get('code') == const.CMD_DATA: # less than 1024!!! - return self.__data_recv[8:] + if self.tcp: + return self.__data_recv[16:] #TODO: check size? + else: + return self.__data_recv[8:] if cmd_response.get('code') == const.CMD_PREPARE_DATA: data = [] bytes = self.__get_data_size() #TODO: check with size + #print "prepare data size is", bytes + if self.tcp: + data_recv = self.__sock.recv(bytes + 32) + recieved = len(data_recv) + tcp_length = unpack('HHI', data_recv[:8])[2] #bytes+8 + if tcp_length < (bytes + 8): + print "request chunk too big!" + response = unpack('HHHH', data_recv[8:16])[0] + if recieved >= (bytes + 32): #complete + if response == const.CMD_DATA: + resp = data_recv[16:bytes+16] # no ack? + #print "resp len", len(resp) + return resp + else: + print "broken packet!!!" + return '' #broken + else: # incomplete + data.append(data_recv[16:]) # w/o tcp and header + bytes -= recieved-16 + while bytes>0: #jic + data_recv = self.__sock.recv(bytes) #ideal limit? + recieved = len(data_recv) + data.append(data_recv) # w/o tcp and header + bytes -= recieved + data_recv = self.__sock.recv(16) + response = unpack('HHHH', data_recv[8:16])[0] + if response == const.CMD_ACK_OK: + return ''.join(data) + #data_recv[bytes+16:].encode('hex') #included CMD_ACK_OK + print "bad response ", data_recv.encode('hex') + #print data + return '' + #else udp while True: #limitado por respuesta no por tamaño - data_recv = self.__sock.recv(1032) + data_recv = self.__sock.recv(response_size) response = unpack('HHHH', data_recv[:8])[0] #print "# %s packet response is: %s" % (pac, response) if response == const.CMD_DATA: data.append(data_recv[8:]) #header turncated - bytes -= 1024 + bytes -= 1024 #UDP elif response == const.CMD_ACK_OK: break #without problem. else: #truncado! continuar? - #print "broken!" + print "broken!" break #print "still needs %s" % bytes return ''.join(data) def read_with_buffer(self, command, fct=0 ,ext=0): """ Test read info with buffered command (ZK6: 1503) """ - MAX_CHUNK = 16 * 1024 + if self.tcp: + MAX_CHUNK = 0xFFc0 #arbitrary, below 0x10008 + else: + MAX_CHUNK = 16 * 1024 command_string = pack('= 8: uid, status, timestamp = unpack('HH4s', attendance_data.ljust(8)[:8]) attendance_data = attendance_data[8:] @@ -934,6 +1098,16 @@ class ZK(object): timestamp = self.__decode_time(timestamp) attendance = Attendance(uid, user_id, timestamp, status) attendances.append(attendance) + elif record_size == 16: # extended + while len(attendance_data) >= 16: + uid, timestamp, status, verified, reserved, workcode = unpack('= 40: uid, user_id, sparator, timestamp, status, space = unpack('H24sc4sc8s', attendance_data.ljust(40)[:40]) @@ -945,64 +1119,7 @@ class ZK(object): attendances.append(attendance) attendance_data = attendance_data[40:] return attendances - def _get_attendance(self): - ''' - return all attendance record - ''' - command = const.CMD_ATTLOG_RRQ - command_string = '' - response_size = 1024 - cmd_response = self.__send_command(command, command_string, response_size) - attendances = [] - if cmd_response.get('status'): - if cmd_response.get('code') == const.CMD_PREPARE_DATA: - bytes = self.__get_data_size() - attendance_data = [] - pac = 1 - while True: #limitado por respuesta no por tamaño - data_recv = self.__sock.recv(1032) - response = unpack('HHHH', data_recv[:8])[0] - #print "# %s packet response is: %s" % (pac, response) - if response == const.CMD_DATA: - pac += 1 - attendance_data.append(data_recv[8:]) #header turncated - bytes -= 1024 - elif response == const.CMD_ACK_OK: - break #without problem. - else: - #truncado! continuar? - #print "broken!" - break - #print "still needs %s" % bytes - if response == const.CMD_ACK_OK: - if attendance_data: - attendance_data = ''.join(attendance_data) - attendance_data = attendance_data[4:] - if self.firmware == 6: - while len(attendance_data) >= 8: - uid, status, timestamp = unpack('HH4s', attendance_data.ljust(8)[:8]) - attendance_data = attendance_data[8:] - if uid == 0: #(on zk it's 16 bytes, extrauid 0, status 255, timestamp 0x0) - continue # probably - user_id = str(uid) #TODO revisar posibles valores cruzar con userdata - timestamp = self.__decode_time(timestamp) - attendance = Attendance(uid, user_id, timestamp, status) - attendances.append(attendance) - else: - while len(attendance_data) >= 40: - uid, user_id, sparator, timestamp, status, space = unpack('H24sc4sc8s', attendance_data.ljust(40)[:40]) - user_id = user_id.split('\x00')[0] - timestamp = self.__decode_time(timestamp) - status = int(status.encode("hex"), 16) - - attendance = Attendance(uid, user_id, timestamp, status) - attendances.append(attendance) - - attendance_data = attendance_data[40:] - self.free_data() - else: - raise ZKErrorResponse("can't _get attendance") - return attendances + def clear_attendance(self): ''' diff --git a/zk/const.py b/zk/const.py index ae369f8..8ca5665 100644 --- a/zk/const.py +++ b/zk/const.py @@ -94,6 +94,8 @@ EF_FPFTR = (1<<8)# be real-time capture fingerprint minutia EF_ALARM = (1<<9)# Alarm signal USER_DEFAULT = 0 +USER_ENROLLER = 2 +USER_MANAGER = 6 USER_ADMIN = 14 FCT_ATTLOG = 1 @@ -103,3 +105,6 @@ FCT_OPLOG = 4 FCT_USER = 5 FCT_SMS = 6 FCT_UDATA = 7 + +MACHINE_PREPARE_DATA_1 = 20560 # 0x5050 +MACHINE_PREPARE_DATA_2 = 32130 # 0x7282 \ No newline at end of file