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))

Sabes si se podría acceder a este reloj desde linux ??
ReplyDeleteSi lo se :). Hay tres formas
Delete1-) 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.
No encuentro referencias sobre "import qrclock". Donde puedo descargarlo o cual es el código fuente?
ReplyDeleteGracias
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.
ReplyDeleteHello
ReplyDeletePlz i need to connect to my IClock device using python language
any one can hel me plz
Hello
ReplyDeleteplz i need to connect my IClock device using python language to my ERP
hel me plz
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...
ReplyDeleteHola.. 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...
ReplyDeleteHi you can find this one for zkt https://github.com/AlSayedGamal/python_zklib/graphs/commit-activity
ReplyDeleteQue 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
ReplyDeleteQue 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