Skip to content

Creating a daiquiri compatible BLISS controller

In order for daiquiri to be able to monitor the status of a BLISS controller and get real time updates, daiquiri requires that the BLISS controller implements channels in order to share the object property values as they change (via events). This is the same concept as for sharing an object between two bliss sessions. Internally daiquiri uses event.connect(object, "property", callback) to subscribe to changes on a BLISS object.

A number of the standard BLISS controllers already implement channels, for example, Axis, Multipleposition, and Shutter. For custom or specialised controllers, channels must be added manually.

Channels can be added in a couple of ways:

Simplest method using BeaconObject

https://gitlab.esrf.fr/bliss/bliss/-/blob/master/bliss/config/beacon_object.py

from bliss.config.beacon_object import BeaconObject

class IntraledController:
    def __init__(self, name, config):
        ...

    @BeaconObject.property(default=0)
    def intensity(self):
        return self._controller.get_intensity()

    @intensity.setter
    def intensity(self, intensity_value):
        # Change the value on the hardware device
        self._controller.set_intensity(intensity_value)

    ...

More involved using Cache directly

from bliss.config.channels import Cache
from bliss.common import event


class IntraledController:
    def __init__(self, name, config):
        ...

        # Initialise a `Cache` which provides a channel, with a default value, and callback
        # The callback is important for synchronisation
        self.__intensity = Cache(
            self, "intensity", default_value=0, callback=self.__intensity_changed
        )

    def __intensity_changed(self, intensity):
        """Send a signal when intensity changes"""
        event.send(self, "intensity", intensity)

    ...

    @autocomplete_property
    def intensity(self):
        return self._controller.get_intensity()

    @intensity.setter
    def intensity(self, intensity_value):
        # Change the value on the hardware device
        self._controller.set_intensity(intensity_value)

        # Update the value in the cache
        self.__intensity.value = intensity_value

    ...

Expected functionality

Now when the intensity is set via:

[session1]
led.intensity = 10

The intensity value will be synchronised between multiple copies of the object.

This can be tested with a few lines of code in a second BLISS session:

[session2]
def cb(*args, **kwargs):
    print("callback", args, kwargs)

led = config.get("led")

from bliss.common import event
event.connect(led, "intensity", cb)

Then in the original session change the led intensity as above, the callback should be executed and print the new values.

Examples of modified controllers

Below is a list of some of the controllers that have been modified to add channels, along with their diffs to explicitly show the changes required.

Intraled

Diff intraled.py

ID26 Attentuator

Diff attenuator.py

ID27 Laser

Diff laser.py