Задача:
При использовании компонента Alpha.HMI.Trends необходимо вывести в легенду описание, содержащее информацию по всей ветке объектов (какому именно датчику, линии, цеху и т.д. относится данный параметр)
Чтобы выглядело, например, так:
По умолчанию в Alpha.HMI.Trend отображается только описание сигнала:
Решение:
В проекте в DevStudio у сигналов Pressure задано описание «Давление» (атрибут Description)
В проекте в DevStudio у всех вышестоящих логических объектов в структуре дерева также указано описание в атрибутах Description. (Датчик №, Линия № и т.д)
Данную задачу можно решить средствами самого решения Alpha.HMI.Trends. Для этого нужно в параметрах окна трендов, указать необходимость отображения в легенде полного описания, а у самого экземпляра Trends задать свойство ShowFullDescription = true :
Таким образом, с данными настройками перед описанием самого параметра будут добавлены описания всех родительских объектов.
Но если необходимо формировать описание каким-то определенным образом (изменить порядок, пропустить определенные объекты, вывести описание не всей ветки объектов), то данный способ не подходит.
Поэтому мы рассмотрим вариант решения с помощью функционала вычисления значений атрибутов.
Вычисляемое выражение, содержащее ссылку на значение другого атрибута, представляет собой конструкцию вида @(Source:Attribute), где Source – алгоритм поиска атрибута, Attribute – тип атрибута. При вычислении значение найденного атрибута будет подставлено вместо вычисляемого параметра.
Значения, которые может иметь алгоритм поиска атрибута Source подробно описано в документации:
Alpha.DevStudio > Руководство пользователя > Разработка проекта > Добавление атрибутов > Вычисление значений атрибутов
Для начала рассмотрим алгоритмы поиска object и parent.
object – атрибут ищется среди атрибутов контекстного объекта.
parent – атрибут ищется среди атрибутов родителя контекстного объекта (элемента, в который объект вложен).
Если вычисляемый параметр указан у сигнала, вложенного в тип, то у объектов этого типа атрибут будет искаться среди атрибутов объекта. (Или у родителя объекта, в случае с parent)
Укажем параметру Pressure в атрибуте «Описание» следующее выражение:
Давление, @(object:System.Attributes.Description), @(parent:System.Attributes.Description)
@(object:System.Attributes.Description) – получим описание объекта, в котором находится данный параметр (Датчик №)
@(parent:System.Attributes.Description) - получим описание родителя объекта, в котором находится данный параметр (Линия №)
Построим решение, применим конфигурацию.
В таком случае получим следующее описание у параметра в трендах.
Для того чтобы сослаться на атрибуты объектов выше по иерархии, необходимо использовать алгоритмы поиска «@N»
«@N» – атрибут будет искаться на N уровней выше относительно вычисляемого параметра.
И тогда мы могли бы прописать следующее выражение:
Давление, @(@1:System.Attributes.Description), @(@2:System.Attributes.Description), @(@3:System.Attributes.Description)
Но, в рассматриваемом проекте – примере все объекты (датчики и др.) описываются через типы (объектно-ориентированный подход.) И наш параметр Pressure также описывается в типе.
И в данном случае использовать алгоритм поиска «@N» из типа не получится.
При построении решения в журнале будет ошибка на разбор пути «@2»
Т.к данный алгоритм будет искать атрибуты относительно самого типа, а не у объектов – экземпляров самого типа.
Поэтому выражение вычисления атрибутов с алгоритмом поиска «@N» будем задавать непосредственно самим объектам.
Для «перекладки» описания объектов всей ветки создадим отдельный пользовательский атрибут.
Документация: Alpha.DevStudio > Руководство пользователя > Разработка проекта > Добавление атрибутов > Создание пользовательских атрибутов
Примечание: Если, мы соберем описание всей ветки в атрибуте Description самого объекта Sens_X(датчика), то нарушим структуру сообщений в событиях (Alarms), т.к. сообщения уже автоматически формируются из описания самого объекта и вышестоящих объектов.
Создадим в нашем проекте пользовательский атрибут AllDescriptions типа string, в нем будем собирать описания ветки объектов.
На уровне сервера, всем экземплярам типа датчика - логическим объектам Sens_1,2… (представляющие сами датчики) добавим созданный ранее пользовательский атрибут AllDescriptions.
И в атрибутах AllDescriptions пропишем выражение:
@(System.Attributes.Description), @(@1:System.Attributes.Description), @(@2:System.Attributes.Description), @(@3:System.Attributes.Description)
Когда объектов очень много, удобнее открыть окно в виде таблицы и через Shift выбрать все строки столбца атрибута и вставить скопированное выражение.
@(System.Attributes.Description) – находим описание самого объекта.
@(@1:System.Attributes.Description) - описание объекта на 1 уровень выше, т.е. родителя и т.д.
И уже у самого параметра Pressure в типе датчика, в атрибуте пропишем следующее выражение:
Давление, @(object:Types.AllDescriptions)
@(object:Types.AllDescriptions) – ссылка на наш пользовательский атрибут объекта.
В итоге получим полное описание объектов по иерархии.

