fananimi / pyzk

Unofficial library of zkteco fingerprint attendance machine
GNU General Public License v2.0
489 stars 319 forks source link

PROBLEMA RESUELTO: Error en la lectura de asistencias a partir del segundo registro MODELO MB560-VL #174

Closed EduardoTorrel closed 1 year ago

EduardoTorrel commented 1 year ago

En el mencionado modelo con firmware actualizado al 2022 se generá un error en la lectura de asistencias a partir del segundo registro El error es debido al seteo desde el segundo registro que era desde la posición 40, en este modelo con firmware actualizado al 2022 debe ser desde la posición 49 asi: attendance_data = attendance_data[49:] adjunto el método y remarco la linea corregida def get_attendance(self): """ return attendance record

    :return: List of Attendance object
    """
    self.read_sizes()
    if self.records == 0:
        return []
    users = self.get_users()
    if self.verbose: print (users)
    attendances = []
    attendance_data, size = self.read_with_buffer(const.CMD_ATTLOG_RRQ)
    if size < 4:
        if self.verbose: print ("WRN: no attendance data")
        return []
    total_size = unpack("I", attendance_data[:4])[0]
    record_size = total_size/self.records
    if self.verbose: print ("record_size is ", record_size)
    attendance_data = attendance_data[4:]
    if record_size == 8:
        while len(attendance_data) >= 8:
            uid, status, timestamp, punch = unpack('HB4sB', attendance_data.ljust(8, b'\x00')[:8])
            if self.verbose: print (codecs.encode(attendance_data[:8], 'hex'))
            attendance_data = attendance_data[8:]
            tuser = list(filter(lambda x: x.uid == uid, users))
            if not tuser:
                user_id = str(uid)
            else:
                user_id = tuser[0].user_id
            timestamp = self.__decode_time(timestamp)
            attendance = Attendance(user_id, timestamp, status, punch, uid)
            attendances.append(attendance)
    elif record_size == 16:
        while len(attendance_data) >= 16:
            user_id, timestamp, status, punch, reserved, workcode = unpack('<I4sBB2sI', attendance_data.ljust(16, b'\x00')[:16])
            user_id = str(user_id)
            if self.verbose: print(codecs.encode(attendance_data[:16], 'hex'))
            attendance_data = attendance_data[16:]
            tuser = list(filter(lambda x: x.user_id == user_id, users))
            if not tuser:
                if self.verbose: print("no uid {}", user_id)
                uid = str(user_id)
                tuser = list(filter(lambda x: x.uid == user_id, users))
                if not tuser:
                    uid = str(user_id)
                else:
                    uid = tuser[0].uid
                    user_id = tuser[0].user_id
            else:
                uid = tuser[0].uid
            timestamp = self.__decode_time(timestamp)
            attendance = Attendance(user_id, timestamp, status, punch, uid)
            attendances.append(attendance)
    else:
        while len(attendance_data) >= 40:
            uid, user_id, status, timestamp, punch, space = unpack('<H24sB4sB8s', attendance_data.ljust(40, b'\x00')[:40])
            if self.verbose: print (codecs.encode(attendance_data[:40], 'hex'))
            user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore')
            timestamp = self.__decode_time(timestamp)

            attendance = Attendance(user_id, timestamp, status, punch, uid)
            attendances.append(attendance)
            **attendance_data = attendance_data[49:]**
    return attendances
kurenai-ryu commented 1 year ago

la ultima versión del codigo reutiliza el valor de record_size, favor verifica en modo verbose el valor calculado para record_size