[Промышленное программирование, Интернет вещей] Промышленный интернет вещей в ПЛК Simatic S7-1x00 на примере протокола MQTT
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Обнаружил в базе знаний Siemens (SIOS) интересный пример использования контроллеров линейки S7-1200 и S7-1500 в качестве клиента протокола MQTTСсылка на первоисточник: https://support.industry.siemens.com/cs/document/109748872/fb-lmqtt_client-for-simatic-s7-cpu?dti=0&pnid=13685&lc=en-RUПо ссылке можно найти саму библиотеку с функциональным блоком MQTT_Client (с открытыми исходниками, кстати) и пояснительную записку к примеру. Документация сама по себе вполне исчерпывающая, знающие английский язык могут смело идти по ссылке и не читать эту заметку, подарив тем самым себе несколько увлекательных часов инженерных изысканий. А для остальных, менее опытных и/или более ленивых, я кратко расскажу основное и продемонстрирую свой пример работы клиента, творчески переработанный под более-менее реальное применение.Кратко о терминах.MQTT — message queuing telemetry transport. Протокол телеметрии для передачи сообщений. Затрудняюсь перевести название корректно на русский.Message — сообщение. Непосредственно, сами передаваемые данные. Сообщение состоит из нескольких частей:-Topic, тема сообщения. Символьная строка, размер которой в исходном примере ограничен 200 символами. Клиенты для получения сообщений должны предварительно подписаться на конкретную тему, т.е. topic-QoS, quality of service. Дополнительный признак, указывающий — ждать ли подтверждения получения сообщения или нет.-Message text, текст сообщения. Текстовая строка из 500 символов.Протокол построен на модели подписчик/издатель, общая логика которого слегка отличается от обычной клиент-серверной модели, привычной в промышленных протоколах. При клиент-серверном подходе один или несколько участников исполняет роль сервера, т.е. узла в сети, который отвечает на запросы клиента. Сервер сам по себе не инициирует связь и не проявляет активность, он лишь отдает запрошенные данные и принимает уставки и команды. При этом адресация данных, тип данных и прочее закладываюся и структурируются изначально на этапе разработки серверной части. Клиент тоже должен знать эту «карту адресов Modbus». Изменение набора данных требует перенастройки и клиента, и сервера.В модели подписчик-издатель, применяемой в протоколе MQTT, совершенно необязательно заранее формировать, конфигурировать или программировать набор данных (топики). Вообще никак данные конфигурировать в серверной части не требуется. Топики создаются автоматически от издателя. Подписчики, в свою очередь, подписываются на топики, причем можно подписаться даже на тот топик, в который не написал ни разу ни один издатель. Как только в этот топик будет отправлено хотя бы одно сообщение, все подписчики его получат.Итак, роли в протоколе MQTT.Издатель — он же publisher. Узел, который отправляет сообщения (текстовую информацию) на определенную тему (topic).Подписчик — он же subscriber. Узел, который подписывается на определенные темы. Новые сообщения в заявленных темах подписчик получает автоматически.Роли издателя и подписчика могут совмещаться на одном и том же узле сети. Это — роли клиента.Роль сервера в протоколе MQTT выполняет узел, который называется брокер. Именно брокер запоминает, какие клиенты на какие темы подписались. Именно брокер принимает сообщения от издателей на определенную тему и автоматически раздает их соответствующим подписчикам.К брокеру может быть подключено несколько и подписчиков, и издателей. Максимальное количество мне неизвестно. Предположу, что все ограничено лишь мощностью железа, на которой работает брокер и настройками стека TCP/IP операционной системы.В первоисточнике (см. ссылке в начале) идет архив с библиотекой LMQTT_Client. Архив необходимо распаковать, а библиотеку — подключить к уже созданному проекту Step 7. Подключение библиотеки выполняется через пункт меню Options → Global Libraries → Open library. В результате Вы увидите следующее:
Библиотека подключена к проектуБиблиотека содержит две версии функционального блока клиента протокола MQTT — для контроллеров S7-1200 и S7-1500. В моем примере будет использоваться младший ПЛК, S7-1214. Реализации отличаются тем, что старшие S7-1500 позволяют адресовать брокер по доменному имени, а S7-1200 — только по ip-адресу. Необходимо перетащить блок LMQTT_Client из библитеки во вкладку Program Files контроллера. Типы данных скопируются в проект автоматически. Далее я отхожу от примера и осуществляю вызов ФБ MQTT_Client из своего собственного функционального блока под названием MQTTExchange:
В принципе, если выполнить все настройки правильно и играть запросами через поля экземпляра функционального блока, то можно проверить работоспособность прямо сейчас. Но вначале пройдемся по основным входным и выходным пинам этого ФБ.enable — при положительном фронте этой дискретной переменной устанавливается соединение с брокером MQTT, при отрицательном фронте соединение разрывается. Т.е. для работы необходимо держать этот вход в состоянии TRUEpublishData — структура для отправки (публикации) сообщения. Состоит из бита запроса на публикацию (для отправки сообщения бит необходимо взвести в истину и снять в ложь после появления флага done или error), топика и текста сообщения, а так же признака качестве QoSsubscribeToTopic — структура, которая содержит флаг запроса на подписку, флаг запроса на отписку (да, можно в любой момент отписаться от топика), непосредственно имя топика и признак качестваНа начальном этапе нам важны следующие две структуры, которые необходимо для установления связи с брокером: это tcpConnParam и mqttParam. Эти структуры я заполняю единожды в OB100 при запуске контроллера. Необходимый минимум для работы протокола описывается ниже.
Аппаратный идентификатор интерфейса контроллераИдентификатор интерфейса ( «сетевой карты» ) ПЛК. В моем случае у меня всего один интерфейс. Его ID я уже помню наизусть, поэтому пишу 64. Подсмотреть Hardware ID можно в аппаратной конфигурации ПЛК.
Следующее — идентификатор соединения. Именно логического соединения по протоколу TCP/IP, connection ID. Должно иметь значение от 1 до 4096, назначается программистом, у каждого логического соединения должен быть свой уникальный «айди», иначе связь не будет функционировать. В моем случае у меня присутствует одно-единственное соединения, и я смело назначаю ему «1»
Следующее назначение — IP-адрес хоста, на котором функционирует брокер.
В данном примере брокер работает на моем домашнем «рабочем» компьютере с публичным статическим ip-адресом. Из соображений информационной безопасности два байта ip-адреса стерты. В качестве брокера выступает mosquitto под Windows. Разные способы установки брокера хорошо описаны по ссылке:http://www.steves-internet-guide.com/install-mosquitto-broker/#manualТам же можно скачать уже настроенный в базе брокер, его я и использую:http://www.steves-internet-guide.com/install-mosquitto-broker/#Никаких особенных настроек не применяется. Сертификаты шифрования не используются (об этом чуть позже). На удаленном компьютере просто запущена программа mosquitto.exe, а на удаленном маршрутизаторе сделан проброс порта 1883 (порт для стандартных коммуникаций MQTT) в локальную сеть.Я умышленно использую брокер, недоступный локально. Одно дело поднять все в рамках локальной сети в горячо любимом диапазоне адресов 192.168.0.х или 192.168.1.х, а совсем другое — убедиться в возможности работы системы, как ей и положено, по удаленным каналам связи. Ведь сам контроллер находится сейчас в лаборатории, он подключен к местному маршрутизатору от провайдера, и у контроллера есть только локальный ip-адрес, а не публичный и, тем более, не публичный статический ip.Кстати, помним, что для организации «выхода в интернет» контроллеру в данном случае необходимо явно указывать «шлюз» в настройках его ip-адреса.
Обязательно надо прописать router address, иначе ПЛК не сможет подключиться к внешнем ресурсам глобальной сетиСледующая настройка — порт, по которому удаленный брокер слушает соединения. По непонятной причине в примере этот порт указан, как 1884, в то время как стандартным портом для нешифрованных коммуникаций является 1883. Задаю его явно:
Последняя настройка — символьное имя клиента. Должно быть уникально в системе. В качестве имени у меня задано S7-1214.
Гораздо разумнее было бы сделать имя клиента уникальным автоматически. Например, сделать его составным из слова «SIMATIC» и уникального серийного номера центрального процессора (прочитав его соответствующей системной функцией и переведя в строковое представление). С остальными настройками рекомендую ознакомиться в документации. Остановлюсь на двух из них, весьма интересных.Первое. Last will. Буквально на русском языке — «завещание» (сетевые граждане такие юмористы!). Если выполнить эту настройку, то клиент при подключении к брокеру передает и ее. В случае «отвала связи» клиента, брокер автоматически разошлет это завещание всем участникам обмена. «Завещание» является таким же сообщением, у него так же задается топик и текст.Второе. Возможность шифрования трафика. Для общего тестирования можно обойтись и без него. В продакшене — ни в коем случае.
Выставив поле activateSecureConn в настройках необходимо провести еще ряд манипуляций — активировать глобальные настройки безопасности проекта, импортировать сертификат брокера, создать сертификат контроллера и так далее. Вопросы зашифрованного соединения я уже поднимал в заметке про OPC UA коммуникации. В целом же действия тут больше напоминают настройки безопасного соединения для Open User Communications (SecOUC). В настоящем примере вопросами безопасности передаваемых данных я пренебрегаю. Подробности настройки описаны все в той же документации.Закончив настройки, необходимо убедиться, что все работает, как надо. Для начала, конечно же, просто подпимем соединение с удаленным брокером. Для этого достаточно подать истину на вход enable функционального блока LMQTT_Client:
Как видно, при поданном enable выходные биты tcpEstablished и mqttEstablished содержат «истину», это означает, что связь установлена успешно. В процессе испытаний я обнаружил интересное поведение блока, а именно — при подачи «истины» на вход enable подтверждение связи появлялось на одну-две секунды и пропадало. Связь устанавливалась только со второй попытки. Кроме того, при физическом обрыве связи этот ФБ просто информирует об отсутсвии соединения, и не предпринимает попыток автоматически пересоединиться. В целях автоматического соединения и пересоединения добавлен следующий нетворк:
Смысл следующий — если в течении 5 секунд установлен флаг запроса связи, но нет подтверждения, снять флаг запроса связи. И если флага запроса нет в течении 5 секунд, установить флаг запроса. В тепличных условиях лаборатории это прекрасно работает. В полевых условиях при нестабильной связи временные константы желательно скорректировать.В данном примере предполагается, что контроллер не только отправляет какую-либо информацию брокеру, но и подписан на топик. Точнее, даже на два топика, чтобы пример был интереснее. В качестве принимаемой информации может быть, что угодно — команды, уставки, запросы архивной информации или состояния оборудования. В принципе, все ограничивается исключительно объёмом свободной рабочей памяти. Вполне логичным будет подписаться на нужные топики сразу после установления связи. И для этого потребуется поиграть с полями структуры subscribeToTopic, которую лучше все воспринимать, как «управляющую» структуру.
По переднему фронту (то есть, по единомоментному факту) установления соединения я поднимаю локальную битовую переменную #SubscriveToTopics и выставляю «номер шага» процедуры подписки в 1. Номер шага используется в связи с тем, что все операции у нас ассинхронные, и их надо выполнять последовательно, одну за другой, а не все сразу (все сразу не выполнятся).Первый шаг подписки — подписаться на топик с названием «global». В случае успешного выполнения операции подписки переходим на следующий шаг. Иначе выполняем процедуру переподключения (хотя, реакция может быть иной, на усмотрение разработчика)
Смотрим. Если выставлен бит «выполняем подписку» и шаг = 1, то……если не выставлен бит управляющей структуры «подписатся», то задать имя интересующего топика (global) и поднять бит управляющей структуры «подписаться»…если бит управляющей структуры «подписаться» поднят, то смотреть на биты выполнения задания done и error. При появлении бита done сбросить бит управляющей структуры «подписаться» и перейти на шаг №2. В случае возникнования ошибки — выполнить переподключение к брокеру.Шаг №2. На этом шаге не нужно делать вообще ничего. Этот шаг требуется для того, чтобы ФБ клиента вызвался хотя бы один раз со сброшенным битом управляющей структуры «подписаться». Для этого есть и более изящные решения, но я обошелся простейшим таймером.
После 100мс ожидания просто идем на следующий шаг, к подписке на второй топик (шаг №3).
Шаг №3 аналогичен шагу №1, за исключением имени топика. После успешного завершения шага №3 сбрасывается локальный бит «выполнить подписку» (#SubscriveToTopics) и обнуляются шаги «подпрограммы подписки».После выполнения подписки можно смело проверять работу клиента. Для этого я вызываю программу mosquitto_pub.exe:
mosquitto_pub.exe -h myhost.mydomain.ru -t global -m «kill all humans»
, гдеmyhost.mydomain.ru — доменное имя удаленного брокераglobal — топик «global», на который только что подписался клиентkill all humans — текст сообщения в топике globalПосле отправки сообщения смотрим выходную структуру subscriptionsMessage:
Как видно, в топике global прошло сообщение «kill all humans»Флаг newMessageReceived нам еще пригодится в дальнейшем. Этот флаг выставляется сразу по получению нового сообщения и действителен в течении одного цикла сканирования. По нему очень удобно будет обрабатывать полученные команды, уставки или запросы.Вторая задача контроллера в этом примере — отправлять информацию о технологическом процессе через равные промежутки времени. Например, каждые сутки. Или каждые два часа. Ну, или каждые 10 секунд, потому что в учебном примере не очень хочется терять время на пустое ожидание. Поэтому каждые 10 секунд я поднимаю локальный флаг «отправить данные» и выставлю шаг «подпрограммы отправки» в 1:
Нетворк отправки данных для разнообразия написан на SCL, а не нарисован в LAD. Право же, оперировать строками в графических языках — не самое удобное дело.
Всего отправляется значение 4 переменных, три из которых заданы статично в блоке данных, а одна — постоянно увеличивается на небольшую дельту. На первом шаге «подпрограммы» задается имя топика, это имя personal0. А так же формируется строка сообщения. Поскольку оперируем мы именно символьными данными, приходится выполнять преобразование типа REAL_TO_WSTRING и конкатенацию строк. Для контроллеров, тем более, начального уровня, это не самое лучшее занятие — очень быстро расходуется память и неплохо так съедаются вычислительные ресурсы. Длина передаваемого сообщения — 500 символов, есть куда развернуться. Можно, так же, добавить еще и метку времени. Можно формировать буфер сообщений, тем самым аккумулируя хотя бы минимум данных на период отсутствия связи. В общем, тут можно делать, что угодно (но лучше делать, что написано в ТЗ).После формирования строки поднимается бит управляющей структуры «отправить сообщение» и меняется номер шага. На втором шаге идет проверка успешности или неуспешности отправки, после чего сбрасывается локальный бит «выполнить отправку» и сбрасывается номер шага «подпрограммы отправки».Запустим клиент MQTT и посмотрим, что приходит в топике personal0 (именно в этот топик ПЛК и отправляет данные):
Ну, и напоследок. Демонстрация возможностей удаленного управления. Если в топике personal0 пришло сообщение exterminate, дискретный выход Q0.0 устанавливается в значение «истина».Команда издателя:
mosquitto_pub.exe -h host.domain.ru -t personal0 -m «exterminate»
Нетворк программы контроллера:
Проверка пришедшего сообщения выполняется только по факту прихода самого сообщения (бит newMessageReceived), что вполне логично. А далее необходимо только проверять имя топика и текст сообщения. Любые дальнейшие действия программируются, как угодно.На этом технический пример заканчивается, и хочется немного порассуждать о возможностях применения. Они есть, и, кажется, весьма широкие. Фактически, это можно применять в любых распределенных недорогих системах, где присутствуют малые объемы информации и, в силу этого, использование специализированных «телемеханических» протоколов нецелесообразно в виду их высокой стоимости. Ну, например, в ЖКХ. Если маленький ПЛК смотрит на расход энергоресурсов (общедомовых, а, может, даже и поквартирных) и раз в сутки отправляет сводку в диспетчерский центр. Или смотрит на состояние общедомового оборудования, шлет параметры раз в час, но при аварии — моментально. Достаточно лишь снабдить ПЛК GSM-модемом, и фактически, ничего больше не требуется, кроме простого компьютера с фиксированным ip-адресом. Рассуждая дальше, можно и без физического ПК обойтись, засунув его «в облако». Главное, не забыть должным образом настроить шифрование трафика. В этом случае имеет смысл данные потребления энергоресурсов из клиента сразу складывать в базу данных, но это уже требует высокоуровневого программированияИли, как вариант, та же распределенная система, но не только сбор данных, но и взаимодействие M2M (контроллер-контроллер). Тут точно так же, достаточно минимального канала связи и доступного брокера.Можно даже и на скаду информацию выводить, не особо заморачиваясь с программированием серверной (брокерской) части. Ведь ничто не мешает настроить все полевые контроллеры на отправку сообщений брокеру, взять еще один контроллер, читать эти сообщения и их результат раскладывать по блокам данных, и уже из них выводить показания на тот же WinCC Advanced.Дальнейшие исследование показали отличное применение mqtt совместно со средой Node-RED. На Node-RED была "нарисована" программа, принимающая эти данные от брокера, разбирающая полученную строку и записывающая всю информацию (метку времени, значение) в базу данных MariaDB. Она же, программа на Node-RED позволила вытаскивать информацию за указанный временной промежуток, показывать ее в виде таблицы, графика и делать выгрузку в виде .csv файла.
===========
Источник:
habr.com
===========
Похожие новости:
- [Законодательство в IT, Карьера в IT-индустрии, Интернет вещей, Здоровье] Китайская компания отслеживает присутствие работников на местах по «умным» подушкам
- [Perl, Беспроводные технологии, Умный дом, DIY или Сделай сам] Софтовый датчик присутствия на Linux AP + ESP8266
- [Умный дом, Интернет вещей, Здоровье] В Alarm.com разработали бесконтактный видеодомофон
- [Промышленное программирование] Односторонние S7-коммуникации в Simatic. Как организовать обмен ПЛК-ПЛК, программируя и загружая только один ПЛК?
- [Глобальные системы позиционирования, IT-инфраструктура, Умный дом, Интернет вещей, Будущее здесь] M2M и IoT — ключевые технологии для современного бизнеса и потребительского рынка. Тренды М2М в 2021 году
- [Информационная безопасность, Производство и разработка электроники, Интернет вещей] Исследователи показали, как клонировать ключи Google Titan через уязвимость чипа NXP
- [Информационная безопасность, CTF] Hack The Box. Прохождение Omni. Ломаем легенький Windows IoT
- [Промышленное программирование, Программирование микроконтроллеров] Программирование Modbus RTU Master на примере Simatic S7-1200 и ПЧ Sinamics V20
- [Промышленное программирование, Программирование микроконтроллеров] Сервер Modbus TCP для Simatic S7-1200 / S7-1500
- [Разработка под Linux, Программирование микроконтроллеров, Схемотехника, Производство и разработка электроники] WSN-LTE шлюз на CC1310 и WP8548. Часть 1
Теги для поиска: #_promyshlennoe_programmirovanie (Промышленное программирование), #_internet_veschej (Интернет вещей), #_simatic, #_s7, #_s71200, #_siemens, #_mqtt, #_iiot, #_iot, #_promyshlennoe_programmirovanie (
Промышленное программирование
), #_internet_veschej (
Интернет вещей
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 09:28
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Обнаружил в базе знаний Siemens (SIOS) интересный пример использования контроллеров линейки S7-1200 и S7-1500 в качестве клиента протокола MQTTСсылка на первоисточник: https://support.industry.siemens.com/cs/document/109748872/fb-lmqtt_client-for-simatic-s7-cpu?dti=0&pnid=13685&lc=en-RUПо ссылке можно найти саму библиотеку с функциональным блоком MQTT_Client (с открытыми исходниками, кстати) и пояснительную записку к примеру. Документация сама по себе вполне исчерпывающая, знающие английский язык могут смело идти по ссылке и не читать эту заметку, подарив тем самым себе несколько увлекательных часов инженерных изысканий. А для остальных, менее опытных и/или более ленивых, я кратко расскажу основное и продемонстрирую свой пример работы клиента, творчески переработанный под более-менее реальное применение.Кратко о терминах.MQTT — message queuing telemetry transport. Протокол телеметрии для передачи сообщений. Затрудняюсь перевести название корректно на русский.Message — сообщение. Непосредственно, сами передаваемые данные. Сообщение состоит из нескольких частей:-Topic, тема сообщения. Символьная строка, размер которой в исходном примере ограничен 200 символами. Клиенты для получения сообщений должны предварительно подписаться на конкретную тему, т.е. topic-QoS, quality of service. Дополнительный признак, указывающий — ждать ли подтверждения получения сообщения или нет.-Message text, текст сообщения. Текстовая строка из 500 символов.Протокол построен на модели подписчик/издатель, общая логика которого слегка отличается от обычной клиент-серверной модели, привычной в промышленных протоколах. При клиент-серверном подходе один или несколько участников исполняет роль сервера, т.е. узла в сети, который отвечает на запросы клиента. Сервер сам по себе не инициирует связь и не проявляет активность, он лишь отдает запрошенные данные и принимает уставки и команды. При этом адресация данных, тип данных и прочее закладываюся и структурируются изначально на этапе разработки серверной части. Клиент тоже должен знать эту «карту адресов Modbus». Изменение набора данных требует перенастройки и клиента, и сервера.В модели подписчик-издатель, применяемой в протоколе MQTT, совершенно необязательно заранее формировать, конфигурировать или программировать набор данных (топики). Вообще никак данные конфигурировать в серверной части не требуется. Топики создаются автоматически от издателя. Подписчики, в свою очередь, подписываются на топики, причем можно подписаться даже на тот топик, в который не написал ни разу ни один издатель. Как только в этот топик будет отправлено хотя бы одно сообщение, все подписчики его получат.Итак, роли в протоколе MQTT.Издатель — он же publisher. Узел, который отправляет сообщения (текстовую информацию) на определенную тему (topic).Подписчик — он же subscriber. Узел, который подписывается на определенные темы. Новые сообщения в заявленных темах подписчик получает автоматически.Роли издателя и подписчика могут совмещаться на одном и том же узле сети. Это — роли клиента.Роль сервера в протоколе MQTT выполняет узел, который называется брокер. Именно брокер запоминает, какие клиенты на какие темы подписались. Именно брокер принимает сообщения от издателей на определенную тему и автоматически раздает их соответствующим подписчикам.К брокеру может быть подключено несколько и подписчиков, и издателей. Максимальное количество мне неизвестно. Предположу, что все ограничено лишь мощностью железа, на которой работает брокер и настройками стека TCP/IP операционной системы.В первоисточнике (см. ссылке в начале) идет архив с библиотекой LMQTT_Client. Архив необходимо распаковать, а библиотеку — подключить к уже созданному проекту Step 7. Подключение библиотеки выполняется через пункт меню Options → Global Libraries → Open library. В результате Вы увидите следующее: Библиотека подключена к проектуБиблиотека содержит две версии функционального блока клиента протокола MQTT — для контроллеров S7-1200 и S7-1500. В моем примере будет использоваться младший ПЛК, S7-1214. Реализации отличаются тем, что старшие S7-1500 позволяют адресовать брокер по доменному имени, а S7-1200 — только по ip-адресу. Необходимо перетащить блок LMQTT_Client из библитеки во вкладку Program Files контроллера. Типы данных скопируются в проект автоматически. Далее я отхожу от примера и осуществляю вызов ФБ MQTT_Client из своего собственного функционального блока под названием MQTTExchange: В принципе, если выполнить все настройки правильно и играть запросами через поля экземпляра функционального блока, то можно проверить работоспособность прямо сейчас. Но вначале пройдемся по основным входным и выходным пинам этого ФБ.enable — при положительном фронте этой дискретной переменной устанавливается соединение с брокером MQTT, при отрицательном фронте соединение разрывается. Т.е. для работы необходимо держать этот вход в состоянии TRUEpublishData — структура для отправки (публикации) сообщения. Состоит из бита запроса на публикацию (для отправки сообщения бит необходимо взвести в истину и снять в ложь после появления флага done или error), топика и текста сообщения, а так же признака качестве QoSsubscribeToTopic — структура, которая содержит флаг запроса на подписку, флаг запроса на отписку (да, можно в любой момент отписаться от топика), непосредственно имя топика и признак качестваНа начальном этапе нам важны следующие две структуры, которые необходимо для установления связи с брокером: это tcpConnParam и mqttParam. Эти структуры я заполняю единожды в OB100 при запуске контроллера. Необходимый минимум для работы протокола описывается ниже. Аппаратный идентификатор интерфейса контроллераИдентификатор интерфейса ( «сетевой карты» ) ПЛК. В моем случае у меня всего один интерфейс. Его ID я уже помню наизусть, поэтому пишу 64. Подсмотреть Hardware ID можно в аппаратной конфигурации ПЛК. Следующее — идентификатор соединения. Именно логического соединения по протоколу TCP/IP, connection ID. Должно иметь значение от 1 до 4096, назначается программистом, у каждого логического соединения должен быть свой уникальный «айди», иначе связь не будет функционировать. В моем случае у меня присутствует одно-единственное соединения, и я смело назначаю ему «1» Следующее назначение — IP-адрес хоста, на котором функционирует брокер. В данном примере брокер работает на моем домашнем «рабочем» компьютере с публичным статическим ip-адресом. Из соображений информационной безопасности два байта ip-адреса стерты. В качестве брокера выступает mosquitto под Windows. Разные способы установки брокера хорошо описаны по ссылке:http://www.steves-internet-guide.com/install-mosquitto-broker/#manualТам же можно скачать уже настроенный в базе брокер, его я и использую:http://www.steves-internet-guide.com/install-mosquitto-broker/#Никаких особенных настроек не применяется. Сертификаты шифрования не используются (об этом чуть позже). На удаленном компьютере просто запущена программа mosquitto.exe, а на удаленном маршрутизаторе сделан проброс порта 1883 (порт для стандартных коммуникаций MQTT) в локальную сеть.Я умышленно использую брокер, недоступный локально. Одно дело поднять все в рамках локальной сети в горячо любимом диапазоне адресов 192.168.0.х или 192.168.1.х, а совсем другое — убедиться в возможности работы системы, как ей и положено, по удаленным каналам связи. Ведь сам контроллер находится сейчас в лаборатории, он подключен к местному маршрутизатору от провайдера, и у контроллера есть только локальный ip-адрес, а не публичный и, тем более, не публичный статический ip.Кстати, помним, что для организации «выхода в интернет» контроллеру в данном случае необходимо явно указывать «шлюз» в настройках его ip-адреса. Обязательно надо прописать router address, иначе ПЛК не сможет подключиться к внешнем ресурсам глобальной сетиСледующая настройка — порт, по которому удаленный брокер слушает соединения. По непонятной причине в примере этот порт указан, как 1884, в то время как стандартным портом для нешифрованных коммуникаций является 1883. Задаю его явно: Последняя настройка — символьное имя клиента. Должно быть уникально в системе. В качестве имени у меня задано S7-1214. Гораздо разумнее было бы сделать имя клиента уникальным автоматически. Например, сделать его составным из слова «SIMATIC» и уникального серийного номера центрального процессора (прочитав его соответствующей системной функцией и переведя в строковое представление). С остальными настройками рекомендую ознакомиться в документации. Остановлюсь на двух из них, весьма интересных.Первое. Last will. Буквально на русском языке — «завещание» (сетевые граждане такие юмористы!). Если выполнить эту настройку, то клиент при подключении к брокеру передает и ее. В случае «отвала связи» клиента, брокер автоматически разошлет это завещание всем участникам обмена. «Завещание» является таким же сообщением, у него так же задается топик и текст.Второе. Возможность шифрования трафика. Для общего тестирования можно обойтись и без него. В продакшене — ни в коем случае. Выставив поле activateSecureConn в настройках необходимо провести еще ряд манипуляций — активировать глобальные настройки безопасности проекта, импортировать сертификат брокера, создать сертификат контроллера и так далее. Вопросы зашифрованного соединения я уже поднимал в заметке про OPC UA коммуникации. В целом же действия тут больше напоминают настройки безопасного соединения для Open User Communications (SecOUC). В настоящем примере вопросами безопасности передаваемых данных я пренебрегаю. Подробности настройки описаны все в той же документации.Закончив настройки, необходимо убедиться, что все работает, как надо. Для начала, конечно же, просто подпимем соединение с удаленным брокером. Для этого достаточно подать истину на вход enable функционального блока LMQTT_Client: Как видно, при поданном enable выходные биты tcpEstablished и mqttEstablished содержат «истину», это означает, что связь установлена успешно. В процессе испытаний я обнаружил интересное поведение блока, а именно — при подачи «истины» на вход enable подтверждение связи появлялось на одну-две секунды и пропадало. Связь устанавливалась только со второй попытки. Кроме того, при физическом обрыве связи этот ФБ просто информирует об отсутсвии соединения, и не предпринимает попыток автоматически пересоединиться. В целях автоматического соединения и пересоединения добавлен следующий нетворк: Смысл следующий — если в течении 5 секунд установлен флаг запроса связи, но нет подтверждения, снять флаг запроса связи. И если флага запроса нет в течении 5 секунд, установить флаг запроса. В тепличных условиях лаборатории это прекрасно работает. В полевых условиях при нестабильной связи временные константы желательно скорректировать.В данном примере предполагается, что контроллер не только отправляет какую-либо информацию брокеру, но и подписан на топик. Точнее, даже на два топика, чтобы пример был интереснее. В качестве принимаемой информации может быть, что угодно — команды, уставки, запросы архивной информации или состояния оборудования. В принципе, все ограничивается исключительно объёмом свободной рабочей памяти. Вполне логичным будет подписаться на нужные топики сразу после установления связи. И для этого потребуется поиграть с полями структуры subscribeToTopic, которую лучше все воспринимать, как «управляющую» структуру. По переднему фронту (то есть, по единомоментному факту) установления соединения я поднимаю локальную битовую переменную #SubscriveToTopics и выставляю «номер шага» процедуры подписки в 1. Номер шага используется в связи с тем, что все операции у нас ассинхронные, и их надо выполнять последовательно, одну за другой, а не все сразу (все сразу не выполнятся).Первый шаг подписки — подписаться на топик с названием «global». В случае успешного выполнения операции подписки переходим на следующий шаг. Иначе выполняем процедуру переподключения (хотя, реакция может быть иной, на усмотрение разработчика) Смотрим. Если выставлен бит «выполняем подписку» и шаг = 1, то……если не выставлен бит управляющей структуры «подписатся», то задать имя интересующего топика (global) и поднять бит управляющей структуры «подписаться»…если бит управляющей структуры «подписаться» поднят, то смотреть на биты выполнения задания done и error. При появлении бита done сбросить бит управляющей структуры «подписаться» и перейти на шаг №2. В случае возникнования ошибки — выполнить переподключение к брокеру.Шаг №2. На этом шаге не нужно делать вообще ничего. Этот шаг требуется для того, чтобы ФБ клиента вызвался хотя бы один раз со сброшенным битом управляющей структуры «подписаться». Для этого есть и более изящные решения, но я обошелся простейшим таймером. После 100мс ожидания просто идем на следующий шаг, к подписке на второй топик (шаг №3). Шаг №3 аналогичен шагу №1, за исключением имени топика. После успешного завершения шага №3 сбрасывается локальный бит «выполнить подписку» (#SubscriveToTopics) и обнуляются шаги «подпрограммы подписки».После выполнения подписки можно смело проверять работу клиента. Для этого я вызываю программу mosquitto_pub.exe: mosquitto_pub.exe -h myhost.mydomain.ru -t global -m «kill all humans»
Как видно, в топике global прошло сообщение «kill all humans»Флаг newMessageReceived нам еще пригодится в дальнейшем. Этот флаг выставляется сразу по получению нового сообщения и действителен в течении одного цикла сканирования. По нему очень удобно будет обрабатывать полученные команды, уставки или запросы.Вторая задача контроллера в этом примере — отправлять информацию о технологическом процессе через равные промежутки времени. Например, каждые сутки. Или каждые два часа. Ну, или каждые 10 секунд, потому что в учебном примере не очень хочется терять время на пустое ожидание. Поэтому каждые 10 секунд я поднимаю локальный флаг «отправить данные» и выставлю шаг «подпрограммы отправки» в 1: Нетворк отправки данных для разнообразия написан на SCL, а не нарисован в LAD. Право же, оперировать строками в графических языках — не самое удобное дело. Всего отправляется значение 4 переменных, три из которых заданы статично в блоке данных, а одна — постоянно увеличивается на небольшую дельту. На первом шаге «подпрограммы» задается имя топика, это имя personal0. А так же формируется строка сообщения. Поскольку оперируем мы именно символьными данными, приходится выполнять преобразование типа REAL_TO_WSTRING и конкатенацию строк. Для контроллеров, тем более, начального уровня, это не самое лучшее занятие — очень быстро расходуется память и неплохо так съедаются вычислительные ресурсы. Длина передаваемого сообщения — 500 символов, есть куда развернуться. Можно, так же, добавить еще и метку времени. Можно формировать буфер сообщений, тем самым аккумулируя хотя бы минимум данных на период отсутствия связи. В общем, тут можно делать, что угодно (но лучше делать, что написано в ТЗ).После формирования строки поднимается бит управляющей структуры «отправить сообщение» и меняется номер шага. На втором шаге идет проверка успешности или неуспешности отправки, после чего сбрасывается локальный бит «выполнить отправку» и сбрасывается номер шага «подпрограммы отправки».Запустим клиент MQTT и посмотрим, что приходит в топике personal0 (именно в этот топик ПЛК и отправляет данные): Ну, и напоследок. Демонстрация возможностей удаленного управления. Если в топике personal0 пришло сообщение exterminate, дискретный выход Q0.0 устанавливается в значение «истина».Команда издателя: mosquitto_pub.exe -h host.domain.ru -t personal0 -m «exterminate»
Проверка пришедшего сообщения выполняется только по факту прихода самого сообщения (бит newMessageReceived), что вполне логично. А далее необходимо только проверять имя топика и текст сообщения. Любые дальнейшие действия программируются, как угодно.На этом технический пример заканчивается, и хочется немного порассуждать о возможностях применения. Они есть, и, кажется, весьма широкие. Фактически, это можно применять в любых распределенных недорогих системах, где присутствуют малые объемы информации и, в силу этого, использование специализированных «телемеханических» протоколов нецелесообразно в виду их высокой стоимости. Ну, например, в ЖКХ. Если маленький ПЛК смотрит на расход энергоресурсов (общедомовых, а, может, даже и поквартирных) и раз в сутки отправляет сводку в диспетчерский центр. Или смотрит на состояние общедомового оборудования, шлет параметры раз в час, но при аварии — моментально. Достаточно лишь снабдить ПЛК GSM-модемом, и фактически, ничего больше не требуется, кроме простого компьютера с фиксированным ip-адресом. Рассуждая дальше, можно и без физического ПК обойтись, засунув его «в облако». Главное, не забыть должным образом настроить шифрование трафика. В этом случае имеет смысл данные потребления энергоресурсов из клиента сразу складывать в базу данных, но это уже требует высокоуровневого программированияИли, как вариант, та же распределенная система, но не только сбор данных, но и взаимодействие M2M (контроллер-контроллер). Тут точно так же, достаточно минимального канала связи и доступного брокера.Можно даже и на скаду информацию выводить, не особо заморачиваясь с программированием серверной (брокерской) части. Ведь ничто не мешает настроить все полевые контроллеры на отправку сообщений брокеру, взять еще один контроллер, читать эти сообщения и их результат раскладывать по блокам данных, и уже из них выводить показания на тот же WinCC Advanced.Дальнейшие исследование показали отличное применение mqtt совместно со средой Node-RED. На Node-RED была "нарисована" программа, принимающая эти данные от брокера, разбирающая полученную строку и записывающая всю информацию (метку времени, значение) в базу данных MariaDB. Она же, программа на Node-RED позволила вытаскивать информацию за указанный временной промежуток, показывать ее в виде таблицы, графика и делать выгрузку в виде .csv файла. =========== Источник: habr.com =========== Похожие новости:
Промышленное программирование ), #_internet_veschej ( Интернет вещей ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 09:28
Часовой пояс: UTC + 5