Skip to content

Derived tags

A derived tag, also called a virtual tag, is a value that Profinity computes automatically and that then behaves exactly like a real tag to every consumer. Dashboards, the historian, rules, and the API all use the same quality and timestamp and can subscribe to it the same way. You configure the computation once, and Profinity keeps it current.

Profinity 2.3 computes a derived tag's value in one of two ways:

  • An expression recomputes whenever a source tag changes and needs no scripting.
  • A script suits a computation that needs more than a single expression.

The table under Expression vs script shows which one fits a given case.

flowchart LR
    Source["Source tags"] --> Calc["Expression or script"] --> Derived["Derived tag"] --> Consumers["Dashboards, historian, rules, API"]
Profinity computes a derived tag from source tags with an expression or a script, and dashboards, the historian, rules and the API then use it like any other tag

Open the derived tags editor

Select DERIVED TAGS under TAG UTILITIES in the side menu. The editor opens as a window over the current page. It needs the View tag collections permission and a loaded profile.

The Derived tags YAML file (optional) setting in the Tags category of the profile settings names the file the editor works on. The editor shows derived tags in a tree of groups on its left side. Select a group or derived tag to open its settings in the inspector on the right.

The Derived Tags editor with one derived tag, Total Array Power, showing its mount path, three dependencies and the expression a.Value + b.Value + c.Value.

Derived Tags editor

Expression-based derived tags

An expression-based derived tag has two parts:

  • One or more dependencies, which are short aliases mapped to source tag paths.
  • A formula that combines the aliases.

It recomputes the moment any dependency changes. To create one, refer to Create a derived tag.

Groups exist only for organisation, and a group can set a mount path:

  • A derived tag with a relative mount path mounts underneath its group's mount path.
  • A derived tag that gives its own absolute path mounts there instead.
  • A nested group's mount path narrows further under its parent's.

Each alias exposes only the reading members: Value, Text, Bool, HasValue, Quality, and IsStale. Path methods such as MatchesPath belong in collections and rules, as described in Tag expressions. An expression can be up to 4096 characters long.

Quality of a derived tag

A derived tag is only as trustworthy as its inputs. By default its quality is the worst of its dependencies' qualities, ranked from best to worst as Good, Stale, Unavailable, and Bad. A derived tag built on a stale input is therefore stale, and it still computes from the input's last value. A derived tag built on an input with no value is unavailable.

To handle missing inputs yourself, for example with a.HasValue, set inputQuality: ignore on the derived tag in the YAML. The YAML is derived_tags.yaml by default, in the derived_tags folder of the profile directory, which is inside the artefacts directory. Profinity reloads the file when it changes, so a hand edit takes effect while Profinity keeps running. If the edited file is unreadable, Profinity keeps the derived tags it already has.

With inputQuality: ignore, the tag evaluates whatever the input quality, and is Good when the expression succeeds. Without that setting, the default inputQuality: propagate applies and the quality follows the worst dependency.

Deleting a derived tag that others depend on

If another derived tag lists the tag being deleted under its dependencies, the editor names those derived tags and asks for confirmation before the delete goes through. Rule expressions are not checked.

Expression vs script

When one expression is not enough, write a script instead. Examples are a computation with several steps, state carried between runs, or several published tags. Refer to Create a derived tag with a script.

Use an expression when... Use a script when...
The computation is simple real-time maths, a unit conversion, or combining a handful of tags The logic needs multiple steps, branching, or state carried between runs
You want automatic history from the defaults You need a timed or on-demand trigger rather than pure tag-change reactivity
You want to populate several tags from one computation

Permissions

The derived tags editor uses the same permission pair as collections. Reading needs View tag collections, and saving needs Modify tag collections. Refer to Roles and permissions for how permissions are granted. Integrators can also use the API.

For the rest of the tag layer, refer to Tag layer, Tag collections, and Script types.