Как стать автором
Обновить

Экономим теги SCADA системы

Уровень сложностиПростой
Время на прочтение3 мин
Количество просмотров2.2K

Чаще всего в SCADA системах используются платные лицензии, в которых прописано ограниченное количество тегов, с которыми можно работать - если хочешь больше тегов (чтобы получать больше сигналов из PLC), то нужно больше платить. Естественно может появиться желание немного сэкономить и выйти из положения ограничившись меньшим количеством тегов, для этого придется немного схитрить, о чем я и хотел бы написать.

Самый простой вариант, который я тоже применял в наших проектах, это использовать вместо дискретных тегов аналоговые - 16 дискретных сигналов можно заменить на одно слово. А вот из слова достать нужный бит средствами самой СКАДА - это уже довольно простая задача. На Intouch, например, при программировании реакция на нажатие кнопки, скрипт который обнуляет 4 бит может выглядеть вот так:

А если нужно, наоборот записать туда 1, то формула будет такая: EMG_DO_W = EMG_DO_W | 0x0010 Функция смены цвета элемента визуализации в зависимости от бита состояния выглядит похожим образом (для примера показал сравнение с десятеричным числом):

Таким нехитрым способом можно без проблем сэкономить 15 тегов (1 тег вместо 16), но все-равно даже так занимается 1 тег. А ведь можно пойти дальше и в некоторых случаях обойтись вообще без тега. Например, есть стандартный блок, так называемый Ready16 - блок показывающий готовность механизма, состоящий из 16 условий (так же 16 бит преобразуются в одно слово) - если любое из условий не соблюдается, то запуск механизма не возможен и поэтому для проверки почему это может быть, нужно подсветить оператору нужные эти условия. Вот так это может выглядеть:

И как же можно сэкономить теги в таком случае? А так что в СКАДА системах обычно бывает встроенная возможность с помощью скриптов запускать внешние программы. Идея простая: запускать программу с нарисованным заранее интерфейсом блока Реди16, которая сама будет подключаться к контроллеру, забирать из него нужный сигнал и рисовать состояние блока в данный момент. Скрипт при клике на кнопку, в котором прописывается адрес сигнала, который программа должна получить, для универсальности можно передать текст ошибок, заголовок окна и т.п. Вот такой скрипт я сделал для запуска внешней программы на Intouch:

FileDelete ("c:\Ready16\text.txt");
DIM f AS MESSAGE;
f =" f:"+StringChar(34)+ "\Ready16\text.txt"+StringChar(34);
FileWriteMessage("c:\Ready16\text.txt",-1,"Готов к работе/в работе",1);
FileWriteMessage("c:\Ready16\text.txt",-1,"Ошибка Привода",1);
FileWriteMessage("c:\Ready16\text.txt",-1,"Связь с Приводом ОК",1);
FileWriteMessage("c:\Ready16\text.txt",-1,"Привод отвечает на команды ",1);
FileWriteMessage("c:\Ready16\text.txt",-1,"Ошибка Тормоза",1);
FileWriteMessage("c:\Ready16\text.txt",-1,"Разъединитель силовой цепи",1);
DIM h AS MESSAGE;
h =" h:"+StringChar(34)+ "40 - Станция Натяжения №2 Ролик №1"+StringChar(34);

StartApp "C:\Ready16\Ready16.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_USER\Software\ready16\value",0,"REG_DWORD");

res = %WS.Run("C:\Ready16\ReadWord.exe s:D800",2,1);
result = %WS.RegRead("HKEY_CURRENT_USER\Software\ready16\value");

В этом примере обмен между программами организован при помощи реестра Windows, хотя можно было бы сделать также через промежуточный файл. Мне просто показалось что реестр работает быстрее, поправьте если ошибаюсь. При запуске функции %WS.Run можно при помощи параметров запускать окно в скрытом режиме, но главное включить последний параметр WaitOnReturn , где 1 - он означает что скрипт запустивший программу дождется ее выполнения и только потом продолжит свой сценарий. В данном случае он запишет состояние реестра (в который наша программа запишет состояние слова по адресу D800 из контроллера) в глобальный тег result

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

Теги:
Хабы:
Всего голосов 2: ↑1 и ↓1+2
Комментарии9

Публикации

Истории

Ближайшие события

Конференция HR API 2024
Дата14 – 15 июня
Время10:00 – 18:00
Место
Санкт-ПетербургОнлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область