Скрипты в DevelSCADA
- четверг, 9 октября 2025 г. в 00:00:02
Для расширения базового функционала среды разработки 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, и, соответственно, влияющая на работу таймера, выводящего сообщение.