added verbose mode (and fixed print statements for python3)

better tcp and python3 support (still todo test
This commit is contained in:
Arturo Hernandez 2018-05-02 17:09:33 -04:00
parent 9f0267b107
commit ae292f1d84
2 changed files with 131 additions and 78 deletions

View File

@ -86,7 +86,7 @@ class ZK_helper(object):
class ZK(object): class ZK(object):
""" Clase ZK """ """ Clase ZK """
def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False): def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False, verbose=False):
""" initialize instance """ """ initialize instance """
self.is_connect = False self.is_connect = False
self.is_enabled = True #let's asume self.is_enabled = True #let's asume
@ -99,6 +99,7 @@ class ZK(object):
#self.firmware = int(firmware) #dummy #self.firmware = int(firmware) #dummy
self.force_udp = force_udp self.force_udp = force_udp
self.ommit_ping = ommit_ping self.ommit_ping = ommit_ping
self.verbose = verbose
self.tcp = False self.tcp = False
self.users = 0 self.users = 0
self.fingers = 0 self.fingers = 0
@ -248,7 +249,7 @@ class ZK(object):
""" """
t = t.encode('hex') t = t.encode('hex')
t = int(self.__reverse_hex(t), 16) t = int(self.__reverse_hex(t), 16)
#print ("decode from %s "% format(t, '04x')) if self.verbose: print ("decode from %s "% format(t, '04x'))
""" """
t = unpack("<I", t)[0] t = unpack("<I", t)[0]
second = t % 60 second = t % 60
@ -303,7 +304,7 @@ class ZK(object):
cmd_response = self.__send_command(const.CMD_CONNECT) cmd_response = self.__send_command(const.CMD_CONNECT)
self.__session_id = self.__header[2] self.__session_id = self.__header[2]
if cmd_response.get('code') == const.CMD_ACK_UNAUTH: if cmd_response.get('code') == const.CMD_ACK_UNAUTH:
#print ("try auth") if self.verbose: print ("try auth")
command_string = make_commkey(self.__password, self.__session_id) command_string = make_commkey(self.__password, self.__session_id)
cmd_response = self.__send_command(const.CMD_AUTH, command_string) cmd_response = self.__send_command(const.CMD_AUTH, command_string)
if cmd_response.get('status'): if cmd_response.get('status'):
@ -313,7 +314,7 @@ class ZK(object):
else: else:
if cmd_response["code"] == const.CMD_ACK_UNAUTH: if cmd_response["code"] == const.CMD_ACK_UNAUTH:
raise ZKErrorResponse("Unauthenticated") raise ZKErrorResponse("Unauthenticated")
print ("connect err response {} ".format(cmd_response["code"])) if self.verbose: print ("connect err response {} ".format(cmd_response["code"]))
raise ZKErrorResponse("Invalid response: Can't connect") raise ZKErrorResponse("Invalid response: Can't connect")
def disconnect(self): def disconnect(self):
@ -745,11 +746,11 @@ class ZK(object):
try: try:
command_string = pack('HB5s8sIxBHI', uid, privilege, password.encode(), name.encode(), card, int(group_id), 0, int(user_id)) command_string = pack('HB5s8sIxBHI', uid, privilege, password.encode(), name.encode(), card, int(group_id), 0, int(user_id))
except Exception as e: except Exception as e:
print("s_h Error pack: %s" % e) if self.verbose: print("s_h Error pack: %s" % e)
print("Error pack: %s" % sys.exc_info()[0]) if self.verbose: print("Error pack: %s" % sys.exc_info()[0])
raise ZKErrorResponse("Cant pack user") raise ZKErrorResponse("Cant pack user")
else: else:
name_pad = name.ljust(24, b'\x00')[:24] name_pad = name.encode().ljust(24, b'\x00')[:24]
card_str = pack('i', int(card))[:4] card_str = pack('i', int(card))[:4]
command_string = pack('HB8s24s4sx7sx24s', uid, privilege, password.encode(), name_pad, card_str, group_id.encode(), user_id.encode()) command_string = pack('HB8s24s4sx7sx24s', uid, privilege, password.encode(), name_pad, card_str, group_id.encode(), user_id.encode())
response_size = 1024 #TODO check response? response_size = 1024 #TODO check response?
@ -765,7 +766,7 @@ class ZK(object):
if not isinstance(user, User): if not isinstance(user, User):
#try uid #try uid
users = self.get_users() users = self.get_users()
users = filter(lambda x: x.uid==user, users) users = list(filter(lambda x: x.uid==user, users))
if len(users) == 1: if len(users) == 1:
user = users[0] user = users[0]
else: else:
@ -826,6 +827,9 @@ class ZK(object):
def delete_user_template(self, uid, temp_id=0): def delete_user_template(self, uid, temp_id=0):
""" """
Delete specific template Delete specific template
for tcp via user_id:
command = 134 # unknown?
command_string = pack('<24sB', user_id, temp_id)
""" """
command = const.CMD_DELETE_USERTEMP command = const.CMD_DELETE_USERTEMP
command_string = pack('hb', uid, temp_id) command_string = pack('hb', uid, temp_id)
@ -843,7 +847,7 @@ class ZK(object):
if not user_id: if not user_id:
#we need user_id (uid2) #we need user_id (uid2)
users = self.get_users() users = self.get_users()
users = filter(lambda x: x.uid==uid, users) users = list(filter(lambda x: x.uid==uid, users))
if len(users) == 1: if len(users) == 1:
user_id = users[0].user_id user_id = users[0].user_id
else: #double? posibly empty else: #double? posibly empty
@ -859,22 +863,68 @@ class ZK(object):
self.refresh_data() self.refresh_data()
def get_user_template(self, uid, temp_id=0): def get_user_template(self, uid, temp_id=0):
""" ZKFinger VX10.0 """ """ ZKFinger VX10.0
for tcp:
command = const.CMD_USERTEMP_RRQ
command_string = pack('hb', uid, temp_id)
"""
command = 88 # comando secreto!!! command = 88 # comando secreto!!!
command_string = pack('hb', uid, temp_id) command_string = pack('hb', uid, temp_id)
response_size = 1024 response_size = 1024 + 8
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
data = [] data = []
if not cmd_response.get('status'): if not cmd_response.get('status'):
return None #("can't get user template") return None #("can't get user template")
#else #else
if cmd_response.get('code') == const.CMD_DATA: # less than 1024!!!
if self.tcp:
size = len(self.__data[8:])
return Finger(uid, temp_id, 1, self.__data[8:])
else:
size = len(self.__data)
return Finger(uid, temp_id, 1, self.__data)
if cmd_response.get('code') == const.CMD_PREPARE_DATA: if cmd_response.get('code') == const.CMD_PREPARE_DATA:
data = []
bytes = self.__get_data_size() #TODO: check with size bytes = self.__get_data_size() #TODO: check with size
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):
if self.verbose: 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?
if self.verbose: print ("resp len", len(resp))
return Finger(uid, temp_id, 1, resp)
else:
if self.verbose: print("broken packet!!!")
return None #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:
resp = b''.join(data)
return Finger(uid, temp_id, 1, resp)
#data_recv[bytes+16:].encode('hex') #included CMD_ACK_OK
if self.verbose: print("bad response %s" % data_recv)
if self.verbose: print(data)
return None
#else udp
size = bytes size = bytes
while True: #limitado por respuesta no por tamaño 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] response = unpack('HHHH', data_recv[:8])[0]
#print("# %s packet response is: %s" % (pac, response)) if self.verbose: print("# %s packet response is: %s" % (pac, response))
if response == const.CMD_DATA: if response == const.CMD_DATA:
data.append(data_recv[8:]) #header turncated data.append(data_recv[8:]) #header turncated
bytes -= 1024 bytes -= 1024
@ -882,19 +932,20 @@ class ZK(object):
break #without problem. break #without problem.
else: else:
#truncado! continuar? #truncado! continuar?
#print("broken!") if self.verbose: print("broken!")
break break
#print("still needs %s" % bytes) if self.verbose: print("still needs %s" % bytes)
data = b''.join(data) data = b''.join(data)
self.free_data()
#uid 32 fing 03, starts with 4d-9b-53-53-32-31 #uid 32 fing 03, starts with 4d-9b-53-53-32-31
return Finger(size, uid, temp_id, 1, data) return Finger(uid, temp_id, 1, data)
def get_templates(self): def get_templates(self):
""" return array of all fingers """ """ return array of all fingers """
templates = [] templates = []
templatedata, size = self.read_with_buffer(const.CMD_DB_RRQ, const.FCT_FINGERTMP) templatedata, size = self.read_with_buffer(const.CMD_DB_RRQ, const.FCT_FINGERTMP)
if size < 4: if size < 4:
print("WRN: no user data") # debug if self.verbose: print("WRN: no user data") # debug
return [] return []
total_size = unpack('i', templatedata[0:4])[0] total_size = unpack('i', templatedata[0:4])[0]
templatedata = templatedata[4:] #total size not used templatedata = templatedata[4:] #total size not used
@ -902,8 +953,8 @@ class ZK(object):
while total_size: while total_size:
size, uid, fid, valid = unpack('HHbb',templatedata[:6]) size, uid, fid, valid = unpack('HHbb',templatedata[:6])
template = unpack("%is" % (size-6), templatedata[6:size])[0] template = unpack("%is" % (size-6), templatedata[6:size])[0]
finger = Finger(size, uid, fid, valid, template) finger = Finger(uid, fid, valid, template)
#print(finger) # test if self.verbose: print(finger) # test
templates.append(finger) templates.append(finger)
templatedata = templatedata[size:] templatedata = templatedata[size:]
total_size -= size total_size -= size
@ -916,14 +967,14 @@ class ZK(object):
return [] return []
users = [] users = []
userdata, size = self.read_with_buffer(const.CMD_USERTEMP_RRQ, const.FCT_USER) userdata, size = self.read_with_buffer(const.CMD_USERTEMP_RRQ, const.FCT_USER)
#print("user size %i" % size) if self.verbose: print("user size %i" % size)
if size <= 4: if size <= 4:
print("WRN: no user data")# debug if self.verbose: print("WRN: no user data")# debug
return [] return []
total_size = unpack("I",userdata[:4])[0] total_size = unpack("I",userdata[:4])[0]
self.user_packet_size = total_size / self.users self.user_packet_size = total_size / self.users
if not self.user_packet_size in [28, 72]: if not self.user_packet_size in [28, 72]:
print("WRN packet size would be %i" % self.user_packet_size) if self.verbose: print("WRN packet size would be %i" % self.user_packet_size)
userdata = userdata[4:] userdata = userdata[4:]
if self.user_packet_size == 28: if self.user_packet_size == 28:
while len(userdata) >= 28: while len(userdata) >= 28:
@ -938,7 +989,7 @@ class ZK(object):
name = "NN-%s" % user_id name = "NN-%s" % user_id
user = User(uid, name, privilege, password, group_id, user_id, card) user = User(uid, name, privilege, password, group_id, user_id, card)
users.append(user) users.append(user)
#print("[6]user:",uid, privilege, password, name, card, group_id, timezone, user_id) if self.verbose: print("[6]user:",uid, privilege, password, name, card, group_id, timezone, user_id)
userdata = userdata[28:] userdata = userdata[28:]
else: else:
while len(userdata) >= 72: while len(userdata) >= 72:
@ -1006,13 +1057,13 @@ class ZK(object):
if not user_id: if not user_id:
#we need user_id (uid2) #we need user_id (uid2)
users = self.get_users() users = self.get_users()
users = filter(lambda x: x.uid==uid, users) users = list(filter(lambda x: x.uid==uid, users))
if len(users) >= 1: if len(users) >= 1:
user_id = users[0].user_id user_id = users[0].user_id
else: #double? posibly empty else: #double? posibly empty
return False #can't enroll return False #can't enroll
if self.tcp: if self.tcp:
command_string = pack('<24sbb',str(user_id), temp_id, 1) # el 1 es misterio command_string = pack('<24sbb',str(user_id).encode(), temp_id, 1) # el 1 es misterio
else: else:
command_string = pack('<Ib', int(user_id), temp_id) # command_string = pack('<Ib', int(user_id), temp_id) #
self.cancel_capture() self.cancel_capture()
@ -1023,69 +1074,70 @@ class ZK(object):
self.__sock.settimeout(60)# default 1min for finger self.__sock.settimeout(60)# default 1min for finger
attempts = 3 attempts = 3
while attempts: while attempts:
print("A:%i esperando primer regevent" % attempts) if self.verbose: print("A:%i esperando primer regevent" % attempts)
data_recv = self.__sock.recv(1032) # timeout? tarda bastante... data_recv = self.__sock.recv(1032) # timeout? tarda bastante...
self.__ack_ok() self.__ack_ok()
#print((data_recv).encode('hex')) if self.verbose: print((data_recv).encode('hex'))
if self.tcp: if self.tcp:
if len(data_recv) > 16: #not empty if len(data_recv) > 16: #not empty
res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0]
print("res %i" % res) if self.verbose: print("res %i" % res)
if res == 0 or res == 6 or res == 4: if res == 0 or res == 6 or res == 4:
# 6 timeout, 4 mismatch error, 0 can't start(why?) # 6 timeout, 4 mismatch error, 0 can't start(why?)
print ("posible timeout o reg Fallido") if self.verbose: print ("posible timeout o reg Fallido")
break break
else: else:
if len(data_recv) > 8: #not empty if len(data_recv) > 8: #not empty
res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0]
print("res %i" % res) if self.verbose: print("res %i" % res)
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") if self.verbose: print ("posible timeout o reg Fallido")
break break
print ("A:%i esperando 2do regevent" % attempts) if self.verbose: print ("A:%i esperando 2do regevent" % attempts)
data_recv = self.__sock.recv(1032) # timeout? tarda bastante... data_recv = self.__sock.recv(1032) # timeout? tarda bastante...
self.__ack_ok() self.__ack_ok()
#print ((data_recv).encode('hex')) if self.verbose: print ((data_recv).encode('hex'))
if self.tcp: if self.tcp:
if len(data_recv) > 8: #not empty if len(data_recv) > 8: #not empty
res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0]
print("res %i" % res) if self.verbose: print("res %i" % res)
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") if self.verbose: print ("posible timeout o reg Fallido")
break break
elif res == 0x64: elif res == 0x64:
print ("ok, continue?") if self.verbose: print ("ok, continue?")
attempts -= 1 attempts -= 1
else: else:
if len(data_recv) > 8: #not empty if len(data_recv) > 8: #not empty
res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0]
print("res %i" % res) if self.verbose: print("res %i" % res)
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") if self.verbose: print ("posible timeout o reg Fallido")
break break
elif res == 0x64: elif res == 0x64:
print ("ok, continue?") if self.verbose: print ("ok, continue?")
attempts -= 1 attempts -= 1
if attempts == 0: if attempts == 0:
print ("esperando 3er regevent") if self.verbose: print ("esperando 3er regevent")
data_recv = self.__sock.recv(1032) # timeout? tarda bastante... data_recv = self.__sock.recv(1032) # timeout? tarda bastante...
self.__ack_ok() self.__ack_ok()
#print ((data_recv).encode('hex')) if self.verbose: print ((data_recv).encode('hex'))
if self.tcp: if self.tcp:
res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0]
else: else:
res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0]
print("res %i" % res) if self.verbose: print("res %i" % res)
if res == 5: if res == 5:
print ("huella duplicada") if self.verbose: print ("huella duplicada")
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") if self.verbose: print ("posible timeout o reg Fallido")
if res == 0: if res == 0:
size = unpack("H", data_recv.ljust(16,b"\x00")[10:12])[0] size = unpack("H", data_recv.ljust(16,b"\x00")[10:12])[0]
pos = unpack("H", data_recv.ljust(16,b"\x00")[12:14])[0] pos = unpack("H", data_recv.ljust(16,b"\x00")[12:14])[0]
print("enroll ok", size, pos) if self.verbose: print("enroll ok", size, pos)
done = True done = True
self.__sock.settimeout(self.__timeout) self.__sock.settimeout(self.__timeout)
self.reg_event(0) # TODO: test
self.cancel_capture() self.cancel_capture()
self.verify_user() self.verify_user()
return done return done
@ -1103,7 +1155,7 @@ class ZK(object):
self.end_live_capture = False self.end_live_capture = False
while not self.end_live_capture: while not self.end_live_capture:
try: try:
print ("esperando event") if self.verbose: print ("esperando event")
data_recv = self.__sock.recv(1032) data_recv = self.__sock.recv(1032)
self.__ack_ok() self.__ack_ok()
if self.tcp: if self.tcp:
@ -1115,10 +1167,10 @@ class ZK(object):
header = unpack('HHHH', data_recv[:8]) header = unpack('HHHH', data_recv[:8])
data = data_recv[8:] data = data_recv[8:]
if not header[0] == const.CMD_REG_EVENT: if not header[0] == const.CMD_REG_EVENT:
print("not event!") if self.verbose: print("not event!")
continue # or raise error? continue # or raise error?
if not len(data): if not len(data):
print ("empty") if self.verbose: print ("empty")
continue continue
"""if len (data) == 5: """if len (data) == 5:
@ -1126,7 +1178,7 @@ class ZK(object):
if len(data) == 12: #class 1 attendance if len(data) == 12: #class 1 attendance
user_id, status, match, timehex = unpack('<IBB6s', data) user_id, status, match, timehex = unpack('<IBB6s', data)
timestamp = self.__decode_timehex(timehex) timestamp = self.__decode_timehex(timehex)
tuser = filter(lambda x: int(x.user_id) == user_id, users) tuser = list(filter(lambda x: int(x.user_id) == user_id, users))
if not tuser: if not tuser:
uid = user_id uid = user_id
else: else:
@ -1136,22 +1188,23 @@ class ZK(object):
user_id, status, match, timehex, res = unpack('<24sBB6sI', data) user_id, status, match, timehex, res = unpack('<24sBB6sI', data)
user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore') user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore')
timestamp = self.__decode_timehex(timehex) timestamp = self.__decode_timehex(timehex)
tuser = filter(lambda x: int(x.user_id) == int(user_id), users) tuser = list(filter(lambda x: int(x.user_id) == int(user_id), users))
if not tuser: if not tuser:
uid = int(user_id) uid = int(user_id)
else: else:
uid = tuser[0].uid uid = tuser[0].uid
yield Attendance(uid, user_id, timestamp, status) yield Attendance(uid, user_id, timestamp, status)
else: else:
print ((data).encode('hex')), len(data) if self.verbose: print ((data).encode('hex')), len(data)
yield data yield data
except timeout: except timeout:
print ("time out") if self.verbose: print ("time out")
yield None # return to keep watching yield None # return to keep watching
except (KeyboardInterrupt, SystemExit): except (KeyboardInterrupt, SystemExit):
print ("break") if self.verbose: print ("break")
break break
print ("exit gracefully") if self.verbose: print ("exit gracefully")
self.__sock.settimeout(self.__timeout)
self.reg_event(0) # TODO: test self.reg_event(0) # TODO: test
if not was_enabled: if not was_enabled:
self.disable_device() self.disable_device()
@ -1186,21 +1239,21 @@ class ZK(object):
if cmd_response.get('code') == const.CMD_PREPARE_DATA: if cmd_response.get('code') == const.CMD_PREPARE_DATA:
data = [] data = []
bytes = self.__get_data_size() #TODO: check with size bytes = self.__get_data_size() #TODO: check with size
#print ("prepare data size is", bytes) if self.verbose: print ("prepare data size is", bytes)
if self.tcp: if self.tcp:
data_recv = self.__sock.recv(bytes + 32) data_recv = self.__sock.recv(bytes + 32)
recieved = len(data_recv) recieved = len(data_recv)
tcp_length = unpack('HHI', data_recv[:8])[2] #bytes+8 tcp_length = unpack('HHI', data_recv[:8])[2] #bytes+8
if tcp_length < (bytes + 8): if tcp_length < (bytes + 8):
print ("request chunk too big!") if self.verbose: print ("request chunk too big!")
response = unpack('HHHH', data_recv[8:16])[0] response = unpack('HHHH', data_recv[8:16])[0]
if recieved >= (bytes + 32): #complete if recieved >= (bytes + 32): #complete
if response == const.CMD_DATA: if response == const.CMD_DATA:
resp = data_recv[16:bytes+16] # no ack? resp = data_recv[16:bytes+16] # no ack?
#print ("resp len", len(resp)) if self.verbose: print ("resp len", len(resp))
return resp return resp
else: else:
print("broken packet!!!") if self.verbose: print("broken packet!!!")
return '' #broken return '' #broken
else: # incomplete else: # incomplete
data.append(data_recv[16:]) # w/o tcp and header data.append(data_recv[16:]) # w/o tcp and header
@ -1215,14 +1268,14 @@ class ZK(object):
if response == const.CMD_ACK_OK: if response == const.CMD_ACK_OK:
return b''.join(data) return b''.join(data)
#data_recv[bytes+16:].encode('hex') #included CMD_ACK_OK #data_recv[bytes+16:].encode('hex') #included CMD_ACK_OK
print("bad response %s" % data_recv) if self.verbose: print("bad response %s" % data_recv)
#print data if self.verbose: print (data)
return '' return ''
#else udp #else udp
while True: #limitado por respuesta no por tamaño while True: #limitado por respuesta no por tamaño
data_recv = self.__sock.recv(response_size) data_recv = self.__sock.recv(response_size)
response = unpack('HHHH', data_recv[:8])[0] response = unpack('HHHH', data_recv[:8])[0]
#print ("# %s packet response is: %s" % (pac, response)) if self.verbose: print ("# %s packet response is: %s" % (pac, response))
if response == const.CMD_DATA: if response == const.CMD_DATA:
data.append(data_recv[8:]) #header turncated data.append(data_recv[8:]) #header turncated
bytes -= 1024 #UDP bytes -= 1024 #UDP
@ -1230,9 +1283,9 @@ class ZK(object):
break #without problem. break #without problem.
else: else:
#truncado! continuar? #truncado! continuar?
print ("broken!") if self.verbose: print ("broken!")
break break
#print ("still needs %s" % bytes) if self.verbose: print ("still needs %s" % bytes)
return b''.join(data) return b''.join(data)
def read_with_buffer(self, command, fct=0 ,ext=0): def read_with_buffer(self, command, fct=0 ,ext=0):
@ -1242,7 +1295,7 @@ class ZK(object):
else: else:
MAX_CHUNK = 16 * 1024 MAX_CHUNK = 16 * 1024
command_string = pack('<bhii', 1, command, fct, ext) command_string = pack('<bhii', 1, command, fct, ext)
#print ("rwb cs", command_string) if self.verbose: print ("rwb cs", command_string)
response_size = 1024 response_size = 1024
data = [] data = []
start = 0 start = 0
@ -1254,7 +1307,7 @@ class ZK(object):
size = len(self.__data) size = len(self.__data)
return self.__data, size return self.__data, size
size = unpack('I', self.__data[1:5])[0] # extra info??? size = unpack('I', self.__data[1:5])[0] # extra info???
#print ("size fill be %i" % size) if self.verbose: print ("size fill be %i" % size)
remain = size % MAX_CHUNK remain = size % MAX_CHUNK
packets = (size-remain) // MAX_CHUNK # should be size /16k packets = (size-remain) // MAX_CHUNK # should be size /16k
for _wlk in range(packets): for _wlk in range(packets):
@ -1264,7 +1317,7 @@ class ZK(object):
data.append(self.__read_chunk(start, remain)) data.append(self.__read_chunk(start, remain))
start += remain # Debug start += remain # Debug
self.free_data() self.free_data()
#print ("_read w/chunk %i bytes" % start) if self.verbose: print ("_read w/chunk %i bytes" % start)
return b''.join(data), start return b''.join(data), start
def get_attendance(self): def get_attendance(self):
@ -1273,22 +1326,22 @@ class ZK(object):
if self.records == 0: #lazy if self.records == 0: #lazy
return [] return []
users = self.get_users() users = self.get_users()
#print users if self.verbose: print (users)
attendances = [] attendances = []
attendance_data, size = self.read_with_buffer(const.CMD_ATTLOG_RRQ) attendance_data, size = self.read_with_buffer(const.CMD_ATTLOG_RRQ)
if size < 4: if size < 4:
print ("WRN: no attendance data") # debug if self.verbose: print ("WRN: no attendance data") # debug
return [] return []
total_size = unpack("I", attendance_data[:4])[0] total_size = unpack("I", attendance_data[:4])[0]
record_size = total_size/self.records record_size = total_size/self.records
#print ("record_size is ", record_size) if self.verbose: print ("record_size is ", record_size)
attendance_data = attendance_data[4:] #total size not used attendance_data = attendance_data[4:] #total size not used
if record_size == 8 : #ultra old format if record_size == 8 : #ultra old format
while len(attendance_data) >= 8: while len(attendance_data) >= 8:
uid, status, timestamp = unpack('HH4s', attendance_data.ljust(8, b'\x00')[:8]) uid, status, timestamp = unpack('HH4s', attendance_data.ljust(8, b'\x00')[:8])
#print attendance_data[:8].encode('hex') if self.verbose: print (codecs.encode(attendance_data[:8], 'hex'))
attendance_data = attendance_data[8:] attendance_data = attendance_data[8:]
tuser = filter(lambda x: x.uid == uid, users) tuser = list(filter(lambda x: x.uid == uid, users))
if not tuser: if not tuser:
user_id = str(uid) #TODO revisar pq user_id = str(uid) #TODO revisar pq
else: else:
@ -1299,13 +1352,13 @@ class ZK(object):
elif record_size == 16: # extended elif record_size == 16: # extended
while len(attendance_data) >= 16: while len(attendance_data) >= 16:
user_id, timestamp, status, verified, reserved, workcode = unpack('<I4sBB2sI', attendance_data.ljust(16, b'\x00')[:16]) user_id, timestamp, status, verified, reserved, workcode = unpack('<I4sBB2sI', attendance_data.ljust(16, b'\x00')[:16])
#print attendance_data[:16].encode('hex') if self.verbose: print(codecs.encode(attendance_data[:16], 'hex'))
attendance_data = attendance_data[16:] attendance_data = attendance_data[16:]
tuser = filter(lambda x: int(x.user_id) == int(user_id), users) tuser = list(filter(lambda x: int(x.user_id) == int(user_id), users))
if not tuser: if not tuser:
#print("no uid {}", user_id) if self.verbose: print("no uid {}", user_id)
uid = str(user_id) uid = str(user_id)
tuser = filter(lambda x: x.uid == user_id, users) # refix tuser = list(filter(lambda x: x.uid == user_id, users)) # refix
if not tuser: if not tuser:
uid = str(user_id) #TODO revisar pq uid = str(user_id) #TODO revisar pq
else: else:
@ -1319,7 +1372,7 @@ class ZK(object):
else: else:
while len(attendance_data) >= 40: while len(attendance_data) >= 40:
uid, user_id, sparator, timestamp, status, space = unpack('<H24sc4sB8s', attendance_data.ljust(40, b'\x00')[:40]) uid, user_id, sparator, timestamp, status, space = unpack('<H24sc4sB8s', attendance_data.ljust(40, b'\x00')[:40])
#print attendance_data[:40].encode('hex') if self.verbose: print (codecs.encode(attendance_data[:40], 'hex'))
user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore') user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore')
timestamp = self.__decode_time(timestamp) timestamp = self.__decode_time(timestamp)
#status = int(status.encode("hex"), 16) #status = int(status.encode("hex"), 16)

View File

@ -2,8 +2,8 @@
from struct import pack #, unpack from struct import pack #, unpack
import codecs import codecs
class Finger(object): class Finger(object):
def __init__(self, size, uid, fid, valid, template): def __init__(self, uid, fid, valid, template):
self.size = size # template only self.size = len(template) # template only
self.uid = uid self.uid = uid
self.fid = fid self.fid = fid
self.valid = valid self.valid = valid