Relative targets and lookups
Relative targets and lookups are available from NeuroomNet version 2026.3.
Normally the target of a component action is fixed: in the script block you select a specific component or group. With many similar stations this leads to a large number of almost identical blocks, for example one block per RFID reader, each addressing "its" exhibit.
With relative targets, the target is determined only when the action runs, starting from the component whose event triggered the block. A single block then covers all stations, and new stations work without changing the script as soon as they are placed correctly in the group hierarchy.
Basis: the group hierarchy
Relative targets use the groups, group types and levels from the Setup module (see Group levels and types). In the example there, groups of the group type "Exhibit" are on the level "Technology", with the levels "Room" and "Buildings" above.
Two kinds of membership need to be distinguished:
- Direct group: the group a component is assigned to, e.g. the exhibit the RFID reader belongs to. Using the user interface, a component is assigned to exactly one group.
- Parent groups: all groups above it, i.e. the room the exhibit is in, the building and so on. The component belongs to these indirectly.
A relative target always covers the chosen group including all its sub groups. Deactivated groups are left out together with their sub groups, just as with group actions.
For relative targets across levels to work, the groups must have group types that are assigned to levels. Without levels, the direct group is simply the group the component is assigned to.
One block for all components of a kind
To make a block trigger for every RFID reader, do not select a single reader as the event source, but a group and then the reader's event, e.g. TagRead. The block then triggers for every reader of this kind anywhere below the group. If you select the top group, for example the building, that is practically every reader.
All relative targets refer to the reader that actually triggered the event.
Target of a component action
For a component action, the field Target determines where the action goes:
| Target | The action goes to … |
|---|---|
| Selected component or group | the component or group selected in the script block (as before) |
| Triggering component itself | the component whose event triggered the block, e.g. a response to the RFID reader |
| Direct group of the triggering component | all matching components in the direct group of the triggering component, e.g. the exhibit at the same reader |
| Group of the triggering component on level … | all matching components in the parent group on this level, e.g. all exhibits in the same room |
| From local variable | all components or groups from a local variable, e.g. the result of a lookup |
Matching means: the component has the same interface as the selected action and, if the action was selected for a specific component type, that type as well. With "Direct group" and "Group on level", the triggering component itself is never included.
Direct group or group on a level? If the direct group of the triggering component is on the level you would select (e.g. reader and exhibit together in one station), both give the same result. The difference:
- Direct group is always the component's own group, whatever level it is on. If a reader is exceptionally assigned directly to a room, that is the room. This option needs no level and therefore also fits after transferring the script to another installation.
- Group on level … is exactly the group on this level, searched upwards from the component's own group. If the own group is already above the selected level, there is no match and the action is skipped.
For "the station the trigger belongs to", Direct group is therefore the rule. "Group on level …" is meant for higher levels, such as all exhibits in the same room.
If there are several matches, the action goes to all of them. If you do not want that, structure the groups more finely, e.g. with a separate group per work station.
You select the action itself as usual via any component of the desired kind. With a relative target, this component only determines the action and the interface; it is not addressed.
Example: RFID reader at an exhibit
A visitor holds their card to any RFID reader. The exhibit at this reader should greet the visitor, and the reader itself should show a confirmation. In addition, the card read last should be stored in a global variable.
- Event: group "Buildings", event
TagReadof the RFID reader. Capture the parameter with the card number in the global variableCurrentTag. - Action 1:
StartAnimationwith the valueloginon the RFID reader, target Triggering component itself. - Action 2:
VisitorDetectedon the exhibit with the card number, target Direct group of the triggering component.
This single block replaces one block per reader. When another exhibit with a reader is added, nothing in the script needs to change.
To try it out, the block can be run with test data, choosing the triggering reader.
Lookups: collecting targets in a variable
Sometimes the result of the search should be used further, for example to check whether anything was found at all, or to apply several actions to the same targets. For this there are three script actions that write their result to a local list variable (text):
| Script action | Result |
|---|---|
| Lookup Related Components | components connected to a component via the groups: in its direct group or in the parent group on a level, optionally only certain interfaces |
| Lookup Components for Groups | all components in the selected groups including sub groups, optionally only certain interfaces |
| Lookup Groups for Component | all groups of a component, i.e. the direct group and all parent groups |
If the component field is left empty, the search starts from the triggering component.
You then use the result in a component action with the target From local variable. The list may contain components of different interfaces: each action only reaches the components that match it, the others are silently skipped.
The variable operation Get List Length returns the number of entries found, for example to react to "nothing found" with an IF condition.
The variable contains technical identifiers of the components and groups, not display names.
When no target is found
If a relative target cannot be resolved, only this one action is skipped; the block continues. This happens when
- no matching component was found (e.g. because the group is deactivated),
- the block was not triggered by a component (e.g. by a timer),
- the triggering component does not match the action (e.g. an exhibit action with the target "Triggering component itself" for a reader event),
- a variable contains unknown components or groups (these are left out, the remaining targets are served).
The skipped action appears in Traffic as an error, with the reason and the details involved (triggering component, interface, level).
The script block already points out a missing trigger while editing: if an action needs the triggering component but the block has no event from a component or group, a warning appears at the action and the action card shows a warning sign.
Replacing an action or component
If you select a different component or a different action for an action or an event, matching settings are kept: fixed values, formulas, variable assignments and the relative target. A parameter is taken over if the new selection has a parameter with the same name and the same data type. A note directly below the selection lists what could not be taken over.
This way you can, for example, replace a device without assigning all parameters again, or switch from VisitorDetected to VisitorLeft without setting the target again.
Good to know
When are relative targets worthwhile?
The real benefit comes when one event stands for several components, i.e. an event on a group, an interface or a component type. Only then is it open at runtime which component triggered, and only a relative target can react to that.
Relative targets can also make sense for an event of a single component:
- Maintenance: if the exhibit in the group is replaced or the station is rebuilt, nothing in the script needs to change.
- Portability: a block with a relative target contains no fixed target component. When transferring it to another installation, only the trigger needs to be assigned.
"Triggering component itself", however, adds nothing for a single trigger, since it is already fixed.
Difference to the "Dynamic Component or Group Action"
The two solve different tasks and complement each other:
| Dynamic Component or Group Action | Relative targets and lookups | |
|---|---|---|
| Question | Which components within a group? | Where, starting from the triggering component? |
| Reference point | fixed: a group selected in the script block | determined only at runtime |
| Selection by | keywords and group type of the sub groups, keywords and status of the components | group hierarchy: direct group, parent group on a level, the trigger itself, a variable |
| Example | "Switch off all projectors tagged Foyer that are online" | "The exhibit at the RFID reader that just read a card" |
The dynamic action always starts from the same group, no matter which component triggered the block. With an event for "all readers" it would address the same components for every reader.
Conversely, relative targets do not filter by keywords or status. The two cannot currently be combined: a dynamic filter is not taken into account for a relative target.