Skip to content

case_study

Office-PC connector for biometric attendance machines

Go · Windows, macOS, Linux · ZKTeco, Hikvision, Dahua, Sintech

Lead engineer — connector, device protocols, office networking, rollout

  • Go
  • Edge WebView2
  • WebKit
  • Ed25519
  • Windows IP Helper, Firewall COM and SCM APIs
  • Hikvision ISAPI
  • ZKTeco TCP protocol
  • ADMS
  • Ruby on Rails
  • GitHub Actions
Office-PC connector for biometric attendance machines: Go · Windows, macOS, Linux · ZKTeco, Hikvision, Dahua, Sintech

problem

The problem

Attendance machines sit on small-office networks the cloud cannot reach. Some can be told to call the cloud by themselves; on real office networks that was the least reliable path, and many models cannot do it at all. Something on the office network has to fetch the punches, and the only host available is a PC nobody on site administers: antivirus suites that hold any child process that looks like network configuration, proxies and HTTPS inspection, guest Wi-Fi that keeps devices apart, and machines left on factory addresses in a different range from everything else.

The first generation, a Python service installed by PowerShell, worked for months and taught the field rules, but most of its bug reports were the installer, and a read-only audit of the production fleet showed the long-lived failures were not protocol errors at all: they were devices recorded in the cloud that had never delivered anything, and agents that heartbeat normally while silently not reading for weeks.

approach

What I engineered

  • A single static Go binary per platform with five independent loops — read, upload, instructions, heartbeat, machine list — that share nothing but an fsync'd spool, so an outage on either side is a delay rather than a loss; a punch the cloud refuses on its own is parked instead of blocking the batch behind it.
  • Identity without a shared secret: a six-digit pairing code and an Ed25519 key generated on the PC that never leaves it (DPAPI-sealed on Windows), requests signed over a five-line canonical string with the server's time carried on the monotonic clock, and a data folder the service refuses to use if anyone else can write it.
  • Readers behind one interface for the ZKTeco binary protocol, Hikvision ISAPI and Dahua CGI, plus relays for ADMS and Sintech UDP push — and the rule that a machine is read only after it proves its own serial, on every read.
  • Reach on networks I don't control: a second address on the PC added only on evidence for machines on factory ranges, bounded discovery (SADP, DHIP, port knocks, OUI fallback) including one router away, and every failure classified into a kind someone on site can fix — proxy, TLS inspection, VPN capture, Wi-Fi isolation, closed port.
  • Time semantics for device wall clocks that survive future-dated clocks, wrong time zones and drift, and a fail-closed handover that imports the old agent's machines, carries its reading positions (never forward, at most seven days back) and turns it off only when nothing can be lost.
  • Windows without system tools: IP Helper, Firewall COM and Service Control Manager calls instead of netsh, PowerShell, arp and sc.exe, guarded by a source-level test; and every fix shipped with one guard verified by reverting the fix and watching it fail.

result

The result

The connector reads real machines from Windows and Mac office PCs on a test environment, and its full suite passes on real Windows in CI. A read-only audit of the production fleet drove a round of fixes before any site switched: authentication fallbacks and a retry for stale digest nonces, a lenient parse of firmware limits, a port left over from another brand, and a handover rule for devices recorded as pushing by themselves while the old agent was in fact reading them.

Self-update is built and signed offline, and deliberately switched off until it installs exactly the bytes it verified, refuses a downgrade and trust-checks its rollback. The production rollout, code signing and reach across sites are the next steps, written up in the last post of the series.

0
ports opened towards the internet
5
device interfaces behind one reader contract
200 → 0
punches lost in a 1,000-punch race reproduction
20k / 14k
lines of Go / lines of tests

Counted from the source and its test suite in November 2026; the race figure was measured in a reproduction before and after the fix. The product, its customers and their sites are not named, and fleet facts appear only as proportions.

work_with_me

Have a project like this?

Tell me the problem on a 20-minute call and I'll tell you how I'd approach it, the same way Office-PC connector for biometric attendance machines started.

Discuss your project