Examples

This section contains a few extra examples.

Simple example

The following example shows the definition of a rectangle device, getting its width and height from other devices:

from facadevice import Facade, logical_attribute, proxy_attribute


class Rectangle(Facade):
    Width = proxy_attribute(property_name="WidthAttribute")

    Height = proxy_attribute(property_name="HeightAttribute")

    @logical_attribute(bind=["Width", "Height"])
    def Area(width, height):
        return width * height


if __name__ == "__main__":
    Rectangle.run_server()

A rectangle device is configured using 2 device properties, e.g.:

  • WidthAttribute: geometry/point/a/x

  • HeightAttribute: geometry/point/b/y

The remote attributes are expected to push either change or periodic events.

A rectangle device exposes 3 float attributes:

  • Width

  • Height

  • Area

Those attributes will be updated as soon as a corresponding event is received. They also pushes events, allowing other high-level devices to react to their changes.

Real-world example

A real-world example of a camera screen device used at MAX-IV:

from tango import DevState

from facadedevice import (
    Facade,
    logical_attribute,
    proxy_attribute,
    proxy_command,
    state_attribute,
)


class CameraScreen(Facade):
    # Proxy attributes

    StatusIn = proxy_attribute(dtype=bool, property_name="StatusInAttribute")

    StatusOut = proxy_attribute(dtype=bool, property_name="StatusOutAttribute")

    # Logical attributes

    @logical_attribute(dtype=bool, bind=["StatusIn", "StatusOut"])
    def Error(self, status_in, status_out):
        return status_in and status_out

    @logical_attribute(dtype=bool, bind=["StatusIn", "StatusOut"])
    def Moving(self, status_in, status_out):
        return not status_in and not status_out

    # Proxy commands

    @proxy_command(property_name="MoveInAttribute", write_attribute=True)
    def MoveIn(self, subcommand):
        subcommand(1)

    @proxy_command(property_name="MoveOutAttribute", write_attribute=True)
    def MoveOut(self, subcommand):
        subcommand(1)

    # State and status

    @state_attribute(bind=["Error", "Moving", "StatusIn"])
    def state(self, error, moving, status_in):
        if error:
            return DevState.FAULT, "A conflict has been detected"
        elif moving:
            return DevState.MOVING, "The screen is moving"
        elif status_in:
            return DevState.INSERT, "The screen is inserted"
        else:
            return DevState.EXTRACT, "The screen is exctracted"


if __name__ == "__main__":
    CameraScreen.run_server()