Control System set up#

The control system interface is in a separated package from pyaml

pyaml itself:
pip install accelerator-middle-layer

tango interface to pyaml:
pip install tango-pyaml

ophyd-asynch interface to pyaml:
pip install pyaml-oa-cs

If the above packages are installed the examples below will work

from pyaml.accelerator import Accelerator

Assuming these lines are present in …/…/tests/config/EBSTune_TANGO.yaml

type: pyaml.accelerator
name: sr
energy: 6e9
controls:
  - type: tango.pyaml.controlsystem
      tango_host: ebs-simu-3:10000
      name: live
...
powerconverter:
      type: tango.pyaml.attribute
...
tune_h:
    type: tango.pyaml.attribute_read_only
...
# work with TANGO
SR_Tango: Accelerator = Accelerator.load("../../tests/config/EBSTune.yaml")
---------------------------------------------------------------------------
PyAMLConfigException                      Traceback (most recent call last)
Cell In[2], line 2
      1 # work with TANGO
----> 2 SR_Tango: Accelerator = Accelerator.load("../../tests/config/EBSTune.yaml")

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/accelerator.py:304, in Accelerator.load(filename, include_locations, ignore_external)
    299 except UnsupportedConfigurationRootError as ex:
    300     raise PyAMLConfigException(
    301         "Accelerator.load() expects a 'pyaml.accelerator' root configuration. "
    302         "Use the factory APIs to build sub-elements directly."
    303     ) from ex
--> 304 return manager.build(ignore_external=ignore_external)

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/manager.py:496, in ConfigurationManager.build(self, ignore_external)
    494     ROOT.set(self._build_root)
    495 snapshot = ConfigurationManager.strip_runtime_internal_metadata(self._snapshot(include_internal_metadata=True))
--> 496 return Accelerator.from_dict(snapshot, ignore_external=ignore_external)

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/accelerator.py:275, in Accelerator.from_dict(config_dict, ignore_external)
    273 # Ensure factory is clean before building a new accelerator
    274 Factory.clear()
--> 275 return Factory.build(config_dict, ignore_external)

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:557, in PyAMLFactory.build(self, data, ignore_external)
    554     return self._build_list(data, ignore_external)
    556 elif isinstance(data, dict):
--> 557     data = self._build_dict(data, ignore_external)
    558     if data is None:
    559         return None

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:401, in PyAMLFactory._build_dict(self, data, ignore_external)
    398         # Do not recurse dict defined in ConfigModel
    399         # pydantic use TypedDict not usable with isinstance
    400         if not self._is_plain_dict_type(field_type):
--> 401             result[key] = self.build(value, ignore_external)
    403 return result

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:554, in PyAMLFactory.build(self, data, ignore_external)
    551     raise PyAMLConfigException(f"Unexpected element found. 'dict' or 'list' expected but got '{type(data).__name__}'")
    553 if isinstance(data, list):
--> 554     return self._build_list(data, ignore_external)
    556 elif isinstance(data, dict):
    557     data = self._build_dict(data, ignore_external)

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:362, in PyAMLFactory._build_list(self, items, ignore_external)
    357 def _build_list(self, items, ignore_external: bool):
    358     """
    359     Recursively build all nested objects contained in a list.
    360     """
--> 362     return [self.build(item, ignore_external) if isinstance(item, (dict, list)) else item for item in items]

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:557, in PyAMLFactory.build(self, data, ignore_external)
    554     return self._build_list(data, ignore_external)
    556 elif isinstance(data, dict):
--> 557     data = self._build_dict(data, ignore_external)
    558     if data is None:
    559         return None

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:382, in PyAMLFactory._build_dict(self, data, ignore_external)
    373 def _build_dict(self, data: dict, ignore_external: bool):
    374     """
    375     Recursively build nested objects referenced by a configuration
    376     dictionary.
   (...)    379     recursive build process and are left unchanged.
    380     """
--> 382     build_info = resolve_build_info(data, ignore_external)
    384     if build_info is None:
    385         return None

File ~/checkouts/readthedocs.org/user_builds/pyaml/envs/latest/lib/python3.13/site-packages/pyaml/configuration/factory.py:238, in resolve_build_info(data, ignore_external)
    236     if ignore_external:
    237         return None
--> 238     raise PyAMLConfigException(
    239         f"Module referenced in {module_str} cannot be found: {module_ex} {location_str} while"
    240     ) from None
    242 # Get the object class name
    243 if class_str is None:

PyAMLConfigException: Module referenced in tango.pyaml.controlsystem cannot be found: No module named 'tango'  while

Assuming these lines are present in …/…/tests/config/EBSTuneOATango.yaml

type: pyaml.accelerator
name: sr
energy: 6e9
controls:
  - type: pyaml-cs-oa.pyaml.controlsystem
      name: live
...
 powerconverter:
      type: pyaml_cs_oa.tangoRW
...
 tune_h:
    type: pyaml_cs_oa.tangoR

this works with Ophyd-Asynch - tango:

SR_OphydAsynch_Tango: Accelerator = Accelerator.load(”…/…/tests/config/EBSTuneOATango.yaml”)

Assuming these lines are present in …/…/tests/config/EBSTuneOAEpics.yaml

type: pyaml.accelerator
name: sr
energy: 6e9
controls:
  - type: pyaml-cs-oa.pyaml.controlsystem
      name: live
...
 powerconverter:
      type: pyaml_cs_oa.epicsRW
...
 tune_h:
    type: pyaml_cs_oa.epicsR

This work with Ophyd-Asynch - epics :

SR_OphydAsynch_Epics: Accelerator = Accelerator.load(”…/…/examples/BESSY2_example/BESSY2Tune.yaml”)