ZKTeco punches that land in Odoo
The device already punches
ZKTeco already captures attendance. Fingerprint, face, card: the clock is not waiting for Odoo in order to let someone in. Odoo does not replace the device.
The work is to make that punch into a log HR can use, without someone exporting a file from the vendor software at the end of the week.
The clocks we have wired already expose a log: a cloud API, or a database the device writes to. We pull from that log. We do not screen-scrape a panel, and we do not replace hardware that is already on the wall.
You hold the device account and the connection credentials. We configure Odoo against them and hand them back.
- Devices
- ZKTeco biometric attendance terminals (fingerprint, face, card, mixed). Existing hardware.
- Odoo side
- Structured punch logs: device, employee code and name, timestamp, in/out direction
- Direction
- Device / vendor log → Odoo. Scheduled pull.
- Delivered for
- Unnamed. Running in production.
- Availability
- Built to order. Not a module on the Apps Store.
A replay is not a second day
The first punch that appears in Odoo is the easy hour. Production is the week the network drops.
The clock buffers, then dumps. A plant clock loses the LAN for an afternoon, stores punches locally, and replays them when it returns. If every replay creates a new day, payroll is now arguing about people who were already marked present.
The same log arrives twice. Cloud APIs and SQL extracts do not promise uniqueness. Without a stable device-log id that Odoo refuses to insert again, the second fetch is a duplicate attendance line.
The employee code is not the Odoo employee. The clock knows a badge number. Odoo knows an employee record. A mismatch is a punch that landed and still cannot be paid.
In and out are not optional. A punch without direction is a timestamp HR cannot use for overtime or a missed check-out. The log has to carry in or out, not only a time.
A failed fetch is a silent month. If the scheduled job dies as a log line, the floor kept punching and Odoo stopped. Month-end is when someone notices.
Paper was the previous integration. Registers, a vendor desktop export, a spreadsheet before payroll. The risk is putting the same ritual back in, only with an API in the middle.
Each of those has an answer below.
Skip the log you already have
A device-log id is the primary key. If that id already exists in Odoo, the fetch skips it. A replay is not a second insert.
The punch is a structured row. Device, employee code, employee name, timestamp, attendance direction. Not a screenshot of the vendor software, not a CSV someone emailed.
A job on a schedule. New logs are pulled on a recurring interval. It is a pull, not a hope that the clock will push when the network feels like it. How often is scoped to the site; it is not “instant” unless the vendor API actually is.
Connection in settings, not in code. Server, database, user, password, port: held in Odoo configuration so a host change is not a module rewrite. We do not keep those credentials after handover.
Failures have to be visible. A fetch that did not run is a state someone can see, not a line that scrolled past in a server log.
Mapping those logs into standard Odoo attendance or payroll, shift rules, and a missed check-out policy is scoped per engagement. This page is the ingest: punches that exist once, with a direction, against the right employee code.
Off the register, into Odoo
Delivered against live clocks, unnamed client. HR and payroll were already in Odoo. Attendance was still paper. The integration pulls the vendor log on a schedule and writes each punch as a searchable record. The register is no longer the source.
That is the same failure mode already named on Metering, Energy & Devices: a device that buffers, then dumps, and an ERP that has to stay right anyway. This page is the ZKTeco landing. The category page keeps Nordpool, Elvaco, and printers.
- Delivered
- Scheduled log pull, device-log id skip, punch rows (device, employee, time, direction), settings-held credentials
- Client
- Unnamed
- Also in this category
- Nordpool and Elvaco, custom receipt and label printers
Credentials you hold
ZKTeco (or compatible) clocks already on the wall, on a network, with a documented way to read logs: the vendor cloud API, or the SQL store the devices already write to. We will not estimate against a closed box we cannot query.
Sandbox or a test window on the live clocks. Duplicate punches, an offline dump, a badge that is not in Odoo: those have to happen before payroll depends on the feed.
An employee-code map: clock badge → Odoo employee. We will not guess.
Someone who owns a missed check-out. The integration records what the clock sent. It does not invent an exit.
We do not sell you terminals, hold your device passwords after handover, or build against a vendor panel with no API and no log database.
Metering, Energy & Devices · Integration engineering · Odoo integration
Which clock is still a register?
Send the device family, whether logs come from a cloud API or a database, and whether payroll already runs in Odoo. We can usually tell you in one reply whether that is a mapped pull or a clock that cannot be queried.