PROYECTO_04

Hikvision

Asistencia y Nómina Hikvision

Sistema que toma las checadas del lector Hikvision y las convierte en nómina automáticamente, sin intervención manual.

TIPO
IoT · Integración
ESTADO
EN PRODUCCIÓN
  • React
  • Vite
  • TailwindCSS
  • Java
  • Spring Boot
  • MySQL
  • Docker
  • Nginx
  • Hikvision ISAPI

CONTEXTO

El terminal biométrico registraba las asistencias, pero el cálculo de nómina seguía haciéndose a mano a partir de esos registros. El sistema cierra ese hueco de punta a punta.

LO DESTACABLE

  • Nómina automática desde checadas reales: entradas, salidas, horas extra y retardos.
  • Reglas configurables por puesto (tolerancia, redondeo, turnos, festivos).
  • Conciliación de checadas faltantes con aprobación del supervisor.

INTEGRACIÓN ISAPI

  • Checadas leídas de /ISAPI/AccessControl/AcsEvent, filtrando el tipo mayor 5 y los menores 38 (tarjeta), 75 (rostro) y 113 (huella).
  • Altas y bajas de personal contra /ISAPI/AccessControl/UserInfo, con employeeNo como la misma clave que identifica al empleado en la nómina.
  • Registro de rostro por multipart en /ISAPI/Intelligent/FDLib/FaceDataRecord: metadatos JSON más el JPEG, dentro del tope de 200 KB y 80×80 px que impone el terminal.
  • Eventos en tiempo real por httpHosts —el terminal hace POST al backend— con alertStream como respaldo si el push se cae.
  • Búsquedas paginadas con searchID fijo y searchResultPosition avanzando por numOfMatches, hasta que responseStatusStrg deja de decir MORE.

AUTENTICACIÓN Y FALLOS

  • Autenticación HTTP Digest (MD5, qop=auth) con conteo de nonce por petición; Basic viene desactivado en el firmware actual.
  • Reloj del terminal sincronizado por NTP: un desfase de más de cinco minutos basta para que el propio Digest deje de validar.
  • Bloqueo de cuenta contemplado: tras varios intentos fallidos el admin queda bloqueado y el 401 trae lockStatus y unlockTime, que se leen para no entrar en bucle de reintentos.
  • El resultado se decide por subStatusCode, no por el código HTTP: deviceUserAlreadyExist se trata como alta idempotente y no como error.

DESPLIEGUE

  • API en Spring Boot 3 + MySQL y SPA en React/Vite, dockerizado tras Nginx con TLS.
  • El protocolo quedó documentado aparte, en un repositorio público de referencia con los endpoints, los códigos de evento y la implementación de Digest.