Pourquoi les bibliothèques open-source ZKTeco ne passent pas à l'échelle (et quoi utiliser à la place)
Nous avons testé 6 bibliothèques open-source ZKTeco en production — pyzk, node-zklib, zklib et d'autres. Chacune a échoué au-delà de 50 terminaux. Voici exactement ce qui casse et l'alternative cloud.
Introduction
Tous les développeurs qui intègrent des terminaux biométriques ZKTeco commencent pareil : recherche GitHub, installation d'une bibliothèque open-source, un script rapide, et ça marche sur un terminal. Puis ils passent en production avec 50+ terminaux, et tout s'effondre. Nous le savons parce que nous l'avons vécu — six bibliothèques open-source testées, chacune poussée jusqu'à son point de rupture, avec un post-mortem documenté.
Si vous évaluez des solutions open-source pour une intégration biométrique, lisez ceci avant d'engager quatre mois de développement sur quelque chose qui ne survivra pas à sa première semaine en production.
Les 6 bibliothèques testées
Nous avons testé toutes les bibliothèques activement maintenues pour communiquer avec les terminaux ZKTeco :
1. pyzk (Python) — L'option la plus populaire. ~800 étoiles GitHub. Encapsule le protocole brut du terminal en classes Python. Utilisée par la majorité des tutoriels et réponses Stack Overflow.
2. node-zklib (JavaScript/Node.js) — La référence pour les développeurs Node. ~400 étoiles. Fonctions asynchrones pour la connexion, la récupération de pointages et la gestion des utilisateurs. Plusieurs forks existent car le projet original est semi-abandonné.
3. zklib (Python) — Alternative plus bas niveau à pyzk. Moins d'abstractions, accès plus direct au protocole. Communauté restreinte mais certains développeurs préfèrent le contrôle.
4. laravel-zkteco (PHP/Laravel) — Wrapper Laravel autour du protocole ZKTeco. Populaire dans l'écosystème PHP, surtout en Asie du Sud-Est et en Amérique latine. ~300 étoiles.
5. php-zkteco (PHP) — Implémentation PHP autonome. Pas de dépendance framework. Utilisée pour les systèmes RH sur mesure en PHP classique.
6. zk-protocol (Divers) — Ensemble de dépôts de documentation du protocole et d'implémentations de référence. Pas une bibliothèque unique, mais une famille de projets que les développeurs forkent et adaptent.
Les six font la même chose : se connecter à un terminal ZKTeco via le protocole brut du terminal sur un réseau local, s'authentifier, lire et écrire des données.
Ce qui marche : un seul terminal sur un réseau local
Soyons honnêtes. Pour un seul terminal sur le même réseau que votre script, ces bibliothèques fonctionnent bien.
Voici pyzk récupérant les pointages d'un terminal :
Propre. Fonctionnel. Résultats en quelques secondes. Même constat avec node-zklib :
```javascript
const ZKLib = require("node-zklib");
const zk = new ZKLib("192.168.1.201", 4370);
await zk.createSocket();
const attendances = await zk.getAttendances();
console.log(attendances);
await zk.disconnect();
```
Si votre besoin se limite à « un terminal, un site, un cron quotidien » — arrêtez de lire. L'open-source suffit. Installez pyzk, écrivez un script, planifiez-le, passez à autre chose.
Mais si vous devez gérer plusieurs terminaux, sur plusieurs sites, en continu — continuez.
from zk import ZK# Connexion à un terminal sur le réseau localzk = ZK('192.168.1.201', port=4370)conn = zk.connect()attendance = conn.get_attendance()for record in attendance:print(f"{record.user_id} a pointé à {record.timestamp}")conn.disconnect()
Là où tout casse
Nous avons déployé chaque bibliothèque dans un environnement de staging calqué sur notre production : 50+ terminaux ZKTeco répartis sur plusieurs sites. En 48 heures, chacune a échoué. Voici les cinq modes de défaillance documentés.
1. La gestion des connexions s'effondre à l'échelle
Chaque bibliothèque gère les connexions de la même façon : un socket persistant par terminal. À 5 terminaux, c'est 5 sockets. Gérable. À 50 terminaux sur 5 sites ? C'est 50 connexions persistantes que votre script doit maintenir simultanément.
# Ce que donne votre code à l'échelle avec pyzkdevices = [ZK('192.168.1.201', port=4370),ZK('192.168.1.202', port=4370),# ... 48 terminaux supplémentairesZK('10.0.5.15', port=4370), # sous-réseau différentZK('172.16.0.8', port=4370), # bureau différent]# Pas de pool de connexions. Pas de health check.# Pas de reconnexion automatique.
2. Aucune logique de retry — une coupure réseau = perte de données
Les micro-coupures réseau sont constantes en production. Un switch redémarre. Le Wi-Fi saute 3 secondes. Un terminal redémarre après une mise à jour firmware. Chaque événement tue la connexion socket.
Les bibliothèques open-source ne retentent rien. La connexion tombe, l'exception est lancée (ou pire, le processus se bloque en silence), et tous les pointages effectués pendant l'interruption sont perdus.
Dans notre test, une interruption réseau de 12 secondes a causé 3 heures de pointages manquants — personne n'avait remarqué que la connexion était morte.
3. I/O bloquant — un terminal lent gèle tout
pyzk, php-zkteco et laravel-zkteco utilisent des I/O bloquantes. Quand vous appelez get_attendance(), le thread entier attend la réponse du terminal. Si un terminal est lent (mauvais réseau, charge élevée, firmware ancien), tous les autres dans votre boucle de polling attendent derrière.
# Ça a l'air innocent...for device_ip in device_list:zk = ZK(device_ip, port=4370, timeout=60)conn = zk.connect()records = conn.get_attendance() # ← bloque iciprocess(records)conn.disconnect()# ...mais si le terminal #3 met 55 secondes à répondre,# les terminaux #4 à #50 font la queue.# Un cycle de 5 min devient un cycle de 45 min.
4. Fuites mémoire après 48 heures
Toutes les bibliothèques testées présentaient des fuites mémoire en session longue. Le schéma était identique : consommation mémoire croissante dès l'heure 0, seuil critique autour de 36-48h, puis crash ou ralentissement extrême.
En production, cela signifie redémarrer votre service d'intégration toutes les 24-48h — ce qui ramène au problème #2 (perte de données pendant le redémarrage).
5. Réseau local uniquement — pas de cloud, pas de multi-site
C'est le problème architectural fondamental. Toutes les bibliothèques communiquent via le protocole brut sur le réseau local. Votre script doit être sur le même réseau que le terminal. Point.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 420" fill="none" style="width:100%;max-width:800px;">
<text x="400" y="30" text-anchor="middle" fill="#94a3b8" font-size="17" font-weight="bold" font-family="system-ui">Architecture open-source : réseau local uniquement</text>
<!-- Bureau A -->
<rect x="30" y="60" width="340" height="150" rx="12" stroke="#64748b" stroke-width="1.5" fill="none" stroke-dasharray="6,4"/>
<text x="200" y="82" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">Bureau A — LAN 192.168.1.x</text>
<rect x="50" y="95" width="130" height="50" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="115" y="125" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Terminal 1</text>
<rect x="50" y="150" width="130" height="50" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="115" y="180" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Terminal 2</text>
<rect x="220" y="110" width="130" height="70" rx="8" stroke="#f87171" stroke-width="2" fill="none"/>
<text x="285" y="140" text-anchor="middle" fill="#f87171" font-size="14" font-family="system-ui">💻 Serveur</text>
<text x="285" y="160" text-anchor="middle" fill="#f87171" font-size="14" font-family="system-ui">local A</text>
<line x1="180" y1="120" x2="220" y2="135" stroke="#64748b" stroke-width="1.5"/>
<line x1="180" y1="175" x2="220" y2="155" stroke="#64748b" stroke-width="1.5"/>
<!-- Bureau B -->
<rect x="430" y="60" width="340" height="150" rx="12" stroke="#64748b" stroke-width="1.5" fill="none" stroke-dasharray="6,4"/>
<text x="600" y="82" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">Bureau B — LAN 10.0.5.x</text>
<rect x="450" y="95" width="130" height="50" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="515" y="125" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Terminal 3</text>
<rect x="450" y="150" width="130" height="50" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="515" y="180" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Terminal 4</text>
<rect x="620" y="110" width="130" height="70" rx="8" stroke="#f87171" stroke-width="2" fill="none"/>
<text x="685" y="140" text-anchor="middle" fill="#f87171" font-size="14" font-family="system-ui">💻 Serveur</text>
<text x="685" y="160" text-anchor="middle" fill="#f87171" font-size="14" font-family="system-ui">local B</text>
<line x1="580" y1="120" x2="620" y2="135" stroke="#64748b" stroke-width="1.5"/>
<line x1="580" y1="175" x2="620" y2="155" stroke="#64748b" stroke-width="1.5"/>
<!-- App cloud -->
<rect x="270" y="280" width="260" height="70" rx="12" stroke="#a78bfa" stroke-width="2" fill="none"/>
<text x="400" y="310" text-anchor="middle" fill="#a78bfa" font-size="15" font-family="system-ui">☁️ Votre app cloud</text>
<text x="400" y="332" text-anchor="middle" fill="#a78bfa" font-size="14" font-family="system-ui">(OVH / Scaleway / AWS)</text>
<!-- Flèches bloquées -->
<line x1="285" y1="180" x2="350" y2="280" stroke="#f87171" stroke-width="2" stroke-dasharray="6,4"/>
<text x="290" y="240" fill="#f87171" font-size="20" font-family="system-ui">✕</text>
<line x1="685" y1="180" x2="450" y2="280" stroke="#f87171" stroke-width="2" stroke-dasharray="6,4"/>
<text x="570" y="240" fill="#f87171" font-size="20" font-family="system-ui">✕</text>
<text x="400" y="400" text-anchor="middle" fill="#f87171" font-size="15" font-weight="bold" font-family="system-ui">⚠ L'app cloud ne peut pas atteindre les terminaux derrière les routeurs</text>
</svg>
Concrètement :
- Déploiements multi-sites → un serveur local par bureau
- Applications cloud (OVH, Scaleway, AWS, Vercel) → aucune communication directe avec les terminaux
- Bureaux distants → tunnels VPN ou redirection de ports — fragile et pénible à maintenir
- Chaque nouveau site → provisionner et maintenir un serveur local supplémentaire
Si vous développez une plateforme RH multi-tenant, un SaaS de paie, ou n'importe quoi d'hébergé dans le cloud, les bibliothèques open-source sont architecturalement incompatibles avec votre stack. Et dans le contexte français, les exigences RGPD et CNIL sur la traçabilité des données biométriques rendent la gestion décentralisée encore plus risquée — chaque serveur local devient un point de contrôle supplémentaire à auditer.
Le vrai coût du « gratuit »
Les bibliothèques open-source coûtent 0 € à installer. Elles coûtent une fortune à faire tourner en production :
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 380" fill="none" style="width:100%;max-width:800px;">
<text x="400" y="30" text-anchor="middle" fill="#94a3b8" font-size="17" font-weight="bold" font-family="system-ui">Coût total : open-source vs. PunchConnect</text>
<!-- Colonne Open Source -->
<rect x="40" y="55" width="330" height="300" rx="12" stroke="#f87171" stroke-width="2" fill="none"/>
<text x="205" y="82" text-anchor="middle" fill="#f87171" font-size="16" font-weight="bold" font-family="system-ui">Open-source (50 terminaux)</text>
<text x="65" y="115" fill="#94a3b8" font-size="14" font-family="system-ui">Débogage protocole</text>
<text x="340" y="115" text-anchor="end" fill="#f87171" font-size="14" font-weight="bold" font-family="system-ui">320h × 75€ = 24 000€</text>
<text x="65" y="145" fill="#94a3b8" font-size="14" font-family="system-ui">Gestion des connexions</text>
<text x="340" y="145" text-anchor="end" fill="#f87171" font-size="14" font-weight="bold" font-family="system-ui">160h × 75€ = 12 000€</text>
<text x="65" y="175" fill="#94a3b8" font-size="14" font-family="system-ui">Serveurs locaux (5 sites)</text>
<text x="340" y="175" text-anchor="end" fill="#f87171" font-size="14" font-weight="bold" font-family="system-ui">2 500€ + 500€/mois</text>
<text x="65" y="205" fill="#94a3b8" font-size="14" font-family="system-ui">VPN / réseau</text>
<text x="340" y="205" text-anchor="end" fill="#f87171" font-size="14" font-weight="bold" font-family="system-ui">80h × 75€ = 6 000€</text>
<text x="65" y="235" fill="#94a3b8" font-size="14" font-family="system-ui">Maintenance continue</text>
<text x="340" y="235" text-anchor="end" fill="#f87171" font-size="14" font-weight="bold" font-family="system-ui">1 500€/mois</text>
<line x1="60" y1="255" x2="350" y2="255" stroke="#64748b" stroke-width="1"/>
<text x="65" y="280" fill="#f87171" font-size="15" font-weight="bold" font-family="system-ui">Total année 1</text>
<text x="340" y="280" text-anchor="end" fill="#f87171" font-size="34" font-weight="bold" font-family="system-ui">68 500€</text>
<text x="205" y="310" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">+ 2 000€/mois de maintenance</text>
<text x="205" y="340" text-anchor="middle" fill="#f87171" font-size="14" font-family="system-ui">1 370€/terminal</text>
<!-- Colonne PunchConnect -->
<rect x="430" y="55" width="330" height="300" rx="12" stroke="#34d399" stroke-width="2" fill="none"/>
<text x="595" y="82" text-anchor="middle" fill="#34d399" font-size="16" font-weight="bold" font-family="system-ui">PunchConnect (50 terminaux)</text>
<text x="455" y="115" fill="#94a3b8" font-size="14" font-family="system-ui">Intégration API</text>
<text x="730" y="115" text-anchor="end" fill="#34d399" font-size="14" font-weight="bold" font-family="system-ui">8h × 75€ = 600€</text>
<text x="455" y="145" fill="#94a3b8" font-size="14" font-family="system-ui">Config terminaux (5 min chacun)</text>
<text x="730" y="145" text-anchor="end" fill="#34d399" font-size="14" font-weight="bold" font-family="system-ui">~4h = 300€</text>
<text x="455" y="175" fill="#94a3b8" font-size="14" font-family="system-ui">Serveurs locaux</text>
<text x="730" y="175" text-anchor="end" fill="#34d399" font-size="14" font-weight="bold" font-family="system-ui">0€ (aucun)</text>
<text x="455" y="205" fill="#94a3b8" font-size="14" font-family="system-ui">VPN / réseau</text>
<text x="730" y="205" text-anchor="end" fill="#34d399" font-size="14" font-weight="bold" font-family="system-ui">0€ (cloud natif)</text>
<text x="455" y="235" fill="#94a3b8" font-size="14" font-family="system-ui">Service mensuel</text>
<text x="730" y="235" text-anchor="end" fill="#34d399" font-size="14" font-weight="bold" font-family="system-ui">Nous contacter</text>
<line x1="450" y1="255" x2="740" y2="255" stroke="#64748b" stroke-width="1"/>
<text x="455" y="280" fill="#34d399" font-size="15" font-weight="bold" font-family="system-ui">Coût d'intégration</text>
<text x="730" y="280" text-anchor="end" fill="#34d399" font-size="34" font-weight="bold" font-family="system-ui">900€</text>
<text x="595" y="310" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">+ tarif mensuel prévisible</text>
<text x="595" y="340" text-anchor="middle" fill="#34d399" font-size="14" font-family="system-ui">Intégration en heures, pas en mois</text>
</svg>
Nous avons passé 4 mois à déboguer des cas limites du protocole brut — dépassements de tampon sur certaines versions firmware, gestion des timeouts différente selon les modèles, encodage des caractères pour les noms avec accents. Quatre mois de temps développeur senior qui auraient pu aller dans le produit.
L'alternative cloud-first
PunchConnect adopte une approche fondamentalement différente. Au lieu que votre code se connecte aux terminaux, les terminaux se connectent au cloud PunchConnect. Vous configurez le terminal dans le tableau de bord, et il commence à envoyer les données. Votre application parle à une API REST — pas aux terminaux.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 340" fill="none" style="width:100%;max-width:800px;">
<text x="400" y="30" text-anchor="middle" fill="#94a3b8" font-size="17" font-weight="bold" font-family="system-ui">Architecture cloud PunchConnect</text>
<!-- Terminaux -->
<rect x="30" y="70" width="150" height="55" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="105" y="103" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Bureau A (12)</text>
<rect x="30" y="140" width="150" height="55" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="105" y="173" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Bureau B (8)</text>
<rect x="30" y="210" width="150" height="55" rx="8" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="105" y="243" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Bureau C (30)</text>
<!-- Flèches vers cloud -->
<line x1="180" y1="97" x2="300" y2="155" stroke="#34d399" stroke-width="2" marker-end="url(#cloudArrFr)"/>
<line x1="180" y1="167" x2="300" y2="167" stroke="#34d399" stroke-width="2" marker-end="url(#cloudArrFr)"/>
<line x1="180" y1="237" x2="300" y2="180" stroke="#34d399" stroke-width="2" marker-end="url(#cloudArrFr)"/>
<!-- PunchConnect Cloud -->
<rect x="300" y="115" width="200" height="110" rx="14" stroke="#34d399" stroke-width="2.5" fill="none"/>
<text x="400" y="155" text-anchor="middle" fill="#34d399" font-size="17" font-weight="bold" font-family="system-ui">PunchConnect</text>
<text x="400" y="178" text-anchor="middle" fill="#34d399" font-size="14" font-family="system-ui">Moteur cloud</text>
<text x="400" y="198" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">50 terminaux • 24 000+ employés</text>
<!-- Flèche vers app -->
<line x1="500" y1="170" x2="590" y2="170" stroke="#a78bfa" stroke-width="2" marker-end="url(#appArrFr)"/>
<text x="545" y="158" text-anchor="middle" fill="#a78bfa" font-size="13" font-family="system-ui">API REST</text>
<!-- Votre App -->
<rect x="590" y="120" width="180" height="100" rx="12" stroke="#a78bfa" stroke-width="2" fill="none"/>
<text x="680" y="155" text-anchor="middle" fill="#a78bfa" font-size="15" font-family="system-ui">💻 Votre app</text>
<text x="680" y="178" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">N'importe quel langage</text>
<text x="680" y="198" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">N'importe quel hébergeur</text>
<!-- Stats -->
<text x="130" y="310" text-anchor="middle" fill="#22d3ee" font-size="34" font-weight="bold" font-family="system-ui">50+</text>
<text x="130" y="332" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">sites supportés</text>
<text x="400" y="310" text-anchor="middle" fill="#34d399" font-size="34" font-weight="bold" font-family="system-ui">5 min</text>
<text x="400" y="332" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">par terminal</text>
<text x="670" y="310" text-anchor="middle" fill="#a78bfa" font-size="34" font-weight="bold" font-family="system-ui">95%</text>
<text x="670" y="332" text-anchor="middle" fill="#64748b" font-size="14" font-family="system-ui">disponibilité garantie</text>
<defs>
<marker id="cloudArrFr" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto"><polygon points="0 0, 10 3.5, 0 7" fill="#34d399"/></marker>
<marker id="appArrFr" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto"><polygon points="0 0, 10 3.5, 0 7" fill="#a78bfa"/></marker>
</defs>
</svg>
Pas de serveurs locaux. Pas d'IP fixe. Pas de tunnels VPN. Pas de débogage de protocole brut. Vous configurez le terminal dans le tableau de bord, et votre code appelle une API REST.
Voici la même récupération de pointages — via PunchConnect :
C'est tout. 50 terminaux, tous les sites, un seul appel API. Pas de sockets à gérer, pas de connexions à surveiller, pas de fuites mémoire à déboguer. PunchConnect gère la communication avec les terminaux — vous gérez votre logique métier.
En pratique :
- Configuration : Paramétrez l'adresse serveur dans le menu du terminal pour pointer vers PunchConnect. ~5 minutes par terminal.
- Intégration : Appelez l'API REST depuis n'importe quel langage, framework ou hébergeur. Du HTTP standard.
- Supervision : Statut des terminaux, connectivité et dernière activité disponibles via le tableau de bord et l'API.
- Mise à l'échelle : Ajouter un terminal sur un nouveau site = même processus de 5 minutes. Aucune modification d'infrastructure.
- Conformité RGPD : Un seul point de collecte centralisé facilite la traçabilité exigée par la CNIL pour les données biométriques.
PunchConnect tourne en production avec 24 000+ employés actifs sur 50+ sites chez AgriWise. Ce n'est pas un prototype — c'est une infrastructure éprouvée.
import requests# Aucune connexion au terminal — un simple appel APIresponse = requests.get("https://api.punchconnect.com/v1/attendance",headers={"Authorization": "Bearer YOUR_API_KEY"},params={"from": "2026-03-01", "to": "2026-03-28"})for record in response.json()["data"]:print(f"{record['employeeId']} a pointé à {record['timestamp']}")
Quand l'open-source reste le bon choix
Nous ne sommes pas là pour descendre les outils open-source. Ils ont des cas d'usage légitimes :
- Apprendre le protocole. Si vous voulez comprendre comment les terminaux ZKTeco communiquent à bas niveau, pyzk et zklib sont d'excellentes ressources pédagogiques.
- Tests en laboratoire. Évaluer un nouveau modèle ZKTeco ? Les bibliothèques open-source sont parfaites pour vérifier la compatibilité rapidement.
- 1-3 terminaux, un seul site, développeur dédié. Si vous avez un petit déploiement, un serveur local déjà maintenu, et un développeur qui prendra en charge l'intégration sur la durée — l'open-source peut fonctionner. Mais connaissez le coût de maintenance avant de vous engager.
- Contribuer à l'écosystème. La communauté open-source ZKTeco a construit quelque chose de précieux. Si vous avez l'expertise protocole, contribuer enrichit tout le monde.
Le point de bascule est net : dès que vous avez besoin de multi-site, d'hébergement cloud, ou de plus d'une poignée de terminaux — vous avez dépassé ce pour quoi ces bibliothèques ont été conçues.
FAQ
Puis-je utiliser pyzk ou node-zklib en production ?
Pour de petits déploiements (1-5 terminaux, un site, même réseau local), oui — avec des réserves. Vous devrez construire votre propre logique de retry, surveillance de connexion et mécanismes de redémarrage. Au-delà, la charge de maintenance croît plus vite que votre parc.
Que se passe-t-il quand une bibliothèque open-source perd la connexion ?
La plupart lancent une exception ou restent bloquées indéfiniment. Aucune ne se reconnecte automatiquement. Les pointages effectués pendant la coupure sont stockés sur le terminal mais ne sont récupérés que lorsqu'on relance manuellement la connexion et qu'on tire l'historique. Certaines bibliothèques ne suivent pas quels enregistrements ont déjà été synchronisés, ce qui génère des doublons.
PunchConnect fonctionne-t-il avec tous les modèles ZKTeco ?
PunchConnect supporte tous les modèles ZKTeco fabriqués après 2015 disposant d'une connectivité réseau (Ethernet ou Wi-Fi). Cela couvre la grande majorité des terminaux en activité : SpeedFace, ProFace, MultiBio, uFace, série K et série UA. Pour un modèle spécifique, vérifiez la compatibilité ou contactez-nous.
Combien de temps prend la migration depuis des bibliothèques open-source ?
La plupart des équipes terminent en 1-2 jours. Le changement côté terminal prend 5 minutes par appareil (configuration de l'adresse serveur). Le changement côté code dépend de votre intégration existante, mais remplacer des appels socket bruts par des appels REST est direct. Nous avons vu des équipes migrer 50+ terminaux en un après-midi.
PunchConnect est-il lui-même open-source ?
Non. PunchConnect est un service cloud managé. La couche de communication avec les terminaux — celle qui casse dans les bibliothèques open-source — est exactement ce que PunchConnect gère pour vous. L'API REST avec laquelle vous interagissez est documentée et utilise les conventions HTTP standard, compatibles avec tout langage ou framework.
---
À lire aussi
- Alternative cloud à node-zklib : connecter des terminaux ZKTeco sans serveurs locaux — Guide de migration spécifique de node-zklib vers PunchConnect
- Transformer un terminal ZKTeco en API REST — Guide complet pour obtenir les pointages via des endpoints HTTP
- Pointage biométrique sans IP fixe — Comment les terminaux cloud éliminent le besoin d'IP statique
- Le protocole push ZKTeco expliqué — Push vs. pull et pourquoi ça compte pour les déploiements cloud