За последний год мы спроектировали (и продолжаем поддерживать) несколько IIoT проектов. Возможно, вы слышали о IIoT, но, на всякий случай, мы попробуем максимально просто объяснить что это такое и почему это интересно разработчикам, архитекторам и администраторам высоконагруженных решений.



IoT — интернет вещей — подразумевает управление устройствами, предназначенными для выполнения простых бытовых задач (открыть ворота гаража, когда подъезжает машина, включить свет по датчику движения или по команде, следить за температурой в помещении), то под IIoT — индустриальным интернетом вещей — обычно имеется в виду “оцифровка” данных с производств, на основе которых можно провести экспертный анализ, часто при помощи машинного обучения.


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


Поток данных — от сенсоров на полях, от промышленных станков, от датчиков газа — поступает в агрегирующие хабы и, далее, в платформу обработки и анализа данных.


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


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


Создаваемая архитектура


Часто в индустриальном IoT нет прямого доступа к датчикам и системам управления, поэтому для соединения уровней OT (операционных технологий) и IT (информационных технологий) используется шлюз.


Таким образом, IIoT архитектура обычно включает в себя: конечные устройства, шлюзы, региональные хабы и, наконец, системы обработки и хранения информации.


Создаваемая архитектура должна обеспечить возможность:


  • Собирать данные с датчиков на шлюз
  • Передавать данные в облако или датацентр
  • Автоматически обновлять конфигурации шлюзов
  • Поддерживать безопасную передачу и обработку большого объема данных

На изображении: архитектура создаваемой системы и ПО, которое мы будем использовать для ее построения на каждом уровне.



Датчики собирают данные и отсылают их на шлюз, используя самые разные проводные и беспроводные протоколы (Serial, RS-485, MODBUS, CAN bus, OPC UA, BLE, WiFi, и т.п.). В нашем примере мы будем иметь в виду, что данные приходят на шлюз по WiFi.


В качестве шлюза будем использовать Raspberry Pi, на котором будет запущен брокер Mosquitto и агент MiNiFi. Mosquitto — это опенсорсный, легковесный брокер сообщений, который мы будем использовать для дальнейшей передачи данных с датчиков по MQTT протоколу. MQTT добавляет минимальный оверхед и поэтому удобен для применения в IoT, когда аппаратные ресурсы конечных устройств ограничены (используются, например, телефоны и микроконтроллеры).


Apache MiNiFi — подпроект Apache NiFi — легковесный агент, который имплементирует основную функциональность Apache NiFi, специально предназначенного для сбора данных на конечных устройствах.


MiNiFi компактен, минимально использует ресурсы и позволяет централизованно управлять всеми агентами. Легко соединяется с NiFi с помощью Site-To-Site (S2S), что позволяет выстроить полноценное управление потоком данных — масштабируемое, безопасное и дающее ясное представление обо всех этапах передачи информации.


В нашей системе MiNiFi подпишется на все топики Mosquitto брокера и будет пересылать каждое сообщение в NiFi, установленный на региональном уровне. Также можно использовать его для соединения с системой SCADA или любым другим источником OT-данных.


На региональном уровне присутствуют два компонента:


Apache NiFi — это мощная система управления потоками данных, поддерживает более 200 коннекторов. Графический интерфейс позволяет быстро и просто проектировать потоки данных.


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


В нашей системе NiFi — это центр сбора данных, который перенаправляет их в различные системы и приложения (HDFS, HBase, Kafka, S3 итп).


MiNiFi C2 Server (MiNiFi Command & Control) это еще один подпроект Apache NiFi, который пока находится в разработке. Его роль — быть центральной точкой конфигурации сотен и тысяч MiNiFi агентов, находящихся в продакшене в полевых условиях (различные залы, заводы, территории). C2 сервер управляет конфигурациями потоков MiNiFi (в терминологии C2 — versioned class of applications) и публикует их через Rest API. MiNiFi агенты могут соединяться с этим API с заданной частотой для обновления собственной конфигурации.


Итак, давайте начнем создавать наш прототип.


Соглашение о именовании доменных имен


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


#сервер с Apache NiFi который занимается потоковой обработкой данных
192.168.0.20 nifi.iot.local 
#сервер с Apache MiNiFi C2 который занимается распространением конфигураций MiNiFi
192.168.0.20 minifi-c2.iot.local
#raspberry pi, собирающий данные на производстве с Apache MiNiFi и MQTT брокером
192.168.0.68 iot-hub-1.iot.local

Подготовка Raspberry Pi: MQTT и MiNiFi


Чтобы установить брокер MQTT Mosquitto и агент MiNiFi запустите следующие команды на вашем Raspberry Pi.


По-умолчанию MiNiFi содержит минимальный набор обработчиков данных. Добавить дополнительные обработчики из комплекта NiFI можно, добавив NAR-архив (NiFi архив) в директорию с библиотеками.


Последней командой мы добавляем NAR MQTT обработчика.


sudo apt-get update
#install and run Mosquitto broker on default port 1883
sudo apt-get install mosquitto
mosquitto
#install and prepare MiNiFi agent
wget http://apache.crihan.fr/dist/nifi/minifi/0.4.0/minifi-0.4.0-bin.tar.gz
tar -xvf minifi-0.4.0-bin.tar.gz
cd minifi-0.4.0
#add mqtt processor
wget https://github.com/ahadjidj-hw/NiFi/raw/master/nifi-mqtt-nar-1.5.0.nar -P ./lib/

Теперь давайте установим сервер управлениями конфигураций MiNiFi C2 на сервер, который будет доступен с Raspberry Pi


Установка и конфигурирование MiNiFi C2 сервера.


Установите MiNiFi C2 сервер на публичный сервер, который будет доступен с MiNiFi агентов. Можно использовать иерархическое размещение серверов C2 для сложных сетевых инфраструктур, как описано чуть ниже. Запустите следующую команду чтобы установить C2 сервер:


wget http://apache.crihan.fr/dist/nifi/minifi/0.4.0/minifi-c2-0.4.0-bin.tar.gz
tar -xvf minifi-c2-0.4.0-bin.tar.gz
cd minifi-c2-0.4.0

  • Сервер C2 будет публиковать конфигурацию, организованную по классам. C2 поддерживает подключаемые “провайдеры конфигурации”:
  • The CacheConfigurationProvider, который обновляет конфигурации исходя из конфигурации заданной в файловой системы или на S3
  • The DelegatingConfigurationProvider, который передает делегирование на другой C2 сервер для создания иерархических структур C2 серверов.
  • The NiFiRestConfigurationProvider, который снимает шаблоны с серверов Apache NiFi через их REST API.

Настроим сервер C2, чтобы использовать NiFi как провайдера конфигурации. Отредактируйте файл ./conf/minifi-c2-context.xml, раскомментируйте xml-блок


<bean class="org.apache.nifi.minifi.c2.provider.nifi.rest.NiFiRestConfigurationProvider">

и пропишите адрес NiFi сервера (http://nifi.iot.local:8080 )


<constructor-arg>
    <value>http://nifi.iot.local:8080/nifi-api</value>
</constructor-arg>

Дальнейшее конфигурирование MiNiFi на Raspberry Pi


По умолчанию, для добавления обработчиков и их конфигураций нужно отредактировать конфиг ./conf/config.yml. Конфигурацию также можно написать вручную или создать ее используя графический интерфейс Apache NiFi с последующим экспортом конфигурации в виде шаблона. Шаблон это XML-файл, который необходимо конвертировать в YML файл конфигурации MiNiFi, используя MiNiFi toolkit. Вот пример конфигурационного файла, который следит за файлом на устройстве и пересылает каждую новую строчку на NiFi, используя протокол S2S.


Для нашего проекта пользоваться ручной настройкой мы не будем. Ведь если MiNiFi-агентов будет много, то будет непросто вручную останавливать, редактировать config.yml и перезагружать агент каждый раз, когда конфигурация будет меняться.


MiNiFi использует Change Ingestor, с помощью которого агент узнает о новых возможных конфигурациях. Change Ingestor это подключаемый модуль, и есть три ChangeIngestor, которые штатно поддерживаются MiNiFi.


  • FileChangeIngestor
  • RestChangeIngestor
  • PullHttpChangeIngestor

Мы будем использовать PullHttpChangeIngestor, чтобы периодически обращаться к серверу C2 и скачивать новую конфигурацию. Чтобы сконфигурировать этот Ingestor необходимо отредактировать файл ./conf/bootstrap.conf, раскомментировать соответствующие строки и установить следующие настройки:


nifi.minifi.notifier.ingestors=org.apache.nifi.minifi.bootstrap.configuration.ingestors.PullHttpChangeIngestor
# Hostname on which to pull configurations from
nifi.minifi.notifier.ingestors.pull.http.hostname=minifi-c2.iot.local
# Port on which to pull configurations from
nifi.minifi.notifier.ingestors.pull.http.port=10080
# Path to pull configurations from
nifi.minifi.notifier.ingestors.pull.http.path=/c2/config
# Query string to pull configurations with
nifi.minifi.notifier.ingestors.pull.http.query=class=iot-minifi-raspberry-agent
# Period on which to pull configurations from, defaults to 5 minutes if commented out
nifi.minifi.notifier.ingestors.pull.http.period.ms=60000

С такой конфигурацией каждый агент MiNiFi будет обращаться к серверу C2 по протоколу REST API по адресу http://minifi-c2.iot.local:10080/c2/config каждую минуту и запрашивать новую конфигурацию для класса iot-minifi-raspberry-agent
Важный момент: периодичность в 1 минуту выставлена только для демонстрации. В продакшен-среде, скорее всего, не придется обновлять агенты с такой частотой.


Прежде чем запускать агент, давайте переместимся на управляющий уровень и настроим MiNiFi C2 сервер и сам Apache NiFi.


Установка и конфигурирование NiFi сервера


Установите NiFi сервер, доступный с C2 сервера и запустите его.


wget http://apache.crihan.fr/dist/nifi/1.6.0/nifi-1.6.0-bin.tar.gz
tar -xvf nifi-1.6.0-bin.tar.gz
cd nifi-1.6.0
./bin/nifi.sh start

Соединитесь с NiFi интерфейсом по адресу http://nifi-dev:8080/nifi/ и создайте флоу, который будет запускаться на MiNiFi агентах, но перед этим добавьте Input Port (добавляется нажатием кнопки Input Port в меню) в корневом слое и назовите его from Raspberry MiNiFi. Это место, где NiFi будет получать файлы потоков от MiNiFi.


Добавьте Funnel и свяжите Input Port с Funnel — в дальнейших статьях мы коснемся обработки данных на стороне Apache NiFi.


Добавьте Processor consumeMQTT для подписки на Mosquitto брокер и подпишите его на все топики iot/sensors/* обратите внимание, что tcp://raspberrypi:1883 эквивалентно tcp://localhost:1883, так как этот поток будет запущен на Raspberry Pi



Используйте Processor UpdateAttribute чтобы добавить атрибут “version” который мы будем использовать для того, чтобы известить систему о переконфигурации. Вы можете добавлять любые дополнительные атрибуты: timestamp, location, имя агента и т.п.



И, наконец, добавьте Remote Process Group (RPG) — чтобы послать принятые события в NiFi. Соедините все эти три процесса.



Ваш поток теперь должен выглядеть как на скриншоте снизу. Левый поток будет запущен на самом Apache NiFi, и будет принимать данные с Apache MiNiFi. Правый поток поток не будет запускаться в рамках Apache Nifi, создан для целей прототипирования и конфигурации, и будет запускаться на Raspberry Pi.



Сохраните правый поток как шаблон с именем “iot-minifi-raspberry-agent.v1”. Принцип именования здесь чрезвычайно важен. Мы должны использовать то же имя, что и имя класса, используемое в конфигурации MiNiFi.


Очень важно — выделить нужно не только сохраняемые компоненты, но и связи между ними.



Размещение и запуск приложения


Перед запуском агентов MiNiFi на Raspberry Pi, давайте проверим, что C2 server правильно сконфигурирован. Откройте URL в вашем браузере: http://c2-server:10080/c2/config?class=iot-minifi-raspberry-agent&version=1 C2 Server должен ответить файлом, содержащим конфигурацию шаблона, который мы построили в YML формате.



Если вместо конфигурации сервер выдает Java Exception — вы столкнулись с проблемой в C2-сервере, упоминаемой здесь:
https://github.com/apache/nifi-minifi/pull/126#issuecomment-388856304
Нужно будет либо поставить версию 0.3.0, либо убрать файл javax.ws.rs-api-2.1.jar из папки lib директории C2-сервера.


Если вы посмотрите на логи C2 server, вы можете увидеть, что сервер принял запрос с параметрами {class=[iot-minifi-raspberry-agent], version=[1]}



Теперь, когда связь между отдельными компонентами архитектуры (MQTT, MiNiFi, NiFi и C2) установлена, запустите агента MiNiFi на Raspberry Pi с помощью команды:


./bin/minifi.sh start

Через несколько секунд вы должны увидеть логи C2 сервера. Хост 192.168.1.50 (в нашем случае это IP адрес устройства Raspberry Pi) запросил C2 сервер предоставить последнюю версию класса “iot-minifi-raspberry-agent”. В сравнении с предыдущим нашим запросом, который мы делали в браузере, вы можете обратить внимание, что MiNiFi не указал версию. Если вы откроете конфигурацию MiNiFi агента в ./conf/config.yml — вы увидите ту же конфигурацию, что мы получили в браузере, задав запрос руками.



MQTT показывает, что MiNiFi агент соединился с брокером и подписался на топики iot/sensors/#



Контроль передаваемых данных


Отлично, теперь давайте сделаем так, чтобы наши датчики начали генерировать данные и публиковать их в MQTT. MiNiFi начнет выгружать информацию и посылать в NiFi, как показано на скриншоте ниже.


Важно: Для того, чтобы компонент Apache NiFi начал работу надо нажать кнопку Play.


Теперь, давайте взглянем в одно из этих сообщений внутри NiFi. Информация идет от датчика “iot/sensors/LightIntensity/z”, версия приложения — 1



Обновление конфигурации MiNiFi


Теперь когда наша инфраструктура работает, а данные идут в наш “дата центр”, давайте задеплоим новую конфигурацию MiNiFi. Зайдите в интерфейс Apache NiFi и отредактируйте обработчик updateAttribute. Измените атрибут “version” на 2 вместо 1 и сохраните новый шаблон “iot-minifi-raspberry-agent.v2”. Вот и все. Новая конфигурация будет автоматически задеплоена.


Вы можете посмотреть на логи сервера C2 и увидеть что новая версия V2 была обнаружена, сервер не нашел ее в своем кэше и загрузил.



Затем MiNiFi обнаруживает новую конфигурацию, резервирует предыдущую конфигурацию выгружает новую и рестартует:



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

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


  1. levap
    03.07.2018 09:32
    +1

    Raspberry Pi в Industrial? Это же просто игрушка для гиков. Или это тесты?


    1. divanus
      03.07.2018 09:47

      Вскройте чтонить от ирридиум… там внутри atmega в лучшем случае


      1. levap
        03.07.2018 09:53

        atmega бывает разная, не вижу в ней ничего плохого для Industrial. Я про температурный диапазон, вибро- влагостойкость, наработку на отказ, защиту внешних интерфейсов и прочие атрибуты industrial-решений. Малинка — чисто любительская платка для домашних экспериментов. С плохо документированным процессором и отсутствием возможности создать собственное решение на этой платформе (информация у меня старая, могу и ошибаться, возможно, сейчас уже можно купить такие процессоры отдельно).


        1. eapotapov Автор
          03.07.2018 12:46

          спасибо за комментарий, просто хочется чтобы можно было это сделать в условных «домашних условиях»

          а в домашних условиях — дошел до магазина и взял raspberry pi

          кстати, есть ли какие-то доступные альтернативы, которые будут надежнее? мы скорее про платформы чем про edge поэтому и самим интересно)


          1. levap
            03.07.2018 13:00

            Из доступного можно посмотреть техасовские ситары (AM437x, AM335x), на них есть дешевые платы BeagleBone Black (они, правда, в коммерческом диапазоне выполнены, но можно и другие варианты найти на -40). Сейчас в России очень хорошую цену на эти процессоры можно получить, если планируется серийное производство. Также, можно обратить внимание на семейство iMX6 и выше (бывший Freescale, а ныне NXP). Тоже выбор огромный под любые требования, но будет дороже ситары. Понятное дело, оба этих решения будут дороже малинок и всякого откровенного китая, но это уже настоящее промышленное решение с нормальной документацией, техподдержкой, ПО и возможностью покупки от 1 штуки под кастомную плату.


            1. levap
              03.07.2018 13:03

              От того же NXP есть новые сетевые процессоры QorIQ, младшие модели вполне доступны по цене, есть отладка за 50 долларов. Допольно специфичная штука, но в сетевых приложениях дает колоссальную производительность.


  1. divanus
    03.07.2018 09:47

    Зачем такое количество костылей и велосипедов? Мдя. Не то, что в наше время! *картинка старичка-пердунчика*