Перейти к содержимому

Элементы из скриптов

Из скрипта можно найти любой элемент открытого экрана, прочитать и изменить любое его свойство, анимации, события и привязки. Всё это работает одинаково в настольном HMI и в браузере.

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

var pump = Screen.Items("Насос1");
Способ Результат
Item Элемент, на событии которого идёт скрипт. На событиях экрана null
Screen.Items("Имя") Элемент по имени; если его нет — ошибка скрипта
Screen.Find("Имя") Элемент по имени или null
Screen.Items() Массив элементов верхнего уровня всех открытых экранов
Screen.All() Массив всех элементов, включая вложенные
el.Children("Имя") Вложенный элемент группы, джина или окна экрана
el.Children() Массив вложенных элементов; у обычного элемента пустой
el.Parent Родитель или null у элемента верхнего уровня

Screen.Items и Screen.Find ищут сначала во всплывающих окнах, начиная с последнего открытого, затем на основном экране, включая группы и экземпляры джинов. В окна экрана поиск не заходит: для них используйте Children.

Массивы — обычные массивы JavaScript:

var lamps = Screen.All().filter(function (e) { return e.Type === "Lamp"; });
lamps.forEach(function (lamp) { lamp.Visible = false; });
Член Описание
.Name Имя объекта
.Id Внутренний идентификатор
.Type Тип: Button, Lamp, Trend, Group… Полный список — в справочнике
.TypeTitle Название типа на русском
.ScreenName Экран, на котором лежит элемент
.Events Массив имён событий, на которые назначены действия

Любое свойство из панели свойств читается и записывается как обычное поле. Имена английские, регистр не важен. Все имена и допустимые значения — в справочнике свойств.

Item.Fill = "#D32F2F";
Item.X = Item.X + 10;
Item.Text = "Авария";
Item.FontSize = 18;
Item.Alignment = "Center";

То же самое методами, если имя свойства лежит в переменной:

var name = "Fill";
Item.Set(name, "#D32F2F");
var color = Item.Get(name);
Метод Описание
.Get(name) Значение из настройки, без учёта анимаций
.Actual(name) Значение, которое сейчас видит оператор, с учётом анимаций
.Set(name, value) Записать свойство
.Has(name) Есть ли такое свойство у элемента
.Properties() Объект со всеми свойствами: { Fill: "#111111", X: 10, … }
.Move(x, y) Переместить
.Resize(width, height) Изменить размер; у группы вместе с содержимым

Значения проверяются:

Вид свойства Что передавать
Цвет "#RRGGBB" или "#AARRGGBB"
Число, целое Число или текст с числом
Флаг true / false
Выбор из списка Имя варианта, регистр не важен: "Center"
Тег, экран, список текстов Имя объекта проекта

Запись неподходящего значения и несуществующего свойства — ошибка скрипта с понятным текстом. Чтение несуществующего свойства возвращает null. Перед чтением можно проверить Has.

Член Чтение и запись Описание
.Visible Да Решение скрипта показывать элемент
.Enabled Да Решение скрипта разрешить управление
.IsShown Только чтение Виден ли сейчас, с учётом анимации «Видимость»
.IsOperable Только чтение Можно ли управлять сейчас, с учётом анимации «Разрешение управления»

Элемент виден, только если и скрипт, и анимация это разрешают. Так же с управлением, и дополнительно действует свойство Право для управления.

Screen.Items("КнопкаПуск").Enabled = Tags("Line.Ready").Value === true;

Запрет влияет только на действия оператора. Скрипт по-прежнему может вызвать событие через Raise или записать тег, а сервер всегда проверяет права сам. Поэтому Enabled не заменяет настройку прав и защиту тега.

Если у элемента есть свойство Tag (значение, лампа, столбик, ползунок, переключатель, прибор и другие):

Член Описание
.Tag Имя тега; можно сменить, элемент переподключится
.Value Значение тега; запись идёт в тег после скрипта, с проверкой прав
.Quality Качество значения
var field = Screen.Items("Уставка");
field.Value = 2.5;
field.Tag = "Tank2.Setpoint"; // тот же элемент теперь показывает другой тег

Обращение к .Value у элемента без тега — ошибка. На событии Изменение значения .Value может ещё содержать прежнее значение: новое приходит с сервера по подписке.

Некоторых настроек нет в панели свойств: анимации, динамика, события, перья тренда, строки таблиц. Для них есть полная настройка элемента.

Член Описание
.Config Копия полной настройки объектом JavaScript, как в файле экрана
.Apply(fields) Наложить поля на настройку

Apply меняет только переданные поля верхнего уровня. Значение null удаляет поле. Менять type нельзя, id игнорируется, а содержимое группы меняется через элементы из Children. Неизвестное поле вызывает ошибку.

Чтобы увидеть устройство настройки конкретного элемента:

HMI.ShowMessage(JSON.stringify(Item.Config, null, 2));

Настройка хранится с именами полей в нижнем регистре первой буквы (fill, penList), а имена событий и свойств внутри events и dynamics — как есть (Click, Fill).

Item.Apply({
events: {
Click: { script: "HMI.ShowMessage('Нажато: ' + Item.Name);" },
DoubleClick: { functions: [{ function: "ShowTrend", args: { Tag: "Tank1.Level" } }] }
}
});

Поле events заменяется целиком. Чтобы добавить одно событие к существующим:

var events = Item.Config.events || {};
events.RightClick = { script: "HMI.SysFct('ShowAlarms');" };
Item.Apply({ events: events });

Имена событий: Click, DoubleClick, LeftDown, LeftUp, RightClick, RightDown, RightUp, MouseEnter, MouseLeave, Change, Activate, Deactivate, KeyDown, KeyUp.

Вызвать события элемента программно:

Screen.Items("КнопкаПуск").Raise("Click");

Действия выполнятся после текущего скрипта.

Item.Apply({
animations: {
appearance: {
tag: "Pump1.State",
type: "Range",
rows: [
{ range: "0", background: "#F2F3F4" },
{ range: "1", background: "#3C9A5F" },
{ range: ">=2", background: "#D32F2F", flashing: true }
]
},
visibility: { tag: "Line.ShowPump", type: "SingleBit" }
}
});
Item.Apply({ animations: null }); // убрать все анимации
var dynamics = Item.Config.dynamics || {};
dynamics.Rotation = { kind: "Linear", tag: "Valve1.Pos", inMin: 0, inMax: 100, outMin: 0, outMax: 90 };
delete dynamics.Fill;
Item.Apply({ dynamics: dynamics });
Screen.Items("Тренд1").Apply({
penList: [
{ tag: "Tank1.Level", color: "#2F6FB0" },
{ tag: "Tank1.Pressure", color: "#D32F2F" }
]
});

Скрипт меняет настройку элемента. Анимации и привязки к тегам применяются поверх неё при каждом обновлении тега.

Item.Fill = "#D32F2F";
Item.Get("Fill"); // "#D32F2F"
Item.Actual("Fill"); // цвет от анимации, если она управляет фоном

Если цвет не меняется, значит, им управляет анимация. Уберите её через Apply.

  • Изменения действуют, пока открыт клиент, и только у этого клиента. Проект и другие операторы их не видят.
  • При переходе на другой экран и обратно изменения сохраняются.
  • Окно джина создаётся при каждом открытии, поэтому изменения внутри него пропадают при закрытии.
  • После выхода пользователя и нового входа экран снова такой, как в проекте.

Вернуть настройку из проекта можно без перезапуска:

Метод Что делает
.Reset() Отменяет изменения элемента и его вложенных элементов, включая Visible и Enabled
Screen.Reset() То же для всех открытых экранов

Reload() создаёт элемент заново: таблица данных перечитывает запрос, тренд заново загружает архив.

Screen.Items("ТаблицаЗаказов").Reload();

Смена тега, экрана и вызов Apply пересоздают элемент автоматически. Обычные свойства (цвет, текст, положение) его не пересоздают, поэтому их можно менять прямо на нажатии кнопки.

Член Описание
Screen.Name Имя основного экрана
Screen.Title Заголовок основного экрана
Screen.Width, Screen.Height Размер в координатах проектирования
Screen.Background Цвет фона
Screen.Names() Массив имён открытых экранов: основной и всплывающие окна
Screen.Items(), Screen.Items(name), Screen.Find(name), Screen.All() Поиск элементов
Screen.Reset() Вернуть настройки из проекта

Открывают и закрывают экраны через HMI.ActivateScreen и HMI.SysFct.