Статья описывает способы экономии тегов в SCADA-системах с платными лицензиями. Приведены приёмы замены дискретных тегов аналоговыми и запуска внешних программ для отображения состояния блока Ready16 без использования тегов.
- В SCADA с платными лицензиями количество тегов ограничено, и его увеличение требует дополнительной оплаты.
- Один аналоговый тег может заменить 16 дискретных сигналов, если упаковать их в слово и извлекать нужный бит средствами SCADA.
- Для экономии тегов можно запускать внешнюю программу, которая сама подключается к контроллеру и отображает состояние блока Ready16.
- Скрипт в Intouch передаёт внешней программе адрес сигнала, заголовок окна и тексты ошибок через файл из-за ограничений на длину аргументов и сообщений.
- Внешняя программа написана на C# с использованием бесплатной библиотеки HslCommunication-Community.
- Обмен данными между SCADA и внешней программой возможен через реестр Windows или промежуточный файл, с ожиданием завершения программы.
- Описанные приёмы предназначены для эксплуатации готовых систем, где появились ограничения по тегам.
- SCADA
- тег
- PLC
- Intouch
- Ready16
- HslCommunication-Community
- HMI
- WaitOnReturn
Кому полезно: Инженерам АСУ ТП, эксплуатирующим SCADA с ограничениями по тегам.
- Библиотека Wonderware INTOUCH 2012 Часть 1 и 2
- Статья На сайте размещен тендер №58 АСУТП УПСВ INTOUCH+SCHNEIDER
Первоисточник: habr.com
Выжимка составлена редакцией сайта с помощью ИИ по тексту статьи.
Чаще всего в SCADA системах используются платные лицензии, в которых прописано ограниченное количество тегов, с которыми можно работать — если хочешь больше тегов (чтобы получать больше сигналов из PLC), то нужно больше платить. Естественно может появиться желание немного сэкономить и выйти из положения ограничившись меньшим количеством тегов, для этого придется немного схитрить, о чем я и хотел бы написать.
Самый простой вариант, который я тоже применял в наших проектах, это использовать вместо дискретных тегов аналоговые — 16 дискретных сигналов можно заменить на одно слово. А вот из слова достать нужный бит средствами самой СКАДА — это уже довольно простая задача. На Intouch, например, при программировании реакция на нажатие кнопки, скрипт который обнуляет 4 бит может выглядеть вот так:
А если нужно, наоборот записать туда 1, то формула будет такая: EMG_DO_W = EMG_DO_W | 0x0010 Функция смены цвета элемента визуализации в зависимости от бита состояния выглядит похожим образом (для примера показал сравнение с десятеричным числом):
Таким нехитрым способом можно без проблем сэкономить 15 тегов (1 тег вместо 16), но все-равно даже так занимается 1 тег. А ведь можно пойти дальше и в некоторых случаях обойтись вообще без тега. Например, есть стандартный блок, так называемый Ready16 — блок показывающий готовность механизма, состоящий из 16 условий (так же 16 бит преобразуются в одно слово) — если любое из условий не соблюдается, то запуск механизма не возможен и поэтому для проверки почему это может быть, нужно подсветить оператору нужные эти условия. Вот так это может выглядеть:
И как же можно сэкономить теги в таком случае? А так что в СКАДА системах обычно бывает встроенная возможность с помощью скриптов запускать внешние программы. Идея простая: запускать программу с нарисованным заранее интерфейсом блока Реди16, которая сама будет подключаться к контроллеру, забирать из него нужный сигнал и рисовать состояние блока в данный момент. Скрипт при клике на кнопку, в котором прописывается адрес сигнала, который программа должна получить, для универсальности можно передать текст ошибок, заголовок окна и т.п. Вот такой скрипт я сделал для запуска внешней программы на Intouch:
И как же можно сэкономить теги в таком случае? А так что в СКАДА системах обычно бывает встроенная возможность с помощью скриптов запускать внешние программы. Идея простая: запускать программу с нарисованным заранее интерфейсом блока Реди16, которая сама будет подключаться к контроллеру, забирать из него нужный сигнал и рисовать состояние блока в данный момент. Скрипт при клике на кнопку, в котором прописывается адрес сигнала, который программа должна получить, для универсальности можно передать текст ошибок, заголовок окна и т.п. Вот такой скрипт я сделал для запуска внешней программы на Intouch:
FileDelete ("c:Ready16text.txt");
DIM f AS MESSAGE;
f =" f:"+StringChar(34)+ "Ready16text.txt"+StringChar(34);
FileWriteMessage("c:Ready16text.txt",-1,"Готов к работе/в работе",1);
FileWriteMessage("c:Ready16text.txt",-1,"Ошибка Привода",1);
FileWriteMessage("c:Ready16text.txt",-1,"Связь с Приводом ОК",1);
FileWriteMessage("c:Ready16text.txt",-1,"Привод отвечает на команды ",1);
FileWriteMessage("c:Ready16text.txt",-1,"Ошибка Тормоза",1);
FileWriteMessage("c:Ready16text.txt",-1,"Разъединитель силовой цепи",1);
DIM h AS MESSAGE;
h =" h:"+StringChar(34)+ "40 - Станция Натяжения №2 Ролик №1"+StringChar(34);
StartApp "C:Ready16Ready16.exe "+h+f+" s:D800"+" l:D801"+" a:D802.1";Удаляем старый текст, добавлем в текстовый файл, новый текст, добавляем адреса и заголовки и передаем все это нашей программе. Первоначально хотелось передать и тексты ошибок аргументами, но в Windows существует ограничение на длину аргументов (у меня получилось 260 символов, о чем сказано и тут в комментариях). Также в Интаче длина сообщения типа message тоже имеет свое ограничение в 160 символов. В общем наиболее простой способ это обмен сообщениями через файл.
Сама программа написана на базе бесплатной библиотеки на C# HslCommunication-Community. Очень странно, что при скачивании с GitHub готовой программы, Windows Defender ругался на вирусы в ней, хотя проверка через virustotal ничего не показала. Исходный код моей программы тут: Ready 16.
Еще был эксперимент с отображением статуса блоков Ready16 при открытии соответствующего окна на HMI. Можно повесить скрипт, который будет запускаться до того как прорисуется интерфейс окна HMI. Скрипт запросит адрес статуса блоков, и уже можно подсвечивать блоки соответствующими цветами:
DIM res AS MESSAGE;
OLE_CreateObject(%WS,"Wscript.Shell");
%WS.RegWrite("HKEY_CURRENT_USERSoftwareready16value",0,"REG_DWORD");
res = %WS.Run("C:Ready16ReadWord.exe s:D800",2,1);
result = %WS.RegRead("HKEY_CURRENT_USERSoftwareready16value");
В этом примере обмен между программами организован при помощи реестра Windows, хотя можно было бы сделать также через промежуточный файл. Мне просто показалось что реестр работает быстрее, поправьте если ошибаюсь. При запуске функции %WS.Run можно при помощи параметров запускать окно в скрытом режиме, но главное включить последний параметр WaitOnReturn , где 1 — он означает что скрипт запустивший программу дождется ее выполнения и только потом продолжит свой сценарий. В данном случае он запишет состояние реестра (в который наша программа запишет состояние слова по адресу D800 из контроллера) в глобальный тег result
PS эти хаки не от разработчиков и не для них, это больше для эксплуатирущих уже готовые системы, у которых в проекте появились ограничения в тегах
Источник: https://habr.com/ru/articles/797667/