Скрипты: различия между версиями
Alex (обсуждение | вклад) |
Alex (обсуждение | вклад) Нет описания правки |
||
| Строка 4: | Строка 4: | ||
Данная статья актуальна для версий АСУД.SCADA 1.5.0 а3 и выше. | Данная статья актуальна для версий АСУД.SCADA 1.5.0 а3 и выше. | ||
ПО АСУД.SCADA позволяет расширить функционал путем написания специальных программный модулей (скриптов) на языке [http://www.lua.org/about.html Lua]. | ПО АСУД.SCADA позволяет расширить функционал путем написания специальных программный модулей (скриптов) на языке [http://www.lua.org/about.html Lua]. | ||
Для написания простых скриптов (реализации несложной логики) вы можете воспользоваться приведенными примерами. Для реализации более сложного функционала потребуется знание основ программирования, в этом случае для помощи в написании скриптов вы можете обратиться к специалистам компании Текон-Автоматика. | |||
Поддерживаются спецификации: | |||
* [http://www.lua.org/manual/5.1/ Lua 5.1] | |||
* библиотека [http://www.wxwidgets.org/ wxWidgets] 2.8.11 | |||
В настоящее время отсутствует встроенная в программное обеспечение возможность отладки/компиляции скрипта | |||
Скрипты находятся в папке Tekon \ ASUD Scada \ Scada \ scripts \ lvm | Скрипты находятся в папке Tekon \ ASUD Scada \ Scada \ scripts \ lvm | ||
* lvm_entry.lua - загрузчик скриптов - изменять не следует. | |||
* built-in \ - папка с базовыми скриптами и вспомогательными модулями - изменять не следует | |||
* custom \ - папка для скриптов пользователей | |||
** ... \ entry.lua - загрузчик скриптов пользователей | |||
Для создания / редактирования скриптов можно использовать: | |||
* простой Блокнот, | |||
* программу [http://notepad-plus-plus.org/ Notepad ++] | |||
* специальную [http://lua-users.org/wiki/LuaIntegratedDevelopmentEnvironments среду разработки]). | |||
Рассмотрим несколько | Рассмотрим несколько вариантов применения скриптов в АСУД.SCADA | ||
=== 1. Текстовое поле + скрипт (вариант 1) === | === 1. Текстовое поле + скрипт (вариант 1) === | ||
Версия от 08:09, 23 июля 2013
Данная статья актуальна для версий АСУД.SCADA 1.5.0 а3 и выше.
ПО АСУД.SCADA позволяет расширить функционал путем написания специальных программный модулей (скриптов) на языке Lua.
Для написания простых скриптов (реализации несложной логики) вы можете воспользоваться приведенными примерами. Для реализации более сложного функционала потребуется знание основ программирования, в этом случае для помощи в написании скриптов вы можете обратиться к специалистам компании Текон-Автоматика.
Поддерживаются спецификации:
В настоящее время отсутствует встроенная в программное обеспечение возможность отладки/компиляции скрипта
Скрипты находятся в папке Tekon \ ASUD Scada \ Scada \ scripts \ lvm
- lvm_entry.lua - загрузчик скриптов - изменять не следует.
- built-in \ - папка с базовыми скриптами и вспомогательными модулями - изменять не следует
- custom \ - папка для скриптов пользователей
- ... \ entry.lua - загрузчик скриптов пользователей
Для создания / редактирования скриптов можно использовать:
- простой Блокнот,
- программу Notepad ++
- специальную среду разработки).
Рассмотрим несколько вариантов применения скриптов в АСУД.SCADA
1. Текстовое поле + скрипт (вариант 1)
Предположим необходимо задать соответствие числовому значению (Тэга1), получаемому от OPC-сервера, некоторое строковое значение (Str1), и отобразить его в АСУД.SCADA. Например, следующего вида:
- 1 - насос включен.
- 0 - насос выключен.
Внимание, в случае если сигнал в OPC-сервере описан как дискретный датчик, следует проверить его настройку Уровень безопасности, должно быть значение Обычный (иначе если происходит отображение сигнала только в текстовое поле - не будет происходить снятия возникшей аварии).
Сначала опишем скрипт выполняющий соответствующее отображение.
В Блокноте создаем файл pumppwr.lua следующего содержания:
function PumpPower (val,qual)
if qual ~= opc.da.tekon.ItemData.QUALITY_GOOD then
return "---"
end
if val.Integer == 0 then
return "Насос выключен"
end
if val.Integer == 1 then
return "Насос включен"
end
return "Неизвестно"
end
Описывается функция PumpPower с двумя входными параметрами
- val - значение переменной OPC-сервера (тип: Variant)
- qual - значение качества переменной OPC-сервера (тип: Integer)
Для типа Variant допустимы следующие преобразования
.Integer - в целое число .Number - в вещественное число .String - в строку .Date - в переменную типа DateTime .Guid - в guid
Переменная качества может принимать одно из следующих константных значений
opc.da.tekon.ItemData.OPC_QUALITY_BAD opc.da.tekon.ItemData.OPC_QUALITY_UNCERTAIN opc.da.tekon.ItemData.OPC_QUALITY_GOOD opc.da.tekon.ItemData.OPC_QUALITY_CONFIG_ERROR opc.da.tekon.ItemData.OPC_QUALITY_NOT_CONNECTED opc.da.tekon.ItemData.OPC_QUALITY_DEVICE_FAILURE opc.da.tekon.ItemData.OPC_QUALITY_SENSOR_FAILURE opc.da.tekon.ItemData.OPC_QUALITY_LAST_KNOWN opc.da.tekon.ItemData.OPC_QUALITY_COMM_FAILURE opc.da.tekon.ItemData.OPC_QUALITY_OUT_OF_SERVICE opc.da.tekon.ItemData.OPC_QUALITY_WAITING_FOR_INITIAL_DATA opc.da.tekon.ItemData.OPC_QUALITY_LAST_USABLE opc.da.tekon.ItemData.OPC_QUALITY_SENSOR_CAL opc.da.tekon.ItemData.OPC_QUALITY_EGU_EXCEEDED opc.da.tekon.ItemData.OPC_QUALITY_SUB_NORMAL opc.da.tekon.ItemData.OPC_QUALITY_LOCAL_OVERRIDE
Следует отметить, что приведенный вариант реализации функции PowerPump не единственный, можно привести следующий равнозначный вариант кода:
PumpToStr=
{
[0] = "Насос выключен",
[1] = "Насос включен"
}
function PumpPower2 (val, qual)
if qual ~= opc.da.tekon.ItemData.QUALITY_GOOD then
return "---"
end
local text = PumpToStr[val.Integer]
if text ~= nil then
return text
end
return "Неизвестно"
end
Далее, сохраняем файл в папке scripts \ lvm \ custom
Открываем в Блокноте файл scripts \ lvm \ custom \ entry.lua и добавляем в первой строке запись
- dofile2("pumppwr.lua")
dofile2("pumppwr.lua")
function main_custom()
end
Сохраняем файл.
Далее запускаем программу АСУД.SCDA.
Размещаем примитив "Текстовое поле". Задаем его свойства:
- Тэг - Тэг1.
- Скрипт \ OnDataChange - PumpPower
Сохраняем настройки АСУД.SCADA
После этого должны увидеть что в Текстовом поле отображается строковое значение, в соответствии с логикой скрипта.
Рассмотренный пример можно загрузить здесь
2. Текстовое поле + скрипт (вариант 2)
В данном варианте рассматривается возможность не только отображения, но и записи в OPC-сервер значения указанного пользователем.
Что может быть актуально, например, при диспетчеризации и управлении сторонним оборудованием, подключаемым по протоколу Modbus.
При этом отображение текущего значения происходит в примитиве Текстовое поле, а при двойном нажатии на примитив открывается окно, в котором пользователю предлагается ввести новое значение.
Возможности:
- чтение числового значения
- преобразование прочитанного значения
- запись числового значения
Вид окна редактирования:
- Окно с текстовым полем (для ввода значения)
Удобно при необходимости простого изменения числового значения
- Окно с выпадающим списком (для выбора значения из списка)
Удобно при изменении значения перечисляемого типа. Например, как в случае с насосом, в варианте 1.
Сначала опишем скрипт.
В Блокноте следует открыть файл scripts \ lvm \ custom \ gui.lua
Данный файл содержит описание базовых классов, обеспечивающих работу с окнами редактирования параметров. В большинстве случаев изменять их не следует.
Переходим в конец файла и ищем строку -- Создание объектов
-------------------------------------------------------------------------------------------------------------------
-- Создание объектов.....
-------------------------------------------------------------------------------------------------------------------
topc_object0 = topc_string_primitive("Объект Edit", WTYPE_EDIT)
topc_object2 = topc_combo ("Объект ComboBox", WTYPE_COMBOBOX)
-- Нумерация элементов по умолчанию с 1
combo2=
{
[0] = "Отключено",
[1] = "Запуск",
[2] = "ДежЛето",
[3] = "Охлажд",
[4] = "Вентиляц",
[5] = "ДежЗима",
[6] = "Прогрев",
[7] = "Нагрев",
[8] = "Обратная",
[9] = "Замерз",
[10] = "АНР Тпр Л",
[11] = "АНР Тпр З",
[12] = "АНР Тобр Д"
}
topc_object2:Elements (combo2)
topc_object1 = topc_combo ("Объект ComboBox", WTYPE_COMBOBOX)
-- Нумерация элементов по умолчанию с 1
combo1=
{
[0] = "Выкл",
[1] = "Вкл"
}
topc_object1:Elements (combo1)
В данном случае создаются объекты:
- topc_object0 - окно с текстовым полем
- topc_object1 - окно с выпадающим меню (элементы меню перечислены в combo1)
- topc_object2 - окно с выпадающим меню (элементы меню перечислены в combo2)
Следует внести изменения в перечисления combo1, combo2 в соответствии с получаемыми данными. По необходимости создать собственные объекты по аналогии.
Сохранить файл.
Далее открываем в Блокноте файл scripts \ lvm \ custom \ entry.lua и добавляем в первой строке запись
- dofile2("gui.lua")
dofile2("gui.lua")
function main_custom()
end
Сохраняем файл.
Далее запускаем программу АСУД.SCADA.
Размещаем примитив "Текстовое поле 1". Задаем его свойства:
- Тэг - Тэг1.
- Скрипт \ LVM объект - topc_object0
Размещаем еще один примитив "Текстовое поле 2". Задаем его свойства:
- Тэг - Тэг2.
- Скрипт \ LVM объект - topc_object1
Внимание, в поле Скрипт следует указывать
- либо LVM объект
- либо функцию OnDataChange (как указано в примере 1).
Сохраняем настройки АСУД.SCADA
3. Анализ изменений сигнала (автомат управления)
Рассмотрим пример простого скрипта, реализующего выключение канала управления КУП-RS подключенного к концентратору Мини-КУН номер 210, при срабатывании дискретного входа номер 4 на концентраторе Мини-КУН номер 202.
Предполагаем, что уже существует настройка OPC-сервера, для концентраторов 210 и 202
Создадим текстовый файл с именем script1.lua в блокноте следующего содержания:
-- описываем карту связи Датчик - Канал управления
-- тэги просто копируем из свойства Тэг примитива АСУД.SCADA
descret_autocall_task_map =
{
["DA.[localhost{188D08EC-72CB-425B-8EA8-EE2308736440}].USB Пульт.202 Мини-КУН.Авария 1"] =
"DA.[localhost{188D08EC-72CB-425B-8EA8-EE2308736440}].USB Пульт.210 Мини-КУН.КУП Канал 1.Остановка"
}
-- в эту функцию будет приходить любые события связанные с изменением состояния датчиков
function DescretSensor_OnDataChange(topc_item, topc_itemdata)
-- проверка данных на валидность
if topc_item~= nil and topc_itemdata~=nil then
if topc_itemdata.Quality ~= opc.da.tekon.ItemData.QUALITY_GOOD or topc_itemdata.Data ==nil then
return
end
-- запрос значения датчика
local int = topc_itemdata.Data.Integer
-- запрос типа датчика
local prop = item:GetProperty(opc.da.tekon.Item.ITEM_TYPE)
-- проверка того, что датчик дискретный
if prop ~= nil and prop.Data.Integer == opc.da.tekon.Item.SENSOR then
if descret_autocall_task_map[topc_item.ItemID] ~= nil then
-- запрос указателя на канал управления связанный с дискретным датчиком
local itemCtrl, bRes = opc.da.tekon.GetItem(descret_autocall_task_map[topc_item.ItemID])
if (itemCtrl~= nil) and bRes then
-- если дискретный датчик активен, выключить канал управления
if int==32769 then
local newData = base.Variant(0);
itemCtrl:AsyncWrite(newData)
end
end
end
end
end
end
-- функция инициализации скрипта
function InitScript1()
-- подписаться на событие (изменение состояния любого датчика)
opc.da.tekon.RegisterEventHandler(
"OPC::DA::TEKON::OnDataChange",
"DescretSensor_OnDataChange")
-- подписаться на событие чтение состояния датчика
opc.da.tekon.RegisterEventHandler(
"OPC::DA::TEKON::OnReadComplete",
"DescretSensor_OnDataChange")
end
Значения дискретного датчика могут быть следующие:
32769 - активная авария (красный воскл.знак на примитиве); 32771 - активная авария, с которой ознакомился диспетчер (желтый воскл.знак на примитиве); 0 - нет аварии.
Подробнее см. дискретные сигналы Tekon OPC DA
Команды каналу управления могут быть следующие:
0 - выключить канал управления; 1 - включить канал управления.
Сохраните файл script1.lua
Откройте в блокноте файл ..scripts\lvm\custom\entry.lua и внесите следующие изменения:
dofile2("gui.lua")
dofile2("script1.lua")
function main_custom()
InitScript1()
end
Сохраните файл, запустите АСУД.SCADA, логика созданного автомата управления должна работать.
Ссылки
Дискретный_сигнал_(OPC-сервер)
--Alex 12:21, 5 июля 2013 (UTC)