Added support for python3 (WIP)

possible broken a lot of things

still needs more safeguards
This commit is contained in:
Arturo Hernandez 2018-04-27 20:00:13 -04:00
parent cb1177f61a
commit 402ba438d1
5 changed files with 213 additions and 204 deletions

View File

@ -5,6 +5,7 @@ import traceback
import argparse import argparse
import time import time
import datetime import datetime
from builtins import input
sys.path.append("zk") sys.path.append("zk")
@ -45,42 +46,42 @@ args = parser.parse_args()
zk = ZK(args.address, port=args.port, timeout=args.timeout, password=args.password, force_udp=args.force_udp) # , 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: try:
print 'Connecting to device ...' print('Connecting to device ...')
conn = zk.connect() conn = zk.connect()
print 'SDK build=1 :', conn.set_sdk_build_1() # why? print('SDK build=1 : %s' % conn.set_sdk_build_1()) # why?
print 'Disabling device ...' print ('Disabling device ...')
conn.disable_device() conn.disable_device()
fmt = conn.get_extend_fmt() fmt = conn.get_extend_fmt()
print 'ExtendFmt : {}'.format(fmt) print ('ExtendFmt : {}'.format(fmt))
fmt = conn.get_user_extend_fmt() fmt = conn.get_user_extend_fmt()
print 'UsrExtFmt : {}'.format(fmt) print ('UsrExtFmt : {}'.format(fmt))
print 'Face FunOn : {}'.format(conn.get_face_fun_on()) print ('Face FunOn : {}'.format(conn.get_face_fun_on()))
print 'Face Version : {}'.format(conn.get_face_version()) print ('Face Version : {}'.format(conn.get_face_version()))
print 'Finger Version : {}'.format(conn.get_fp_version()) print ('Finger Version : {}'.format(conn.get_fp_version()))
print 'Old Firm compat : {}'.format(conn.get_compat_old_firmware()) print ('Old Firm compat : {}'.format(conn.get_compat_old_firmware()))
net = conn.get_network_params() net = conn.get_network_params()
print 'IP:{} mask:{} gateway:{}'.format(net['ip'],net['mask'], net['gateway']) print ('IP:{} mask:{} gateway:{}'.format(net['ip'],net['mask'], net['gateway']))
now = datetime.datetime.today().replace(microsecond=0) now = datetime.datetime.today().replace(microsecond=0)
if args.updatetime: if args.updatetime:
print '--- Updating Time---' print ('--- Updating Time---')
conn.set_time(now) conn.set_time(now)
zk_time = conn.get_time() zk_time = conn.get_time()
dif = abs(zk_time - now).total_seconds() dif = abs(zk_time - now).total_seconds()
print 'Time : {}'.format(zk_time) print ('Time : {}'.format(zk_time))
if dif > 120: if dif > 120:
print("WRN: TIME IS NOT SYNC!!!!!! (local: %s) use command -u to update" % now) print("WRN: TIME IS NOT SYNC!!!!!! (local: %s) use command -u to update" % now)
print 'Firmware Version : {}'.format(conn.get_firmware_version()) print ('Firmware Version : {}'.format(conn.get_firmware_version()))
print 'Platform : %s' % conn.get_platform() print ('Platform : %s' % conn.get_platform())
print 'DeviceName : %s' % conn.get_device_name() print ('DeviceName : %s' % conn.get_device_name())
print 'Pin Width : %i' % conn.get_pin_width() print ('Pin Width : %i' % conn.get_pin_width())
print 'Serial Number : %s' % conn.get_serialnumber() print ('Serial Number : %s' % conn.get_serialnumber())
print 'MAC: %s' % conn.get_mac() print ('MAC: %s' % conn.get_mac())
print '' print ('')
print '--- sizes & capacity ---' print ('--- sizes & capacity ---')
conn.read_sizes() conn.read_sizes()
print conn print (conn)
print '' print ('')
print '--- Get User ---' print ('--- Get User ---')
users = conn.get_users() users = conn.get_users()
max_uid = 0 max_uid = 0
prev = None prev = None
@ -90,15 +91,15 @@ try:
if user.uid > max_uid: if user.uid > max_uid:
max_uid = user.uid max_uid = user.uid
privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege 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 ('-> 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 (' 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 (len (user.repack73()), user.repack73().encode('hex'))
#print '' #print ('')
if args.adduser and user.uid == args.adduser: if args.adduser and user.uid == args.adduser:
prev = user prev = user
if args.deleteuser: if args.deleteuser:
print '' print ('')
print '-- Delete User UID#%s ---' % args.deleteuser print ('-- Delete User UID#%s ---' % args.deleteuser)
#TODO implementar luego #TODO implementar luego
conn.delete_user(args.deleteuser) conn.delete_user(args.deleteuser)
users = conn.get_users() #update users = conn.get_users() #update
@ -106,8 +107,8 @@ try:
if user.uid > max_uid: if user.uid > max_uid:
max_uid = user.uid max_uid = user.uid
privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege 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 ('-> 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 (' 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 len (user.repack73()), user.repack73().encode('hex')
#print '' #print ''
if args.adduser and user.uid == args.adduser: if args.adduser and user.uid == args.adduser:
@ -118,25 +119,26 @@ try:
if prev: if prev:
user = prev user = prev
privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege privilege = 'User' if user.privilege == const.USER_DEFAULT else 'Admin-%s' % user.privilege
print '' print ('')
print '--- Modify User %i ---' % user.uid print ('--- Modify User %i ---' % user.uid)
print '-> UID #{:<5} Name : {:<27} Privilege : {}'.format(user.uid, user.name, 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 (' Group ID : {:<8} User ID : {:<8} Password : {:<8} Card : {}'.format(user.group_id, user.user_id, user.password, user.card))
#discard prev #discard prev
else: else:
print '--- Add new User %i ---' % uid print ('--- Add new User %i ---' % uid)
name = raw_input('Name :') name = input('Name :')
admin = raw_input('Admin (y/n):') admin = input('Admin (y/N):')
privilege = 14 if admin == 'y' else 0 privilege = 14 if admin == 'y' else 0
password = raw_input('Password :') password = input('Password :')
user_id = raw_input('User ID2 :') user_id = input('User ID2 :')
card = int(raw_input('Card :')) card = input('Card :')
card = int(card) if card else 0
if prev: if prev:
conn.delete_user(uid) #borrado previo conn.delete_user(uid) #borrado previo
try: try:
conn.set_user(uid, name, privilege, password, '', user_id, card) conn.set_user(uid, name, privilege, password, '', user_id, card)
except ZKErrorResponse, e: except ZKErrorResponse as e:
print "error: ", e print ("error: %s" % e)
#try new format #try new format
zk_user = User(uid, name, privilege, password, '', user_id, card) zk_user = User(uid, name, privilege, password, '', user_id, card)
conn.save_user_template(zk_user) conn.save_user_template(zk_user)
@ -147,34 +149,34 @@ try:
else: else:
conn.test_voice(23) # not registered conn.test_voice(23) # not registered
conn.refresh_data() conn.refresh_data()
print "Voice Test ..." print ("Voice Test ...")
conn.test_voice(10) conn.test_voice(10)
if args.templates: if args.templates:
print "Read Templates..." print ("Read Templates...")
templates = conn.get_templates() templates = conn.get_templates()
for tem in templates: for tem in templates:
print tem print (tem)
if args.records: if args.records:
print "Read Records..." print ("Read Records...")
attendance = conn.get_attendance() attendance = conn.get_attendance()
i = 0 i = 0
for att in attendance: for att in attendance:
i +=1 i +=1
print "ATT {:>6}: uid:{:>3}, t: {}".format(i, att.uid, att.timestamp) print ("ATT {:>6}: uid:{:>3}, t: {}".format(i, att.uid, att.timestamp))
print '' print ('')
print '--- sizes & capacity ---' print ('--- sizes & capacity ---')
conn.read_sizes() conn.read_sizes()
print conn print (conn)
print '' print ('')
except Exception, e: except Exception as e:
print "Process terminate : {}".format(e) print ("Process terminate : {}".format(e))
print "Error: %s" % sys.exc_info()[0] print ("Error: %s" % sys.exc_info()[0])
print '-'*60 print ('-'*60)
traceback.print_exc(file=sys.stdout) traceback.print_exc(file=sys.stdout)
print '-'*60 print ('-'*60)
finally: finally:
if conn: if conn:
print 'Enabling device ...' print ('Enabling device ...')
conn.enable_device() conn.enable_device()
conn.disconnect() conn.disconnect()
print '' print ('')

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from base import ZK from .base import ZK
VERSION = (0, 3) VERSION = (0, 9)
__all__ = ['ZK'] __all__ = ['ZK']

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
#from builtins import str
from datetime import datetime from datetime import datetime
from socket import AF_INET, SOCK_DGRAM, SOCK_STREAM, socket from socket import AF_INET, SOCK_DGRAM, SOCK_STREAM, socket
from struct import pack, unpack from struct import pack, unpack
@ -110,6 +111,7 @@ class ZK(object):
self.__session_id = 0 self.__session_id = 0
self.__reply_id = const.USHRT_MAX-1 self.__reply_id = const.USHRT_MAX-1
self.__data_recv = None self.__data_recv = None
self.__data = None
def __create_socket(self): def __create_socket(self):
""" based on self.tcp""" """ based on self.tcp"""
if self.tcp: if self.tcp:
@ -167,7 +169,7 @@ class ZK(object):
return pack('H', checksum) return pack('H', checksum)
def __send_command(self, command, command_string='', response_size=8): def __send_command(self, command, command_string=b'', response_size=8):
''' '''
send command to the terminal send command to the terminal
''' '''
@ -186,12 +188,12 @@ class ZK(object):
self.__sock.sendto(buf, self.__address) self.__sock.sendto(buf, self.__address)
self.__data_recv = self.__sock.recv(response_size) self.__data_recv = self.__sock.recv(response_size)
self.__header = unpack('HHHH', self.__data_recv[:8]) self.__header = unpack('HHHH', self.__data_recv[:8])
except Exception, e: except Exception as e:
raise ZKNetworkError(str(e)) raise ZKNetworkError(str(e))
self.__response = self.__header[0] self.__response = self.__header[0]
self.__reply_id = self.__header[3] self.__reply_id = self.__header[3]
self.__data = self.__data_recv[8:] #could be empty
if self.__response in [const.CMD_ACK_OK, const.CMD_PREPARE_DATA, const.CMD_DATA]: if self.__response in [const.CMD_ACK_OK, const.CMD_PREPARE_DATA, const.CMD_DATA]:
return { return {
'status': True, 'status': True,
@ -203,14 +205,14 @@ class ZK(object):
} }
def __ack_ok(self): def __ack_ok(self):
""" event ack ok """ """ event ack ok """
buf = self.__create_header(const.CMD_ACK_OK, "", self.__session_id, const.USHRT_MAX - 1) buf = self.__create_header(const.CMD_ACK_OK, b'', self.__session_id, const.USHRT_MAX - 1)
try: try:
if self.tcp: if self.tcp:
top = self.__create_tcp_top(buf) top = self.__create_tcp_top(buf)
self.__sock.send(top) self.__sock.send(top)
else: else:
self.__sock.sendto(buf, self.__address) self.__sock.sendto(buf, self.__address)
except Exception, e: except Exception as e:
raise ZKNetworkError(str(e)) raise ZKNetworkError(str(e))
@ -221,7 +223,7 @@ class ZK(object):
Returns the amount of bytes that are going to be sent""" Returns the amount of bytes that are going to be sent"""
response = self.__response response = self.__response
if response == const.CMD_PREPARE_DATA: if response == const.CMD_PREPARE_DATA:
size = unpack('I', self.__data_recv[8:12])[0] size = unpack('I', self.__data[:4])[0]
return size return size
else: else:
return 0 return 0
@ -236,23 +238,26 @@ class ZK(object):
"""Decode a timestamp retrieved from the timeclock """Decode a timestamp retrieved from the timeclock
copied from zkemsdk.c - DecodeTime""" copied from zkemsdk.c - DecodeTime"""
"""
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') #print ("decode from %s "% format(t, '04x'))
"""
t = unpack("<I", t)[0]
second = t % 60 second = t % 60
t = t / 60 t = t // 60
minute = t % 60 minute = t % 60
t = t / 60 t = t // 60
hour = t % 24 hour = t % 24
t = t / 24 t = t // 24
day = t % 31 + 1 day = t % 31 + 1
t = t / 31 t = t // 31
month = t % 12 + 1 month = t % 12 + 1
t = t / 12 t = t // 12
year = t + 2000 year = t + 2000
@ -286,17 +291,17 @@ 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" #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'):
self.is_connect = True self.is_connect = True
# set the session iduid, privilege, password, name, card, group_id, timezone, user_id = unpack('HB5s8s5sBhI',userdata.ljust(28)[:28]) # set the session id
return self return self
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"]) 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):
@ -336,10 +341,10 @@ class ZK(object):
''' '''
return the firmware version return the firmware version
''' '''
cmd_response = self.__send_command(const.CMD_GET_VERSION,'', 1024) cmd_response = self.__send_command(const.CMD_GET_VERSION,b'', 1024)
if cmd_response.get('status'): if cmd_response.get('status'):
firmware_version = self.__data_recv[8:].split('\x00')[0] firmware_version = self.__data.split(b'\x00')[0]
return firmware_version return firmware_version.decode()
else: else:
raise ZKErrorResponse("Can't read frimware version") raise ZKErrorResponse("Can't read frimware version")
@ -348,12 +353,12 @@ class ZK(object):
return the serial number return the serial number
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = '~SerialNumber' command_string = b'~SerialNumber'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
serialnumber = self.__data_recv[8:].split('=')[-1].split('\x00')[0] serialnumber = self.__data.split(b'=')[-1].split(b'\x00')[0]
return serialnumber return serialnumber.decode() # string?
else: else:
raise ZKErrorResponse("can't read serial number") raise ZKErrorResponse("can't read serial number")
@ -362,13 +367,13 @@ class ZK(object):
return the serial number return the serial number
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = '~Platform' command_string = b'~Platform'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
platform = self.__data_recv[8:].split('=')[-1].split('\x00')[0] platform = self.__data.split(b'=')[-1].split(b'\x00')[0]
return platform return platform.decode()
else: else:
raise ZKErrorResponse("can't get platform") raise ZKErrorResponse("can't get platform")
@ -377,13 +382,13 @@ class ZK(object):
return the serial number return the serial number
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = 'MAC' command_string = b'MAC'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
mac = self.__data_recv[8:].split('=')[-1].split('\x00')[0] mac = self.__data.split(b'=')[-1].split(b'\x00')[0]
return mac return mac.decode()
else: else:
raise ZKErrorResponse("can't get mac") raise ZKErrorResponse("can't get mac")
@ -392,13 +397,13 @@ class ZK(object):
return the serial number return the serial number
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = '~DeviceName' command_string = b'~DeviceName'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
device = self.__data_recv[8:].split('=')[-1].split('\x00')[0] device = self.__data.split(b'=')[-1].split(b'\x00')[0]
return device return device.decode()
else: else:
raise ZKErrorResponse("can't read device name") raise ZKErrorResponse("can't read device name")
@ -407,13 +412,13 @@ class ZK(object):
return the face version return the face version
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = 'ZKFaceVersion' command_string = b'ZKFaceVersion'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
response = self.__data_recv[8:].split('=')[-1].split('\x00')[0] response = self.__data.split(b'=')[-1].split(b'\x00')[0]
return response return int(response) if response else 0
else: else:
return None return None
@ -422,13 +427,13 @@ class ZK(object):
return the fingerprint version return the fingerprint version
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = '~ZKFPVersion' command_string = b'~ZKFPVersion'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
response = self.__data_recv[8:].split('=')[-1].split('\x00')[0] response = self.__data.split(b'=')[-1].split(b'\x00')[0]
return response return int(response) if response else 0
else: else:
return None return None
@ -437,14 +442,14 @@ class ZK(object):
determine extend fmt determine extend fmt
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = '~ExtendFmt' command_string = b'~ExtendFmt'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
fmt = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) fmt = (self.__data.split(b'=')[-1].split(b'\x00')[0])
#definitivo? seleccionar firmware aqui? #definitivo? seleccionar firmware aqui?
return int(fmt) return int(fmt) if fmt else 0
else: else:
raise ZKErrorResponse("can't read extend fmt") raise ZKErrorResponse("can't read extend fmt")
@ -453,14 +458,14 @@ class ZK(object):
determine extend fmt determine extend fmt
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = '~UserExtFmt' command_string = b'~UserExtFmt'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
fmt = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) fmt = (self.__data.split(b'=')[-1].split(b'\x00')[0])
#definitivo? seleccionar firmware aqui? #definitivo? seleccionar firmware aqui?
return (fmt) return int(fmt) if fmt else 0
else: else:
return None return None
@ -469,14 +474,14 @@ class ZK(object):
determine extend fmt determine extend fmt
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = 'FaceFunOn' command_string = b'FaceFunOn'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
response = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) response = (self.__data.split(b'=')[-1].split(b'\x00')[0])
#definitivo? seleccionar firmware aqui? #definitivo? seleccionar firmware aqui?
return (response) return int(response) if response else 0
else: else:
return None return None
@ -485,43 +490,43 @@ class ZK(object):
determine extend fmt determine extend fmt
''' '''
command = const.CMD_OPTIONS_RRQ command = const.CMD_OPTIONS_RRQ
command_string = 'CompatOldFirmware' command_string = b'CompatOldFirmware'
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
response = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) response = (self.__data.split(b'=')[-1].split(b'\x00')[0])
#definitivo? seleccionar firmware aqui? #definitivo? seleccionar firmware aqui?
return response return int(response) if response else 0
else: else:
return None return None
def get_network_params(self): def get_network_params(self):
ip = self.__address[0] ip = self.__address[0]
mask = '' mask = b''
gate = '' gate = b''
cmd_response = self.__send_command(const.CMD_OPTIONS_RRQ, 'IPAddress', 1024) cmd_response = self.__send_command(const.CMD_OPTIONS_RRQ, b'IPAddress', 1024)
if cmd_response.get('status'): if cmd_response.get('status'):
ip = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) ip = (self.__data.split(b'=')[-1].split(b'\x00')[0])
cmd_response = self.__send_command(const.CMD_OPTIONS_RRQ, 'NetMask', 1024) cmd_response = self.__send_command(const.CMD_OPTIONS_RRQ, b'NetMask', 1024)
if cmd_response.get('status'): if cmd_response.get('status'):
mask = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) mask = (self.__data.split(b'=')[-1].split(b'\x00')[0])
cmd_response = self.__send_command(const.CMD_OPTIONS_RRQ, 'GATEIPAddress', 1024) cmd_response = self.__send_command(const.CMD_OPTIONS_RRQ, b'GATEIPAddress', 1024)
if cmd_response.get('status'): if cmd_response.get('status'):
gate = (self.__data_recv[8:].split('=')[-1].split('\x00')[0]) gate = (self.__data.split(b'=')[-1].split(b'\x00')[0])
return {'ip': ip, 'mask': mask, 'gateway': gate} return {'ip': ip.decode(), 'mask': mask.decode(), 'gateway': gate.decode()}
def get_pin_width(self): def get_pin_width(self):
''' '''
return the serial number return the serial number
''' '''
command = const.CMD_GET_PINWIDTH command = const.CMD_GET_PINWIDTH
command_string = ' P' command_string = b' P'
response_size = 9 response_size = 9
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
width = self.__data_recv[8:].split('\x00')[0] width = self.__data.split(b'\x00')[0]
return bytearray(width)[0] return bytearray(width)[0]
else: else:
raise ZKErrorResponse("can0t get pin width") raise ZKErrorResponse("can0t get pin width")
@ -540,13 +545,13 @@ class ZK(object):
command = const.CMD_GET_FREE_SIZES command = const.CMD_GET_FREE_SIZES
response_size = 1024 response_size = 1024
cmd_response = self.__send_command(command,'', response_size) cmd_response = self.__send_command(command,b'', response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
size = len(self.__data_recv[8:]) size = len(self.__data)
if size == 80: if size == 80:
fields = unpack('iiiiiiiiiiiiiiiiiiii', self.__data_recv[8:]) fields = unpack('iiiiiiiiiiiiiiiiiiii', self.__data)
else: #92? else: #92?
fields = unpack('iiiiiiiiiiiiiiiiiiiiiii', self.__data_recv[8:]) fields = unpack('iiiiiiiiiiiiiiiiiiiiiii', self.__data)
self.users = fields[4] self.users = fields[4]
self.fingers = fields[6] self.fingers = fields[6]
self.records = fields[8] self.records = fields[8]
@ -590,9 +595,9 @@ class ZK(object):
"""obtener la hora del equipo""" """obtener la hora del equipo"""
command = const.CMD_GET_TIME command = const.CMD_GET_TIME
response_size = 1032 response_size = 1032
cmd_response = self.__send_command(command, '', response_size) cmd_response = self.__send_command(command, b'', response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
return self.__decode_time(self.__data_recv[8:12]) return self.__decode_time(self.__data[:4])
else: else:
raise ZKErrorResponse("can't get time") raise ZKErrorResponse("can't get time")
@ -611,7 +616,7 @@ class ZK(object):
shutdown the device shutdown the device
''' '''
command = const.CMD_POWEROFF command = const.CMD_POWEROFF
command_string = '' command_string = b''
response_size = 1032 response_size = 1032
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if cmd_response.get('status'): if cmd_response.get('status'):
@ -724,15 +729,15 @@ class ZK(object):
if not group_id: if not group_id:
group_id = 0 group_id = 0
try: try:
command_string = pack('HB5s8s5sBHI', uid, privilege, str(password), str(name), chr(0), 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, e: except Exception as e:
print "s_h Error pack: %s" % e print("s_h Error pack: %s" % e)
print "Error pack: %s" % sys.exc_info()[0] 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, '\x00')[:24] name_pad = name.ljust(24, b'\x00')[:24]
card_str = pack('i', int(card))[:4] card_str = pack('i', int(card))[:4]
command_string = pack('HB8s24s4sc7sx24s', uid, privilege, password, name_pad, card_str, chr(0), group_id, str(user_id)) 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?
cmd_response = self.__send_command(command, command_string, response_size) cmd_response = self.__send_command(command, command_string, response_size)
if not cmd_response.get('status'): if not cmd_response.get('status'):
@ -780,7 +785,7 @@ class ZK(object):
if not cmd_response.get('status'): if not cmd_response.get('status'):
raise ZKErrorResponse("Cant prepare data") raise ZKErrorResponse("Cant prepare data")
remain = size % MAX_CHUNK remain = size % MAX_CHUNK
packets = (size - remain) / MAX_CHUNK packets = (size - remain) // MAX_CHUNK
start = 0 start = 0
for _wlk in range(packets): for _wlk in range(packets):
self.__send_chunk(buffer[start:start+MAX_CHUNK]) self.__send_chunk(buffer[start:start+MAX_CHUNK])
@ -847,7 +852,7 @@ class ZK(object):
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(1032)
response = unpack('HHHH', data_recv[:8])[0] response = unpack('HHHH', data_recv[:8])[0]
#print "# %s packet response is: %s" % (pac, response) #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
@ -855,10 +860,10 @@ class ZK(object):
break #without problem. break #without problem.
else: else:
#truncado! continuar? #truncado! continuar?
#print "broken!" #print("broken!")
break break
#print "still needs %s" % bytes #print("still needs %s" % bytes)
data = ''.join(data) data = b''.join(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(size, uid, temp_id, 1, data)
@ -867,7 +872,7 @@ class ZK(object):
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 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
@ -876,7 +881,7 @@ class ZK(object):
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(size, uid, fid, valid, template)
#print finger # test #print(finger) # test
templates.append(finger) templates.append(finger)
templatedata = templatedata[size:] templatedata = templatedata[size:]
total_size -= size total_size -= size
@ -889,21 +894,21 @@ 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 #print("user size %i" % size)
if size <= 4: if size <= 4:
print "WRN: no user data" # debug 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 ", self.user_packet_size 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:
uid, privilege, password, name, card, group_id, timezone, user_id = unpack('HB5s8s5sBhI',userdata.ljust(28)[:28]) uid, privilege, password, name, card, group_id, timezone, user_id = unpack('<HB5s8sIxBhI',userdata.ljust(28, b'\x00')[:28])
password = unicode(password.split('\x00')[0], errors='ignore') password = (password.split(b'\x00')[0]).decode(errors='ignore')
name = unicode(name.split('\x00')[0], errors='ignore').strip() name = (name.split(b'\x00')[0]).decode(errors='ignore').strip()
card = unpack('Q', card.ljust(8,'\x00'))[0] #or hex value? #card = unpack('I', card)[0] #or hex value?
group_id = str(group_id) group_id = str(group_id)
user_id = str(user_id) user_id = str(user_id)
#TODO: check card value and find in ver8 #TODO: check card value and find in ver8
@ -911,20 +916,20 @@ 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 #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:
uid, privilege, password, name, separator, group_id, user_id = unpack('Hc8s24s4sx7sx24s', userdata.ljust(72)[:72]) uid, privilege, password, name, card, group_id, user_id = unpack('<HB8s24sIx7sx24s', userdata.ljust(72, b'\x00')[:72])
#u1 = int(uid[0].encode("hex"), 16) #u1 = int(uid[0].encode("hex"), 16)
#u2 = int(uid[1].encode("hex"), 16) #u2 = int(uid[1].encode("hex"), 16)
#uid = u1 + (u2 * 256) #uid = u1 + (u2 * 256)
privilege = int(privilege.encode("hex"), 16) #privilege = int(privilege.encode("hex"), 16)
password = unicode(password.split('\x00')[0], errors='ignore') password = (password.split(b'\x00')[0]).decode(errors='ignore')
name = unicode(name.split('\x00')[0], errors='ignore').strip() name = (name.split(b'\x00')[0]).decode(errors='ignore').strip()
group_id = unicode(group_id.split('\x00')[0], errors='ignore').strip() group_id = (group_id.split(b'\x00')[0]).decode(errors='ignore').strip()
user_id = unicode(user_id.split('\x00')[0], errors='ignore') user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore')
card = int(unpack('I', separator)[0]) #card = int(unpack('I', separator)[0])
if not name: if not name:
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)
@ -963,7 +968,7 @@ class ZK(object):
def set_sdk_build_1(self): def set_sdk_build_1(self):
""" """ """ """
command = const.CMD_OPTIONS_WRQ command = const.CMD_OPTIONS_WRQ
command_string = "SDKBuild=1" command_string = b"SDKBuild=1"
cmd_response = self.__send_command(command, command_string) cmd_response = self.__send_command(command, command_string)
if not cmd_response.get('status'): if not cmd_response.get('status'):
return False #raise ZKErrorResponse("can't set sdk build ") return False #raise ZKErrorResponse("can't set sdk build ")
@ -994,33 +999,33 @@ 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 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') #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,"\x00")[16:18])[0] res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0]
print "res", res 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") 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,"\x00")[8:10])[0] res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0]
print "res", res print("res %i" % res)
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") print ("posible timeout o reg Fallido")
break break
print "A:%i esperando 2do regevent" % attempts 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') #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,"\x00")[16:18])[0] res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0]
print "res", res print("res %i" % res)
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") print ("posible timeout o reg Fallido")
break break
@ -1029,8 +1034,8 @@ class ZK(object):
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,"\x00")[8:10])[0] res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0]
print "res", res print("res %i" % res)
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") print ("posible timeout o reg Fallido")
break break
@ -1038,20 +1043,20 @@ class ZK(object):
print ("ok, continue?") print ("ok, continue?")
attempts -= 1 attempts -= 1
if attempts == 0: if attempts == 0:
print "esperando 3er regevent" 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') #print ((data_recv).encode('hex'))
if self.tcp: if self.tcp:
res = unpack("H", data_recv.ljust(24,"\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,"\x00")[8:10])[0] res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0]
if res == 6 or res == 4: if res == 6 or res == 4:
print ("posible timeout o reg Fallido") print ("posible timeout o reg Fallido")
if res == 0: if res == 0:
size = unpack("H", data_recv.ljust(16,"\x00")[10:12])[0] size = unpack("H", data_recv.ljust(16,b"\x00")[10:12])[0]
pos = unpack("H", data_recv.ljust(16,"\x00")[12:14])[0] pos = unpack("H", data_recv.ljust(16,b"\x00")[12:14])[0]
print "enroll ok", size, pos print("enroll ok", size, pos)
done = True done = True
self.__sock.settimeout(self.__timeout) self.__sock.settimeout(self.__timeout)
self.cancel_capture() self.cancel_capture()
@ -1081,27 +1086,27 @@ class ZK(object):
#else #else
if cmd_response.get('code') == const.CMD_DATA: # less than 1024!!! if cmd_response.get('code') == const.CMD_DATA: # less than 1024!!!
if self.tcp: if self.tcp:
return self.__data_recv[16:] #TODO: check size? return self.__data[8:] #TODO: check size?
else: else:
return self.__data_recv[8:] return self.__data
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 #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!" 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) #print ("resp len", len(resp))
return resp return resp
else: else:
print "broken packet!!!" 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
@ -1114,16 +1119,16 @@ class ZK(object):
data_recv = self.__sock.recv(16) data_recv = self.__sock.recv(16)
response = unpack('HHHH', data_recv[8:16])[0] response = unpack('HHHH', data_recv[8:16])[0]
if response == const.CMD_ACK_OK: if response == const.CMD_ACK_OK:
return ''.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 ", data_recv.encode('hex') print("bad response %s" % data_recv)
#print data #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) #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
@ -1131,10 +1136,10 @@ class ZK(object):
break #without problem. break #without problem.
else: else:
#truncado! continuar? #truncado! continuar?
print "broken!" print ("broken!")
break break
#print "still needs %s" % bytes #print ("still needs %s" % bytes)
return ''.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):
""" Test read info with buffered command (ZK6: 1503) """ """ Test read info with buffered command (ZK6: 1503) """
@ -1143,7 +1148,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 #print ("rwb cs", command_string)
response_size = 1024 response_size = 1024
data = [] data = []
start = 0 start = 0
@ -1152,12 +1157,12 @@ class ZK(object):
raise ZKErrorResponse("RWB Not supported") raise ZKErrorResponse("RWB Not supported")
if cmd_response['code'] == const.CMD_DATA: if cmd_response['code'] == const.CMD_DATA:
#direct!!! small!!! #direct!!! small!!!
size = len(self.__data_recv)-8 size = len(self.__data)
return self.__data_recv[8:], size return self.__data, size
size = unpack('I', self.__data_recv[9:13])[0] # extra info??? size = unpack('I', self.__data[1:5])[0] # extra info???
#print "size fill be %i" % size #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):
data.append(self.__read_chunk(start,MAX_CHUNK)) data.append(self.__read_chunk(start,MAX_CHUNK))
start += MAX_CHUNK start += MAX_CHUNK
@ -1165,8 +1170,8 @@ 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 #print ("_read w/chunk %i bytes" % start)
return ''.join(data), start return b''.join(data), start
def get_attendance(self): def get_attendance(self):
""" return attendance record """ """ return attendance record """
@ -1176,15 +1181,15 @@ class ZK(object):
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 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 #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)[:8]) uid, status, timestamp = unpack('HH4s', attendance_data.ljust(8, b'\x00')[:8])
attendance_data = attendance_data[8:] attendance_data = attendance_data[8:]
user_id = str(uid) #TODO revisar posibles valores cruzar con userdata user_id = str(uid) #TODO revisar posibles valores cruzar con userdata
timestamp = self.__decode_time(timestamp) timestamp = self.__decode_time(timestamp)
@ -1192,7 +1197,7 @@ class ZK(object):
attendances.append(attendance) attendances.append(attendance)
elif record_size == 16: # extended elif record_size == 16: # extended
while len(attendance_data) >= 16: while len(attendance_data) >= 16:
uid, timestamp, status, verified, reserved, workcode = unpack('<I4sBB2sI', attendance_data.ljust(16)[:16]) uid, timestamp, status, verified, reserved, workcode = unpack('<I4sBB2sI', attendance_data.ljust(16, b'\x00')[:16])
attendance_data = attendance_data[16:] attendance_data = attendance_data[16:]
user_id = str(uid) #TODO revisar posibles valores cruzar con userdata user_id = str(uid) #TODO revisar posibles valores cruzar con userdata
timestamp = self.__decode_time(timestamp) timestamp = self.__decode_time(timestamp)
@ -1200,10 +1205,10 @@ class ZK(object):
attendances.append(attendance) attendances.append(attendance)
else: else:
while len(attendance_data) >= 40: while len(attendance_data) >= 40:
uid, user_id, sparator, timestamp, status, space = unpack('H24sc4sc8s', attendance_data.ljust(40)[:40]) uid, user_id, sparator, timestamp, status, space = unpack('<H24sc4sB8s', attendance_data.ljust(40, b'\x00')[:40])
user_id = user_id.split('\x00')[0] user_id = user_id.split(b'\x00')[0]
timestamp = self.__decode_time(timestamp) timestamp = self.__decode_time(timestamp)
status = int(status.encode("hex"), 16) #status = int(status.encode("hex"), 16)
attendance = Attendance(uid, user_id, timestamp, status) attendance = Attendance(uid, user_id, timestamp, status)
attendances.append(attendance) attendances.append(attendance)

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from struct import pack #, unpack from struct import pack #, unpack
import codecs
class Finger(object): class Finger(object):
def __init__(self, size, uid, fid, valid, template): def __init__(self, size, uid, fid, valid, template):
self.size = size # template only self.size = size # template only
@ -7,7 +8,8 @@ class Finger(object):
self.fid = fid self.fid = fid
self.valid = valid self.valid = valid
self.template = template self.template = template
self.mark = str(template[:6]).encode("hex") #self.mark = str().encode("hex")
self.mark = codecs.encode(template[:6], 'hex')
def repack(self): #full def repack(self): #full
return pack("HHbb%is" % (self.size), self.size+6, self.uid, self.fid, self.valid, self.template) return pack("HHbb%is" % (self.size), self.size+6, self.uid, self.fid, self.valid, self.template)

View File

@ -11,7 +11,7 @@ class User(object):
self.user_id = user_id self.user_id = user_id
self.card = card # 64 int to 40 bit int self.card = card # 64 int to 40 bit int
def repack29(self): # with 02 for zk6 (size 29) def repack29(self): # with 02 for zk6 (size 29)
return pack("<BHB5s8s5sBhI", 2, self.uid, self.privilege, self.password, self.name, pack("Q", self.card), int(self.group_id), 0, int(self.user_id)) return pack("<BHB5s8sIxBhI", 2, self.uid, self.privilege, self.password, self.name, self.card, int(self.group_id) if self.group_id else 0, 0, int(self.user_id))
def repack73(self): #with 02 for zk8 (size73) def repack73(self): #with 02 for zk8 (size73)
#password 6s + 0x00 + 0x77 #password 6s + 0x00 + 0x77
# 0,0 => 7sx group id, timezone? # 0,0 => 7sx group id, timezone?