Часть 2: Информативный интерфейс SCADA – вы читаете эту статью
В этой статье я хочу поделиться своим видением того, каким должен быть удобный и информативный интерфейс SCADA системы.
Все иллюстрации в статье – это скриншоты, сделанные с разработанной мной SCADA системы, которая уже несколько лет работает на объектах заказчиков. Это не фантазии на тему как должно быть и не картинки из презентации.
При разработке я опирался на известную книгу «The High Performance HMI Handbook» (Hollifield, Oliver, Nimmo, Habibi), а также на интерфейс Citect SCADA.
Введение
Интерфейс SCADA системы предназначен для контроля за состоянием и управления оборудованием объекта. Все отображаемые графические элементы, символы, пиктограммы и их цвет, должны служить только одной цели – доносить пользователю максимум информации о состоянии системы. Всё что не несёт информации, а служит только целям дизайна и другим украшательствам, должно быть отброшено т.к. вносит дополнительный шум и распыляет внимание пользователя.
Особенно нужно избегать добавления каких-либо фотореалистичных изображений объекта и оборудования. Также недопустима любая анимация или мигание, особенно при нормальной работе оборудования. Всё это вносит визуальный шум, перетягивает внимание пользователя на себя и мешает считыванию другой информации.
К сожалению, в разных отраслях есть собственные стандарты, которые жёстко регламентируют способ отображения информации и могут помешать созданию интерфейса по описываемой концепции. Например, в энергетике есть стандарт «Правила отображения технологической информации» утверждённый системным оператором единой энергетической системы, который задаёт в том числе цветовую маркировку, где красный, жёлтый и другие яркие цвета используются для индикации нормального состояния объекта.
Основная концепция
Если всё работает нормально, то ничего не должно привлекать внимание пользователя. При этом пользователь не должен тратить время и читать все цифровые или текстовые значения чтобы понять, что всё работает нормально. Это можно описать как «взгляду не за что зацепиться».
Все статичные (неизменяемые) элементы отображаются чёрным цветом, а меняющиеся со временем значения синим, зелёным или красным.
Условные обозначения

Пример – всё нормально

Если посмотреть более внимательно, то пользователь заметит:
Секция 2: Увлажнители выведены из работы.
Система: Вентилятор шкафа находится в ручном режиме управления.
Пример – всё нормально и некоторое оборудование активно

Всё оборудование, состояние которого отображается зелёным цветом, включено или находится в движении.
Первая версия интерфейса не выделяла активное оборудование зелёным цветом, всё отображалось синим. Но при внедрении системы я обнаружил, что обязательно нужно как-то выделять активное оборудование. Дело в том, что наши пользователи часто управляют оборудованием вручную, даже при наличии модуля автоматического управления климатом. И им необходимо быстро понимать, осталось ли какое-то оборудование во включенном состоянии, чтобы не забыть его отключить.
Пример – есть проблемы

Секция 1: Нет связи с датчиком температуры канала. Обрыв линии связи или датчик вышел из строя.
Секция 2:
Температура продукта меньше или равна заданной пользователем нижней аварийной границы.
Вентилятор 2 – оборудование отключено и находится в состоянии аварии. Например, сработало тепловое реле защиты электродвигателя. Возможно, двигатель заклинил, изношены подшипники и т.д.
Секция 3: Температура канала больше или равна заданной пользователем верхней предупредительной границы.
Улица (метеостанция): Датчик температуры возвращает некорректное значение. Помехи на линии связи или система самодиагностики датчика фиксирует отклонения в его работе.
Иерархическая организация экранов интерфейса
При разработке системы было решено отказаться от формирования интерфейса в виде экранов и мнемосхем со схематичным изображением помещений и оборудования объекта.
Даже похожие по назначению объекты заказчиков очень сильно различаются по структуре и составу оборудования. Например, в одном овощехранилище может быть 2 секции (помещения), а в другом 10. В каждой секции состав и количество оборудования может отличаться на порядок.
Я видел на объектах, как в других системах, нарисовав один раз изображение какого-то «усреднённого» хранилища, пытаются разместить поверх него большое количество оборудования, в итоге интерфейс превращается в бесконечный массив из картинок электродвигателей, датчиков и кнопок управления. При таком подходе, для каждого объекта надо полностью перерисовывать мнемосхему, для большинства объектов вообще нужна иерархия из экранов и мнемосхем. Но создание такого интерфейса затратный по времени (=деньгам) процесс, поэтому в реальности так никто не делает – у наших заказчиков просто нет соответствующих бюджетов.
Также наша SCADA имеет web-интерфейс, который должен автоматически адаптироваться под экраны мобильных устройств. Любые схематичные изображения или мнемосхемы невозможно автоматически масштабировать, чтобы ими было удобно пользоваться на маленьких экранах – для них придётся создавать отдельное представление интерфейса.
Поэтому решено было реализовать интерфейс из экранов с прямоугольными плитками, плитка – это представление отдельного физического объекта (здание, помещение и т.д.) или программного модуля системы (модуль автоуправления климатом, SMS оповещения, графиков и т.д.). Каждая плитка выступает в роли ссылки на описываемый объект.
Такой подход позволяет описать любой объект в виде иерархической структуры с неограниченной вложенностью. На экранах верхнего уровня в плитках выводится наиболее значимая информация о нижележащем объекте. На экранах самого нижнего уровня находятся не плитки, а уникальные компоненты для управления и настройки оборудования.
Структура интерфейса объекта оп��сывается в JSON файле. Сервис Web-UI при старте читает этот файл и выполняет автоматическую компоновку всех экранов и плиток.
Реализована отдельная утилита, которая позволяет удобно формировать интерфейс для каждого объекта заказчика и сохранять его в JSON файл. Этот код находится в отдельном проекте и просто служит для удобства формирования файла JSON, можно вручную всё в файле JSON описать используя любой текстовый редактор.
Пример кода на C# для формирования интерфейса
public static ModelStorage Create(API.Model model) { ModelBuilderContext builderContext = new ModelBuilderContext(model) .CreateHomePage() .CreateWeatherPage() .CreateSystemPage(); for (int sectionId = 1; sectionId <= 3; sectionId++) { builderContext .CreateSectionPage(sectionId) .CreateSectionEquipmentPage(sectionId) .CreateSectionSensorsPage(sectionId) .CreateSectionRoomSensorsPage(sectionId) .CreateSectionSensorsProductPage(sectionId) .CreateSectionClimateControlPage(sectionId); } builderContext .AddChartTags( new ChartTag(builderContext.GetTagId("Секция 1 - Датчик температуры бурта Среднее", "SensorInput"), "Секция 1"), new ChartTag(builderContext.GetTagId("Секция 2 - Датчик температуры бурта Среднее", "SensorInput"), "Секция 2"), new ChartTag(builderContext.GetTagId("Секция 3 - Датчик температуры бурта Среднее", "SensorInput"), "Секция 3")); return builderContext.GetModel(); } static ModelBuilderContext CreateHomePage(this ModelBuilderContext builderContext) { UIPage page = new() { Id = "home", ParentId = null, Header = "Хранилище", GroupBoxes = new List<UIGroupBox>() }; page.GroupBoxes.Add( new UIGroupBox() { PageId = "weather", Header = "Улица", Items = new List<UIGroupBoxItem>() { new UIGroupBoxItem() { Name = "T", TagId = builderContext.GetTagId($"Метеостанция - Датчик температуры улицы", "SensorInput"), }, new UIGroupBoxItem() { Name = "RH", TagId = builderContext.GetTagId($"Метеостанция - Датчик влажности улицы", "SensorInput"), }, } }); // ... return builderContext.AddPages(page); } static ModelBuilderContext CreateWeatherPage(this ModelBuilderContext builderContext) { UIPage page = new() { Id = "weather", ParentId = "home", Header = "Улица", EquipmentItems = new List<UIEquipmentItem>() { new UIEquipmentItem() { Name = "T", TagGroupId = $"Метеостанция - Датчик температуры улицы", ComponentType = UIComponentType.Sensor }, new UIEquipmentItem() { Name = "RH", TagGroupId = $"Метеостанция - Датчик влажности улицы", ComponentType = UIComponentType.Sensor }, } }; return builderContext.AddPages(page); }
1. Верхний уровень – домашняя страница
Общая сводная информация о объекте. В плитках только самая важная информация о нижележащем объекте.

Секция 1-3 – это физические помещения хранилища.
Улица – уличная метеостанция.
Система – всё что относится к общему оборудованию. В данном случае подогрев клапанов всех секций подключен к одному реле, поэтому вынесен на эту плитку.
График температуры продукта – программный модуль для отображения графиков по архивным значениям.
2. Средний уровень – секция
На этом уровне в плитках отображается всё оборудование секции.
Если оборудования очень много, то можно сделать ещё один или несколько дополнительных уровней иерархии. И наоборот, если оборудования очень мало, то этого уровня может вообще не быть.

3. Нижний уровень – управление и настройка оборудования
На экранах самого нижнего уровня находятся не плитки, а уникальные компоненты для управления и настройки оборудования.
Для доступа к настройкам нужно нажать кнопку «…».
3.1 Датчики

3.2 Датчики помещения

3.3 Температура продукта

Раскрыто меню настройки у датчика среднего:

Сверху отображаются виртуальные (программные) датчики среднего и дельты с расчётными значениями на основе 6 физических датчиков температуры.
Датчик среднего значения – среднее арифметическое значений группы датчиков.
Среднее = Сумма всех значений / Количество значений
Датчик максимальной разницы значений (дельта) – среди значений группы датчиков определяется минимальное и максимальное значение, затем вычисляется модуль от разницы этих значений.
Дельта = |Максимальное значение - Минимальное значение|
Это очень важное значение. Большая дельта температур может означать:
Неравномерное перемешивание воздуха внутри хранилища.
В хранимом продукте имеются очаги гниения.
Промерзает стена хранилища.
3.4 Оборудование

Если представить страницу в виде таблицы со строками и колонками, то можно следующим образом описать колонки:
Название.
Текущее состояние.
Заданное состояние (команда). Кнопка с активной командой имеет голубой фон. Если кнопки «бледные», то ручное управление заблокировано.
Режим управления. Ручной – управление оборудованием осуществляется пользователем вручную, с помощью кнопок с командами. Авто – оборудование управляется автоматически программным модулем, например, модулем автоуправления климатом. Если оборудование не привязано к какому-либо модулю автоуправления, то у него нет кнопок выбора режима управления, т.е. оборудованием можно управлять только вручную.
Кнопка «…» для отображения настроек оборудования.
Раскрыто меню настройки у клапана и увлажнителя 1:

3.5 Автоуправление климатом
Настройки программного модуля автоуправления климатом хранилища.
Этот модуль содержит множество настроек, поэтому у него всегда собственная плитка и отдельный экран настройки. У параметров имеется текстовое описание.

Всплывающее окно для изменения числового значения

Описание элементов окна:

У разных параметров шаг может отличаться. Например, у некоторых параметров маленький шаг = 0,1, а большой = 1, а у других маленький шаг = 1, а большой = 10.
У параметров (тегов) обычно заданы границы минимального и максимального значени��, соответственно все элементы окна позволяют менять значение только в допустимом диапазоне.
Итог
Данный подход к созданию интерфейса хорошо себя зарекомендовал на объектах. Им удобно пользоваться как на сенсорном экране с диагональю 17 дюймов, так и на мобильных устройствах.
Также такой простой интерфейс без графики потребляет минимум интернет трафика, что особенно важно при использовании мобильных устройств в отдалённых местах за городом.
Принцип, когда при нормальной работе «взгляду не за что зацепиться» оказался удобным – можно не подходить близко к экрану, чтобы понять, есть какие-то проблемы в работе или нет.
