This release is a pre-release and may not be stable for production use.
dls_va_ioc_sim
Simulate a DLS vacuum IOC, and the PLC behind it.
Everything a PLC would decide — valve interlocking, combining a gauge pair, the pressure itself — is decided here instead, and served over Channel Access so that a screen, an archiver or another IOC cannot tell it apart from the real thing. The PV interface mirrors the DLS support-module templates device for device.
An instance is generated from the builder XML the real IOC is built from, so simulating a cell is a one-liner rather than a writing job.
| What | Where |
|---|---|
| Source | https://github.com/DiamondLightSource/dls-va-ioc-sim |
| PyPI | pip install dls-va-ioc-sim |
| Docker | docker run ghcr.io/diamondlightsource/dls-va-ioc-sim:latest |
| Releases | https://github.com/DiamondLightSource/dls-va-ioc-sim/releases |
Generating a simulation
$ dls-va-ioc-sim generate .../SR-BUILDER/etc/makeIocs/SR03C-VA-IOC-01.xml 99
wrote sr99c-va-ioc-01.py
One file, named after the IOC in lower case, and it is the IOC and its launcher
both. The 99 rewrites the cell number in every device name, so SR03C comes
up as SR99C and the simulation cannot be taken for the real machine — as does
the non-standard Channel Access port it serves on, which is set at the top of
the file itself.
$ ./sr99c-va-ioc-01.py
A PEP 723 header names the version of this
package that wrote it and a uv run --script shebang starts it, so an instance
runs wherever uv does with nothing installed
first, and goes on running when the framework moves on. In an environment that
already has the package, python sr99c-va-ioc-01.py is the same thing.
Two simulations at once want two ports, and the environment still wins:
$ EPICS_CA_SERVER_PORT=6066 EPICS_CA_REPEATER_PORT=6067 ./sr99c-va-ioc-01.py
Then drive it over Channel Access. Stopping pumps makes the pressure rise, starting them brings it back, and opening a valve equalises two volumes:
$ caput SR99A-VA-GIONP-01:STOP 1 # a whole group of supplies
$ camonitor SR99A-VA-GAUGE-01:P # watch it come up
A whole ring at once
start serves any number of written instances as a single IOC, on one port —
which is what a container wants, and the only shape that works where every pod
shares a node's network stack:
$ dls-va-ioc-sim start sr*.py --no-interactive
24 instance(s), 49920 records, 1032 devices: sr01c-va-ioc-01.py, …
One instance behaves exactly as running that instance does. Generate each cell with its own number: distinct PV names are what let them share one database.
To look at a cell without committing to a file, run builds the same devices
straight from the XML:
$ dls-va-ioc-sim run .../SR03C-VA-IOC-01.xml 99
The one thing the XML cannot say
A builder XML says which devices exist and which groups they are in. It says nothing about the beam pipe — which valve stands between which two lengths of it, how many litres a section holds, what it outgasses. On the real machine that comes off a P&ID.
So the generated file carries a vacuum layout marked *** EDIT ME ***: one
volume per domain, joined by nothing, with capacities and gas loads guessed from
the installed pumping speed. It runs out of the box and it is not the beam pipe.
Making it the machine means splitting a domain where a valve really divides it
and putting a gate() between the halves:
vacuum = vacuumLayout(
straight,
gate("SR99A-VA-VALVE-01"),
arc,
)
A gate's neighbours are simply the entries either side of it, so there is no second place for the topology to disagree with itself.
Generate, then edit. The generator refuses to overwrite an existing pair
without --force, because the layout in the one you have is the only part that
took any thought.
Three layers
The thing to hold onto is that "space" and "volume" are different concepts that used to share a name:
- A volume is a length of beam pipe: it holds gas, it has a capacity in litres, and pumps and gauges sit on it. It publishes nothing — no real IOC has a record for how many litres a section holds.
- A group (
GIONP-nn,GVALV-nn, …) is a device standing for several others. Writing toGIONP-01:STARTstarts every pump underneath it, and a group's members may themselves be groups. - A space (
SPACE-nn) is what an operator is shown: a pressure, a status lamp and controls. It owns nothing — every record either reads a group or writes to one.
Pressure belongs to a volume, not to a device. A group of volumes settles where its total gas load balances its total pumping speed, so the interesting behaviour is emergent rather than scripted: opening a valve onto a vented section spoils the good side and trips its ion pumps on high pressure, and a tripped pump stays latched until its volume is back below its setpoint.
Verifying a change
Build the database and diff it against the version before your change:
$ dls-va-ioc-sim dbdump sr99c-va-ioc-01.py before.db
$ # ...make the change...
$ dls-va-ioc-sim dbdump sr99c-va-ioc-01.py after.db
$ diff before.db after.db
For a change to how an instance is assembled, expect that diff to be empty — byte identical, not shape identical. For a change to a device class it is meant to be non-empty, and is then the record-by-record statement of what you changed. That is a far stronger check than running the IOC and a far cheaper one. Diff before you run.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dls_va_ioc_sim-1.0.0b6.tar.gz.
File metadata
- Download URL: dls_va_ioc_sim-1.0.0b6.tar.gz
- Upload date:
- Size: 211.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
468051a2ac9a752bc8e7387e825e9b1793de86e9396b7c0256cfae97bbe748cc
|
|
| MD5 |
be564683d9411a35822092a3631b075f
|
|
| BLAKE2b-256 |
a9786d27d89bc28362f459c2e33df750a4088adcda39fc3aed1727337104b0b6
|
File details
Details for the file dls_va_ioc_sim-1.0.0b6-py3-none-any.whl.
File metadata
- Download URL: dls_va_ioc_sim-1.0.0b6-py3-none-any.whl
- Upload date:
- Size: 92.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36296f7d1bf4d5de59f669327c79981e89dd0147e798ddb9c952f1fd2f90e96c
|
|
| MD5 |
dc07ca4a81a940423bff4822c22b5886
|
|
| BLAKE2b-256 |
45c05d51b158cb19887bfd0fe6354efb2747364b1d3f3498b563b014fcf83b20
|