Распределённый ПЛК без шкафов автоматики

от автора

Cобираем АСУ ТП на 4diac FORTE, PostgreSQL и FUXA SCADA

INSOL-1000 в сборе: центральный модуль с OLED и пять модулей расширения на DIN-рейке

INSOL-1000 в сборе: центральный модуль с OLED и пять модулей расширения на DIN-рейке

Insol-1000 в сборе: центральный модуль с OLED и с модулями расширения на DIN-рейке.

Insol-Node-10-220.

 

 Классическая АСУ ТП — это шкаф с центральным контроллером в операторной, к которому стягиваются километры кабелей с полевых датчиков. Это работает, но дорого, неудобно при расширении и плохо ложится на современные объекты, где «полевая» часть размазана по большой территории. Стандарт IEC 61499 в этом месте предлагает другую модель: программа описывается как сеть функциональных блоков, и одна и та же программа распределяется сразу по нескольким независимым устройствам в сети — без центрального ПЛК.

В этой статье я покажу, как это выглядит на практике. Соберём небольшую распределённую систему на двух устройствах: ПЛК INSOL-1000 (FreeRTOS, STM32H) занимается полевым уровнем — опрашивает дискретные входы, считает 4–20 мА, рулит OLED-дисплеем; шлюз INSOL Node (Linux) — это «верх» с PostgreSQL, встроенным OPC UA сервером и SCADA-платформой FUXA. Между ними — UDP multicast по схеме PUBLISH/SUBSCRIBE. Среда разработки одна — 4diac IDE, runtime один — 4diac FORTE, программа одна, но разрезанная между устройствами.

TL;DR

•             4diac — open-source реализация IEC 61499 от Eclipse Foundation. IDE + лёгкий C++ runtime FORTE.

•             Логика — это сеть функциональных блоков (FB), соединённых по событиям и данным. Блоки выполняются только при получении события — никаких циклов сканирования в стиле классического IEC 61131-3.

•             Программа описывается один раз, потом распределяется на нужные устройства через маппинг. Деплой — по сети, в RAM устройства; для автономной работы создаётся *.fboot файл, который runtime подхватывает при старте.

•             Сетевая интеграция между устройствами — через блоки PUBLISH_N / SUBSCRIBE_N (UDP multicast). Без брокера, без центрального сервера.

•             На INSOL Node поверх этого готово работает PostgreSQL (архивирование), OPC UA-сервер (для SCADA и MES) и FUXA — веб-SCADA с редактором мнемосхем прямо в браузере.

Дальше — как это собрать с нуля.

Часть 1. Что такое IEC 61499 и чем он отличается от привычного IEC  61131

Если коротко: классический IEC 61131-3 — это про сканирующий цикл одного устройства. Программа лежит в одном контроллере, циклически читает входы, считает логику, пишет выходы. Когда нужно «разнести» систему — между ПЛК ставятся отдельные шлюзы, Modbus-мосты и прочее склеивающее железо.

IEC 61499 переворачивает модель:

•             Программа независима от железа. Сначала вы описываете всё приложение целиком — как сеть функциональных блоков. На каком устройстве что будет выполняться — решается позже, в System Configuration.

•             Событийная модель. У каждого блока есть отдельные входы для событий (тонкие красные линии в редакторе) и для данных (синие линии). Блок исполняется в тот момент, когда на событийный вход пришёл триггер — не раньше и не позже. Цикл опроса организуется явно — обычно блоком E_CYCLE с заданным периодом.

 

•             Распределение приложения. Через маппинг одна и та же сеть блоков «разрезается» между устройствами. Часть блоков уезжает на INSOL-1000, часть — на INSOL Node.

•             Прямая связь между устройствами. PUBLISH/SUBSCRIBE — это UDP multicast: издатель льёт пакеты на групповой адрес, подписчики ловят. Никакого центрального брокера, никакого посредника.

Распределение одного приложения по нескольким устройствам — классическая иллюстрация IEC 61499

Распределение одного приложения по нескольким устройствам — классическая иллюстрация IEC 61499

Application Model описывается как сеть FB. System Model — устройства и сеть. Маппинг кладёт FB на устройства.

Где это особенно полезно: распределённые объекты — нефтегазовая телеметрия, ЖКХ, протяжённые объекты вроде водоканалов, фабрики с разбросанной по корпусам автоматикой. Всё, где централизованный шкаф управления — это либо длинные дорогие кабельные трассы, либо вообще нерешаемая задача.

Важный нюанс: UDP не гарантирует доставку. Для критичных управляющих сигналов нужна триггерная схема с подтверждением — SUBSCRIBE отправляет назад «эхо», PUBLISH повторяет, если эхо не пришло за таймаут. Это вы строите сами поверх стандартных блоков. Для телеметрии/архивирования штатного multicast обычно достаточно.

Часть 2. Что в наборе

Аппаратная часть для примера:

Устройство

Роль

Платформа

Runtime

INSOL-1000

Полевой ПЛК — DI/DO/AI/AO, RS-485, OLED

STM32H, FreeRTOS

4diac FORTE как отдельный поток внутри FreeRTOS

INSOL Node

Шлюз — БД, OPC UA, SCADA, web

Linux

4diac FORTE на Linux

INSOL-1000 — модульный ПЛК с шиной I-BUS: к базовому модулю слева цепляются модули питания, справа — модули расширения (I1001 8DO, I1002 8DI, I1003 / I1004 аналог 4–20 мА с HART, I1005 для термопар/RTD). Между ПЛК в сети — однопарный Ethernet 10BASE-T1L (до 1500 м между устройствами, скорость 10 Мбит/с, питание PoDL прямо по той же витой паре).

Структура распределённой системы: от полевого 10BASE-T1L снизу до SCADA/MES сверху

Структура распределённой системы: от полевого 10BASE-T1L снизу до SCADA/MES сверху

Полевой уровень распределяется прямо по объекту. На верхнем уровне — обычная Ethernet/Gigabit-сеть до SCADA.

В этой статье сеть нас интересует постольку-поскольку — всё, что нужно знать, что устройства просто находятся в одном сегменте Ethernet сети.

Из софта:

•             4diac IDE — на ПК разработчика. Сборка от Insol лежит на их сайте, основана на Eclipse, в неё уже добавлены .fbt-типы под Insol-Node и Insol-1000 — иначе пришлось бы вручную подкладывать библиотеку.

•             4diac FORTE — прошитый на устройствах runtime. На INSOL-1000 — внутри FreeRTOS, на INSOL Node — поверх Linux. Поддерживает все элементарные типы IEC 61131-3 рев. 2, базовые/составные/интерфейсные FB, адаптеры, online-реконфигурацию приложений без остановки.

•             На INSOL Node поверх FORTE работает экосистема верхнего уровня: PostgreSQL, OPC UA сервер (open62541), Modbus TCP клиент (libmodbus), и FUXA SCADA.

Качаем дистрибутив 4diac IDE и тестовый проект с insolsoft.ru → «Техподдержка» → «ПО 4diac». Тестовый проект — это .zip с уже готовой структурой Type Library (блоки INSOL_IO, I1000_4_20MA_IN/OUT, I1000_DISPLAY, I1000_PID, SQL_SET_*, SQL_GET_VAL) и парой Application-схем. Дальше — раскручиваем по шагам.

Часть 3. Подготовка устройств через web-интерфейс

Прежде чем запускать IDE, нужно подготовить устройства. У обоих — встроенный web на стандартных портах.

3.1. INSOL-1000: проверка прошивки и алиасы каналов

Открываем http://192.168.0.132 (адрес виден на встроенном OLED). В разделе «Прибор → О системе» — текущая версия прошивки. Если она старее, чем на сайте — обновляем через web. Если web-интерфейс не отзывается — есть аварийный режим: удерживаем две вертикальные кнопки на лицевой панели до подачи питания, тогда контроллер стартует в bootloader.

Дальше — самое важное: алиасы каналов. Алиас — это понятное имя физического канала, которое потом будет указываться в параметре PARAMS функциональных блоков IB / QB / IW / QW в 4diac. Это удобно: вы пишете ‘ain0’ вместо адреса вида «addr:0,channel:1», и эти же алиасы используются всеми верхнеуровневыми компонентами — PostgreSQL, OPC UA, FUXA.

Таблица алиасов каналов FORTE в web-интерфейсе INSOL-1000

Таблица алиасов каналов FORTE в web-интерфейсе INSOL-1000

Веб-интерфейс 1000 «Таблица идентификаторов каналов FORTE». Каждому физическому каналу даётся короткое имя, под которым он будет виден из 4diac.

Алиас

Блок 4diac

Физика

di0 … di7 (din0…din7 в новой прошивке)

IB (input bit)

Дискретные входы

do0 … do3 (dout0…dout3 в новой прошивке)

QB (output bit)

Дискретные выходы

ain0 … ain2

IW (input word)

Аналоговые входы 4–20 мА

aout0

QW (output word)

Аналоговый выход 4–20 мА

Алиасы чувствительны к регистру. Значение в PARAMS блока должно совпадать с web-интерфейсом байт в байт — ‘AIN0’ и ‘ain0’ это разные каналы, и runtime молча подсунет «не тот». В разных прошивках префиксы могут отличаться (di0/din0, do0/dout0) — сверяйтесь с тем, что реально показано в таблице.

3.2. INSOL Node: запуск сервиса FORTE

Тоже web-интерфейс. Идём в раздел Forte → Сервисы Forte 3, нажимаем «Добавить сервис», задаём порт (в примере 60001), выбираем сборку (на первый запуск — заводская, например test31). На первом запуске оставляем Forte bootfile пустым — иначе при старте FORTE подхватит старую программу из .fboot и проигнорирует то, что вы хотите задеплоить из IDE.

Запускаем сервис кнопкой ▶. Всё — устройства готовы принимать программу.

Устройство

IP

Порт MGR

INSOL Node

192.168.0.176

60001 (задаётся при создании сервиса)

INSOL-1000

192.168.0.132

61499 (фиксированный)

Часть 4. Проект в 4diac IDE

Создаём проект: File → New → 4DIAC Project, имя test33, выбираем рабочую папку — Finish. В System Explorer появляется дерево проекта с пустым System и Type Library.

4.1. Подкладываем библиотеку блоков INSOL

В Type Library создаём подпапки 1000, inode, userblock и складываем туда .fbt файлы. В сборке IDE от Insol они уже включены, но если вы ставили оригинальный 4diac с eclipse.dev, придётся скачать библиотеку отдельно с insolsoft.ru в рамках предложенного дистрибутива.

System Explorer с разложенной библиотекой блоков

System Explorer с разложенной библиотекой блоков

Type Library проекта test33: папка 1000 — блоки для контроллера (I1000_4_20MA_IN/OUT, I1000_DISPLAY, I1000_PID, INSOL_IO), папка inode — блоки для шлюза (SQL_GET_VAL, SQL_SET_*), userblock — место для своих блоков. Внизу — стандартные библиотеки 4diac 3.1.0.

Минимальный набор для нашего демо:

•             В 1000/: INSOL_IO, I1000_4_20MA_IN, I1000_4_20MA_OUT, I1000_DISPLAY, опционально I1000_PID

•             В inode/: SQL_SET_BOOL, SQL_SET_INT, SQL_SET_REAL, SQL_SET_LONG, SQL_SET_STRING, SQL_GET_VAL

•             В userblock/ — пока пусто, сюда положим свой кастомный блок чуть позже.

4.2. System Configuration — где какое устройство

Дважды кликаем на System. Правой кнопкой → New Device для каждого из двух устройств. Задаём имена и MGR_ID:

Имя в проекте

Тип устройства

MGR_ID

node

INSOL Node

192.168.0.176:60001

PLC132

INSOL-1000

192.168.0.132:61499

С этого момента IDE знает, кто на проводе, и может туда деплоить.

4.3. Application для INSOL-1000

Создаём Application с именем PLC132 — это сеть блоков, которая поедет на полевой контроллер(Insol-1000). Ключевые элементы схемы:

•             INSOL_IO — обязательно первый блок. Инициализирует шину I-BUS. Параметр QI = 1 (включено). Все остальные I/O-блоки запустятся только после события CNF от INSOL_IO.

•             E_CYCLE (DT = T#50ms) → IB (PARAMS = ‘di0’ … ‘di3’) — циклический опрос дискретных входов с периодом 50 мс. Каждый IB отдаёт на выходе OUT булеву переменную текущего состояния входа.

•             IW (‘ain0’ … ‘ain2’) → I1000_4_20MA_IN → F_REAL_AS_WSTRING → I1000_DISPLAY — аналоговые входы 4–20 мА, перевод в REAL (масштабирование), форматирование в строку и вывод на OLED.

•             QB (‘do0’ … ‘do3’) — дискретные выходы.

•             I1000_4_20MA_OUT → QW (‘aout0’) — аналоговый выход 4–20 мА. Уставка для него приходит сверху от INSOL Node.

•             PUBLISH_3 (ID = «239.0.0.1:13201») публикует три значения ain0..ain2 в multicast.

Полная схема Application PLC132

Полная схема Application PLC132

Application PLC132: INSOL_IO инициализирует I-BUS, E_CYCLE крутит опрос, аналоговые входы идут через масштабирование на OLED, дискретные выходы — на полевые реле. SUBSCRIBE_1 ловит уставку aout0 с верхнего уровня.

Адрес 239.0.0.x — это IANA-зарезервированный диапазон для административно-локального multicast, рутер за пределы локального сегмента такие пакеты не выпустит. Порт можно выбирать любой свободный — в примере 13201 для аналога, 13202 для обратного канала.

4.4. Applications для INSOL Node

На стороне Node делаем два Application — для разделения по смыслу:

Node1 — приём аналоговых значений и публикация уставки:

•             SUBSCRIBE_3 (ID = «239.0.0.1:13201») ловит то, что опубликовал PLC132. На каждое полученное событие IND выходят три значения RD_1..RD_3.

•             SQL_SET_REAL (по одному на каждый канал, параметр NAME = ‘ain0’, ‘ain1’, ‘ain2’) пишет значения в PostgreSQL. Если переменная в БД ещё не существует — она будет создана автоматически при первом вызове. Если задать HIST = TRUE, блок начнёт ещё и архивировать историю в tag_archive.

•             Обратный путь: E_CYCLE (T#1s) → SQL_GET_VAL (NAME = ‘aout0’) → F_STRING_AS_REAL → PUBLISH_1 (ID = «239.0.0.1:13202»). Раз в секунду читаем уставку из БД (туда её положит оператор через FUXA), конвертируем строку в REAL и публикуем в сеть. PLC132 подписан на этот же multicast и применит её к aout0.

Application Node1

Application Node1

Node1: верхняя ветка — SUBSCRIBE_3 ловит ain0..ain2 и складывает в PostgreSQL через SQL_SET_REAL. Нижняя ветка — E_CYCLE раз в секунду читает уставку aout0 из БД и публикует её обратно в сеть.

Node2 — приём дискретных сигналов: SUBSCRIBE_4 (ID = «231.0.0.1:60002») → SQL_SET_BOOL для di0..di3. Отдельный multicast-канал для дискретки.

4.5. Маппинг и деплой

Возвращаемся в System Configuration. Перетаскиваем(маппим) PLC132 Application на устройство PLC132, Node1 и Node2 — на node. Элементы окрашиваются в цвет соответствующего устройства. Это и есть маппинг.

Дальше — Online → Connect to System. Если устройства живы и порты совпадают, индикаторы у обоих горят зелёным. Жмём Deploy → Start (▶). Программа улетает в RAM устройств. С этого момента IDE в Online-режиме показывает текущие значения на каждой линии связи в реальном времени — это, пожалуй, самая удобная штука в 4diac: вы буквально видите, как событие пробежало по схеме и какие данные где сейчас лежат.

Пока программа в RAM — после reboot устройства её там не будет. Это нормальный режим отладки. Финальное развёртывание — через Boot-файл, разберём ниже.

Часть 5. Кастомный блок: ST-алгоритм, отладка, экспорт в C++

Базовых блоков обычно не хватает, и стандарт позволяет писать свои. Типов несколько: Basic FB (с алгоритмом на ST и собственным конечным автоматом — ECC), Composite FB (собранный из других FB), Service Interface FB (для нативного взаимодействия с runtime — обычно C++), Simple FB. Самый частый случай — Basic FB.

Сделаем учебный блок NewBlock, который принимает три REAL и возвращает их сумму, среднее, минимум и максимум.

5.1. Интерфейс блока

Правой кнопкой на Type Library/userblock → New → Basic Function Block. Имя — NewBlock. Во вкладке Interface:

•             Входное событие: REQ, с ассоциированными переменными ri1, ri2, ri3 (тип REAL).

•             Выходное событие: CNF, с переменными rmin, rsumm, rmax, rmidl (тип REAL).

5.2. Алгоритм на ST

Создаём алгоритм MATH2 (вкладка Algorithms). Реальный код, который попадает в кодогенерацию FORTE:

Алгоритм MATH2 в редакторе 4diac IDE

Алгоритм MATH2 в редакторе 4diac IDE

ST-редактор 4diac IDE с алгоритмом MATH2. Все типы констант указываются явно (INT#0, REAL#3.0) — это конвенция IEC 61131-3, FORTE на ней настаивает.

Структурированный текст здесь — обычный IEC 61131-3 рев. 2. Полная спецификация — на сайте PLCopen, конкретные ограничения runtime FORTE — в eclipse.dev/4diac/doc.

5.3. ECC — конечный автомат блока

Во вкладке ECC рисуем минимальный автомат с двумя состояниями:

•             START (начальное) — пустое, ничего не делает.

•             State — выполняет MATH2 и эмитит CNF.

Переходы:

•             START → State по событию REQ.

•             State → START по безусловному условию 1 — то есть сразу после выполнения алгоритма возвращаемся в начальное состояние, готовы ловить следующий REQ.

Рис. Диаграмма ECC

 

5.4. Отладка локально

Самое полезное в 4diac IDE — это локальная отладка FB без устройства. Правый клик по типу блока в дереве → Debug As → 1 Debug FB Type запускает runtime прямо на машине разработчика и подключает блок к нему.

Режим отладки в 4diac IDE: ST-код, переменные и значения в реальном времени

Режим отладки в 4diac IDE: ST-код, переменные и значения в реальном времени

Тот же MATH2 в режиме отладки: точка останова на END_ALGORITHM, в Variables справа видны живые значения ardata = [11.0, 23.4, 32.1], maximum = 32.1, middle = 22.166666. Слева внизу — FB Debug с панелью входов и выходов блока: ri1 = 0.0, ri2 = 11.0, ri3 = 23.4 → rmin = 11.0, rsumm = 66.5, rmax = 32.1, rmidl = 22.166666.

Что доступно:

•             Watch Variables — текущие значения всех переменных блока. Любую можно вручную поменять «на лету».

•             Force Event — отправить REQ руками и посмотреть, что блок выдаст на CNF. Без всякого внешнего железа.

•             Точки останова на переходах ECC — выполнение приостанавливается на переходе, пошагово смотрим, что и почему сработало.

•             Debug Stack — порядок вызовов алгоритмов и событий.

•             Подсветка текущего состояния ECC в реальном времени — то самое визуальное «глаза-смотрят-как-программа-бежит», ради которого многие в IEC 61499 и пришли.

5.5. Экспорт созданного модуля в C++ и сборка под Linux

Чтобы наш блок поехал на INSOL Node, нужно сгенерировать его C++ исходники и подложить в сборку FORTE на устройстве.

В IDE — правой кнопкой на NewBlock → Export, в визарде выбираем 4diac IDE → 4diac IDE Type Export, экспортер 4diac FORTE 3.x, целевая папка — рабочий каталог сборки. На выходе получаем два файла: NewBlock.cpp и NewBlock.h.

Дальше — web-интерфейс INSOL Node → Forte → Сборки Forte3 → выбираем активную сборку → Сборка. Включаем чекбокс рядом с NewBlock в списке «Использовать ФБ при компиляции», сохраняем, жмём «Компилировать». Статус сменится на «Скомпилирован» — это значит, что блок собран в новый бинарник FORTE и зарегистрирован в реестре типов. Перезапускаем сервис ▶ — и NewBlock теперь доступен в IDE наравне со стандартными библиотечными блоками. Можно перетаскивать на схему.

Часть 6. Верхний уровень: PostgreSQL → OPC UA → FUXA

Это та часть, ради которой INSOL Node, собственно, и существует. В типичном проекте АСУ ТП «верхним уровнем» обычно занимается отдельный сервер с разнородной обвязкой: лицензионная SCADA ( WinCC, MasterSCADA  и пр.), отдельный OPC-сервер вроде KEPServerEX, historian, СУБД, веб-сервер для удалённого доступа к HMI, плюс прослойка пользователей и прав, средства мониторинга, отчётный модуль. Каждый компонент — свой инсталлятор, своя лицензия, свой формат конфигурации, свой канал техподдержки. Половину времени проекта уходит на то, чтобы все эти кусочки начали разговаривать друг с другом.

INSOL Node — это всё то же самое, но в одной коробке, под одной web-консолью. На Linux-устройстве уже предустановлено и работает:

•             4diac FORTE runtime — собственно среда исполнения IEC 61499. То, ради чего мы и пришли.

•             PostgreSQL — встроенная промышленная СУБД. Переменные создаются автоматически блоками SQL_SET_*; ничего заранее настраивать не нужно. Архивные данные, журналы событий, конфигурации — всё здесь.

•             OPC UA сервер (open62541) — самый распространённый промышленный стандарт интеграции. Автоматически экспонирует всё, что есть в PostgreSQL. Поддерживает Historical Access — внешняя SCADA или MES получат и реальное время, и историю.

•             FUXA SCADA — open-source веб-SCADA/HMI. Редактор мнемосхем работает прямо в браузере, никакого Windows-клиента ставить не нужно. Доступ с планшета, телефона, любой машины в сети.

•             Modbus TCP-клиент (libmodbus) — для интеграции с полевыми устройствами сторонних производителей: частотными приводами, счётчиками электроэнергии, расходомерами и прочей классикой.

•             Web Server Insol-Node — единая web-консоль, в которой управляется всё сразу: пользователи и права доступа, сервисы FORTE и их сборки, настройки OPC UA, доступ к SCADA, отчёты, диагностика сети, обзор подключённых устройств.

Под капотом — open-source стек везде, где это возможно: PostgreSQL, open62541, FUXA, 4diac FORTE. Никаких подписок «$N за тег», лицензий на клиентские подключения, отдельных серверов историка. Один разовый платёж за железо — и интеграционный слой собран.

Что важно для проектировщика: компоненты уже сшиты между собой по реальным шинам, а не по бумажным схемам. Блок SQL_SET_REAL положил значение → PostgreSQL немедленно отдал его в OPC UA → подписанный клиент SCADA получил уведомление → точка на тренде нарисовалась. Все три шага происходят без вашего участия и без единой строчки кода.

Минимальный проект АСУ ТП, который раньше требовал сервера с Windows, SCADA-лицензии, KEPServerEX, отдельной СУБД и недели настройки сетки между ними — здесь собирается за пару часов и помещается в DIN-реечный модуль.

Дальше — что именно даёт каждый компонент.

 

6.1. PostgreSQL

В Node предустановлен PostgreSQL и небольшая обвязка над ним. Блоки SQL_SET_* сделаны так, что они сами создают переменную в БД при первом обращении — не нужно заранее лезть в psql и делать CREATE TABLE.

Список источников Insol NET — переменные PostgreSQL с живыми значениями

Список источников Insol NET — переменные PostgreSQL с живыми значениями

Раздел «Источники» в Insol NET: ain0..ain2 (Float, добавлены автоматически блоком SQL_SET_REAL), aout0 (Float, добавлен вручную как уставка), di0..di3 (Bool, тоже автоматически). Колонка «Обновлено» показывает реальный темп прихода данных.

Поддерживаемые блоки:

Блок

Тип

Что делает с HIST=TRUE

SQL_SET_BOOL

BOOL

Архивирует состояния дискретных сигналов

SQL_SET_INT

INT (16 бит)

Архив целых

SQL_SET_REAL

REAL

Архив трендов аналоговых измерений

SQL_SET_LONG

DWORD (32 бита)

Архив счётчиков

SQL_SET_STRING

STRING

Архив текстовых сообщений

SQL_GET_VAL

ANY → STRING

Чтение из БД по имени переменной

Обратите внимание: уставки оператора (то, что не приходит из 4diac, а вводится в SCADA) добавляются в БД руками — через web-интерфейс INSOL Node, который под капотом просто пишет в ту же таблицу. А потом 4diac читает их обратно через SQL_GET_VAL.

6.2. OPC UA — без настройки

Всё, что лежит в PostgreSQL, автоматически публикуется встроенным OPC UA сервером (open62541) на стандартном порту 4840. Пространство имён и политику безопасности можно подкрутить в web, но для старта достаточно дефолтов: Security Mode: None, endpoint opc.tcp://192.168.0.176:4840.

Архивные данные для переменных с HIST=TRUE отдаются через OPC UA Historical Access — это значит, что SCADA сможет рисовать тренды не только по «живым» данным, но и по истории.

6.3. FUXA — мнемосхема в браузере

FUXA — это open-source веб-SCADA/HMI на Angular (есть на GitHub: frangoteam/FUXA). Поддерживает OPC UA, Modbus TCP/RTU, MQTT, прямой коннект к PostgreSQL/SQLite/InfluxDB. На INSOL Node она уже установлена и запущена — открываем http://192.168.0.176:1881.

Шаги настройки выглядят так:

Подключение OPC UA. В режиме Editor → шестерёнка → Connections → + → OPC UA:

Name:         opcnode
Endpoint URL: opc.tcp://192.168.0.176:4840
Security:     None

Connect → статус Connected → Save.

Теги. В разделе Tags добавляем по тегу на каждую переменную, выбирая узлы из дерева OPC UA.

Дерево OPC UA в FUXA: переменные INSOL Node, готовые к привязке

Дерево OPC UA в FUXA: переменные INSOL Node, готовые к привязке

Browse Tags in Server в FUXA: под Objects → opcserver видны ain0..ain2 (Float, R, R) и aout0 (Float, R/W, R/W). Атрибуты доступа берутся прямо из OPC UA — FUXA понимает, какие переменные можно писать, а какие только читать.

Имя тега обычно совпадает с алиасом канала на INSOL-1000 — так проще трассировать:

Тег FUXA

Узел OPC UA

Тип

ain0, ain1, ain2

Objects → opcserver → ain0..2

Float

aout0

Objects → opcserver → aout0

Float (R/W)

di0..di3

Objects → opcserver → di0..3

Boolean

do0..do3

Objects → opcserver → do0..3

Boolean (R/W)

Мнемосхема. В Pages создаём страницу MainView. Из палитры тянем элементы:

  • Gauge для ain0 — диапазон 4..20 (если в «сырых» миллиамперах) или 0..100 (в физических единицах, если конвертация уже сделана на стороне 4diac). Цветовые зоны зелёная/жёлтая/красная — норма/предупреждение/авария.

  • Switch для do0. Поскольку тег R/W, при клике FUXA пишет новое значение в OPC UA. Дальше оно попадает в PostgreSQL, оттуда SQL_GET_VAL забирает его на INSOL-1000 и переключает физический выход. Логически — обычное «нажал кнопку — лампа загорелась», но цепочка под капотом длинная: браузер → OPC UA → БД → FORTE на Node → publish → subscribe → FORTE на PLC132 → QB → реле.

  • Chart для трендов. Источник — либо OPC UA Historical Access (если переменная заведена с HIST=TRUE), либо встроенный DAQ в FUXA (она сама может писать значения тегов в SQLite и строить тренды из него). Второе удобнее, когда нужен быстрый дашборд без перенастройки 4diac.

Готовая мнемосхема в FUXA: три gauge с живыми значениями + цифровой индикатор aout0

Готовая мнемосхема в FUXA: три gauge с живыми значениями + цифровой индикатор aout0

Финальный вид мнемосхемы в режиме просмотра. aout0 = 4.589 mA — это уставка, заданная оператором; ain0..ain2 — аналоговые входы с физического INSOL-1000. Цветовые зоны 4..20 мА с переходом красный/жёлтый/зелёный.

Сохраняем (Save), переключаемся в режим View. Частота обновления — по умолчанию 1 секунда, настраивается per-tag. Готовую мнемосхему можно открыть напрямую по http://192.168.0.176:1881/lab — например, с планшета в полноэкранном режиме.

Часть 7. Boot-файл — переходим в режим «работает само»

Пока мы всё деплоили в RAM. Чтобы система оживала сама после reboot устройства, нужен *.fboot файл. XML структура описывающая все используемые блоки в проекте и связи между ними

В IDE: правой кнопкой на Application → Create Boot File. Для каждого устройства генерируется свой .fboot. Дальше:

  1. INSOL-1000: web-интерфейс → «Сервисы» → загружаем *.fboot для PLC132.

  2. INSOL Node: настройки сервиса 4diac FORTE → в поле Forte bootfile выбираем загруженный *.fboot для node, включаем «Автозапуск».

  3. Перезагружаем оба устройства.

Runtime при старте обнаруживает .fboot и поднимает приложение. Подключение IDE больше не требуется — система автономна.

На этапе отладки всегда удаляйте Boot-файл с устройства перед очередным Deploy. Иначе FORTE поднимется с .fboot-версии, проигнорирует только что задеплоенную из IDE, и вы будете долго ловить «фантомные» отличия.

Часть 8. Что в итоге

Что получилось из коробки:

  • Распределённая система без центрального ПЛК. Полевая логика (опрос I/O, отображение на OLED, аналоговый выход) живёт на STM32H с FreeRTOS. Архив, SCADA и интеграционный слой — на Linux-шлюзе. Связь — UDP multicast в одном Ethernet-сегменте.

  • Одна программа на все устройства. Описана один раз в 4diac IDE, разрезается через маппинг. Online-отладка показывает значения на всех линиях схемы в реальном времени — без отдельных средств трассировки.

  • Стандартизованный верх. OPC UA сервер с историческим доступом, готовый к подключению любой нормальной SCADA или MES. FUXA встроена как референсный HMI, но никто не мешает подключить ту же условную МастерСкаду или WinCC.

  • Расширяемость через свои блоки. Удобный инструмент компиляции собственных наработок. Basic FB → ST → отладка локально → экспорт в C++ → сборка на устройстве → доступен в IDE. Цикл «придумал блок — встроил в библиотеку» — минут за двадцать.

Где это не серебряная пуля:

  • IEC 61499 всё ещё непривычен — инженеров, которые уверенно его читают, на порядок меньше, чем спецов по классическому 61131-3.

  • Multicast накладывает требования на сеть: managed-коммутаторы с поддержкой IGMP snooping, никаких «домашних» свитчей в продакшене.

  • Гарантированной доставки нет — для критичных сигналов управления вы строите свой ACK-протокол поверх PUBLISH/SUBSCRIBE.

  • Online-реконфигурация — мощная штука, но требует дисциплины: «горячую подмену» работающего алгоритма легко превратить в недокументированный инцидент.

Полезные ссылки

ссылка на оригинал статьи https://habr.com/ru/articles/1041066/