Как мы построили систему проверки RFID-браслетов

Один из проектов, где за простым действием «приложить браслет» скрывается полноценная клиент-серверная архитектура.

Задача была следующая: сотрудник должен в любой точке объекта приложить RFID-браслет гостя и практически мгновенно понять, действителен он или нет.

Причём проверка должна работать как на стационарных ПК, так и на Android-смартфонах.

Архитектура

В итоге система получилась из нескольких компонентов:

RFID-браслет → считыватель → Windows/Android-клиент → REST API → Backend → PostgreSQL / ZKTeco

Серверная часть построена на:

Python Django PostgreSQL REST API Linux Gunicorn Nginx

Главным идентификатором браслета является его UID.

Windows-клиент

На стационарных точках используется отдельное приложение для Windows и USB RFID-считыватель.

Алгоритм максимально простой:

сотрудник прикладывает браслет; приложение получает UID; UID отправляется на API; сервер выполняет проверку; клиент получает структурированный ответ; на экране отображается статус гостя.

Никакого ручного ввода номеров или поиска по спискам.

При этом клиент практически не содержит бизнес-логики — большая её часть находится на сервере.

Это позволяет централизованно менять правила проверки без обновления каждой рабочей станции.

Android

Для мобильных сотрудников сделали отдельный Android-клиент.

Он работает с тем же API и теми же серверными правилами, что и Windows-приложение.

То есть источник проверки один:

ПК и смартфон не имеют собственных независимых баз.

Это важно, потому что иначе очень быстро возникает рассинхронизация данных.

Причём здесь ZKTeco?

На объекте уже работает инфраструктура контроля доступа на базе ZKTeco, поэтому полностью игнорировать существующую систему было бы неправильно.

Мы построили проверку в несколько этапов.

Сначала backend ищет UID в собственной базе.

Условно:

UID → API → PostgreSQL

Если браслет найден — сервер сразу формирует результат.

Но есть более интересный сценарий.

UID отсутствует в нашей системе

Отсутствие UID в локальной базе ещё не означает, что браслет неизвестен объекту.

Поэтому реализована дополнительная проверка через ZKTeco / ZKBio CVSecurity.

Получается примерно такая цепочка:

RFID Reader ↓ Windows / Android ↓ REST API ↓ Поиск UID в нашей БД ↓ не найден ↓ проверка в ZKTeco ↓ ZKBio CVSecurity ↓ результат обратно в приложение

Таким образом, наша система работает не изолированно, а дополняет уже существующую СКУД.

Причём пользователю совершенно неважно, откуда фактически пришёл результат.

Он просто прикладывает браслет.

Почему backend сделали центральным

Можно было написать приложение, которое напрямую обращается к системе контроля доступа.

Но тогда пришлось бы хранить параметры подключения и часть внутренней логики на каждом устройстве.

Мы пошли другим путём.

Клиент знает только, что нужно проверить UID.

А уже сервер решает:

— есть ли идентификатор в нашей БД; — активен ли он; — какой у него статус; — требуется ли дополнительная проверка; — нужно ли обратиться к ZKTeco; — какие данные вообще разрешено вернуть конкретному клиенту.

Фактически API стал прослойкой между пользовательскими приложениями и внутренней инфраструктурой.

Плюс журналирование

Каждая проверка может фиксироваться на сервере:

устройство → UID → результат → время проверки

Это позволяет анализировать работу системы и разбирать спорные ситуации без хранения лишней информации непосредственно на рабочих станциях.

Итог

В результате получилось уже не просто приложение для RFID-считывателя, а небольшая распределённая система:

Windows client + Android client + REST API + PostgreSQL + интеграция с ZKTeco.

Самое интересное здесь — абстракция.

Для сотрудника всё выглядит так:

приложил браслет → получил ответ.

А внутри в этот момент может выполняться несколько проверок, запрос к собственной базе, обращение к внешней системе контроля доступа и формирование ответа API.

Наверное, это один из лучших признаков нормальной автоматизации:

чем сложнее система внутри, тем проще она должна выглядеть для человека снаружи.