Saturday 14 January 2012

Connect to a zk clock


I'm spent a half week try to connect this clock. I use reverse engineering to create a network script that read network packages and do some black magic, but i don't have good result. When i give up, Found this wonderful page that's show me how to dispatch the dll of the clock (The sdk only works in windows, is here). !!!Bingo :) !!Boom goes the dynamite :).

 I study the sdk a weekend. Now i'm proud of my code.

This are the methods of the sdk in the code.

Connect_Net(ip, port) # connect to devie
ReadAllUser(machineNumber) #read all user data and put into a buffer
SSR_GetAllUserInfo(machineNumber, EnrrollNumber, Name, Password, Privilege, Enable)  #get all the user data from the buffer
ReadGeneralLogData(machineNumber) # read all the attendance data of the clock in put into a buffer
SSR_GetGeneralLogData
EnableDevice(machinenumber, state) # enabled or disabled the clock

For more information read the TFT manual that comes with the sdk

#!/usr/bin/env python 
#coding:utf-8 
# Author:  peter --<pjl@hpc.com.py> 
# Purpose: manage the dll of the zk software, thanks to sy, for the prototype code 
# Created: 06/12/2011 
# Todo 
# 2012/01/06 
# we add a ldap proxy to diferrent the user company 

# -*- coding: utf-8 -*-   
from win32com.client import Dispatch   
import sys   
from datetime import datetime   
import sys, logging 
import qrclock 
from proxy import PrLdap 


######################################################################## 
class ZkDispatch(object): 
    """Manage the windows enviroment for the zk connections to the iclock 2000""" 
    __doc__ = 'Manage the operations on the biometric clock' 
    __userdata = [] 
    __logdata = [] 
    __clock = "" 
    __today = datetime.today().strftime('%Y-%m-%d')     
    __proxyldap = PrLdap.ProxyLdap()         

    #---------------------------------------------------------------------- 
    def __init__(self): 
        """ 
        Instance the database class, and distpatch the windows dll of the zk sdk 
        """ 
        self.dbmanag = qrclock.QuerysClock(host="XXX.XXX.XXX.XXX", user="XXX", passwd="XXXX", db="XXXXX") 
        self.zk = Dispatch("zkemkeeper.ZKEM") 
        logging.basicConfig(format='%(asctime)s %(message)s',filename="c:\\iclock.log",level=logging.DEBUG)                            

    #----------------------------------------------------------------------         
    def Connect(self, ip, port, mn): 
        """ 
        first connections to the clock, and retrieve the initialize data 
        Connect_Net(ip, port) 
        """ 
        self.__clock = ip 
        logging.info("conectando al reloj %s" % ip) 

        #devPort = 4370   
        #devIPAddr = ’192.168.30.198′   

        flag = self.zk.Connect_Net(ip,port)   
        if flag:   
            logging.info("Conexion exitosa al reloj") 

        else: 
            logging.info("Error de conexion, verifique el dispositivo")             

        if self.zk.ReadAllUserID(mn): 
            #print self.zk.GetAllUserInfo(mn, 0, "", "", 0, False) 

            while True:   
                #s= self.zk.GetAllUserInfo(mn, 0, "", "", 0, False) 
                s= self.zk.SSR_GetAllUserInfo(mn, 0, "", "", 0, False)                 
                #s= self.zk.GetAllUserID(mn, 0, None, 0, False)                 
                if s[0]:   
                    #print type(s[3]) 
                    #print s 
                    self.__userdata.append((s[1], s[2])) 

                else:   
                    break               

    #---------------------------------------------------------------------- 
    def QueryAttendanceDb(self, dateb=__today, datee=__today, mn=1):                 
        """ 
        Read all the log data by the given date, . 
        we use here the SSR_GetGeneralLogData function of the sdk that use the following parameters 
        machinenumber, enrollnumber, verifymode, outmode, year, month, day, hour, minute, second 
        """ 
        tmpstore = [] 
        if self.zk.ReadGeneralLogData(mn): 
            while True:
        #i don't why, but no matters if you give a specific date, the method get all the records from the beginning 
                att = self.zk.SSR_GetGeneralLogData(mn, "", 0, 0,2011, 12, 4, 0, 0, 0, 0) 
                #att = self.zk.SSR_GetGeneralLogData(mn, "", None, None, 2011, 5, 13, None, None, None, None) 
                if att[0]: 
                    tmpstore.append(att) 
                    #print att 
                else: 
                    break 

        for v in tmpstore: 
            for u in self.__userdata: 
                if v[1] == u[0]: 
                    dtlog = datetime(v[4], v[5], v[6], v[7], v[8], v[9]) 
                    dlog = dtlog.strftime("%Y-%m-%d") 
                    tlog = dtlog.strftime("%H:%M:%S") 
                    ta = self.ChangeAuthType(v[2])             
                    tc = self.ChangeCheckType(v[3]) 
                    user = u[1].replace(","," ") 
                    self.__logdata.append((v[1], user, ta, tc, dlog, tlog)) 

        for rl in self.__logdata: 
            dcheck = (rl[0], rl[4], rl[5], rl[3]) 
            if self.dbmanag.CheckFirstTime(dcheck): 
                #proxy ldap 
                r = self.__proxyldap.FormatUserCompany(rl[0]) 
               
                if r: 
                    empresa = r[0][1]["Empresa"][0] 
                else: 
                    empresa = "NULL" 
                try: 
                    dcinser = (rl[0], rl[1].split()[-1].strip(), rl[1].split()[0].strip(), rl[4], rl[5], self.__clock, rl[2], rl[3], empresa)             
                    self.dbmanag.InsertData(dcinser) 
                except: 
                    logging.info("Error al insertar el dato %s" % rl[0]) 

    #---------------------------------------------------------------------- 
    def ClearLog(self, mn=1): 
        """Clear all the log attendance of the lock""" 
        logging.info("Borrando logs de registros") 
        self.zk.ClearGLog(mn) 
        logging.info("Borrando logs de registros Exito")    

    #---------------------------------------------------------------------- 
    def Enabled(self, mn=1, state=1): 
        """Enalbed or disable the device""" 
        if state == 0: 
            logging.info("Desactivando dispositivo")    
        else: 
            logging.info("Activando dispositivo")                     
        self.zk.EnableDevice(mn, state) 


    #---------------------------------------------------------------------- 
    def ChangeCheckType(self, ctyp): 
        """change the check type for a human data""" 

        if ctyp == 0: 
            return "Entrada" 

        if ctyp == 1: 
            return "Salida" 

        if ctyp == 2: 
            return "Salida Intermedia" 

        if ctyp == 3: 
            return "Entrada Intermedia"    

        if ctyp == 4: 
            return "Entrada Almuerzo"        

        if ctyp == 5: 
            return "Salida Almuerzo"            

    #---------------------------------------------------------------------- 
    def ChangeAuthType(self, atyp): 
        """change the auth type for a human data""" 

        if atyp == 0: 
            return "Clave" 

        if atyp == 1: 
            return "Huella"    

        if atyp == 2: 
            return "Tarjeta"        

        if atyp == 3: 
            return "Clave"            

        if atyp == 4: 
            return "Clave"                

        if atyp == 5: 
            return "Clave"                    

        if atyp == 6: 
            return "Clave"    
     
    #---------------------------------------------------------------------- 
    def CalculeTime(self, times): 
        """ 
        calculate how long take the transactions 
        """ 
        ini = times[0] 
        end = times[1] 
        horai, minutoi, segundoi = ini.split(":") 
        horai = int(horai) 
        minutoi = int(minutoi) 
        segundoi = int(segundoi) 
         
        valor0 = (horai*60)+(minutoi*60)+segundoi 
        horae, minutoe, segundoe = end.split(":") 
        horae = int(horae) 
        minutoe = int(minutoe) 
        segundoe = int(segundoe) 
        valor1 = (horae*60)+(minutoe*60)+segundoe 
        dur = valor1 - valor0 
         
        logging.info("Duracion de la conexion %s segundos" % str(dur)) 
         

if __name__ == '__main__':   
    clock = ZkDispatch() 
    ini = datetime.today() 
    ini = ini.strftime("%H:%M:%S")     
    clock.Connect('192.168.0.50', 4370, 1) 
    clock.Enabled(1, 0) 
    clock.QueryAttendanceDb() 
    clock.ClearLog(mn=1) 
    clock.Enabled(1, 1)     
    end = datetime.today() 
    end = end.strftime("%H:%M:%S") 
    clock.CalculeTime((ini, end)) 
 
 
 

11 comments:

  1. Sabes si se podría acceder a este reloj desde linux ??

    ReplyDelete
    Replies
    1. Si lo se :). Hay tres formas
      1-) Abrir las dll's y pasar todo el codigo a otro lenguaje
      2 -) Instalar las dll's en wine e interactuar con ellas a partir de wine
      3 -) Interartuar con la interfaz web que suelen traer esos relojes.

      La mas util es la tercera, pero dependiendo de que tanta opciones le hallan puesto a la interfaz web, te veras limitado.

      Delete
  2. No encuentro referencias sobre "import qrclock". Donde puedo descargarlo o cual es el código fuente?
    Gracias

    ReplyDelete
  3. Hola, Amigo. he visto tu código muy interesante, pero he buscado información sobre qrclock y no encuentro, es una biblioteca echa por usted? por favor dar mas información relevante. Gracias Amigo, Suerte.

    ReplyDelete
  4. Hello
    Plz i need to connect to my IClock device using python language
    any one can hel me plz

    ReplyDelete
  5. Hello
    plz i need to connect my IClock device using python language to my ERP
    hel me plz

    ReplyDelete
  6. Hola.. saludos desde Tijuana Mexico... podrian orientarme como leer y restaurar las fotografias de un reloj de estos , de echo es el iface800 ...segun el sdk hay 3 funciones de manipulacion de fotografias, pero ninguna me funciona o es que ando perdido.... agradezco de antemano su atencion...

    ReplyDelete
  7. Hola.. saludos desde Tijuana Mexico... podrian orientarme como leer y restaurar las fotografias de un reloj de estos , de echo es el iface800 ...segun el sdk hay 3 funciones de manipulacion de fotografias, pero ninguna me funciona o es que ando perdido.... agradezco de antemano su atencion...

    ReplyDelete
  8. Hi you can find this one for zkt https://github.com/AlSayedGamal/python_zklib/graphs/commit-activity

    ReplyDelete
  9. Que tal.. Saludos... Quiza alguien pueda orientarme de como conectar usando COnnect_Net mas de 1 reloj con ZKemKeeper, asi como lo hace al att.com?... gracias de antemano

    ReplyDelete
  10. Que tal.. Saludos... Quiza alguien pueda orientarme de como conectar usando COnnect_Net mas de 1 reloj con ZKemKeeper, asi como lo hace al att.com?... gracias de antemano

    ReplyDelete