Tango device TRL naming for hierarchical FastCS controllers — two options for community input
We are adding Tango support to FastCS,
a Python framework that auto-generates control-system interfaces from a class
hierarchy describing an instrument. We need community input on how to map that
hierarchy to Tango TRLs.
Context: the PandA example
PandA is a motion-sequencing controller
used at several UK/EU synchrotrons. A site may run multiple PandA boards, each
exposing a hierarchy of typed functional blocks, some with multiple instances
(vectors). In FastCS this maps to:
Panda ← top-level controller (one per physical board)
├── SeqVector
│ ├── Seq[1] ← has attributes: enable, prescale, table, …
│ └── Seq[2]
├── PulseVector
│ ├── Pulse[1]
│ └── Pulse[2]
└── Pcap ← singular block; attributes: enable, arm, …
Each node should become one Tango device exposing only its own attributes.
The question is how to assign TRLs, given that a deployment has – say – two
PandA boards on beamline BL04I. The EPICS PV convention at Diamond for the two
sequencer blocks on PandA board 2 is BL04I-EA-PANDA-02:SEQ:1 and
BL04I-EA-PANDA-02:SEQ:2.
Naming convention baseline (from community examples)
The Tango community norm we have observed (ESRF, Soleil, MAX IV, ALBA, DESY, SKA):
| TRL segment |
Meaning |
Style |
| domain |
site / facility / beamline |
uppercase or lowercase depending on site |
| family |
hyphen-joined device-type hierarchy |
lowercase-hyphen |
| member |
dot-joined instance indices |
purely numeric |
SKA reference (confirmed by SKA developer):
mid-cbf/mcs-fsp/01
mid-cbf/mcs-fsp-corr-subarray/01.03 ← FSP 01, subarray 03
Family = full type path; member = all instance indices in hierarchy order. This
gives clean wildcards: BL04I/panda-seq/* = every SEQ block on the beamline.
The challenge for PandA is that the board number (e.g. 2 for PANDA-02) is
not a ControllerVector index inside the FastCS hierarchy — it is the
identity of the top-level controller. There is no natural place in the path for
it. Two options follow.
Option A — Board number encoded in the controller id, split at the transport
The user names each top-level controller <type>-<n>. FastCS validates that
ids used with the Tango transport must end in -n where n is purely numeric
(e.g. panda-2 is valid; panda-2-ext is not). The transport strips the
trailing -n, using the string part for the family and the numeric part as the
first member index.
# fastcs.yaml (two PandA boards on BL04I)
controllers:
- id: panda-1
type: pandablocks.Panda
port: 8888
- id: panda-2
type: pandablocks.Panda
port: 8889
transport:
- tango:
domain: BL04I
TRL derivation: for a path like ["panda-2", "seq", 1], split the id into
string part panda and numeric part 2; collect all numeric parts
(id suffix + ControllerVector indices) into the member, all string parts into
the family.
| Device |
FastCS path |
TRL |
| PandA 2 — top-level |
["panda-2"] |
BL04I/panda/2 |
| PandA 2 — Pcap |
["panda-2", "pcap"] |
BL04I/panda-pcap/2 |
| PandA 2 — Seq[1] |
["panda-2", "seq", 1] |
BL04I/panda-seq/2.1 |
| PandA 2 — Seq[2] |
["panda-2", "seq", 2] |
BL04I/panda-seq/2.2 |
| PandA 1 — Seq[1] |
["panda-1", "seq", 1] |
BL04I/panda-seq/1.1 |
Wildcard examples:
- All Seq blocks on BL04I:
BL04I/panda-seq/* ✓
- All Seq blocks on PandA 2:
BL04I/panda-seq/2.* ✓
- All devices of PandA 2: no single wildcard (different family per block type)
Problem: a single board's devices span multiple families (panda,
panda-pcap, panda-seq, …), so there is no wildcard to select all devices
belonging to one physical board.
Option B — Full base TRL as the controller id
The controller id is itself a valid Tango TRL (D/F/M). FastCS derives
sub-controller TRLs by appending the relative sub-path (all segments,
hyphen-joined) to the member segment. FastCS validates every resulting TRL
before registering.
# fastcs.yaml (two PandA boards on BL04I)
controllers:
- id: BL04I/panda/1
type: pandablocks.Panda
port: 8888
- id: BL04I/panda/2
type: pandablocks.Panda
port: 8889
transport:
- tango: {}
TRL derivation: for id D/F/M and relative path [s1, s2, …],
the sub-controller TRL is D/F/M-s1-s2-….
| Device |
FastCS path |
TRL |
| PandA 2 — top-level |
["BL04I/panda/2"] |
BL04I/panda/2 |
| PandA 2 — Pcap |
["BL04I/panda/2", "pcap"] |
BL04I/panda/2-pcap |
| PandA 2 — Seq[1] |
["BL04I/panda/2", "seq", 1] |
BL04I/panda/2-seq-1 |
| PandA 2 — Seq[2] |
["BL04I/panda/2", "seq", 2] |
BL04I/panda/2-seq-2 |
| PandA 1 — Seq[1] |
["BL04I/panda/1", "seq", 1] |
BL04I/panda/1-seq-1 |
Wildcard examples:
- All devices of PandA 2:
BL04I/panda/2* ✓
- All PandA devices on BL04I:
BL04I/panda/* ✓
- All Seq blocks on BL04I:
BL04I/panda/*-seq-*
Problem: the member field mixes type names with instance indices
(2-seq-1), departing from the convention that member = purely numeric indices.
Tools that parse the member as structured numeric data would need to handle this.
Comparison
|
Option A |
Option B |
| Family |
Clean type hierarchy (panda-seq) |
Clean type hierarchy (panda) |
| Member |
Purely numeric (2.1) ✓ |
Mixed type + indices (2-seq-1) |
SKA family/member convention |
✓ matches |
✗ non-numeric member |
| Wildcard: all Seq blocks |
BL04I/panda-seq/* ✓ |
BL04I/panda/*-seq-* |
| Wildcard: all devices of one board |
No single wildcard |
BL04I/panda/2* ✓ |
| Wildcard: all PandA devices |
BL04I/panda*/ (catches other families) |
BL04I/panda/* ✓ |
| Config burden |
domain only |
Per-controller base TRL |
| Id constraint |
Must end in -n |
No constraint |
Question for the Tango community
Which option is preferable in practice — and does the choice matter for real
tooling at your facility?
- Does a non-numeric member (
2-seq-1, Option B) break any archiving, alarm,
or subscription tooling you use?
- Is the inability to wildcard across one physical board's devices (Option A) a
practical problem, or do users typically subscribe by device type rather than
by physical unit?
- Is there a third pattern we have not considered?
Tango device TRL naming for hierarchical FastCS controllers — two options for community input
We are adding Tango support to FastCS,
a Python framework that auto-generates control-system interfaces from a class
hierarchy describing an instrument. We need community input on how to map that
hierarchy to Tango TRLs.
Context: the PandA example
PandA is a motion-sequencing controller
used at several UK/EU synchrotrons. A site may run multiple PandA boards, each
exposing a hierarchy of typed functional blocks, some with multiple instances
(vectors). In FastCS this maps to:
Each node should become one Tango device exposing only its own attributes.
The question is how to assign TRLs, given that a deployment has – say – two
PandA boards on beamline BL04I. The EPICS PV convention at Diamond for the two
sequencer blocks on PandA board 2 is
BL04I-EA-PANDA-02:SEQ:1andBL04I-EA-PANDA-02:SEQ:2.Naming convention baseline (from community examples)
The Tango community norm we have observed (ESRF, Soleil, MAX IV, ALBA, DESY, SKA):
SKA reference (confirmed by SKA developer):
Family = full type path; member = all instance indices in hierarchy order. This
gives clean wildcards:
BL04I/panda-seq/*= every SEQ block on the beamline.The challenge for PandA is that the board number (e.g.
2forPANDA-02) isnot a
ControllerVectorindex inside the FastCS hierarchy — it is theidentity of the top-level controller. There is no natural place in the path for
it. Two options follow.
Option A — Board number encoded in the controller id, split at the transport
The user names each top-level controller
<type>-<n>. FastCS validates thatids used with the Tango transport must end in
-nwherenis purely numeric(e.g.
panda-2is valid;panda-2-extis not). The transport strips thetrailing
-n, using the string part for the family and the numeric part as thefirst member index.
TRL derivation: for a path like
["panda-2", "seq", 1], split the id intostring part
pandaand numeric part2; collect all numeric parts(id suffix + ControllerVector indices) into the member, all string parts into
the family.
["panda-2"]BL04I/panda/2["panda-2", "pcap"]BL04I/panda-pcap/2["panda-2", "seq", 1]BL04I/panda-seq/2.1["panda-2", "seq", 2]BL04I/panda-seq/2.2["panda-1", "seq", 1]BL04I/panda-seq/1.1Wildcard examples:
BL04I/panda-seq/*✓BL04I/panda-seq/2.*✓Problem: a single board's devices span multiple families (
panda,panda-pcap,panda-seq, …), so there is no wildcard to select all devicesbelonging to one physical board.
Option B — Full base TRL as the controller id
The controller id is itself a valid Tango TRL (
D/F/M). FastCS derivessub-controller TRLs by appending the relative sub-path (all segments,
hyphen-joined) to the member segment. FastCS validates every resulting TRL
before registering.
TRL derivation: for id
D/F/Mand relative path[s1, s2, …],the sub-controller TRL is
D/F/M-s1-s2-….["BL04I/panda/2"]BL04I/panda/2["BL04I/panda/2", "pcap"]BL04I/panda/2-pcap["BL04I/panda/2", "seq", 1]BL04I/panda/2-seq-1["BL04I/panda/2", "seq", 2]BL04I/panda/2-seq-2["BL04I/panda/1", "seq", 1]BL04I/panda/1-seq-1Wildcard examples:
BL04I/panda/2*✓BL04I/panda/*✓BL04I/panda/*-seq-*Problem: the member field mixes type names with instance indices
(
2-seq-1), departing from the convention that member = purely numeric indices.Tools that parse the member as structured numeric data would need to handle this.
Comparison
panda-seq)panda)2.1) ✓2-seq-1)family/memberconventionBL04I/panda-seq/*✓BL04I/panda/*-seq-*BL04I/panda/2*✓BL04I/panda*/(catches other families)BL04I/panda/*✓domainonly-nQuestion for the Tango community
Which option is preferable in practice — and does the choice matter for real
tooling at your facility?
2-seq-1, Option B) break any archiving, alarm,or subscription tooling you use?
practical problem, or do users typically subscribe by device type rather than
by physical unit?