Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Всем доброго времени суток! В этой статье мы подробнее остановимся на ПО терминала учета рабочего времени и контроля доступа, о разработке которого я писал в прошлой статье. Данная статья является логическим продолжением, т.к. в прошлой статье я рассматривал всё железо терминала, поэтому настоятельно рекомендую ознакомиться для дальнейшего понимания написанного.
Вкратце: по заказу клиентов нужно было разработать терминал учета рабочего времени (с возможностями СКУД), который бы фиксировал временные интервалы сотрудников (как рабочие, так и перерывы) по отпечатку пальца. Получаемая информация, в свою очередь, формировалась бы в отчеты и табели в аналитическом облачном сервисе TARGControl. “Железо” уже готово, осталось дело за малым - разработать ПО для нашего терминала.
Общие требования к ПО терминала:
Работа с системой TARGControl Cloud.
Выбор на дисплее событий доступа (причины входа/выхода) сотрудниками.
Принятие решений о допуске/не допуске сотрудников на рабочее место.
Хранение базы данных с сотрудниками, идентификаторами и информации о проходах.
Фотофиксация сотрудников.
Рассылка уведомлений.
Удобный интерфейс для работы и настройки устройства.
Что нам понадобится для этого:
Подготовить и сконфигурировать операционную систему под наши нужды.
Выбор, установка и конфигурирование фреймворка GUI.
Разработка архитектуры ПО.
Выбор, установка и настройка СУБД
Разработка микросервисов.
Выбор фреймворка для разработки WEB-интерфейса.
Вот примерный перечень задач, которые нам необходимо решить для реализации данного проекта. Следует уточнить, что перечень задач - не последовательность действий, а совокупность, выполняемая параллельно.
Вкратце пробежимся по инструментам, которые нам понадобятся для разработки.
Начнем по порядку - операционная система нашего одноплатного компьютера, который мы выбрали в прошлой статье (Raspberry PI CM3+) , конечно же, Raspberry Pi OS (ранее Raspbian). Что касается настроек ОС, в первую очередь мы установим Python. На момент разработки использовалась версия 3.6. Также зарезервируем swap для расширения оперативной памяти (предпочтительно для версии Raspberry с EMMC).
Очень важно продумать грамотную архитектуру взаимодействия сервисов составляющих ПО. Определим примерную модель взаимодействия на следующей схеме.
Как видно из схемы, ПО разделено на множество отдельных микросервисов. Такая архитектура позволяет построить надежную систему - при выходе из строя одного из компонентов работоспособность системы не нарушится. Также такая архитектура позволяет легко добавлять новые микросервисы в дальнейшем, что делает такую систему расширяемой.
Что касается, сервисов, то их подавляющее большинство будут реализованы на Python3.
Также нам необходимо спроектировать “мозг” нашего ПО, который бы принимал логические решения на основании состояния прочих сервисов и выдавал конечный результат (итог работы). Проще говоря, нам нужно было создать логическое ядро, которое будет решать, пускать человека на работу или не пускать, при этом отдавать команды прочим сервисам. Что касается “прочих сервисов”, в их число входят сервисы обработки и управления считывателями, управления замками и турникетами, получение данных с систем алкотестирования и видеонаблюдения, датчиков открытия и закрытия двери, кнопок выхода и кнопок пожарной эвакуации.
Разумеется, такая система оперирует большими потоками данных, часть из которых необходимо хранить на постоянной основе. Из этой потребности вытекает, что нам просто необходим сервис управления базой данных. К слову, в качестве СУБД будем использовать объектно-реляционную PostgreSQL. Здесь можно очень долго обсуждать, почему именно она, а не, например, MySQL, однако на момент разработки, по нашему мнению, PostgreSQL была более функциональной... Сервис управления базами данных организован таким образом, что у нас всегда будет хранится слепок основной информации из БД в кэше сервиса для быстрого доступа к этим данным.
Также наша система должна иметь возможность работы с серверными решениями TARGControl (облачной либо локальной УРВ-системой, куда и выгружаются временные интервалы с терминала). Отсюда вытекает реализация отдельного сервиса синхронизации с TARGControl. Сразу обмолвимся, что терминал изначально и создавался, как один из инструментов работы с TARG.
Для удобства работы с системой, ее управлением и конфигурированием мы реализуем WEB-интерфейс терминала.
Для облегчения работы логического ядра и коммуникации между сервисом также реализуем несколько побочных микросервисов для управления маршрутизацией, идентификацией и обработкой событий перед сохранением в БД.
Разработка
А теперь подробнее о самой разработке. Основные сервисы ПО TARGControl мы реализовали на базе Raspberry на Python3, в число этих сервисов входит: логическое ядро системы, сервис синхронизации с облаком TARG, сервис управления БД, а также большинство сервисов управляющих периферией (замки, кнопки и прочие). Можно также отметить, что здесь была задействована работа с GPIO (general-purpose input/output).
Думаем вопрос, почему мы используем Python не возникнет, однако ответ на него достаточно прост. Главное преимущество, что на текущий момент данный язык позволяет быстрыми темпами дорабатывать новый функционал, что является ключевым преимуществом при разработке гибких систем.
Как видно из описанной ранее структуры, система представляет из себя набор сервисов на Python, обмен данными между которыми происходит посредством ZeroMQ. Почему именно ZeroMQ, а не, например, RabbitMQ?
Легковесность - фактически надстройка над Socket.
Позволяет использовать Linux Socket, которые очень быстрые.
Позволяет сделать любую систему маршрутизации.
Итого эта библиотека позволяет быстро и удобно обмениваться данными между сервисами, а также синхронизировать потоки внутри сервисов. Подробнее о zmq можно почитать здесь.
К сожалению, не все необходимые сервисы можно написать на Python, некоторые из них, требующие особого быстродействия, например, такие как интерфейс Wiegand. Глобальная блокировка интерпретатора (GIL), лежащая в основе интерпретатора Python, а также процессы Linux (особенно при высокой загрузке) не позволяют обеспечить необходимые временные интервалы стандарта интерфейса Wiegand, поэтому данный сервис был реализован на языке C и собран в качестве драйверного модуля ядра Linux. Для реализации этого модуля использовались следующие библиотеки:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/timer.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/interrupt.h>
В качестве способа взаимодействия мы прибегли к архитектурному стилю REST API, эта архитектура позволит нам реализовать собственное управление посредством веб-интерфейса, а также передать внешний API для сторонних разработчиков, которые пожелают интегрировать устройство в работу своей системы. Для этого мы выбрали WEB-фреймворк Flask, т.к он предоставляет простоту и гибкость в работе, позволяя пользователю самому выбирать, как реализовать те или иные вещи + архитектура REST API лежит в основе Flask. К слову, ближайший конкурент Flask - Django сразу предлагает решения “из коробки”, что для данной задачи не совсем подходит. Однако не будем разбираться, какой из этих фреймворков лучше.
Для реализации WEB-интерфейса системы выбор пал на популярнейший из фреймворков Angular. Одной из ключевых особенностей в выборе этого фреймворка стал язык программирования TypeScript. Статическая типизация позволяет в дальнейшем избежать критических ошибок (или хотя бы минимизировать их). Также он удобно документируется и отлично приспособлен для работы с вышеупомянутым Flask.
Для маршрутизации бэка и фронта для дестрибутива Linux наиболее подходящим web-сервером будет nginx.
Стабильную бесперебойную работу сервисов поддерживает супервизор runit-systemd - daemon-сервис. Почему не init, спросите вы? Нам не нужно было контролировать все процессы запуска, нужен был лишь результат и корректная работа, с чем runit-systemd справляется на отлично (почитать подробнее можно здесь).
В итоге “скрещивания” всех вышеупомянутых сервисов и инструментов мы получили работоспособный продукт - терминал/контроллер TARGControl.
Рады представить вам результат нашей плодотворной работы (усердной, упорной).
Рассмотрим подробнее WEB терминала, изучив подробнее функционал терминала. Как мы видим, здесь есть следующие вкладки:
Статус - в данной вкладке мы можем увидеть все данные о состоянии терминала, его конфигурацию и журнал ошибок.
Сотрудники - здесь отображаются все сотрудники и их идентификаторы (отпечатки пальцев, RFID или PIN), которых вы добавили в базу устройства. При использовании облака TARGControl сотрудники и их идентификаторы автоматически подгрузятся в базу терминала.
Пропуска - здесь мы можем создать пропуска для сотрудников, которые имеют ограниченное кол-во использований и срок действия.
Инструктажи и справки - создание документов для сотрудников. Актуально, если на рабочее место нужно пропускать сотрудников, которые имеют, например, действующую мед справку.
Журнал событий - отчет по всем проходам сотрудников.
Отчет - отчет по отработанному времени сотрудников и их нарушениям. Более расширенные отчеты можно просмотреть в TARGControl Cloud, куда и подгружаются данные с терминала.
Охрана - здесь отображаются все проходы, выполняемые через терминал. В данном случае проходил идентификацию Сотрудник 1 и несколько раз "отмечался" неизвестный сотрудник. (Общение между фронтендем и бэкендем построено с помощью использования WebSocket, что позволяет нам в режиме реального времени отображать актуальную информацию о работе системы).
Настройки - самая важная вкладка, где мы сможем настроить терминал. Как мы видим на скриншоте, в WEB мы реализовали настройки терминала, которые позволят гибко настроить многие вещи, такие как:
Настройка времени терминала (NTP и ручное).
Настройки встроенной камеры терминала (качество фото, разрешение и момент срабатывания).
Конфигурирование встроенных считывателей, замков, турникетов, действий при пожарной тревоге и различных периферийных устройств (алкотестеры, внешние считыватели и др.)
Общие настройки терминала: метод учета времени, включение новостей на терминале, ограничение на количество хранимых фотографий, о чем упоминалось в прошлой статье, и др.
Отладочные логи - все логи, сохраняемые на терминале с момента его запуска.
Настройки синхронизации с облаком TARGControl.
Настройка уведомлений (email, http).
Создание различных учетных записей для входа на терминал. По умолчанию admin и user.
Email - настройка SMTP-сервера для рассылки уведомлений на почту.
Ethernet - базовые настройки Ethernet. Включение или отключение DHCP.
IP-камеры - Настройка IP-камер, Ethernet, выходного Wiegand и др
Wiegand Out - настройка конфигурация выходного Wiegand и его длины кода.
В общем, возможностей действительно много. WEB-интерфейс это хорошо, но у нас терминал с дисплеем, поэтому было бы неплохо на нем что-нибудь показывать. Так как ОС нашего устройства Raspberry Pi OS, то есть дистрибутив Linux, мы решили, что наиболее подходящим фреймворком для построения графических интерфейсов будет QT, который позволяет удобно разрабатывать на машине под Linux и посредством кросс-компиляции отлаживать проект на устройстве. Собственно, результат работы на картинке ниже.
При включении терминала мы столкнемся с экраном 1 - Ожидание идентификатора. После успешного распознавания (с помощью карты, отпечатка либо PIN), нам предложит выбрать событие доступа - экран 3.
Просмотреть краткую информацию об устройстве вы можете во вкладке Статус (экран 2). Также с помощью терминала вы можете зарегистрировать отпечатки пальцев, RFID-карты либо задать PIN сотрудникам, которые есть в базе устройства.
Для автоматизации сборки новых версий ПО используем систему сборки Jenkins. Помимо терминала, у нас есть и контроллеры для СКУД, которые имеют общую базу микросервисов, однако некоторые из них отличаются. Поэтому сборка прошивок осуществляется при помощи разных конфигураций Jenkins.
Для обновления ПО на терминале реализован сервис на Python. Само обновление может происходить как через веб-интерфейс терминала, так и через облако TARGControl (конечно, при его использовании).
Для интеграции с внешними системами можно использовать выходной интерфейс Wiegand. Для интеграции же с другими системами можно использовать уведомления посредством http-запросов, а для глубокой интеграции с терминалом (контроллером) у нас открыт API, изучить подробнее можно здесь: Swagger UI. Так же существует возможность отправлять уведомления на почту, для этого реализована настройка SMTP-сервера, что показывал ранее в разделе настроек.
Итого, как было упомянуто выше, терминал синхронизируется с облаком нашей системы учета рабочего времени TARGControl.
Чтобы подключить его к облаку, заходим в WEB-интерфейс терминала - в Настройки, и во вкладке Сервер, выбираем тип облака, в нашем случае TARGControl Cloud (если ПО развернуто на локальном сервере, прописывает его IP), вводим саму учетную запись с паролем (данные, которые указывали при регистрации в TARGControl) и указываем время синхронизации. Готово. После этой несложной операции события, регистрируемые данным терминалом, будут загружаться на облаке.
Теперь, когда терминал и облако синхронизированы, совершенно вся информация передается из терминала в TARGControl Cloud. Это касается не только временных интервалов и проходов, но и результатов алкотестирования, весоизмерения, ошибок, связанных с идентификаций и др. Все данные можно удобно структурировать с помощью различных отчетов (за период, по затратам времени на определенный вид работ, по нарушениям, по объектам и т.д.). То есть облачный сервис представляет собой систему, занимающейся аналитикой всех полученных данных с устройств. При этом все данные, внесенные на облако, будут подгружены и на терминале.
В заключение вынесем тезисно следующие функции, предоставляемые терминалом D1:
Разработан удобный WEB-интерфейс для конфигурирования терминала.
На терминале реализован графический интерфейс для взаимодействия сотрудников с устройством.
Поддержка нескольких способов идентификации - биометрия по отпечатку пальцев, RFID-карты и вход по PIN-коду.
Работа терминала как контроллера. То есть может использоваться для построения полноценного СКУД.
Фотофиксация событий и хранение фотографий на контроллере. При синхронизации с TARGControl все фото залетают на облако, где их и можно просмотреть, не подключаясь к самому контроллеру. (О совместной работе терминала и облака расскажу в следующей статье).
Фиксация событий доступа на терминале (проходы, выбор событий на дисплее, нажатие кнопки). События также загружаются на облако.
Возможность подключения алкотестеров, считывателей, IP-камер и других устройств.
Создание уведомлений.
И многие другие функции, которые работают при совместной работе с системой УРВ (отчеты, табели, учет времени по рабочим графикам и т.д. ).
Бесконечно много можно говорить о терминале, или как говорил пластиковый космонавт, борец с преступностью Базз Лайтер - “Бесконечность не предел”. Поэтому, если будет спрос, в следующей статье опишу разработку терминала как можно подробнее (от конфигурирования настроек до исходного кода). Статья получилась большая, но можно еще больше...
В случае возникновения вопросов или критических замечаний, прошу последовать в комментарии для бурного осуждения обсуждения!