Реализация Интернета вещей для промышленного оборудования простыми методами

За последние несколько лет довелось принимать участие и руководить проектами объединения в одну сеть через Интернет: различного оборудования: станков, торговых автоматов, датчиков, очистителей воздуха. Технологии использовались самые разные, в том числе основанные на Microsoft Azure Iotedge и Amazon Web Services.

На основе полученного опыта и личных предпочтений, хотелось реализовать проект, не связанный с большими корпорациями и в минимально необходимой конфигурации, без излишеств и легко развертываемый на любом сервере с Debian. При этом без экзотики, на основе MQTT и прочая. Так как обычно приходится осуществлять поддержку своих разработок, хотелось понадежнее и попроще, с запасом по добавлению новых функций по желаниям Заказчиков.

Эту идею удалось реализовать в работе, связанной с "умными" очистителями воздуха для помещений. Картинка, иллюстрирующая идею в части протоколов и основных составляющих:

Предприятие Заказчика традиционно занималось очистителями воздуха с ультрафиолетовыми лампами и озонаторами. Им требовалось устройство управления, с сенсорным дисплеем и Raspberry Pi, звуковым оповещением о наличии озона в помещении.

На первом этапе требовалось автономное устройство управления, без реализации сервера, со следующими функциями:

  • управление включением ультрафиолетовых (УФ) ламп и озонатора с помощью двух реле,предельный ток 3А и 1А;

  • автозапуск пользовательского интерфейса (GUI) после включения питания, отсутствие возможности обхода GUI пользователем (kiosk-режим);

  • аудио выход для воспроизведения звуковых оповещений (необходимо для безопасной работы озонатора);

  • независимые таймеры работы УФ-облучателя и озонатора, дополнительная парольная защита таймера озонатора;

  • вывод показателей качества воздуха, получаемых от встроенного в основной модуль датчика, на сенсорный дисплей (на выделенном экране GUI «Графики/производительность» );

  • возможность доступа к сети по WiFi-каналу, средства удалённого администрирования ПО;

  • экран «Графики/производительность» позволяет оценить текущую дозу УФ-облучения (Дж/м2), объём обрабатываемого воздуха и выбранный показатель качества воздуха.

При загрузке системы первым экраном запускается анимация и далее следует переключение на экран главного меню очистителя воздуха. Набор диалоговых экранов, заданный для первой версии ПО:

Впоследствии это ПО дорабатывалось, и экранов стало более 25, примерный состав экранов одной из промежуточных версий:

Как в большинстве случаев, Заказчик и его оборудование, находились далеко от нас, поэтому все работы проводились удаленно и на наших прототипах устройств. Первым делом Заказчику был необходим рекомендуемый нами состав покупных модулей для устройства управления, который можно оперативно купить, и собрать работающий прототип на его и на нашей стороне.

По его просьбе, мы разработали перечень элементов со ссылками, также схему соединений в максимально наглядном виде. Заказчик имел большой опыт в электрике, Raspberry Pi и всякие модули были в новинку, поэтому схему рисовали максимально наглядно, нужную документацию сотрудники Заказчика выпускали впоследствии самостоятельно. Одна из первых версий схемы соединения:

GUI и ПО системы управления очистителем и журналирования событий писали на Python. Представленная система в процессе внедрения постоянно дорабатывалась, усложнялись требования к логике работы и системе таймеров, датчикам, управлению дополнительными средствами очистителя.
После реализации и тестирования первых итераций было введено ШИМ-управление скоростью вращения вентилятора очистителя воздуха, ранее управлявшегося дополнительной Arduino-совместимой платой.
Была реализована возможность настройки визуальных и звуковых оповещений о предстоящем включении потенциально опасных режимов работы озонатора, во время их работы и после завершения в течение установленного времени.
Одной из существенных проблем в эксплуатации являлось одновременное изменение параметров работы очистителя воздуха несколькими сотрудниками, в частности некорректное задание параметров работы озонатора, что приводило к внеплановой выдаче звуковых оповещений, нарушало рабочие процессы клиентов заказчика и приводило к подозрениям на сбои в работе ПО очистителей. Решением стало ведение журналов (логов) как изменений пользовательских настроек, так и круглосуточной телеметрии.
Пример фрагмента отладочного журнала первой итерации, где <date*> и <time*> метки даты-времени:

<date1> <time1>  - Powered on
<date1> <time2>  - Ozone timer keyholder passcode entry
<date1> <time3>  - Ozone timer set to: Monday 12:43 - 14:53
<date1> <time4>  - Settings menu keyholder passcode entry
<date1> <time5>  - Engineer settings menu keyholder passcode entry
<date1> <time6>  - Powered on
<date1> <time7>  - Ozone timer keyholder passcode entry
<date1> <time8>  - Ozone timer set to: Tuesday 18:36 - 20:46
<date1> <time9>  - start sound: 'Ozone Release Warning.mp3'
<date1> <time10> - switch on the Ozone
<date1> <time11> - Powered on
<date1> <time12> - Powered on

Необходимо было спроектировать масштабируемую БД и разработать средства доступа к БД для администратора, обслуживающего персонала заказчика и клиентов. Позднее, для интеграции очистителей в систему «умное здание», была добавлена поддержка сетей BACNet с доступом к состоянию реле озонатора и УФ-облучателя, а также показаниям датчиков.

Для Raspberry Pi были разработаны два модуля ПО, работающих как отдельные процессы.

Модуль GUI. Помимо интерфейса пользователя, обеспечивает ведение логов, отправку телеметрии на сервер, обеспечивает исполнение команд удаленного управления. Графический интерфейс пользователя реализован на основе набора полноразмерных изображений, предоставленных Заказчиком, был написан на Python с применением библиотеки Pygame, что обеспечило необходимую скорость прорисовки и реакции на действия пользователя.

Процесс отладки модуля GUI
Процесс отладки модуля GUI

Основные данные в телеметрии:

  • уровень CO2;

  • показатель качества воздуха;

  • параметры работы УФ-облучателя (время очередного запуска и длительность цикла), дни работы, наличие и параметры интервалов исключений работы;

  • длительности интервалов заблаговременного оповещения о работе озонатора, работы озонатора и интервала с оповещением об окончании работы озонатора;

  • состояния обоих реле;

  • громкость звуковых оповещений;

  • скорость работы вентилятора;

Второй модуль ПО отвечает за связь с сервером:

  • принимает состояние очистителя воздуха и данные телеметрии от модуля пользовательского интерфейса и пересылает на сервер по MQTT-протоколу;

  • реализует буфер данных очистителя воздуха в оперативной памяти и локальных файлах для временного хранения при обрывах связи;

  • принимает команды управления очистителем от сервера по MQTT-протоколу и пересылает в модуль пользовательского интерфейса;

  • обеспечивает стабильность подключения к MQTT-брокеру, восстанавливает соединение при потере;

  • организует и открывает обратный SSH-туннель с сервером для администрирования управляющего ПО очистителя воздуха и операционной системы, закрывает его по командам с сервера и по истечении таймаута.

Связь между модулями осуществляется по протоколу UDP.

В реальных условиях работы распределённой сети неизбежны обрывы сетевых соединений, при которых без дополнительных мер происходит как пропуск без фиксации в журналах потенциально небезопасных изменений, так и утеря части информации, полученной с датчиков. Немедленная резервная запись всех сообщений на носитель по мере их получения в этом случае также не подходит, так как Raspberry Pi используется в конфигурации «по умолчанию», т.е. с microSD картой, имеющей ограниченный ресурс перезаписи. Решением проблемы стало введение двухэтапной системы сбора информации. При отправке пакета данных из модуля графического интерфейса фактически происходит его добавление в список, находящийся в оперативной памяти. По превышении таймаута содержимое списка единовременно записывается в файл, содержимое которого затем по таймауту отправки отправляется на сервер. Факт успешного приёма списка сервером подтверждается, файлы без подтверждённого приёма не удаляются и при очередном таймауте предпринимается следующая попытка их отправки. При восстановлении соединения после обрыва содержимое всех созданных локальных файлов отправляется в порядке их создания.

В качестве MQTT-брокера был использован Eclipse Mosquitto, на стороне клиентов для подключения применялся Paho MQTT Python client.

Из доступных режимов аутентификации и защиты MQTT-протокола как наиболее гибкий был выбран режим с клиентскими сертификатами, требующий создания сертификатов как для клиента, так и для сервера, подписываемых удостоверяющим центром.

Фрагмент кода инициализации MQTT-клиента:

our_client = mqtt.Client( client_id = MAC_address, clean_session = False ) 
our_client.tls_set(ca_certs="ca.crt", certfile="client.crt", keyfile="client.key", cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
our_client.tls_insecure_set(True)
our_client.on_message = message_function
our_client.on_connect = on_connect
our_client.loop_start() # запуск MQTT-клиента

В MQTT доступны средства гарантированной доставки сообщений на основе значений параметра QoS:
QoS == 0 – однократная отправка сообщения без подтверждения получения;
QoS == 1 – потенциально многократная отправка-получение сообщения с подтверждением получения и сохранением в очереди;
QoS == 2 – гарантированно однократные отправка-получение сообщения с подтверждением получения.
Пропускная способность точек доступа клиентов по оценкам заказчика оказалась достаточна для передачи при значении QoS == 2, которое и было выбрано для последующих версий ПО.

Для удалённого внесения изменений в конфигурацию ПО и операционной системы, обновления сертификатов, удалённой отладки в протокол обмена были добавлены команды организации и управления обратным SSH-туннелем к серверу от очистителя воздуха.

В качестве сервера был выбран VDS среднего ценового сегмента на хостинге, обеспечивающем минимальный пинг с сетями заказчика. По условиям аренды на сервере предоставлялись: Debian 11 с root-доступом, выход в Интернет с «белым» IP-адресом, возможность создания и обновления SSL-сертификата на доменное имя в течение всего срока действия договора, возможность хранения фиксированного количества резервных копий состояния виртуальной машины.

После обновления ОС и установки необходимого ПО были проведены базовые мероприятия по повышению защищённости, закрыт удалённый доступ к БД, изменены реквизиты сетевого доступа к серверу, созданы локальные учётные записи. Также были изменены порты по умолчанию сервисов MQTT-брокер и SSH, закрыт стандартный SSH-порт 22.

Для хранения данных использовалась СУБД MariaDB, входящая в состав ОС по умолчанию. В БД хранятся данные о пользователях, логи состояний зарегистрированных очистителей воздуха, текущая телеметрия от каждого очистителя и многое другое.

Для разработки сайта использовался Python и Flask. Модуль сайта реализует удалённый доступ с ПК и мобильных клиентов по HTTPS через web-интерфейс к журналам данных и отчётам БД, аутентифицирует пользователей, разграничивает права доступа при предоставлении данных из БД, позволяет производить мониторинг сети и отдельных очистителей воздуха на уровне клиентов и администратора, изменять настройки очистителей. Пользователь может, например, применить выбранные настройки (таймеры и т.п.) сразу ко всем купленным им очистителям. Или сделать удаленный сброс.

Пример основной страницы десктопной версии сайта:

Отображаются две группы устройств — автономные модули с датчиками качества воздуха (о них планируется следующая статья) и очистители воздуха, текущие данные качества воздуха и состояния реле по каждому очистителю и автономному модулю, есть возможность вывода графиков данных за указанный период, добавления и удаления очистителей и модулей.

Пример выводимых графиков содержания CO2 и качества воздуха за выбранный период времени:

Пример страницы добавления нового очистителя воздуха:

Пример страница удаленного управления выбранного очистителя воздуха:

Пример журнала очистителя воздуха, отображается успешный вход на страницу управления озонатором без внесения изменений, временные метки включения и выключения блока ультрафиолетовых ламп:

Далее, примеры мобильных версий страниц сайта:

Одним из требований являлось обеспечение минимальной задержки при передаче состояния очистителя воздуха и команд управления. Для этого в протоколах обмена указанная часть обрабатывалась отдельно от сбора общей телеметрии, итоговое время от действия пользователя в графическом интерфейсе до изменения состояния реле очистителя было обычно в пределах 2 секунд, аналогичное время было получено и при отображении текущих параметров воздуха.

Первоначально планировалась также разработка мобильных приложений, не только сайта. Но в процессе эксплуатации вместе с Заказчиком пришли к выводу, что сайта для удаленного доступа вполне достаточно.

В следующей статье планирую рассказать о добавлении автономных модулей датчиков качества воздуха на основе ESP32 к этой системе. Если это интересно, конечно.