За последние несколько лет довелось принимать участие и руководить проектами объединения в одну сеть через Интернет: различного оборудования: станков, торговых автоматов, датчиков, очистителей воздуха. Технологии использовались самые разные, в том числе основанные на 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 к этой системе. Если это интересно, конечно.

Комментарии (11)


  1. malykhin
    22.09.2022 17:01
    +1

    Насколько понял из статьи, ОС у вас грузится с sd-карты. Как-то решали проблему поломки загрузки из-за некорректного отключения по питанию? Там же, насколько я помню, /boot - это FAT, и который всегда монтируется в RW. Я когда занимался этим, то довольно часто получалось условно "сломать всё" тупо передергиванием питания во время записи чего-либо на карту.


    1. raspberry_pi_soft Автор
      22.09.2022 17:17

      Пришлось в своё время много мучаться с этой проблемой. Портилась файловая система после выключения питания, причем часто даже было не восстановить средствами ОС. Наблюдал ещё изменения размера маленького файла до 3Гб неожиданное и т.п. Добавлял принудительную проверку целостности файловой системы при старте, отключал запись части логов... Но всё это было с Raspberry Pi где-то до 2019г., потом как-то сошло на нет. Думаю, проблема была в схеме и они ее исправили. На всякий случай до сих пор только фирменные БП использую и micro SD Sandisk.


      1. select26
        22.09.2022 21:21

        Дело не фирменной карте. Вам про другое совсем говорят: сквошфс, оверлай и т.д. С карты образ читается только один раз при загрузке, разворачивается в памяти и больше она не используется.

        Обновление системы как делаете? Грамотно спроектированная система должна иметь как минимум две версии ПО. И при сбое обновления, загружаться со второй копии.

        Тут совсем другой подход нужен.

        И перевод интерфейса лучше вычитать.

        Обратный SSH tunnel - это грамотное решение!


        1. raspberry_pi_soft Автор
          22.09.2022 23:30

          SD карта чувствительна к напряжению питания. Если в момент снятия по питанию будут какие-то импульсы, броски напряжения - то часто портятся данные на карте. Программными методами это не исправить. Некоторые это "лечили" хорошим фильтром по питанию на стороне Raspberry Pi. В самой Raspberry Pi конденсаторов по питанию маловато.

          Откуда берутся такие импульсы при выключении? Обычно покупали блоки питания подешевле, с достаточным большим шумом по питанию, и с нехорошим переходным процессом на выходе 5В при снятии питания 220В.

          Порча файловой системы была просто внешним проявлением порчи информации на физическом уровне.

          Поэтому лучше использовать фирменный БП, с ним таких проблем нет.

          Кстати, сечение и длина провода питания тоже очень важны. С тонким длинным проводом и дешевым китайским адаптером на 1А получалось испортить данные на SD карте без всяких отключений питания. Объяснение было простое, потребляемый ток Pi меняется, тонкий провод в такой ситуации хороший делитель напряжения, а близко к 1А и сам БП выдает меньше 5В, ещё и с повышенными пульсациями. Как следствие - скачки напряжения питания на SD карте.

          Почему важна фирменная карта Sandisk? Обычно она сама собой не портилась через месяц-два использования в Pi, как некоторые другие. Это по результатам эксплуатации. Был проект с распределенной сетью торговых автоматов с Pi внутри, где количество автоматов в сети выросло от 100 до 10000 в течении нескольких лет. Там любопытная статистика получилась в итоге.


          1. select26
            23.09.2022 11:37

            Ну при чем тут питание? SD Card имеют очень ограниченный ресурс даже на чтение, не говорю уж про запись. И ваш опыт "она сама собой не портилась через месяц-два использования" - это просто ничто по сравнению с роутерами, у которых время работы изменяется годами, а то и десятилетиями.
            Я вам про промышленный подход пытался расказать. Зачем изобретать велосипед?


  1. beeptec
    23.09.2022 11:35
    +1

    Интересная концепция. Такой вот вопрос возник, чем руководствовался архитектор такой системы? Применение ARM, а не х86-64, продиктовано стоимостью платформы, инструментами среды разработки, нечто третье? Из описания вижу, что HTMI браузерная реализация сбора и мониторинга телеметрии по сетевым протоколам с распределенной топологией? 2 секунды тянут за собой суммарную инертность контроля реального состояния среды сбора информации. Для телеметрии, почему не полнофункциональный GUI Dashboard, при том что у Вас присутствует сервер? Возможно из за ограничений ARM?
    В целом судя по названию статьи, ожидал решение с применением встраиваемых PC на защищенных коммуникациях Lora или оптоволокне.


    1. raspberry_pi_soft Автор
      23.09.2022 12:30

      У подобных одноплатных ЭВМ на основе ARM преимущества: низкая стоимость, малое потребление, малые габариты. Это не пустой звук для тех, кто подбирал для своей системы промышленные одноплатные ЭВМ. Как правило, не требуется вентилятор, достаточно пассивного охлаждения. Наличие интерфейсов, свойственных скорее микроконтроллеру - I2C, UART, ШИМ, GPIO. Выбор был в пользу конкретно Raspberry Pi, у неё лучше всех поддержка производителем в части ПО, на уровне системы, драйвера и т.п. Огромное сообщество, легко найти нужную информацию.

      Да, браузерная реализация. С телеметрией какая история... Заказчик просил добавлять параметры, функции, датчики постепенно, в течении двух лет, соответственно оговаривал как их отображать. То есть доработки делались на основе опыта эксплуатации и пожеланий покупателей этих приборов. ARM отличная платформа, если всё в порядке с наличием драйверов. Был печальный опыт с Beaglebone и Orange Pi.


      1. beeptec
        23.09.2022 13:00

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

        Не знаю о кокой именно сборке Малины и применяемой версии Debian идет речь, или я что-то пропустил, суть в том что Linux периодически меняет политику поддержки и развития, что тянет за собой ограничения по драйверам, которые не поспевают, а порой безнадежно вгоняют в уныние тех, кто однажды сделал ставку на долгую и безоблачную жизнь с перспективой на расширение функционала. В Вашем случае это никак не промышленная реализация, нечто ближе к "умный дом - без окон и дверей, полна горница людей", если что прадон за прямоту.
        Линейка SBC не ограничена архитектурой ARM, для гурманов есть и х86-64 стики с полным джентльменским набором по коммуникациям и периферии. Самое быстрое, что пришло на память, к примеру LattePanda? Чем не одноплатник, по ходу он 5и вольтовый, на борту, для экспериментаторов есть GPIO, х16 микроконтроллер, не помню тип.


        1. raspberry_pi_soft Автор
          23.09.2022 13:56

          Долгой и безоблачной жизни здесь нет. С каждой новой версией Debian, и новой версии аппаратуры что-то меняется, иногда очень неприятные сюрпризы бывают. Обычно проблемы решаемы. Для этого и существует поддержка разработчиков конкретной системы.

          Просто на некоторых платформах проблем меньше, на некоторых значительно больше.


        1. raspberry_pi_soft Автор
          23.09.2022 14:04

          Сейчас нет большой разницы, что выбрать, x86 или ARM. Выбираем тот вариант ЭВМ, с которой меньше проблем.


          1. beeptec
            23.09.2022 15:00

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

            Что касается ARM? Если нужно что-то компактное, энергоэффективное и бесшумное, работающее от аккумулятора (смартфонам, маршрутизаторам и прочим многочисленным девайсам) на простой ARM софт.

            Что касается промышленности, это ограничения в строну распределения 1-й большой задачи с распределениями PCs, в Вашем случае одноплатников под свои индивидуальные задачи, далее локальные или разнесенные коммуникации на уровне серверного обмена уровня PLC, по сути промышленные контроллеры так и устроены на микроконтроллерах в т.ч. и ARM.

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