Как я проект в OpenSCADA сделал

в 11:20, , рубрики: linux, open source, scada, асу тп, бесплатная SCADA, Промышленное программирование

Речь в статье пойдет о той самой OpenSCADA, которая под Linux и с oscada.org.

Зачем:
• потому что SCADA на самом деле достойна внимания и популяризации;
• в некоторых малобюджетных или маленьких проектах просто безальтернативная;
• судя по статьям про АСУТП на хабре, многим читателям АСУТП представляется черной магией, недо-IT или чем-то похожим (ломают несчастный modbus, мучают WinCC, которая и так еле тарахтит… Люди читают и охают: «Как так можно…. дырявое ПО в промышленности», но никого не удивляет ломание Win95 и 6го ослика. Поломали бы LON шифрованный, OPC, OPC_UA…… А WinCC сама расшаривает папку с проектом с именем вида WinCC_Project_xxxxxx при первом открытии + это вы еще не видели как ее плагин к Excel может намертво винду подвесить при неаккуратной вставке ячеек чуть больше, чем он может за раз осилить!) – добавим ликбеза;

Как я проект в OpenSCADA сделал
Как вам такое?

Как я проект в OpenSCADA сделал
А такое?

Как я проект в OpenSCADA сделал
Индусы вообще не любят обрабатывать ошибки… Зачем, и та-а-ак сойдет…

Вообще, единственные, кто работает в Сименсе — это МЕНЕДЖЕРЫ. Им при жизни надо памятник ставить. С такими менеджерами программистам можно не напрягаться.

• хабр приносит пользу мне (в плане информации) – принесу хабру и я;
• избавится от read-only для участия в комментариях.

Для кого:
• для тех, кто не слышал про openSCADA да и вообще про OpenSource SCADA под Linux, но интересуется подобным;
• для тех, кто слышал, но все не было времени попробовать, дабы понять, нужно ли оно;
• для тех, кто открыл – посмотрел — не разобрался — закрыл;

Почему openSCADA:
• в данном проекте требовалось сэкономить;
• ТЗ не заставляло использовать что-либо конкретное;
• в данном случаем можно использовать связь с ПЛК по Modbus (например, если б требовалось передавать алармы с меткой времени ПЛК, то увы….).

Дано:
• парочка генераторов по полтора мегаватта;
• место оператора для управления всем этим;
• ПЛК B&R, связь со SCADA по ModbusTCP.

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

Должен сказать, что ее автор вполне грамотно подошел к задаче (даже получил второе высшее как программист, первое — электронщик). Использует CPP, Qt, svn и т.п. Т.е. самую свежую версию вы можете скачать и собрать, не дожидаясь оформления релиза. Отдельно надо сказать о обратной связи по багам. Заметили багу? Пишите на форуме в разделе «Отслеживание ошибок» и, вуаля, она исправлена. Конкретные примеры: от 40 минут до 4 часов, причем был случай и после 12 ночи. Можете исправить сами и Рома добавит. А теперь скажите, кто из гигантов производства, хотя бы промышленного ПО, делает хотя бы всего лишь на порядок дольше? Например MS для MS Project ……. М?

Вам недостаточно документации в wiki? Заходите на вики под своим форумным ником и дополняете.

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

Как я проект в OpenSCADA сделал

На первый взгляд, у openSCADA высок порог вхождения да и сам разработчик говорит, что ваш предыдущий опыт работы со SCADA вряд ли пригодится, но это только на первый взгляд. Все есть непонятно, непонятно называется, непонятно, как это работает. Документация не особо-то структурирована. Пример — результат поиска по сайту изобилует фразами «аргумент атрибута параметра»:

Как я проект в OpenSCADA сделал

Поэтому есть демо проект — AGLKS. C него и надо начать. Создать на его основе свой, расковырять составляющие, подсматривать как реализована та или иная фича. Я так и сделал: оставил корневую страницу и способ навигации по страницам.

image
Пример объяснения концепции взаимодействия внутренностей openSCADA

Составляющие openSCADA:
QTCfg – QT конфигуратор (сбор данных, вычисления, архивы);

Как я проект в OpenSCADA сделал

Vision – графический интерфейс пользователя («картинки»);

Как я проект в OpenSCADA сделал

QTCfg — БД

Как я проект в OpenSCADA сделал

Основа этой SCADA – базы данных, т.е. все проекты хранятся в БД. Может это и хорошо, но вот для простого «скопировать проект из папки Х на флешку» или «скопировать клапан с одного проекта в другой» не тривиально. В случае с БД SQLite вся база есть файлик и копировать из папки на флешку не сложно. А для PostgeSQL? С копированием графического элемента из одного проекта в другой задачка. Хотя никто не мешает вести библиотеку чего-либо в отдельной БД и в свой проект просто подключать нужный экземпляр. Все таблицы всех баз можно посмотреть и есть поле ввода SQL запроса, так что можете в табличном редакторе склеить запросы и массово что-то внедрить в свой проект вместо бесконечного тыкания мышкой.

QTCfg — Контроллер

Как я проект в OpenSCADA сделал

В сборе данных настройка связи с нашим ПЛК B&R проста: как часто опрашивать, modbus протокол (TCP/IP, RTU, ASCII), адрес транспорты, modbus-адрес нашего ПЛК B&R и тп. Стоит особенно отметить настройку «Максимальный параметр блока запроса» – это сколько регистров за раз запрашивать у нашего ПЛК. Некоторые устройства просто не отвечают, если запросить более некоторого количества. Например, этим «страдает» корректор газа ЕК-270, панель управления PCC3300 у двигателей Cummins.

Статус вполне информативен, особенно при проблемах связи – есть и текст, и код ошибки, легко обрабатывать в скриптах.

QTCfg — выходной транспорт MBTCP

Как я проект в OpenSCADA сделал

Настройка связи с ПЛК – как? Есть транспорты и есть транспортные протоколы. Куда? В транспортах есть Сокеты, в Сокетах Выходной и Входной транспорт. ModbusTCP вроде через сокеты, но в Транспортных протоколах есть Modbus.
Настройка связи с ПЛК находится в Транспорты – Сокеты – Выходной транспорт – ИмяМоегоТранспорта. Для modbusTCP конфигурация выглядит незатейливо. Всплывающая подсказка помогает.

В Статусе видим текущее состояние, особенно актуально при отладке, диагностике.

QTCfg – Modbus – диагностика

Как я проект в OpenSCADA сделал

Для сбора данных с нашего ПЛК B&R создали контроллер в разделе ModBUS. В Runtime на вкладке «Диагностика» наблюдаем обмен пакетами. Если ПЛК не отвечает – тут же видим причину.

QTCfg — Пользовательский протокол

Как я проект в OpenSCADA сделал

Пользовательский протокол – это вообще мега-фича openSCADA, открывающая ей двери много куда. В данном модуле вы можете описать свой протокол, который отсутствует в openSCADA. Например, те самые modbus-подобные с 32-битными регистрами и т.п. На картинке приведен пример протокола для теплосчетчика ВКТ-7 от Теплоком. Так что можете сами сваять в ПЛК свой modbus-подобный протокол с 64-битными регистрами, метками времени и шифрованием и в openSCADA реализовать его прием.

Более того, вы можете реализовать свой протокол на С++ как *.so и подключить как модуль в Сбор данных при сборке openSCADA. За пример можно взять модуль SNMP.

Свой механизм алармов как раз и хотим оформить как модуль в Сборе данных, а внутри использовать не массив (который не удобен для сортировки), а SQLite с работой в оперативке вместо файлов.

QTCfg — JavaLikeCalc

Как я проект в OpenSCADA сделал

Все пользовательские функции реализуются в разделе Сбор данных – JavaLikeCalc – Библиотека – ваша_библиотека. Вызов своих функций весьма коряв: SYS.DAQ.JavaLikeCalc[«lib_MyLib»][«MyFunc»], префикс «lib_» у имени библиотеки «MyLib» обязателен. Вариантов вызова функций два: статично прописываем имя функции в коде или динамично составляем имя в коде.

Отладка собственных функций через аналог printf() – просто пишете в Архив, что вам надо. Никаких «по шагам или breakpoint». Подсветка синтаксиса есть. Автообъявление переменных при первом использовании – будьте осторожны с очепятками – создаст новую переменную и в путь. В каждой функции есть объект this – ссылка на саму функции, например, можно в скрипте обращаться к атрибутам функции в цикле и т.п. Так же есть флаг f_start – флаг первого исполнения функции, туда удобно засунуть инициализацию или что-то подобное одноразовое.

QTCfg – Пример собственной функции prioritets на языке JavaLikeCalc

Как я проект в OpenSCADA сделал

Пример создания пользовательской функции. Язык – JavaLikeCalc (он же единственный). Входные/выходные переменные функции описываете в таблице IO. Порядок имеет значение: 1 строка = 1 переменная при вызове функции. Менять местами строки в IO можно.

Обращаться к тегам можно несколькими способами. В openSCADA вообще одно и то же можно сделать как минимум двумя способами. Доступ к тегу (атрибуту в терминах openSCADA) в коде можно осуществить так SYS.DAQ[«JavaLikeCalc»][LocalPLC][Local_Param][«myTag»].get(), где " JavaLikeCalc " – статично заданный модуль Сбора данных, "LocalPLC" — имя контроллера в модуле Сбора данных, заданный через переменную, " myTag " – статично заданное имя тега, get() – функция запроса значения тега.

В JavaLikeCalc синтаксис употребления встроенных функций таков: strMyTag.StrToInt()? где StrToInt() – функция конвертации текста в целое число, strMyTag – наша текстовая переменнаяю. Эта особенность синтаксиса употребления встроенных функций привела к тому, что в Vision доступ к свойствам объекта осуществляется не через точку (MyObject.property1), а через нижнее подчеркивание (MyObject_property1), что значительно снижает читабельность, поскольку "_" в именах тегов используется вместо пробела.
Еще пример синтаксис: this[«pgCont»].attrSet(«geomY»,soOff).attrSet(«geomH»,this[«pgCont»].attr(«geomH»)+soSize)

QTCfg – исполнить функцию

Как я проект в OpenSCADA сделал

Вкладка «Исполнить» позволяет проверить свою функцию не отходя от кассы. Плюс покажет затраченное на выполнение функции время.

QTCfg – вызов стороннего приложения на JavaLikeCalc (на примере моей функции play_warn)

Как я проект в OpenSCADA сделал

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

QTCfg — SETS

Как я проект в OpenSCADA сделал

Для «локальных» тегов используем контроллер в разделе JavaLikeCalc. Контроллер назвали «LocVars», в нем создали а-ля группы тегов actions, calibrs, sets(«параметры» в терминах openSCADA). Эти параметры полезны и использованы неслучайно. С ними связан удобный механизм привязки графики к тегам в графическом редакторе Vision. Мы еще к этому вернемся. В поле «Поля данных» пишем имена наших «локальных» тегов. Эти теги сохраняют свои значения после перезагрузки компьютера.

QTCfg — SETS values

Как я проект в OpenSCADA сделал

Значения наших «локальных» тегов можно посмотреть и задать на вкладке «Атрибуты». В данном случае «sets» – это просто логическая группа тегов, а сами теги в терминах openSCADA – это атрибуты. Какая SCADA позволяет подобное в столь же простой форме?

QTCfg — actions

Как я проект в OpenSCADA сделал

Нам для собственных нужд в SCADA нужны локальные теги. Пришлось создать контроллер и ему присвоить функцию. Фишка в том, что значения атрибутов (кои есть аналоги классических тегов) сохраняются при перезагрузке компьютера.

QTCfg — параметр G1

Как я проект в OpenSCADA сделал

Параметром зовется логическая единица с набором тегов. У нас деление по узлам и агрегатам. «Включен» – обрабатывается ли он в текущий момент, «Включать» – включать ли при запуске SCADA.

Конфигурация тегов и адресов в случае Modbus просто песня – это просто текст, который легко склеивается в табличном редакторе, легко правится в openSCADA. Например, по проекту у вас есть теги read-only, вы их оформили в регистры 30ххх. В openSCADA это выглядит как RI_b15:101:rw:TagName:TagComment. В таком случае на вкладке Атрибуты вы не сможете задавать значения тегов, хотя и прописали rw. Легким движением руки в любом блокноте заменам RI_ на R_ и у вас уже регистры 40ххх. В таком случае в можете задавать значения тегам на вкладке Атрибуты, что есть намного удобнее, чем вычислять бит в слове и лезть в modbus симулятор и задавать в десятичном виде. Если регистр 40ххх, но rw, то задавать значения на вкладке Атрибуты не сможете. RI_b15:101 – это 15 бит в 30101 регистре modbus.

QTCfg — параметр G1 — значения

Как я проект в OpenSCADA сделал

В Runtime очень просто наблюдать текущие значения тегов. Открываем вкладку «Атрибуты» требуемого параметра контроллера и наблюдаем, если регистр 40ххх и «rw», то и управляем – для отладки незаменимо. Попробуйте повторить подобное в WinCC или Citect …. Хотя в WinCC можно посмотреть значение тега, наведя на него мышку.

QTCfg — параметр G1 — архивация значений

Как я проект в OpenSCADA сделал

Конфигурация архивирования тега – поставить галку на вкладке «Архивация». Любой тег можно архивировать одновременно в различные архивы.
Что важно: информация в архиве СЖАТА (а не просто миллион строк вида timestamp|tagName|tagValue).

Структура файла:

image

Механизм последовательной упаковки значений:
image

Там еще куча тонкостей типа «жесткой сетки» и «времени высокого разрешения»…

QTCfg – архив сообщений

Как я проект в OpenSCADA сделал

Конфигурируем архив сообщений: будем хранить в БД, с категорией «LOG» (категория в данном случае просто префикс для фильтрации наших сообщений от системных), размер архива в часах.

QTCfg – архив сообщений – сообщения

Как я проект в OpenSCADA сделал

Посмотреть свои сообщения в своем архиве – вкладка «Сообщения» у соответствующего нашего архива.

Архив сообщений — папка и файл

Как я проект в OpenSCADA сделал

Архив сообщений – текстовые файлы (вполне читабельные). Старые файлы закатываеются архиватором gzip согласно настройкам по архивированию сообщений.

QTCfg – архив трендов

Как я проект в OpenSCADA сделал

Конфигурируем тренды: храним на файловой системе (рекомендация Ромы), как часто считывать значения, как часто в архив записывать, путь для файлов-архивов, размер архива в часах и т.д.

QTCfg – архив трендов – значения

Как я проект в OpenSCADA сделал

Посмотреть значения архива значений можно тут же на вкладке «Архивы». Есть возможность экспорта в файл *.CSV или *.WAV.

QTCfg – архив трендов – график

Как я проект в OpenSCADA сделал

Архив трендов на графике не отходя от кассы – не вопрос. Размеры изображения графика можно менять.

QTCfg — конфигурация алармов

Как я проект в OpenSCADA сделал

Поскольку в openSCADA нет алармов в классическом понимании SCADA систем (вместо них Рома придумал нарушения – некая абстракция не пойми чего, уровень нарушений задается программистом проекта в момент формирования нарушения и не говорит ни о чем), пришлось создать свой механизм. Создали отдельный контроллер на JavaLikeCalc и задали ему мониторить значения нужных тегов на предмет алармов и формировать список активных алармов.

QTCfg — нарушения

Как я проект в OpenSCADA сделал

Встроенный механизм «проговаривания» нарушений (нарушения у openSCADA – это некая абстракции в сторону алармов). Отсюда взяли команду для проигрывания файлов для собственного механизма озвучивания алармов.

QTCfg – синтез речи

Как я проект в OpenSCADA сделал

Надо отметить: встроенный механизм «алармов» openSCADA позволяет проговаривать текст сообщения движком tts. Установите tts с русским языком – встроенные «алармы» (т.е. нарушения) заговорят на русском.


Vision-разработка

Как я проект в OpenSCADA сделал

Переходим к графике. Для этого используется «вторая половина» openSCADA – Vision.

QTCfg – Vision

Как я проект в OpenSCADA сделал

Настройка Vision из QTCfg: задаем с каким пользователем откроется Vision в разработке и в Runtime графический интерфейс пользователя, какой проект запускать в Runtime.

Vision-разработка — виджеты

Как я проект в OpenSCADA сделал

Виджет – это графическая единица (клапан, задвижка, генератор, поле ввода и даже целая страница).

Вкладка Виджеты – здесь находятся все виджеты, собранные в библиотеки. Это некая общая база хранения графических единиц.
Есть возможность в один виджет-страницу динамично в Runtime вставлять другие виджеты. Аналог WinCC-шных PictureWindow. Для этого на страницу надо поместить виджет и задать ему свойство «контейнер» и свойству группа дать какое-нибудь имя. Вставляемый виджет должен иметь ту же группу.

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

Vision-разработка – проекты

Как я проект в OpenSCADA сделал

А вот на вкладке Проект мы уже собираем скелет графической части нашего проекта из экземпляров библиотечных виджетов (набираем страницы и определяем навигацию по ним). В Проекте мы можем задавать персональные свойства библиотечным виджетам – например, виджет «окно с данными от цифрового мультиметра» – создаем 5 окон для пяти высоковольтных ячеек и привязываем к тегам соответствующих ячеек.

Vision-разработка — групповое изменение свойств

Как я проект в OpenSCADA сделал

Очень удобная опция: групповое изменение свойств нескольких объектов – выделили объекты и сразу всем задали.

Vision-разработка — text – аргументы

Как я проект в OpenSCADA сделал

У стандартного графического элемента «Text» есть очень полезная особенность – аргументы.

Таким образом, один элемент Text позволяет реализовать законченный форматированный элемент мнемосхемы вида «P = 32, кВт», где «P» – обозначение параметра, «32» – его значение (значение тега), «кВт» – единицы измерения. Т.е. динамически привязывает только значение тега, остальное уже есть. Формат прост: «P = %1, кВт» (вместо %1 будет значение тега).

Vision-разработка — рисование фигур

Как я проект в OpenSCADA сделал

Вот с рисование не очень. Рисование геометрических фигур возможно только в неком контейнере типа Box. Как видно на рисунке в поле Список элементов линии представлены в текстовом виде line(15.359|0.505):(15.359|22.915):::::::::::. Попробуйте угадать кто где … Но не так все грустно. Как видно на рисунке под меню файл есть кнопки для рисования прямых, кривых Безье, окружностей. А что грустно? Например, окружность задается по пяти точкам, а не привычным прямоугольником/квадратом.

Как я проект в OpenSCADA сделал

Меняя координаты любой из пяти точек прочее получить черти-что вместо того, что надо. Заливка цветом возможна только для замкнутого контура, т.е. обычный столбик с заливкой цветом от 0% до 100% реализуется контуром «прямоугольник» плюс «палка-поперечина», которая делит наш прямоугольник на две половины. Заливку ставим для одной половины нашего прямоугольника. Параллельно сдвигаем «палку-поперечину», меняя соотношение площадей половинок – меняется и площадь заливки. Т.е. сделать заливку круга – та еще задача. Короче рисовать надо приноровится, а иногда и изголиться. А вот в Citect с такого рода заливками проблем нет.

Как я проект в OpenSCADA сделал
Пример заливки в Citect

Нарисовать подобное в openSCADA целая задача.

Библиотечный виджет — sets – обработка

Как я проект в OpenSCADA сделал

Вот мы и подошли к самому интересному – связыванию графики на странице (да и вообще на любом виджете) с тегами (атрибутами в терминах openSCADA). Для открытия вышеуказанного окна надо дать фокус нашему виджету и нажать кнопку с гаечным ключом Как я проект в OpenSCADA сделал. В открывшемся окне на вкладке Обработка на языке JavaLikeCalc пишем, собственно, всю обработку, создаем дополнительные переменные у виджетов, конфигурим переменные виджетов. Чтобы иметь возможно работать с атрибутом (в данном случае атрибут = переменная), надо у соответствующего атрибута поставить галку в столбце «Обработка».

Второй способ обратиться к атрибуту: vcaAttrGet(strParsePath(path,0)+"/pg_control/pg_ElCadr/a_pgOpen").
Третий способ: через объект this — this.nodeList(«pg_» ) означает получить список виджетов у главного виджета.
Во втором и третьем случае ставить галку «Обработка» не надо.

Обратите внимание на колонку «Конфигурационный шаблон» – это как раз та самая изюминка связывания с тегами, про которую я говорил ранее. Там вы задаете шаблон в виде «параметр|атрибут», где параметр и атрибут – сущности из модуля Сбор данных. И тогда на вкладке Связи нам достаточно привязать параметр (например, G1), а атрибуты свяжутся автоматически согласно заданным шаблонам. Если параметр содержит 100 атрибутов, сэкономите массу времени. Умелое проектирование с таким маневрированием позволяет делать весьма гибкие системы.
Связать можно не только с тегом из Сбора данных, но и с любым атрибутом виджета, чем я и пользуюсь.

Библиотечный виджет — general – связи

Как я проект в OpenSCADA сделал

Как я уже говорил, связаться с тегом можно прямо из кода в обработке (SYS.DAQ.xxx и так далее вплоть до тега), а можно на вкладке Связи. Чтобы атрибут появился на вкладке Связи ему надо задать тип связи в колонке Конфигурация на вкладке Обработка:

Постоянная — во вкладке связей виджета появляется поле указания постоянной, например, особого цвета или заголовка для шаблонных кадров;
Входная связь — связь с динамикой только для чтения;
Выходная связь — связь с динамикой только для записи;
Полная связь — полная связь с динамикой (чтение и запись).

Плюсик в конце строки-привязки говорит корректности пути.

Библиотечный виджет — sets — связи с атрибутом виджета

Как я проект в OpenSCADA сделал

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

Библиотечный виджет — объект this

Как я проект в OpenSCADA сделал

Пример работы с переменными виджета через объект этого виджета this.

Библиотечный виджет — vcaAttrGet

Как я проект в OpenSCADA сделал

Тот самый третий способ обращения к переменным виджета через vcaAttrGet.

Библиотечный виджет — обработка событий клавиатуры/мыши

Как я проект в OpenSCADA сделал

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

Vision — таблица — редактирование

Как я проект в OpenSCADA сделал

Графический элемент «таблица» создается а-ля HTML. На момент разработки описываемого проекта получить координаты «выделенный столбец: выделенная строка» было невозможно, вставить в ячейку объект типа поле ввода/флажок/кнопка невозможно. Может сейчас возможностей добавилось.

Тренды

Как я проект в OpenSCADA сделал

Один холст может содержать до 99 перьев включительно (передаем привет Wonderware с ее 8 без доплаты).
А вот интерфейс взаимодействия с перьями приходится делать самому. Можно взять пример из демо-проекта, но там много ручной работы при конфигурировании. Для первого раза пойдет, но далее хочется более автоматизированного (из скрипта) интерфейса. Внешне подходит как Citect, но там таблица с флажками для управления видимостью перьев, а в openSCADA пока нет подходящего инструментария. Либо надо другую реализацию легенды придумать. Или на С++/Qt свою написать и в openSCADA добавить.

Механизм экспорта и печати

В нижнем правом углу экрана постоянно находится информационная панель, содержащая кнопки печати Как я проект в OpenSCADA сделал и экспорта Как я проект в OpenSCADA сделал, отображает текущего пользователя.

Как я проект в OpenSCADA сделал
«Информационная панель в нижнем правом углу экрана»

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

Как я проект в OpenSCADA сделал
Смена пользователя – выбор требуемого

Как я проект в OpenSCADA сделал
Смена пользователя – ввод пароля

Если необходимо напечатать только часть страницы, необходимо нажать стрелку рядом с кнопкой печати и выбрать необходимое.

Как я проект в OpenSCADA сделал

Список доступных для печати страниц:

Как я проект в OpenSCADA сделал

То же самое и для экспорта.

Как я проект в OpenSCADA сделал

Имя файла в поле должно содержать соответствующее расширение (*.png, *.xpm,*.jpg).
В случае выбора несуществующего на странице элемента появляется предупреждающее сообщение.

Страницы экспортируются в файлы изображений. Документы экспортируются в файлы web-страниц (*.html, которые можно открывать любым web-браузером и печатать из него) или текстовый файл (*.csv, который можно открыть в MS Excel или другом табличном редакторе для дальнейшей обработки). Документы в openSCADA — это встроенный базовый тип виджетов из которых можно создавать свои любые отчетные формы. Конфигурация а основе HTML и CSS.

Как я проект в OpenSCADA сделал

Вывод: openSCADA — очень даже энтерпрайз.

Автор: s60

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js