AI Скрипты в DevelSCADA

AI

Редактор
Регистрация
23 Август 2023
Сообщения
3 019
Лучшие ответы
0
Реакции
0
Баллы
51
Offline
#1
Для расширения базового функционала среды разработки DevelSCADA, система поддерживает возможность использования скриптов. Основным языком для разработки скриптов является JavaScript. Скрипты, в свою очередь поддерживают весь функционал языка JavaScript, дополняя его функциями работы с системой DevelSCADA.

Система поддерживает работу с двумя видами скриптов - скрипты интерфейса и скрипты ПЛК. Оба типа скриптов имеют идентичные интерфейсы для взаимодействия с системой, но при этом имеют разное предназначение.

Скрипты интерфейса предназначены в первую очередь для работы с элементами пользовательского интерфейса. Они могут быть созданы как в разделе «Скрипты» дерева проектов, так и в функциях обработки событий графических элементов интерфейса. Скрипты интерфейса работают на стороне клиента в его окне интерфейса, соответственно если несколько клиентов подключены к системе одновременно, у каждого клиента будут работать собственные экземпляры скриптов. Это необходимо учитывать при необходимости синхронизации визуального представления интерфейса, если предусмотрена одновременная работа несколькими пользователями. Так же скрипты интерфейса, привязанные с событиям графических элементов экрана, работают, соответственно, только на том экране, на котором они созданы. Так же и скрипты, созданные в разделе «Скрипты», запускаются каждый раз при переходе с экрана на экран. Если проект будет запущен, но при этом к нему не будет подключено ни одного клиента, никакие скрипты интерфейса работать не будут. Если необходимо постоянная работа скриптов, вне зависимости от работы клиентов и активного экрана, для этого необходимо использовать скрипты ПЛК.

Скрипты ПЛК запускаются сразу при старте проекта, и выполняются до тех пор, пока исполнение проекта не будет остановлено. В отличие от скриптов интерфейса, скрипты ПЛК не имеют функций прямого взаимодействия с элементами графического интерфейса, но при этом они работают постоянно, вне зависимости от того, что происходит в графическом интерфейсе. Скрипты ПЛК могут быть созданы только в разделе «Скрипты» дерева проекта.

Пример использования скриптов интерфейса


Выполнение скрипта интерфейса можно привязать к событию элемента интерфейса редактора экрана. Для примера сделаем скрипт, который будет выполняться при нажатии кнопки. Создадим в рабочей области экрана кнопку и выберем в свойствах элемента, в разделе «События», возле события «Нажатие», тип события «Скрипт».



После этого необходимо нажать кнопку редактирования скрипта.



Откроется окно текстового редактора скрипта.



Напишем код скрипта.

async function main(val) {
log('Hello world');
}

Запустим проект на исполнение. При нажатии на кнопку, в системный журнал будет выводиться текст сообщения скрипта.



Если необходимо создать функцию, которая будет вызываться многократно из разных мест графического интерфейса, удобнее всего ее создать в разделе «Скрипты» дерева проекта. Это можно сделать правым кликом из контекстного меню, либо по кнопке «Добавить» в самом разделе.



В появившемся окне необходимо выбрать «Скрипт интерфейса».



В разделе «Скрипты» появится созданный нами скрипт, и откроется окно текстового редактора скрипта.



Скрипты интерфейса могут иметь функцию init, которая всегда вызывается при загрузке любого экрана. В ней можно выполнять какие либо подготовительные операции, необходимые для работы остального кода. Добавим в данный скрипт собственную функцию вида:

export function myFunc() {
log('myFunc called');
}

Внимание! Все функции, доступ к которым необходим не только из данного скрипта, обязательно должны иметь ключевое слово export.

В результате скрипт должен иметь следующий вид:



Теперь вернемся к скрипту кнопки и отредактируем его код.

async function main(val) {
//log('Hello world');
let mySctipt = await ds.include('script_gui0');
mySctipt.myFunc();
}

Для доступа к функциям скрипта, предварительно нужно его подключить системной функцией ds.include, передав в качестве аргумента ей - имя скрипта. В результате в переменную myScript мы получим объект нашего скрипта, из которого в дальнейшем вызываем описанную в нем функцию.

Теперь при нажатии на кнопку, в системный журнал будет выведено сообщение из кода функции скрипта.


Пример использования скриптов ПЛК


Скрипты ПЛК создаются только в разделе «Скрипты» дерева проекта. Создается он аналогично скрипту интерфейса, с выбором соответствующего типа скрипта.



Для примера, создадим скрипт, который ежесекундно выводит в журнал сообщение с текущим временем.

async function init() {
while (true) {
log('Current date:', new Date());
await ds.sleep(1000);
}
}

Код скрипта разместим в функции init, которая будет вызываться при запуске проекта. После запуска проекта увидим сообщения в системном журнале, которые будут выводиться вне зависимости от того, какой экран проекта в данный момент открыт. Скрипт прекратит свое выполнение лишь после завершения выполнения проекта.


Взаимодействие скриптов интерфейса и ПЛК


Скрипты интерфейса могут вызывать функции скриптов ПЛК посредством вызова функции callPlc. При этом скрипты ПЛК не могут напрямую обращаться к функциям скриптов интерфейса. Это связано с тем, что контекстов исполнения скриптов интерфейса может быть несколько, или не быть ни одного, а контекст выполнения скриптов ПЛК всегда существует, и он всегда один. В связи с этим реализация доступа из скриптов ПЛК к функциям скриптов интерфейса не была реализована, чтобы не усложнять работу системы дополнительными проверками их доступности и синхронизацией. Если же необходимо из скриптов ПЛК влиять на работу скриптов интерфейса, то это можно легко реализовать, используя общие переменные устройства «Память».

Пример вызова функции скрипта ПЛК из скрипта интерфейса


Создадим в скаде код логики работы некоего устройства. К примеру сделаем таймер на 3 секунды, который будет выводить сообщение в журнал. Так же создадим функцию, которая будет управлять состоянием видимости сообщения. Так как этот код должен работать постоянно при работе проекта, его необходимо создать в скрипте ПЛК. Для этого создадим скрипт следующего вида:

let isActive = true;

async function init() {
while (true) {
if (isActive) log('hi');
await ds.sleep(3000);
}
}

function setActive(state) {
log('Set state:', state);
isActive = state;
}

Должен получиться проект следующего вида:



Далее создадим на экране две кнопки для включения и отключения статуса отображения сообщения посредством вызова функции ds.plcCall, которая вызывает функцию из скрипта ПЛК. Создадим в кнопках скрипты следующего содержания:

async function main(val) {
await ds.plcCall('script_plc0.setActive', [ true ]);
}

и

async function main(val) {
await ds.plcCall('script_plc0.setActive', [ false ]);
}

Запустим проект и понажимаем кнопки, в журнале будет видно как вызывается функция ПЛК setActive, изменяющая содержимое переменной isActive, и, соответственно, влияющая на работу таймера, выводящего сообщение.

 
Сверху Снизу