Let’s consider a common scenario in control system development: You’ve created an automation feature that orchestrates multiple devices via channel access. The sequence of actions is simple, but you must ensure that each step begins only after the previous one has completed successfully. How can you achieve this reliably?

Here are three options:

  1. Execute a step and wait some time before executing the next one.
  2. Execute a step and poll the device to check if the step has been finished
  3. Use the native Channel Access feature - putNotify to do the job.

Why Option 1 is problematic

The first option is the least reliable. Relying on fixed delays can lead to unpredictable behavior. If time isn’t the decisive factor in determining the success of a step, a simple time-based approach can cause errors.

Polling: A better, but imperfect solution

Option 2, polling, is more effective but introduces complexity. Client logic must implement the polling mechanism, which adds to the development effort. Frequent polling increases network traffic, potentially leading to performance issues, especially in a large installations.

The putNotify solution: Clean and elegant

Option 3—using the putNotify (or processNotify in newer versions of EPICS Base)—is the most robust and efficient solution. It simplifies client logic by eliminating the need for polling and reduces network traffic.

So, how do we use it? Let’s break it down.

The putNotify mechanism allows you to trigger a record and get notified whenn the process completes. For a detailed description of the mechanism look at the EPICS Application Developer’s Guide, section 5.11

For now, let’s stay with the simplified version of the mechanism, which could be simplified to

To use this mechanism, we can use the BUSY record which you can find in the busy module. It is basically a modified BO record that does not return immediately but pretends to be “busy” until another record changes its state to “Done”.

How It Works
The Busy record waits for some external condition or process to change its state to “Done”. Typically it is handled by device support. You can read more on how it works here.

A Simple Example
Let’s try the most straightforward example: putting a value to the bo record that starts some process.

Database:

record(bo, process){
    field(ZNAM, "0")
    field(ONAM, "1")
    field(OUT, "busy PP")
}

Using caput to interact with process record

Notice that caput returns immediately. What if the process takes time, and we would like to wait until the process is finished? Let’s add the busy record to the setup. (I’m not going to cover installation process, I assume that the EPICS base and support modules are installed on your machine).

Our database looks like the following.

record(bo, process){
    field(ZNAM, "0")
    field(ONAM, "1")
    field(OUT, "busy PP")
}

record(busy, busy){}

record(bo, process-done){
    field(DOL, "0")
    field(OMSL, "closed_loop")
    field(OUT, "busy PP")
}

Here’s what happens:

  1. The process record triggers the busy record.
  2. The busy record remains “Busy” until another record changes its state to “Done”.
  3. The process-done record eventually finishes the job, forcing the busy record into the “Done” state. This record is processed by the internal logic, which determines when the task triggered by the process record has completed.

To run the put command with putNotify mechanism, use the following command:

$ caput -c process 1

The command will wait until the process-done record is triggered.

By using the putNotify mechanism, you can ensure that each step of your automation sequence waits for the previous to finish, leading to more robust and reliable control systems. Obviously, it is on developers of individual device drivers to use the busy record in their implementations.

How to use it from IOC?
We can utilise a sscan record for that, but scanning is a topic for another time.

Final Thoughts
The putNotify feature is often overlooked and re-implemented at higher levels of the controls system.
Whether you’re new to EPICS or a seasoned developer, using busy record will improve the robustness of your automation.

Happy controlling!