Скрипты: различия между версиями

Материал из TekonWiki
Перейти к навигацииПерейти к поиску
Строка 122: Строка 122:
В данном варианте рассматривается возможность не только отображения, но и записи  в OPC-сервер значения указанного пользователем.
В данном варианте рассматривается возможность не только отображения, но и записи  в OPC-сервер значения указанного пользователем.


Данная возможность может быть актуальна, например, при диспетчеризации и управлении сторонним оборудованием, подключаемым по протоколу [[Modbus-устройства|Modbus]].
Что может быть актуально, например, при диспетчеризации и управлении сторонним оборудованием, подключаемым по протоколу [[Modbus-устройства|Modbus]].


При этом отображение текущего значения происходит в примитиве Текстовое поле, а при двойном нажатии на примитив открывается окно, в котором пользователю предлагается ввести новое значение.
При этом отображение текущего значения происходит в примитиве Текстовое поле, а при двойном нажатии на примитив открывается окно, в котором пользователю предлагается ввести новое значение.
Строка 128: Строка 128:
Возможности:
Возможности:
* чтение числового значения
* чтение числового значения
* преобразование прочитанного значения
* запись числового значения  
* запись числового значения  


Строка 204: Строка 205:
Сохраняем файл.
Сохраняем файл.


Далее запускаем программу АСУД.SCDA.
Далее запускаем программу АСУД.SCADA.


Размещаем примитив "Текстовое поле 1". Задаем его свойства:
Размещаем примитив "Текстовое поле 1". Задаем его свойства:

Версия от 09:18, 22 июля 2013


Данная статья актуальна для версий АСУД.SCADA 1.5.0 а3 и выше.

ПО АСУД.SCADA позволяет расширить функционал путем написания специальных программный модулей (скриптов) на языке Lua.

Скрипты находятся в папке Tekon \ ASUD Scada \ Scada \ scripts \ lvm

lvm_entry.lua - загрузчик скриптов - изменять не следует.
built-in \    - папка с базовыми скриптами и вспомогательными модулями - изменять не следует
custom \ - папка для скриптов пользователей
   ... \ entry.lua - загрузчик скриптов пользователей 

Для создания / редактирования скриптов можно использовать простой Блокнот или воспользоваться специальными утилитами.

Рассмотрим несколько примеров применения скриптов в АСУД.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)