Collection of Agents and Simulations for ACSS. Note: To run the project local you need to install ACSS Core on your machine which can be found at github (https://github.com/desy-ml/acss-core).
First you need to clone the repository.
Because each agent is an own project with it's own dependencies (Pipfile) you need to navigate to the Agent's directory first. For example:
cd agents/orbit
Inside the directory you have to set the config.yaml file to tell the Agent where to find the ACSS Core Services.
Here is an example of config.yaml file.
Notes: You have to replace localhost with the real server name if the ACSS Core Services aren't running on your local machine.
observer:
# used to check if jbb is done
url: localhost:5003
event_db_pw: xxxxx
# event_db_url:
event_db_usr: root
register:
# registers all services
url: localhost:5004
simulation:
# sql database which maps the machine parameter
sim_db_pw: xxxxx
sim_db_usr: root
sim_db_url: localhost:3306
msg_bus:
# message bus
broker_urls: localhost:9094,localhost:9096
Afterwards, set the path to the config yaml file with ACSS_CONFIG_FILEPATH and the root path with PATH_TO_ACSS_SERVICES_ROOT.
export ACSS_CONFIG_FILEPATH = /path/to/acss-config.yaml
export PATH_TO_ACSS_SERVICES_ROOT = /path/to/acss-services
Additionally the path to the project have to be set in the PYTHONPATH environment variable
export PYTHONPATH = /path/to/acss-services
Alternatively, setting the env values can be also done by defining an .env file in the root folder. The file's content look like this
ACSS_CONFIG_FILEPATH = /path/to/acss-config.yaml
PATH_TO_ACSS_SERVICES_ROOT = /path/to/acss-services
PYTHONPATH = /path/to/acss-services
To run an Agent you need to activate the python env. This will automatically load the env values in .env if defined.
python3 -m pipenv shell
Afterwards you can run the Agent inside the environment
python agents/testing/silly_agent.py
To interact with ACSS (e.g trigger, start, list, stop Agents) you can used KafkaPipeClient which is a part of the acss_core lib that can be installed with pip.
from acss_core.client.utils import get_services
agts, sims = get_services()
agts['SillyAgent'].run()
To create an Agent you need to clone the ml-pipe-service repository first.
Afterwards create a new directory under the Agent directory.
cd agents && mkdir test_agent
Set up a virtual environment inside the directory
cd test_agent
mkdir .venv
python3 -m pipenv install
Note: pipenv can be installed with pip on your local python
python3 -m pip install pipenv
Now install the package acss-core with pipenv.
python3 -m pipenv install acss-core
The package acss-core provides different adapters to get parameters from the machine or simolation. In this example PetraMachineAdapter is used
from acss_core.adapter.petra.PetraMachineAdapter import PetraMachineAdapter
Afterwards you create a class which inherits form SimpleService.
class SillyAgent(SimpleService):
def __init__(self, name, read):
super().__init__(name, read)
self.factor = 1.0
self.machine_adapter = PetraMachineAdapter.create_for_agent(self)
def info(self):
return "Agent reads horizontal corrector currents and multiply a factor to each current. The factor can be reconfigured."
def reconfig_event(self, msg):
factor = msg.get('factor')
if factor is None:
_logger.error("reconfig message doesn't have 'factor' as a key.")
else:
_logger.debug(f"set new factor to: {factor}")
self.factor = factor
exclude_cor = msg.get('exclude_cor')
if exclude_cor != None:
self.machine_adapter.ignore_hcors(exclude_cor)
self.machine_adapter.ignore_vcors(exclude_cor)
def proposal(self, params):
_logger.debug(f"use factor: {self.factor}")
hcors = self.machine_adapter.get_hcors(names=self.machine_adapter.get_hcor_device_names(), is_group_call=True)
vcors = self.machine_adapter.get_vcors(names=self.machine_adapter.get_vcor_device_names(), is_group_call=True)
self.machine_adapter.set_hcors(self.machine_adapter.get_hcor_device_names(), [val * self.factor for val in hcors])
self.machine_adapter.set_vcors(self.machine_adapter.get_vcor_device_names(), [val * self.factor for val in vcors])
self.machine_adapter.commit()
Inside this class you need to overload
def proposal(self, params)
which will be called when the Agent is triggered.
To read and write the Machine/Simulation parameter you can use the read and write member functions of the Agent. Here is an example for Petra:
def proposal(self, params):
vcors = self.read('/PETRA/Cms.PsGroup', 'PeCorV', 'GroupDevices')
self.write("/PETRA/Cms.PsGroup", 'PeCorV', 'Strength.Soll', input=vcors)
The read callable have to be set while initializing the Agent. Currently only a Reader for the "Tine" Control System is implemented.
if __name__ == '__main__':
agent = SillyAgent('silly_agent', read=TineSimReader.create_for_petra())
agent.init_local()
It is possible to write your own Reader and Writer for an other Control System by defining a read and write callable which fullfil the read/write interface:
def __call__(self, channel: str, device: str, _property: str, **kwargs):
#custom code
Optionally you can overload
def reconfig_event(self, msg):
#custom code
which give you the possibility to reset internal parameters without restarting your Agent.