# Adding a new service ## Python setup Install the [uv](https://docs.astral.sh/uv/) package manager ## CLI (Command-Line Interface) We have our own cli called `agebd`. To use the cli, first clone this repo. Then: ``` cd cli uv sync source .venv/bin/activate agebd --help ``` ### Adding a new service ``` agebd service add --help ``` **This command has side effects you should know about before running it.** It requires a clean working tree, then it: 1. Assigns the service the next free IOC port and registers it in [`config/services_registry.yml`](https://gitea.psi.ch/sls/hla_framework_bd/src/branch/main/config/services_registry.yml). 2. Adds the service to `AGEBD-CPCL-MASTER`'s IOC pattern file, so it gets the standard ALH lifecycle PVs (`AGEBD-ALH$(SUFFIX):$(SERVICE)-*`) and appears in the `ServiceManager` GUI screen. 3. Appends a row to [`iocs_overview.md`](ioc/iocs_overview.md). 4. Creates a new branch **`feature/add-service-`**, scaffolds the new service's files from the templates, and **pushes the branch automatically** — you don't run `git push` yourself. Pushing that branch triggers the `Add new service` Gitea Actions workflow (`.gitea/workflows/add-new-service.yml`), which deploys `master`, installs/restarts its IOC, deploys your new service, and installs/starts its own IOC — all in `dev`. Check the Actions tab for that run to confirm it succeeded before doing anything else with the new service. ## Environments The services are deployed to 2 environments: | Environment | Network | Host | Deploy path on host | |---|---|---|---| |`prod` | `machine`| `sls-vserv-bd-hla01` | `/sls/bd/hla/prod/` | | `dev` | `office` | `sls-vserv-bd-hla01-dev` | `/sls/bd/hla/dev/` | ### Process Variables (PVs) We distinguish between - `prod` vs `dev` PVs - **service specific** PVs from a dedicated IOC vs **external** PVs from other IOCs #### PVs - Service Specific These are defined as EPICS records in your service's own `services//current/ioc/*.template` file, instantiated by `services//current/ioc/AGEBD-CPCL-_main.subs`. `prod` and `dev` PVs automatically get created: at deploy time, `{{ agebd_env_suffix_upper }}`/ `{{ agebd_env_suffix_lower }}` placeholders in those files are substituted with `-DEV`/`-dev` in `dev`, or left empty in `prod` (see `.gitea/scripts/deploy-service.sh`). In your code, you only use the `prod` name of a PV, e.g. `PV("AGEBD-MYSERVICE:MYPVNAME")`. The `PVLink`/`DevPVLink` framework (`packages/agebd/src/agebd/pv.py`) automatically appends `-DEV` when the service runs in `dev` — but **only** for PVs belonging to your own service, plus `AGEBD-ALH`/`AGEBD-MASTER`. See "External" below for PVs owned by another service. #### PVs - External PVs owned by another service (including another AGEBD service, e.g. `AGEBD-PARAMS:...` used from a different service) or by real accelerator hardware (e.g. `ARS01-MOCT-...`) are used verbatim — no `-DEV` suffix is ever added, even in `dev`. #### PVs - Examples | Environment | Service Specific | External | |---|---|---| |`prod` | `PV("AGEBD-MYSERVICE:MYPVNAME")` read&write | `PV("AGEOP-SOME-SERVICE:SOME-PVNAME")` read&write | | `dev` | `PV("AGEBD-MYSERVICE-DEV:MYPVNAME")` read&write | `PV("AGEOP-SOME-SERVICE:SOME-PVNAME")` readonly | ### Python For python services there are 3 environments. The python environment is set through the env variable `AGEBD_ENV`. | Environment | PVs | |---|---| | `AGEBD_ENV=prod` | uses `prod` PVs | | `AGEBD_ENV=dev` | uses `dev` PVs | | `AGEBD_ENV=local` | uses fake/mock python objects as PVs, no access to real PVs |