
    Lwgb                         d dl Z d dlmZ d dlmZmZmZmZmZ d dlmZm	Z	 d dl
Z
ddlmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddZddZ G d de      Z G d de      Zy)    N)datetime)AF_INET
SOCK_DGRAMSOCK_STREAMsockettimeout)packunpack   )const)
Attendance)ZKErrorConnectionZKErrorResponseZKNetworkError)User)Fingerc                 B    	  ||       S # t         t        f$ r |cY S w xY wN)
ValueError	TypeError)valto_typedefaults      >/var/www/horilla/myenv/lib/python3.12/site-packages/zk/base.py	safe_castr      s*    s|	" s   
 c           
         t        |       } t        |      }d}t        d      D ]  }| d|z  z  r	|dz  dz  }|dz  } ||z  }t        d|      }t        d|      }t        d|d   t	        d      z  |d   t	        d      z  |d   t	        d	      z  |d
   t	        d      z        }t        d|      }t        d|d   |d         }d|z  }t        d|      }t        d|d   |z  |d   |z  ||d
   |z        }|S )zv
    take a password and session_id and scramble them to send to the machine.
    copied from commpro.c - MakeKey
    r       r      Is   BBBBZK   S   Os   HH   )intranger	   r
   ord)key
session_idtickskiBs         r   make_commkeyr/      s+   
 c(CZJ	A2Y 16Na!AQA	
 OAT1AwA	!s3x	!s3x	!s3x	!s3x	A 	uaAUAaD!A$AuAwA	!q	!q		!q	A H    c                   *    e Zd ZdZddZd Zd Zd Zy)	ZK_helperz
    ZK helper class
    c                 2    ||f| _         || _        || _        y)z5
        Construct a new 'ZK_helper' object.
        N)addressipport)selfr5   r6   s      r   __init__zZK_helper.__init__A   s     Dz	r0   c                 (   ddl }ddl}|j                         j                         dk(  rdnd}d|z   dz   | j                  z   }|j                         j                         dk(  rdnd	}|j                  ||j                  |j                  |
      dk(  S )zX
        Returns True if host responds to a ping request

        :return: bool
        r   Nwindowsz-n 1z	-c 1 -W 5zping   FT)stdoutstderrshell)
subprocessplatformsystemlowerr5   callPIPE)r7   r?   r@   ping_strargsneed_shs         r   	test_pingzZK_helper.test_pingI   s     	$&oo/557B6x'#-7$OO-335y@%dt#-??#-??")  + /00 	0r0   c                     t        t        t              | _        | j                  j	                  d       | j                  j                  | j                        }| j                  j                          |S )z%
        test TCP connection
        
   )r   r   r   client
settimeout
connect_exr4   close)r7   ress     r   test_tcpzZK_helper.test_tcpZ   sQ    
 Wk2r"kk$$T\\2
r0   c                 l    t        t        t              | _        | j                  j	                  d       y)z%
        test UDP connection
        rJ   N)r   r   r   rK   rL   r7   s    r   test_udpzZK_helper.test_udpe   s$     Wj1r"r0   N)  )__name__
__module____qualname____doc__r8   rH   rP   rS    r0   r   r2   r2   <   s    0"	#r0   r2   c                      e Zd ZdZdDdZd Zd Zd Zd Zd Z	d Z
dEd	Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdFdZd Zd Zd Z d Z!d  Z"d! Z#d" Z$d# Z%dGd$Z&d% Z'd& Z(d' Z)d( Z*d) Z+d* Z,dHd+Z-dId-Z.g fd.Z/d/ Z0d0 Z1dJd1Z2dKd2Z3dKd3Z4d4 Z5d5 Z6d6 Z7d7 Z8d8 Z9d9 Z:dJd:Z;dLd;Z<d< Z=d= Z>d> Z?d? Z@d@ ZAdMdAZBdB ZCdC ZDy,)NZKz
    ZK main class
    c	                 ~   |t         _        ||f| _        t        t        t
              | _        | j                  j                  |       || _        || _	        d| _
        t        j                  dz
  | _        d| _        d| _        d| _        d| _        t%        ||      | _        || _        || _        || _        || _        | | _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _         d| _!        d| _"        d| _#        d| _$        d| _%        d| _&        d| _'        d| _(        y)a  
        Construct a new 'ZK' object.

        :param ip: machine's IP address
        :param port: machine's port
        :param timeout: timeout number
        :param password: passint
        :param force_udp: use UDP connection
        :param omit_ping: check ip using ping before connect
        :param verbose: showing log while run the commands
        :param encoding: user encoding
        r   r   NFT1   ))r   encoding_ZK__addressr   r   r   	_ZK__sockrL   _ZK__timeout_ZK__password_ZK__session_idr   	USHRT_MAX_ZK__reply_id_ZK__data_recv	_ZK__data
is_connect
is_enabledr2   helper	force_udp
ommit_pingverbosetcpusersfingersrecordsdummycardsfingers_cap	users_caprec_capfaces	faces_cap
fingers_avusers_avrec_avnext_uidnext_user_iduser_packet_sizeend_live_capture)	r7   r5   r6   r   passwordrl   rm   rn   r_   s	            r   r8   zZK.__init__q   s'    !dWj1w' "//A-D)"$  =



 " %r0   c                     | j                   S )z"
        for boolean test
        )ri   rR   s    r   __nonzero__zZK.__nonzero__   s     r0   c                 `   | j                   rdt        t        t              | _        | j                  j                  | j                         | j                  j                  | j                         y t        t        t              | _        | j                  j                  | j                         y r   )
ro   r   r   r   ra   rL   rb   rM   r`   r   rR   s    r   __create_socketzZK.__create_socket   sg    88 +6DKKK""4>>2KK""4>>2 *5DKKK""4>>2r0   c                 v    t        |      }t        dt        j                  t        j                  |      }||z   S )z:
        witch the complete packet set top header
        <HHI)lenr	   r   MACHINE_PREPARE_DATA_1MACHINE_PREPARE_DATA_2)r7   packetlengthtops       r   __create_tcp_topzZK.__create_tcp_top   s4     V65779U9UW]^V|r0   c                    t        d|d||      |z   }t        ddt        |      z  z   |      }t        d| j                  |            d   }|dz  }|t        j
                  k\  r|t        j
                  z  }t        d||||      }||z   S )zc
        Puts a the parts that make up a packet together and packs them into a byte string
        <4Hr   8Bz%sBHr   )r	   r
   r   _ZK__create_checksumr   re   )r7   commandcommand_stringr*   reply_idbufchecksums          r   __create_headerzZK.__create_header   s     5'1j(;nLTEC$777=#t55c:;A>Au&'H5'8ZB^##r0   c           
         t        |      }d}|dkD  rY|t        dt        d|d   |d               d   z  }|dd }|t        j                  kD  r|t        j                  z  }|dz  }|dkD  rY|r||d   z   }|t        j                  kD  r'|t        j                  z  }|t        j                  kD  r'| }|dk  r|t        j                  z  }|dk  rt        d|      S )zr
        Calculates the checksum of the packet to be sent to the time clock
        Copied from zkemsdk.c
        r   r   r   BBr!   N)r   r
   r	   r   re   )r7   plr   s       r   __create_checksumzZK.__create_checksum   s    
 F!esDqtQqT$:;A>>H!"A%//)EOO+FA !e !B%'H('H ( 9l'H l C""r0   c                     t        |      dk  ryt        d|dd       }|d   t        j                  k(  r|d   t        j                  k(  r|d   S y)z
        return size!
           r   r   Nr   r!   )r   r
   r   r   r   )r7   r   
tcp_headers      r   __test_tcp_topzZK.__test_tcp_top   sT     v;>FF2AJ/
a=E888Z]eNjNj=ja= r0   c                    |t         j                  t         j                  fvr| j                  st	        d      | j                  ||| j                  | j                        }	 | j                  r| j                  |      }| j                  j                  |       | j                  j                  |dz         | _        | j                  | j                        | _        | j                  dk(  rt!        d      t#        d| j                  dd       | _        | j                  dd | _        nd| j                  j)                  || j*                         | j                  j                  |      | _        t#        d| j&                  dd       | _        | j$                  d   | _        | j$                  d   | _        | j&                  dd | _        | j0                  t         j4                  t         j6                  t         j8                  fv rd	| j0                  d
S d| j0                  d
S # t,        $ r}t!        t/        |            d}~ww xY w)z.
        send command to the terminal
        zinstance are not connected.r   r   zTCP packet invalidr      Nr#   T)statuscodeF)r   CMD_CONNECTCMD_AUTHri   r   _ZK__create_headerrd   rf   ro   _ZK__create_tcp_topra   sendrecv_ZK__tcp_data_recv_ZK__test_tcp_top_ZK__tcp_lengthr   r
   _ZK__headerrg   sendtor`   	Exceptionstr_ZK__responserh   
CMD_ACK_OKCMD_PREPARE_DATACMD_DATA)r7   r   r   response_sizer   r   es          r   __send_commandzZK.__send_command   s    5,,enn==doo#$ABB""7ND<M<Mt_	)xx++C0  %'+{{'7'78I'J$$($7$78L8L$M!$$)()=>> &ud.B.B1R.H I#'#7#7#; ""37#';;#3#3M#B  &ud.>.>r.B C --*--*&&qr*??u//1G1GXX 
 OO
 	
  	) Q((	)s   #D,H$ $	I-IIc                    | j                  t        j                  d| j                  t        j                  dz
        }	 | j
                  r-| j                  |      }| j                  j                  |       y| j                  j                  || j                         y# t        $ r}t        t        |            d}~ww xY w)z
        event ack ok
        r0   r   N)r   r   r   rd   re   ro   r   ra   r   r   r`   r   r   r   )r7   r   r   r   s       r   __ack_okzZK.__ack_ok  s     ""5#3#3S$:K:KU___`M`a	)xx++C0  %""37 	) Q((	)s   8B 8&B 	C(B<<Cc                 ~    | j                   }|t        j                  k(  rt        d| j                  dd       d   }|S y)z
        Checks a returned packet to see if it returned CMD_PREPARE_DATA,
        indicating that data packets are to be sent

        Returns the amount of bytes that are going to be sent
        IN   r   )r   r   r   r
   rh   )r7   responsesizes      r   __get_data_sizezZK.__get_data_size!  s>     ??u---#t{{2A/2DKr0   c                 v    d}t        t        t        |      dz              D ]  }|||dz  |dz  dz    z  } |S )N r!   )reversedr'   r   )r7   hexdatar-   s       r   __reverse_hexzZK.__reverse_hex/  sJ    %C1-. 	+ACAq1uk**D	+r0   c                     t        d|      d   }|dz  }|dz  }|dz  }|dz  }|dz  }|dz  }|dz  dz   }|dz  }|dz  dz   }|dz  }|dz   }t        ||||||      }|S )	zm
        Decode a timestamp retrieved from the timeclock

        copied from zkemsdk.c - DecodeTime
        <Ir   <         r        r
   r   )	r7   tsecondminutehourdaymonthyeards	            r   __decode_timezZK.__decode_time5  s     4OARGRG2vG"fqjGB
G4xT5#tVV<r0   c                 V    t        d|      \  }}}}}}|dz  }t        ||||||      }|S )z-
        timehex string of six bytes
        6Br   r   )	r7   timehexr   r   r   r   r   r   r   s	            r   __decode_timehexzZK.__decode_timehexR  s?     28g1F.eS$T5#tVV<r0   c                     |j                   dz  dz  dz  |j                  dz
  dz  z   |j                  z   dz
  dz  |j                  dz  |j                  z   dz  z   |j
                  z   }|S )zL
        Encode a timestamp so that it can be read on the timeclock
        d   r   r   r   iQ r   )r   r   r   r   r   r   )r7   r   r   s      r   __encode_timezZK.__encode_time[  sx     ffslb 2%!''A+);<quuDqHffrkAHH4:;=>XXF 	
 r0   c                    d| _         | j                  s5| j                  j                         st	        d| j
                  d   z        | j                  s$| j                  j                         dk(  rd| _        | j                          d| _
        t        j                  dz
  | _        | j                  t        j                        }| j                   d   | _
        |j#                  d      t        j$                  k(  rW| j&                  rt)        d       t+        | j,                  | j                        }| j                  t        j.                  |      }|j#                  d	      r	d
| _        | S |d   t        j$                  k(  rt3        d      | j&                  rt)        dj5                  |d                t3        d      )z>
        connect to the device

        :return: bool
        Fzcan't reach device (ping %s)r   H   r   r!   r   ztry authr   TUnauthenticatedzconnect err response {} zInvalid response: Can't connect)r   rm   rk   rH   r   r`   rl   rP   r   _ZK__create_socketrd   r   re   rf   _ZK__send_commandr   r   getCMD_ACK_UNAUTHrn   printr/   rc   r   ri   r   format)r7   cmd_responser   s      r   connectz
ZK.connectg  sc    !&t{{'<'<'> !?$..QRBS!STT~~$++"6"6"8A"=$&D!//A-**5+<+<= MM!,F#u';';;||UJ/)$//4;L;LMN..u~~~NLH%"DOKF#u';';;%&788||U$>$E$ElSYFZ$[\!"CDDr0   c                     | j                  t        j                        }|j                  d      r.d| _        | j
                  r| j
                  j                          yt        d      )zL
        diconnect from the connected device

        :return: bool
        r   FTzcan't disconnect)r   r   CMD_EXITr   ri   ra   rN   r   r7   r   s     r   
disconnectzZK.disconnect  sS     **5>>:H%#DO{{!!#!"455r0   c                     | j                  t        j                        }|j                  d      rd| _        yt        d      )zo
        re-enable the connected device and allow user activity in device again

        :return: bool
        r   TzCan't enable device)r   r   CMD_ENABLEDEVICEr   rj   r   r   s     r   enable_devicezZK.enable_device  s>     **5+A+ABH%"DO!"788r0   c                     | j                  t        j                        }|j                  d      rd| _        yt        d      )z{
        disable (lock) device, to ensure no user activity in device while some process run

        :return: bool
        r   FTzCan't disable device)r   r   CMD_DISABLEDEVICEr   rj   r   r   s     r   disable_devicezZK.disable_device  s>     **5+B+BCH%#DO!"899r0   c                     | j                  t        j                  dd      }|j                  d      r.| j                  j                  d      d   }|j                         S t        d      )z/
        :return: the firmware version
        r0      r       r   zCan't read frimware version)r   r   CMD_GET_VERSIONr   rh   splitdecoder   )r7   r   firmware_versions      r   get_firmware_versionzZK.get_firmware_version  sa     **5+@+@dKH%#{{009!<#**,,!"?@@r0   c                 .   t         j                  }d}d}| j                  |||      }|j                  d      rS| j                  j                  dd      d   j                  d      d   }|j                  dd	      }|j                         S t        d
      )z,
        :return: the serial number
        s   ~SerialNumber r   r      =r   r   r   r   r0   zCan't read serial number	r   CMD_OPTIONS_RRQr   r   rh   r   replacer   r   )r7   r   r   r   r   serialnumbers         r   get_serialnumberzZK.get_serialnumber  s     ''-**7NMRH%;;,,T15b9??HKL'//c:L&&((!"<==r0   c                 .   t         j                  }d}d}| j                  |||      }|j                  d      rS| j                  j                  dd      d   j                  d      d   }|j                  dd	      }|j                         S t        d
      )z,
        :return: the platform name
        s
   ~Platform r   r   r   r   r   r   r   r0   zCan't read platform namer  )r7   r   r   r   r   r@   s         r   get_platformzZK.get_platform  s     '')**7NMRH%{{((q1"5;;GDQGH''c2H??$$!"<==r0   c                 
   t         j                  }d}d}| j                  |||      }|j                  d      rA| j                  j                  dd      d   j                  d      d   }|j                         S t        d	      )
z4
        :return: the machine's mac address
        s   MAC r   r   r   r   r   r   r   zcan't read mac address)r   r  r   r   rh   r   r   r   )r7   r   r   r   r   macs         r   get_macz
ZK.get_mac  s~     ''#**7NMRH%++##D!,R066w?BC::<!":;;r0   c                     t         j                  }d}d}| j                  |||      }|j                  d      rA| j                  j                  dd      d   j                  d      d   }|j                         S y	)
z>
        return the device name

        :return: str
        s   ~DeviceName r   r   r   r   r   r   r   r   )r   r  r   r   rh   r   r   )r7   r   r   r   r   devices         r   get_device_namezZK.get_device_name  su     ''+**7NMRH%[[&&tQ/399'B1EF==?"r0   c                     t         j                  }d}d}| j                  |||      }|j                  d      rF| j                  j                  dd      d   j                  d      d   }|rt        |t        d      S dS y	)
z+
        :return: the face version
        s   ZKFaceVersion r   r   r   r   r   r   r   N)r   r  r   r   rh   r   r   r&   r7   r   r   r   r   r   s         r   get_face_versionzZK.get_face_version  s     ''-**7NMRH%{{((q1"5;;GDQGH3;9XsA.BBr0   c                 8   t         j                  }d}d}| j                  |||      }|j                  d      rX| j                  j                  dd      d   j                  d      d   }|j                  dd	      }|rt        |t        d      S dS t        d
      )z2
        :return: the fingerprint version
        s   ~ZKFPVersion r   r   r   r   r   r   r   r0   zcan't read fingerprint version)
r   r  r   r   rh   r   r  r   r&   r   r  s         r   get_fp_versionzZK.get_fp_version  s     '',**7NMRH%{{((q1"5;;GDQGH''c2H2:9XsA.AA!"BCCr0   c                    | j                  t        j                  |d      }| j                  t        j                  |d      }| j                  t        j                  |d      }| j                  t        j                  |d      }y)z!
        clear ACK_error
        r   N)r   r   CMD_ACK_ERRORCMD_ACK_UNKNOWN)r7   r   r   s      r   _clear_errorzZK._clear_error  sp     **5+>+>PTU**5+@+@.RVW**5+@+@.RVW**5+@+@.RVWr0   c                 "   t         j                  }d}d}| j                  |||      }|j                  d      rF| j                  j                  dd      d   j                  d      d   }|rt        |t        d      S dS | j                  |       y	)
&
        determine extend fmt
        s   ~ExtendFmt r   r   r   r   r   r   r   N	r   r  r   r   rh   r   r   r&   r  r7   r   r   r   r   fmts         r   get_extend_fmtzZK.get_extend_fmt  s     ''***7NMRH%;;$$T1-b177@CC-09S#q)7a7n-r0   c                 "   t         j                  }d}d}| j                  |||      }|j                  d      rF| j                  j                  dd      d   j                  d      d   }|rt        |t        d      S dS | j                  |       y	)
z+
        determine user extend fmt
        s   ~UserExtFmt r   r   r   r   r   r   r   Nr  r  s         r   get_user_extend_fmtzZK.get_user_extend_fmt/  s     ''+**7NMRH%;;$$T1-b177@CC-09S#q)7a7n-r0   c                 "   t         j                  }d}d}| j                  |||      }|j                  d      rF| j                  j                  dd      d   j                  d      d   }|rt        |t        d      S dS | j                  |       y	)
r  s
   FaceFunOn r   r   r   r   r   r   r   Nr  r  s         r   get_face_fun_onzZK.get_face_fun_on?  s     '')**7NMRH%))$226<<WEaHH2:9XsA.AAn-r0   c                 "   t         j                  }d}d}| j                  |||      }|j                  d      rF| j                  j                  dd      d   j                  d      d   }|rt        |t        d      S dS | j                  |       y	)
z(
        determine old firmware
        s   CompatOldFirmware r   r   r   r   r   r   r   Nr  r  s         r   get_compat_old_firmwarezZK.get_compat_old_firmwareO  s     ''1**7NMRH%))$226<<WEaHH2:9XsA.AAn-r0   c                    | j                   d   }d}d}| j                  t        j                  dd      }|j	                  d      r1| j
                  j                  dd      d   j                  d	      d   }| j                  t        j                  d
d      }|j	                  d      r1| j
                  j                  dd      d   j                  d	      d   }| j                  t        j                  dd      }|j	                  d      r1| j
                  j                  dd      d   j                  d	      d   }|j                         |j                         |j                         dS )z$
        get network params
        r   r0   s
   IPAddress r   r   r   r   r   r   s   NetMask s   GATEIPAddress )r5   maskgateway)r`   r   r   r  r   rh   r   r   )r7   r5   r$  gater   s        r   get_network_paramszZK.get_network_params_  s9    ^^A**5+@+@BRTXYH%++##D!,R066w?BB**5+@+@.RVWH%KK%%dA.r288A!DD**5+@+@BVX\]H%KK%%dA.r288A!DDiik4;;=T[[]SSr0   c                     t         j                  }d}d}| j                  |||      }|j                  d      r,| j                  j                  d      d   }t        |      d   S t        d      )z(
        :return: the PIN width
        s    P	   r   r   r   zcan0t get pin width)r   CMD_GET_PINWIDTHr   r   rh   r   	bytearrayr   )r7   r   r   r   r   widths         r   get_pin_widthzZK.get_pin_widthq  sp     ((**7NMRH%KK%%g.q1EU#A&&!"788r0   c                 ~    t         j                  }| j                  |      }|j                  d      ryt	        d      )z5
        clear buffer

        :return: bool
        r   Tzcan't free data)r   CMD_FREE_DATAr   r   r   r7   r   r   s      r   	free_datazZK.free_data  s<     %%**73H%!"344r0   c                    t         j                  }d}| j                  |d|      }|j                  d      rC| j                  r)t        t        j                  | j                  d             t        | j                        }t        | j                        dk\  rt        d| j                  dd       }|d   | _        |d	   | _        |d
   | _        |d   | _        |d   | _        |d   | _        |d   | _        |d   | _        |d   | _        |d   | _        |d   | _        | j                  dd | _        t        | j                        dk\  r-t        d| j                  dd       }|d   | _        |d   | _        yt1        d      )z(
        read the memory ussage
        r   r0   r   r   P   20iNr      r   rJ   r         r            3ir   r!   Tzcan't read sizes)r   CMD_GET_FREE_SIZESr   r   rn   r   codecsencoderh   r   r
   rp   rq   rr   rs   rt   ru   rv   rw   rz   r{   r|   rx   ry   r   )r7   r   r   r   r   fieldss         r   
read_sizeszZK.read_sizes  sb    ****73FH%||U6==U#CDt{{#D4;;2%t{{3B'78#AY
%ay%ay#BZ
#BZ
#)": !'%bz"(* &r
$Rj"kk"#.4;;2%dkk#2&67#AY
!'!"455r0   c                     t         j                  }t        dt        |      dz        }| j	                  ||      }|j                  d      ryt        d      )z
        unlock the door

        thanks to https://github.com/SoftwareHouseMerida/pyzk/

        :param time: define delay in seconds
        :return: bool
        r   rJ   r   TzCan't open door)r   
CMD_UNLOCKr	   r&   r   r   r   )r7   timer   r   r   s        r   unlockz	ZK.unlock  sR     ""c#d)B,/**7NCH%!"344r0   c                 (   d| j                   rdnd| j                  d   | j                  d   | j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  | j                  fz  S )z
        for debug
        zFZK %s://%s:%s users[%i]:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%iro   udpr   r   )ro   r`   r   rp   rv   rq   ru   rr   rw   rx   ry   rR   s    r   __str__z
ZK.__str__  sw     XXXE5$..*;T^^A=N!!4::t~~LL$**LL$,,JJ[
 
 	
r0   c                     t         j                  }| j                  |      }|j                  d      rd| _        d| _        yt        d      )z;
        restart the device

        :return: bool
        r   Fr   Tzcan't restart device)r   CMD_RESTARTr   r   ri   r}   r   r0  s      r   restartz
ZK.restart  sJ     ##**73H%#DODM!"899r0   c                     t         j                  }d}| j                  |d|      }|j                  d      r| j	                  | j
                  dd       S t        d      )z-
        :return: the machine's time
          r0   r   Nr   zcan't get time)r   CMD_GET_TIMEr   r   _ZK__decode_timerh   r   )r7   r   r   r   s       r   get_timezZK.get_time  s]     $$**7CGH%%%dkk"1o66!"233r0   c                     t         j                  }t        d| j                  |            }| j	                  ||      }|j                  d      ryt        d      )zj
        set Device time (pass datetime object)

        :param timestamp: python datetime object
        r   r   Tzcan't set time)r   CMD_SET_TIMEr	   _ZK__encode_timer   r   r   )r7   	timestampr   r   r   s        r   set_timezZK.set_time  sU     $$dD$6$6y$AB**7NCH%!"233r0   c                     t         j                  }d}d}| j                  |||      }|j                  d      rd| _        d| _        yt        d      )z&
        shutdown the machine
        r0   rL  r   Fr   Tzcan't poweroff)r   CMD_POWEROFFr   r   ri   r}   r   )r7   r   r   r   r   s        r   poweroffzZK.poweroff  sX     $$**7NMRH%#DODM!"233r0   c                 ~    t         j                  }| j                  |      }|j                  d      ryt	        d      )Nr   Tzcan't refresh data)r   CMD_REFRESHDATAr   r   r   r0  s      r   refresh_datazZK.refresh_data   s:    ''**73H%!"677r0   c                     t         j                  }t        d|      }| j                  ||      }|j	                  d      ryy)a1  
        play test voice:

         0 Thank You

         1 Incorrect Password

         2 Access Denied

         3 Invalid ID

         4 Please try again

         5 Dupicate ID

         6 The clock is flow

         7 The clock is full

         8 Duplicate finger

         9 Duplicated punch

         10 Beep kuko

         11 Beep siren

         12 -

         13 Beep bell

         14 -

         15 -

         16 -

         17 -

         18 Windows(R) opening sound

         19 -

         20 Fingerprint not emolt

         21 Password not emolt

         22 Badges not emolt

         23 Face not emolt

         24 Beep standard

         25 -

         26 -

         27 -

         28 -

         29 -

         30 Invalid user

         31 Invalid time period

         32 Invalid combination

         33 Illegal Access

         34 Disk space full

         35 Duplicate fingerprint

         36 Fingerprint not registered

         37 -

         38 -

         39 -

         40 -

         41 -

         42 -

         43 -

         43 -

         45 -

         46 -

         47 -

         48 -

         49 -

         50 -

         51 Focus eyes on the green box

         52 -

         53 -

         54 -

         55 -


        :param index: int sound index
        :return: bool
        r   r   TF)r   CMD_TESTVOICEr	   r   r   )r7   indexr   r   r   s        r   
test_voicezZK.test_voice  sB    ~ %%c5)**7NCH%r0   Nc                    t         j                  }|| j                  }|s| j                  }|st	        |      }|t         j
                  t         j                  fvrt         j
                  }t        |      }| j                  dk(  ra|sd}	 t        d|||j                  | j                  d      |j                  | j                  d      |t        |      dt        |      	      }	n|j                  | j                  d      j%                  d
d      dd
 }t        dt        |            dd }t        d|||j                  | j                  d      |||j                         |j                               }	d}| j'                  ||	|      }| j                  rt        d|z         |j)                  d      st#        d      | j+                          | j                  |k(  r| xj                  dz  c_        | j                  |k(  rt	        | j                        | _        yy# t        $ rY}
| j                  rt        d|
z         | j                  r#t        dt        j                          d   z         t#        d	      d}
~
ww xY w)a1  
        create or update user by uid

        :param name: name ot the user
        :param privilege: check the const.py for reference
        :param password: int password
        :param group_id: group ID
        :param user_id: your own user ID
        :param card: card
        :return: bool
        Nr^   r   HB5s8sIxBHIignoreerrorszs_h Error pack: %szError pack: %szCan't pack userr   r   r   r   HB8s24s4sx7sx24sr   zResponse: %sr   zCan't set userr   )r   CMD_USER_WRQr}   r~   r   USER_DEFAULT
USER_ADMINr&   r   r	   r>  r_   r   rn   r   sysexc_infor   ljustr   r   rZ  )r7   uidname	privileger   group_iduser_idcardr   r   r   name_padcard_strr   r   s                  r   set_userzZK.set_userO  s    $$;--C++#hGU//1A1ABB**I	N	  B&9!%mS)X__UYUbUbks_Etvz  wB  wB  CG  CP  CP  Ya  wB  wb  dh  jm  nv  jw  yz  |  @G  |H  "I {{4=={BHHWUVYWYZHD#d),Ra0H!"4c9hooVZVcVcltoFuw  BJ  LT  L[  L[  L]  _f  _m  _m  _o  pN**7NMR<<~<=)!"233==CMMQM' #DMM 2D (!  9<<';a'?!@<<'7#,,.:K'K!L%&7889s   AH" "	J+AI??Jc           	      n   t        t              ss| j                         }t        t	        fd|            }t        |      dk(  r|d   n7t        t	        fd|            }t        |      dk(  r|d   nt        d      t        |t              r|g}d}d}d}d}|D ]N  }	|	j                         }
|t        dd	j                  ||	j                  z   |      z  }|t        |
      z  }||
z  }P | j                  d
k(  rj                         }nj                         }t        dt        |      t        |      t        |            }||z   |z   |z   }| j                  |       d}t        dddd      }| j!                  ||      }|j#                  d      st        d      | j%                          y)z
        save user and template

        :param user: user
        :param fingers: list of finger. (The maximum index 0-9)
        c                 "    | j                   k(  S r   rk  xusers    r   <lambda>z'ZK.save_user_template.<locals>.<lambda>  s    155$; r0   r   r   c                 4    | j                   t              k(  S r   ro  r   rw  s    r   rz  z'ZK.save_user_template.<locals>.<lambda>  s    qyy#d)/C r0   zCan't find userr0   r   z<bHbIr!   r^   IIIn   z<IHHr   r   r   zCan't save utempN)
isinstancer   	get_userslistfilterr   r   r   repack_onlyr	   rk  fidr   repack29repack73_send_with_bufferr   r   rZ  )r7   ry  rq   rp   tusersfpacktablefnumtstartfingertfpupackheadr   r   r   r   s    `               r   save_user_templatezZK.save_user_template~  s    $%NN$E&!6>?F6{aayf%CUKLv;!#!!9D)*;<<gv&iG 	F$$&CT'1dhhvzz0A6JJEc#hFSLE		
   B&MMOEMMOEE3u:s5z3u:>%-v&fb1-**7NC)!"455r0   c                 |   d}t        |      }| j                          t        j                  }t	        d|      }| j                  ||      }|j                  d      st        d      ||z  }||z
  |z  }d}	t        |      D ]  }
| j                  ||	|	|z           |	|z  }	  |r| j                  ||	|	|z           y y )Nr   r   r   zCan't prepare datar   )
r   r1  r   r   r	   r   r   r   r'   _ZK__send_chunk)r7   buffer	MAX_CHUNKr   r   r   r   remainpacketsstart_wlks              r   r  zZK._send_with_buffer  s    	6{((c4**7NC)!"677	!&=Y.'N 	DfU5?;<YE	 fU5<89 r0   c                     t         j                  }| j                  ||      }|j                  d      ryt	        d      )Nr   TzCan't send chunk)r   r   r   r   r   )r7   r   r   r   s       r   __send_chunkzZK.__send_chunk  s:    ..**7NCH%!"455r0   c                    | j                   r?r=d}t        dt              |      }| j                  ||      }|j	                  d      ryy|s:| j                         }t        t        fd|            }|sy|d   j                  }t        j                  }t        d||      }| j                  ||      }|j	                  d      ryy)	z
        Delete specific template

        :param uid: user ID that are generated from device
        :param user_id: your own user ID
        :return: bool
           z<24sBr   TFc                 4    | j                   t              k(  S r   r|  rx  ro  s    r   rz  z)ZK.delete_user_template.<locals>.<lambda>      !))S\*A r0   r   hb)ro   r	   r   r   r   r  r  r  rk  r   CMD_DELETE_USERTEMP)r7   rk  temp_idro  r   r   r   rp   s      `    r   delete_user_templatezZK.delete_user_template  s     88G!'3w<AN..wGL)NN$E A5IJE(,,C++dC1**7NCH%r0   c                 f   |s:| j                         }t        t        fd|            }|sy|d   j                  }t        j
                  }t        d|      }| j                  ||      }|j                  d      st        d      | j                          || j                  dz
  k(  r|| _        yy)	z
        delete specific user by uid or user_id

        :param uid: user ID that are generated from device
        :param user_id: your own user ID
        :return: bool
        c                 4    | j                   t              k(  S r   r|  r  s    r   rz  z ZK.delete_user.<locals>.<lambda>  r  r0   Fr   hr   zCan't delete userr   N)r  r  r  rk  r   CMD_DELETE_USERr	   r   r   r   rZ  r}   )r7   rk  ro  rp   r   r   r   s     `    r   delete_userzZK.delete_user  s     NN$E A5IJE(,,C''c3**7NC)!"5664==1$%DM &r0   c                    |s:| j                         }t        t        fd|            }|sy|d   j                  }t	        d      D ]r  }d}t        d||      }d}| j                  |||      }	| j                         }
|
"|
dd	 }|d
d dk(  r|dd
 }t        ||d|      c S | j                  sht        d       t | j                  rt        d       y)z
        :param uid: user ID that are generated from device
        :param user_id: your own user ID
        :return: list Finger object of the selected user
        c                 4    | j                   t              k(  S r   r|  r  s    r   rz  z&ZK.get_user_template.<locals>.<lambda>   r  r0   Fr   r#   X   r  rL  Nr   is         r   zretry get_user_templatezCan't read/find finger)r  r  r  rk  r'   r	   r   _ZK__recieve_chunkr   rn   r   )r7   rk  r  ro  rp   _retriesr   r   r   r   r   resps      `        r   get_user_templatezZK.get_user_template  s     NN$E A5IJE(,,Ca 	HG!$W5N$M..wVL'')DCRy9 ;;9Dc7At44||U$=>	 ||U$<=r0   c           	      \   | j                          | j                  dk(  rg S g }| j                  t        j                  t        j
                        \  }}|dk  r| j                  rt        d       g S t        d|dd       d   }| j                  r%t        dj                  ||t        |                   |dd }|rot        d|dd       \  }}}}t        d	|dz
  z  |d|       d   }t        ||||      }	| j                  rt        |	       |j                  |	       ||d }||z  }|ro|S )
z0
        :return: list of Finger object
        r   r   zWRN: no user datar-   z*get template total size {}, size {} len {}NHHbbr5  z%is)r@  rq   read_with_bufferr   
CMD_DB_RRQFCT_FINGERTMPrn   r   r
   r   r   r   append)
r7   	templatestemplatedatar   
total_sizerk  r  validtemplater  s
             r   get_templateszZK.get_templates  s;    	<<1I	!2253C3CUEXEXYd!8||U#67ICa!23A6
<< L S ST^`dfijvfw xy#AB'$*6,r2B$C!D#sEetAv.Qt0DEaHHCeX6F||U6]V$'.L$J  r0   c                      j                           j                  dk(  rd _        d _        g S g }d} j	                  t
        j                  t
        j                        \  }} j                  r$t        dj                  |t        |                   |dk  rt        d       g S t        d|dd       d   }| j                  z   _         j                  d	vr$ j                  rt        d
 j                  z         |dd } j                  dk(  rt        |      dk\  rct        d|j                  dd      dd       \  }}}}	}
}}}||kD  r|}|j                  d      d   j!                   j"                  d      }|	j                  d      d   j!                   j"                  d      j%                         }	t'        |      }t'        |      }|	sd|z  }	t)        ||	|||||
      }|j+                  |        j                  rt        d||||	|
|||	       |dd }t        |      dk\  rnSt        |      dk\  rDt        d|j                  dd      dd       \  }}}}	}
}}|j                  d      d   j!                   j"                  d      }|	j                  d      d   j!                   j"                  d      j%                         }	|j                  d      d   j!                   j"                  d      j%                         }|j                  d      d   j!                   j"                  d      }||kD  r|}|	sd|z  }	t)        ||	|||||
      }|j+                  |       |dd }t        |      dk\  rD|dz  }| _        t'        |       _        	 t-         fd|D              r|dz  }t'        |       _        n	 |S .)z.
        :return: list of User object
        r   r   r]   zuser size {} (= {})r   zWRN: missing user datar   N)r^   r   zWRN packet size would be  %ir^   z<HB5s8sIxBhIr   ra  rb  zNN-%sz[6]user:r   z<HB8s24sIx7sx24sc              3   V   K   | ]   }|j                   j                  k(  s| " y wr   )ro  r~   ).0ur7   s     r   	<genexpr>zZK.get_users.<locals>.<genexpr>b  s"     FqyyD4E4E'E1Fs   )))r@  rp   r}   r~   r  r   CMD_USERTEMP_RRQFCT_USERrn   r   r   r   r
   r   rj  r   r   r_   stripr   r   r  any)r7   rp   max_uiduserdatar   r  rk  rm  r   rl  rp  rn  timezonero  ry  s   `              r   r  zZK.get_users-  s    	::?DM!DI..u/E/Eu~~V$<<4;;D#h-PQ19*+IC!-a0
 *TZZ 7$$0||U#ADDYDY#YZAB<  B&h-2%TZ[ijrjxjxy{  ~E  kF  GJ  HJ  kK  ULQY$h'=C'$NN73A6>>t}}U]>^

7+A.66t}}X6V\\^x=g,"W,DCy(HgtTT"<<z#y(DRVX`bjls!t#BC= h-2% h-2%JPQcemesestvx  fA  BE  CE  fF  KGGY$h$NN73A6>>t}}U]>^

7+A.66t}}X6V\\^$NN73A6>>t}}U]>^ddf"==1!4<<T]]S[<\=C'"W,DCy(HgtTT"#BC= h-2% 	1LFeFF1$'L! r0   c                 x    t         j                  }| j                  |      }t        |j	                  d            S )z@
        cancel capturing finger

        :return: bool
        r   )r   CMD_CANCELCAPTUREr   boolr   r0  s      r   cancel_capturezZK.cancel_capturei  s5     ))**73L$$X.//r0   c                 ~    t         j                  }| j                  |      }|j                  d      ryt	        d      )zQ
        start verify finger mode (after capture)

        :return: bool
        r   TzCant Verify)r   CMD_STARTVERIFYr   r   r   r0  s      r   verify_userzZK.verify_users  s;     ''**73H%!-00r0   c                     t         j                  }t        d|      }| j                  ||      }|j	                  d      st        d|z        y)z
        reg events
        r   r   zcant' reg events %iN)r   CMD_REG_EVENTr	   r   r   r   )r7   flagsr   r   r   s        r   	reg_eventzZK.reg_event  sQ     %%sE***7NC)!"7%"?@@ *r0   c                 p    t         j                  }d}| j                  ||      }|j                  d      syy)Ns
   SDKBuild=1r   FT)r   CMD_OPTIONS_WRQr   r   r7   r   r   r   s       r   set_sdk_build_1zZK.set_sdk_build_1  s8    ''&**7NC)r0   c                 ~   t         j                  }d}|sG| j                         }t        t	        fd|            }t        |      dk\  r|d   j                  }ny| j                  r&t        dt        |      j                         |d      }nt        dt        |      |      }| j                          | j                  ||      }|j                  d      st        d|fz        | j                   j#                  d	       d
}	|	r| j$                  rt'        d|	z         | j                   j)                  d      }
| j+                          | j$                  rt'        t-        j                  |
d             | j                  rrt        |
      dkD  rt/        d|
j1                  dd      dd       d   }| j$                  rt'        d|z         |dk(  s
|dk(  s|dk(  r| j$                  rt'        d       n	t        |
      dkD  r_t/        d|
j1                  dd      dd       d   }| j$                  rt'        d|z         |dk(  s|dk(  r| j$                  rt'        d       n| j$                  rt'        d|	z         | j                   j)                  d      }
| j+                          | j$                  rt'        t-        j                  |
d             | j                  rt        |
      dkD  rt/        d|
j1                  dd      dd       d   }| j$                  rt'        d|z         |dk(  s|dk(  r| j$                  rt'        d       n|dk(  r| j$                  rt'        d       |	dz  }	nt        |
      dkD  rt/        d|
j1                  dd      dd       d   }| j$                  rt'        d|z         |dk(  s|dk(  r| j$                  rt'        d       n%|dk(  r| j$                  rt'        d       |	dz  }	|	r|	dk(  rb| j                   j)                  d      }
| j+                          | j$                  rt'        t-        j                  |
d             | j                  r#t/        d|
j1                  dd      dd       d   }n"t/        d|
j1                  dd      dd       d   }| j$                  rt'        d|z         |dk(  r| j$                  rt'        d       |dk(  s|dk(  r| j$                  rt'        d       |dk(  r_t/        d|
j1                  dd      dd       d   }t/        d|
j1                  dd      dd        d   }| j$                  rt'        d!||       d"}| j                   j#                  | j2                         | j5                  d       | j                          | j7                          |S )#z
        start enroll user

        :param uid: uid
        :param temp_id: template id
        :param user_id: user ID
        :return: bool
        Fc                 "    | j                   k(  S r   rv  rx  rk  s    r   rz  z ZK.enroll_user.<locals>.<lambda>  s    !%%* r0   r   r   z<24sbbz<Ibr   zCant Enroll user #%i [%i]r   r#   zA:%i esperando primer regeventrL  r   r   r   r   r   r9  zres %ir5  r   zposible timeout  o reg Fallidor   rJ   zposible timeoutzA:%i esperando 2do regeventr   zok, continue?   zfinger duplicater   r6  z	enroll okT)r   CMD_STARTENROLLr  r  r  r   ro  ro   r	   r   r>  r&   r  r   r   r   ra   rL   rn   r   r   _ZK__ack_okr=  r
   rj  rb   r  r  )r7   rk  r  ro  r   donerp   r   r   attempts	data_recvrO   r   poss    `            r   enroll_userzZK.enroll_user  s    ''NN$E 4e<=E5zQ(**88!(3w<+>+>+@'1MN!%Ww?N**7NC)!"=W~"MNNr"||U#Ch#NO((.IMMO||U6==5#ABxxy>B& ioob&A"R&HI!LC||U8c>%:ax3!8sax<<0P)Qy>A% ioob&A!B&GHKC||U8c>%:ax3!8<<0A)B||U$AH$LM((.IMMO||UFMM)U$CDxxy>A% ioob&A"R&HI!LC||U8c>%:ax3!8<<0P)Q<<)@ Ay>A% ioob&A!B&GHKC||U8c>%:ax3!8<<0P)Q<<)@ AU V q=((.IMMO||UFMM)U$CDxxS)//"W"=b"DEaHS)//"W"=a"CDQG||U8c>2ax<<(:!;ax3!8<<(9!:qyc9??2g#>r"#EFqIS)//"W"=b"DEaH<<{D#!>t~~.qr0   c              #     K   | j                   }| j                         }| j                          | j                          | j                   s| j	                          | j
                  rt        d       | j                  t        j                         | j                  j                  |       d| _        | j                  sN	 | j
                  rt        d       | j                  j                  d      }| j                          | j                  r't!        d|dd       d   }t!        d	|dd
       }|d
d }nt#        |      }t!        d|dd       }|dd }|d   t        j$                  k(  s| j
                  rt        d|d   z         t#        |      s| j
                  rt        d       t#        |      dk\  rEt#        |      dk(  rt!        d|      \  }}	}
|dd }nyt#        |      dk(  rt!        d|dd       \  }}	}
|dd }nQt#        |      dk(  rt!        d|dd       \  }}	}
}|dd }n(t#        |      dk\  rt!        d|dd       \  }}	}
}|dd }t'        t(              rt+              n$j-                  d      d   j/                  d      | j1                  
      }t3        t5        fd|            }|st)              }n|d   j6                  }t9        |	|       t#        |      dk\  rE| j                  sN| j
                  rt        d       | j                  j                  | j@                         | j                  d       |s| jC                          yy# t:        $ r | j
                  rt        d       d Y t<        t>        f$ r | j
                  rt        d       Y w xY ww)z,
        try live capture of events
        zstart live_captureFzesperando eventrL  r   Nr   r!   HHHHr   r   r   znot event! %xemptyr   z<IBB6sr   z<24sBB6s$   z
<24sBB6s4s4   z<24sBB6s20sr   ra  rb  c                 "    | j                   k(  S r   ro  r  s    r   rz  z!ZK.live_capture.<locals>.<lambda>$  s    !))w2F r0   ztime outbreakzexit gracefully)"rj   r  r  r  r   rn   r   r  r   	EF_ATTLOGra   rL   r   r   r  ro   r
   r   r  r  r&   r   r   r   _ZK__decode_timehexr  r  rk  r   r   KeyboardInterrupt
SystemExitrb   r   )r7   new_timeoutwas_enabledrp   r  r   headerr   r   punchr   _otherrS  tuserrk  ro  s                  @r   live_capturezZK.live_capture  sY     oo  << 45u'{+ %''/<<(9!: KK,,T2	88!&)BQ-8;D#FIaO<F$RS>Dy>D#E9Ra=9F$QR=DayE$7$77||U?VAY+F%G4y||UG_$i2o4yB:@4:P7#BCyTb;A*dSVTVi;X8&%#BCyTbCI,X\]`^`XaCb@&%&#BCyTbCI-Y]^a_aYbCc@&%&#BCy!'3/"%g,#*==#9!#<"D"DH"D"U $ 5 5g >I (F!NOE !'l#Ahll$WiLL/ $i2o' ''b << 12t~~.q!   <<
!3
%z2 <<sW   B>OCM0 	O
"M0 ,O-EM0 OA!O0$N>O%N>;O=N>>Oc                     t         j                  }d}| j                  ||      }|j                  d      rd| _        yt        d      )zl
        clear all data (included: user, attendance report, finger database)

        :return: bool
        r   r   r   Tzcan't clear data)r   CMD_CLEAR_DATAr   r   r}   r   r  s       r   
clear_datazZK.clear_data6  sJ     &&**7NCH%DM!"455r0   c           	      (   g }| j                  |      }| j                  rt        dj                  ||             |dk  r| j                  rt        d       y|dz
  |k  r7| j                  rt        d       | j	                  ||dz
        \  }}|j                  |       |t        |      z  }| j                  rt        dj                  |             || j                  j                  |dz         z   }| j                  r#t        d	j                  t        |                   | j	                  ||      \  }}|j                  |       | j                  r.t        d
j                  |t        |      t        |                   dj                  |      |fS t        |      }| j                  rt        dj                  ||             t        d|dd       d   }||dz   k\  r{|t        j                  k(  rA|d|dz    }| j                  r#t        dj                  t        |                   |||dz   d fS | j                  rt        dj                  |             y| j                  rt        dj                  |dz
               |j                  |d|dz           ||dz
  z  }d}	|dk  r,||d }	| j                  rt        d|	j                  d             |dkD  r"| j                  |      }|j                  |       dj                  |      |	fS )zh data_recv, raw tcp packet
         must analyze tcp_length

         must return data, broken
         ztcp_length {}, size {}r   zIncorrect tcp packet)Nr0   r   z tcp length too small... retryingz'new tcp DATA packet to fill misssing {}r   z#new tcp DATA starting with {} bytesz)for misssing {} recieved {} with extra {}r0   zrecieved {}, size {}r  r   zresp complete len {}Nzincorrect response!!! {}z%try DATA incomplete (actual valid {})brokenr   )r   rn   r   r   _ZK__recieve_tcp_datar  r   ra   r   joinr
   r   r   r>  _ZK__recieve_raw_data)
r7   r  r   r   
tcp_lengthr  bhrecievedr   broken_headers
             r   __recieve_tcp_datazZK.__recieve_tcp_dataE  s    ((3
<< 8 ? ?
D QR?||U$:;Nd"||U$FG..y*q.IHD"KKCID||U$M$T$TUY$Z[T[[--dRi99I||U$I$P$PQTU^Q_$`a..y$?HD"KK||U$O$V$VW[]`ae]fhklnho$pq88D>2%%y><< 6 = =h MN&)Ab/215r	"5>>) dRi0<<(>(E(Ec$i(P!QYtbyz222<<'A'H'H'R!S ||U$K$R$RS[\^S^$_`KK	"tby23HrM!DMax )$% 0<<=2H2H2O!Pax 33D9	I&88D>=00r0   c                    g }| j                   rt        dj                  |             |dkD  r| j                  j	                  |      }t        |      }| j                   rt        dj                  |             |dk  r:| j                   r.t        dj                  t        j                  |d                   |j                  |       ||z  }| j                   rt        dj                  |             |dkD  rdj                  |      S )	z partial data ? zexpecting {} bytes raw datar   zpartial recv {}r   z
   recv {}r   zstill need {}r0   )
rn   r   r   ra   r   r   r=  r>  r  r  )r7   r   r   r  r   s        r   __recieve_raw_datazZK.__recieve_raw_datau  s    << = D DT JKQh((.I9~H||U$5$<$<X$FG#~$,,|7J7J6==YbdiKj7k0lKK	"HD||UO$:$:4$@A Qh xx~r0   c                 l	   | j                   t        j                  k(  rW| j                  r| j                  r8t        dj                  t        | j                        | j                               t        | j                        | j                  dz
  k  ry| j                  dz
  t        | j                        z
  }| j                  rt        dj                  |             | j                  |      }dj                  | j                  |g      S | j                  rt        d       | j                  S | j                  r-t        dj                  t        | j                                     | j                  S | j                   t        j                  k(  rg }| j                         }| j                  rt        dj                  |             | j                  rt        | j                        d|z   k\  r| j                  dd }n.| j                  dd | j                  j                  |d	z         z   }| j!                  ||      \  }}|j#                  |       t        |      d
k  r|| j                  j                  d
      z   }n|}t        |      d
k  rgt        dt        |      z         | j                  rt        |j%                  d             || j                  j                  d
t        |      z
        z  }| j'                  |      s| j                  rt        d       yt)        d|dd
       d   }|t        j*                  k(  r(| j                  rt        d       dj                  |      S | j                  rt        d|z         | j                  rt        t-        j$                  |d             y	 | j                  j                  d      }t)        d|dd       d   }| j                  rt        dj                  |             |t        j                  k(  r|j#                  |dd        |dz  }n,|t        j*                  k(  rn3| j                  rt        d       n| j                  rt        d|z         dj                  |      S | j                  rt        d| j                   z         y)z recieve a chunk z'_rc_DATA! is {} bytes, tcp length is {}r   need more data: {}r0   Enough dataz_rc len is {}z&recieve chunk: prepare data size is {}Nr   r   z$trying to complete broken ACK %s /16r   zinvalid chunk tcp ACK OKr  r   zchunk tcp ACK OK!zbad response %srL  r   z# packet response is: {}r   zbroken!zstill needs %szinvalid response %s)r   r   r   ro   rn   r   r   r   rh   r   r  r  r   _ZK__get_data_sizera   r   r  r  r>  r   r
   r   r=  )	r7   need	more_datar   r   r  r  r  r   s	            r   __recieve_chunkzZK.__recieve_chunk  s   ??enn,xx<<(Q(X(XY\]a]h]hYikok|k|(}!~t{{#t'8'81'<= --1S5EED||U,@,G,G,M%N $ 7 7 =I88T[[)$<==||UM%:;;&<<(>(>s4;;?O(P!Q{{"__ 6 66D'')D||U$L$S$STX$YZxxt{{#D1 $ABI $AB$++2B2B4"92M MI&*&=&=i&N#mD!}%* -0@0@0D DI -Iy>B&AC	NRS||UI,<,<U,C%D!1!1"s9~2E!FFI**95||U,F%G!&)Ab/:1=u///||U,?%@88D>)<<'89'D!E<<d5(A!B  KK,,V4	!%2A7:<<(B(I(I((S!Tu~~-KK	!".DLD!1!11||UI%6<<(84(?!@  88D>!||U$9DOO$KLr0   c                     t        d      D ]N  }d}t        d||      }| j                  r|dz   }nd}| j                  |||      }| j	                         }|L|c S  t        d||fz        )z*
        read a chunk from buffer
        r#   i  z<iir   rL  zcan't read chunk %i:[%i])r'   r	   ro   r   r  r   )	r7   r  r   r  r   r   r   r   r   s	            r   __read_chunkzZK.__read_chunk  s     a 	NHG!%5Nxx $r	 (..wVL'')D	N ""<t}"LMMr0   c                    | j                   rd}nd}t        dd|||      }| j                  rt        d|       d}g }d}| j	                  d||      }	|	j                  d	      st        d
      |	d   t        j                  k(  rm| j                   r=| j                  r8t        dj                  t        | j                        | j                               t        | j                        | j                  dz
  k  r| j                  dz
  t        | j                        z
  }
| j                  rt        dj                  |
             | j                  |
      }dj                  | j                  |g      t        | j                        t        |      z   fS | j                  rt        d       t        | j                        }| j                  |fS t        | j                        }| j                  |fS t        d| j                  dd       d   }| j                  rt        d|z         ||z  }||z
  |z  }| j                  rt        dj                  |||             t!        |      D ](  }|j#                  | j%                  ||             ||z  }* |r&|j#                  | j%                  ||             ||z  }| j'                          | j                  rt        d|z         dj                  |      |fS )zB
        Test read info with buffered command (ZK6: 1503)
        i  i @  z<bhiir   zrwb csr   r   i  r   zRWB Not supportedr   z#DATA! is {} bytes, tcp length is {}r   r  r0   r  r   r  zsize fill be %iz;rwb: #{} packets of max {} bytes, and extra {} bytes remainz_read w/chunk %i bytes)ro   r	   rn   r   r   r   r   r   r   r   r   rh   r   r  r  r
   r'   r  _ZK__read_chunkr1  )r7   r   fctextr  r   r   r   r  r   r	  r
  r   r  r  r  s                   r   r  zZK.read_with_buffer  s    88I!Igq'3<<<.9**4O)!"5665>>1xx<<(M(T(TUXY]YdYdUegkgxgx(y!zt{{#t'8'81'<= --1S5EED||U,@,G,G,M%N $ 7 7 =I88T[[)$<=s4;;?ORUV_R`?```||UM%:t{{+D;;,,4;;'{{D((c4;;q+,Q/<< 1D 89	!;9,<< ] d delnwy  !A  B'N 	DKK))%	:;YE	 KK))%89VOE<< 85 @Axx~u$$r0   c                    | j                          | j                  dk(  rg S | j                         }| j                  rt	        |       g }| j                  t        j                        \  }}|dk  r| j                  rt	        d       g S t        d|dd       d   }|| j                  z  }| j                  rt	        d|       |dd }|dk(  rt        |      dk\  rt        d|j                  dd	      dd       \  }}}	| j                  r"t	        t        j                  |dd d
             |dd }t        t        fd|            }
|
st              n|
d   j                   | j#                  |      }t%        |||	      }|j'                  |       t        |      dk\  r|S |dk(  rGt        |      dk\  r6t        d|j                  dd	      dd       \  }}}	}}t              | j                  r"t	        t        j                  |dd d
             |dd }t        t        fd|            }
|
sh| j                  rt	        d       t              t        t        fd|            }
|
st              n.|
d   j(                  |
d   j                   n|
d   j(                  | j#                  |      }t%        |||	      }|j'                  |       t        |      dk\  r6|S t        |      dk\  rt        d|j                  dd	      dd       \  }}}	}| j                  r"t	        t        j                  |dd d
             j+                  d	      d   j-                  d      | j#                  |      }t%        |||	      }|j'                  |       |dd }t        |      dk\  r|S )zV
        return attendance record

        :return: List of Attendance object
        r   r   zWRN: no attendance datar   Nzrecord_size is r   HB4sBr   r   c                 "    | j                   k(  S r   rv  r  s    r   rz  z#ZK.get_attendance.<locals>.<lambda>  s    aeesl r0   r   z	<I4sBB2sIc                 "    | j                   k(  S r   r  r  s    r   rz  z#ZK.get_attendance.<locals>.<lambda>,  s    aii7.B r0   z	no uid {}c                 "    | j                   k(  S r   rv  r  s    r   rz  z#ZK.get_attendance.<locals>.<lambda>0  s    !%%72B r0   (   z<H24sB4sB8sra  rb  )r@  rr   r  rn   r   r  r   CMD_ATTLOG_RRQr
   r   rj  r=  r>  r  r  r   ro  rN  r   r  rk  r   r   )r7   rp   attendancesattendance_datar   r  record_sizer   rS  r  r  
attendancereservedworkcodespacerk  ro  s                  @@r   get_attendancezZK.get_attendance  s    	<<1I << $ 5 5e6J6J K!8||U$=>IC!!45a8
 -<< 1;?)!"-!o&!+06w@U@UVWY`@abdcd@e0f-VY<<obq6I5(Q!R"1!""5V$:EBC!#hG#Ah..G ..y9	'FE3O
"":. o&!+V ? Bo&",HN{\k\q\qrtv}\~  @C  AC  ]D  IEEFE8Xg,<<v}}_Sb5I5'Q!R"1"#"6V$BEJK||U;%@g,C (BE!JKE !'l#Ahll"'("2"2(,,C ..y9	'FE3O
"":.' o&",<  o&",@F}VeVkVklnpwVxy|z|V}@~=Wfi<<ocr6JE(R!S"==1!4<<H<M ..y9	'FE3O
"":."1"#"6 o&", r0   c                 ~    t         j                  }| j                  |      }|j                  d      ryt	        d      )zD
        clear all attendance record

        :return: bool
        r   TzCan't clear response)r   CMD_CLEAR_ATTLOGr   r   r   r0  s      r   clear_attendancezZK.clear_attendanceG  s<     ((**73H%!"899r0   )rT   r   r   FFFzUTF-8)r0   r   )r0   )r#   )r   )Nr   r   r   r   r   r   )r   r   r   )r   r   )rJ   )r   r   )ErU   rV   rW   rX   r8   r   r   r   r   r   r   r   r  r  _ZK__reverse_hexrN  r  rR  r   r   r   r   r   r  r  r
  r  r  r  r  r  r  r   r"  r'  r-  r1  r@  rD  rG  rJ  rO  rT  rW  rZ  r^  rs  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r#  rY   r0   r   r[   r[   m   sj   0&d3$#4	$
L):
E:69:	A>> <"D X    T$956@5 

:
4448EN-3^ 02 )V:$6< .82:x01A]~C"J6.1`@DN$,%\@D:r0   r[   r   )2   )rh  r   r   r   r   r   r   structr	   r
   r=  r   r   r  r   	exceptionr   r   r   ry  r   r  r   r   r/   objectr2   r[   rY   r0   r   <module>r)     sO    
  D D    " I I  "J.# .#be: e:r0   