############ Command map ############ Purpose ------- The *command map* is a Python dictionary used as a knowledge base to describe how CSP.LMC commands are decomposed into a hierarchy of Tasks and LeafTasks (i.e. a MainTask task-tree). Command maps are defined for both the CSP Controller and CSP Subarray. Each command definition includes metadata used for execution management (e.g. execution type and allowed conditions) and the list of subtasks to be executed on connected subsystems. Internal CSP.LMC operations can also be represented in the map. In that case, the ``command_name`` parameter corresponds to the Component Manager method to be invoked. A key benefit of this approach is the decoupling between command definition and execution logic, allowing updates to the command structure without modifying the TaskComposer and TaskExecutor code. The command map is consumed by the :doc:`maintask_composer` component. Top-level structure ------------------- The command map is keyed by command name (e.g. ``on``, ``configure``). Each command entry may include: * ``type`` (mandatory for composite tasks) Execution strategy of the task. Supported values: ``parallel``, ``sequential``. * ``allowed_states`` (mandatory for executable root commands) Specifies a guard condition evaluated before building/targeting tasks. * ``attr_name``: name of the attribute to check (e.g. ``state``, ``obs_state``) * ``attr_value``: list of allowed values for that attribute * ``tasks`` (mandatory for composite tasks) Dictionary of subtasks. Keys identify either: * a nested task node (arbitrary name), or * a *handler keyword* resolved by the MainTaskComposer. Handler keywords ---------------- Some subtask keys are interpreted as *handler keywords* and are resolved by the TaskComposer into LeafTasks (or Tasks grouping multiple LeafTasks) targeting specific subsystems or internal operations. The following handler keywords are supported by the current implementation: * ``cbf``, ``pss``, ``resource_manager`` Create a DEVICE LeafTask targeting the corresponding subsystem component selected from the Component Manager context. * ``pst`` Creates a PARALLEL Task containing one DEVICE LeafTask per applicable PST beam (typically all online beams and/or beams referenced by the current resources configuration). * ``csp_subs`` Creates a PARALLEL Task containing one DEVICE LeafTask per online CSP subarray (controller use-case). * ``internal`` Creates an INTERNAL LeafTask targeting the Component Manager itself. The command name corresponds to a CM method invoked internally. Leaf task properties -------------------- For handler keywords producing LeafTasks, the following properties may be present in the map: * ``command_name`` (mandatory) Name of the command to execute. For DEVICE tasks, this is the TANGO command name. For INTERNAL tasks, it is the Component Manager method name. * ``reject_missing`` (optional, default: ``False``) When enabled, task composition is rejected if a subsystem/device explicitly requested by the current resources configuration cannot be converted into a LeafTask because it is unavailable or not in one of the allowed states. * ``skip_subtasks`` (optional, default: ``False``) Controls sequential execution behaviour. When enabled on a task or subtask in a sequential chain, subsequent subtasks may be skipped if a failure is detected during execution. Note: this flag has no effect for subtasks of parallel tasks. .. note:: Although ``reject_missing`` is supported by the composer as a generic task-composition option, it is currently used only by the ``configure`` command and it is applied to ``pst``, ``pss`` and ``cbf`` subtasks to ensure that task composition fails fast if a required target cannot be included in the execution tree. Resources-based targeting ------------------------- Task composition depends on the resources dictionary available in the Component Manager context. This dictionary is keyed by subsystem FQDN. Each matching entry identifies a target device to which the command should be forwarded. If the corresponding value is ``None``, the command is issued without argument; otherwise, the associated value is used as command input argument. For subsystem handlers such as ``cbf``, ``pss`` and ``pst``, the composer filters candidate devices according to: * their presence in the resources configuration; * their availability in the online components set; * their compliance with the allowed state condition. If ``reject_missing`` is set to ``True``, task composition fails when a requested device cannot be converted into a valid LeafTask. Example ------- The following example shows a Controller command map entry for the ``on`` command: .. code-block:: python :caption: Command map example - Controller device "on": { "type": "parallel", "allowed_states": { "attr_name": "state", "attr_value": [ DevState.OFF, DevState.STANDBY, DevState.UNKNOWN, ], }, "tasks": { "csp_subs": {"command_name": "on"}, "resource_manager": {"command_name": "on"}, "pst": {"command_name": "on"}, "pss": {"command_name": "on"}, "cbf": {"command_name": "on"}, }, }