Component subpackage

This module implements infrastructure for component management in MCCS.

class ComponentManagerWithUpstreamPowerSupply(hardware_component_manager, power_supply_component_manager, logger, max_workers, communication_state_callback, component_state_callback, **state)

A component manager for managing a component and a separate upstream power supply.

MCCS manages numerous hardware devices that can’t turn turn themselves off and on directly. Rather, in order for a Tango device to turn its hardware off or on, it needs to contact the Tango device for an upstream device that supplies power to the hardware, and tell that tango device to supply/deny power to the hardware.

This class implements a pattern for this common situation.

__init__(hardware_component_manager, power_supply_component_manager, logger, max_workers, communication_state_callback, component_state_callback, **state)

Initialise a new instance.

Parameters:
  • hardware_component_manager (MccsBaseComponentManager) – the component manager that manages the hardware (when it is turned on).

  • power_supply_component_manager (MccsBaseComponentManager) – the component manager that manages supply of power to the hardware.

  • logger (Logger) – a logger for this object to use

  • max_workers (int) – nos of worker threads for async commands

  • communication_state_callback (Callable[[CommunicationStatus], None]) – callback to be called when the status of the communications channel between the component manager and its component changes

  • component_state_callback (Optional[Callable[..., None]]) – callback to be called when the component state changes

  • state (Any) – keyword arguments specifying initial values for any other state to be reported by the component state changed callback

off(task_callback=None)

Tell the upstream power supply proxy to turn the hardware off.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

a task status and message.

on(task_callback=None)

Tell the upstream power supply proxy to turn the hardware on.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

a task status and message.

start_communicating()

Establish communication with the hardware and the upstream power supply.

Return type:

None

stop_communicating()

Establish communication with the hardware and the upstream power supply.

Return type:

None

class DeviceComponentManager(name, logger, max_workers, communication_state_callback, component_state_callback)

An abstract component manager for a Tango device component.

__init__(name, logger, max_workers, communication_state_callback, component_state_callback)

Initialise a new instance.

Parameters:
  • name (str) – the name of the device

  • logger (Logger) – the logger to be used by this object.

  • max_workers (int) – Nos of worker threads for async commands.

  • communication_state_callback (Callable[[CommunicationStatus], None]) – callback to be called when the status of the communications channel between the component manager and its component changes

  • component_state_callback (Callable[..., None]) – callback to be called when the component state changes

property health: HealthState | None

Return the evaluated health state of the device.

This will be either the health state that the device reports, or None if the device is in an admin mode that indicates that its health should not be rolled up.

Returns:

the evaluated health state of the device.

off(task_callback=None)

Turn the device off.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

a result code & message

on(task_callback=None)

Turn the device on.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

a result code and message

property power_state: PowerState | None

Return the current power state of the device.

Returns:

the current power state of the device.

reset(task_callback=None)

Reset the device.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

a result code, or None if there was nothing to do.

standby(task_callback=None)

Turn the device to standby.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

a result code, or None if there was nothing to do.

start_communicating()

Establish communication with the component, then start monitoring.

This is a public method that enqueues the work to be done.

Return type:

None

stop_communicating()

Cease monitoring the component, and break off all communication with it.

Return type:

None

class DriverSimulatorSwitchingComponentManager(driver_component_manager, simulator_component_manager, initial_simulation_mode)

A component manager that switches between driver and simulator components.

It uses the simulation mode to determine which component to drive.

__init__(driver_component_manager, simulator_component_manager, initial_simulation_mode)

Initialise a new instance.

Parameters:
set_communication_state_callback(communication_state_callback)

Set the callback to be called when communication status changes.

Parameters:

communication_state_callback (Optional[Callable[[CommunicationStatus], None]]) – the callback to be called when status of communication with the component changes. If None, no callback will be called.

Return type:

None

set_component_state_callback(component_state_callback)

Set the callback to be called when component state changes.

Parameters:

component_state_callback (Optional[Callable[..., None]]) – the callback to be called when component state changed. If None, no callback will be called.

Return type:

None

property simulation_mode: SimulationMode

Return the simulation mode.

Returns:

the simulation mode

class HardwareClient(ip_address, port=80)

An abstract client to establish a connection to hardware.

This must be subclassed to establish the actual network protocol.

__init__(ip_address, port=80)

Create a new instance.

Parameters:
  • ip_address (str) – IP address of server

  • port (int) – Port of server

connect()

Check if connected and establish a connection with the client.

If this is not possible, returns None.

None if no connection available, True if connection OK

Return type:

Optional[bool]

execute_command(command, parameters='')

Execute the command.

Parameters:
  • command (str) – Name of command to be executed

  • parameters (str) – Parameters of the command

Return type:

CommandResponseType

Returns:

dictionary with execute_command result

get_attribute(attribute)

Get the attribute from the device.

Parameters:

attribute (str) – Name of attribute to get

Return type:

AttributeResponseType

Returns:

dictionary with get_attribute method result

set_attribute(attribute, value)

Set the attribute value.

Parameters:
  • attribute (str) – Name of attribute to set

  • value (Any) – value to set

Return type:

AttributeResponseType

Returns:

dictionary with set_attribute method result

class MccsBaseComponentManager(*args, **kwargs)

The base component manager for MCCS.

set_communication_state_callback(communication_state_callback)

Set the callback to be called when communication status changes.

Parameters:

communication_state_callback (Optional[Callable[[CommunicationStatus], None]]) – the callback to be called when status of communication with the component changes. If None, no callback will be called.

Return type:

None

set_component_state_callback(component_state_callback)

Set the callback to be called when component state changes.

Parameters:

component_state_callback (Optional[Callable[..., None]]) – the callback to be called when component state changed. If None, no callback will be called.

Return type:

None

class MccsComponentManagerProtocol(*args, **kwargs)

Specification of the interface of an MCCS component manager (for type-checking).

Classes that provide this interface are considered to be an MCCS component manager even if they don’t inherit from MccsBaseComponentManager. (e.g. the SwitchingComponentManager implements a passthrough mechanism that makes it an MCCS component manager even though it doesn’t inherit from MccsBaseComponentManager).

__init__(*args, **kwargs)
property communication_state: CommunicationStatus

Return the status of communication with the component.

off()

Turn off the component.

Return type:

ResultCode

on()

Turn on the component.

Return type:

ResultCode

reset()

Reset the component.

Return type:

ResultCode

standby()

Put the component into standby mode.

Return type:

ResultCode

start_communicating()

Establish communication with the component.

Return type:

None

stop_communicating()

Break off communicating with the component.

Return type:

None

class ObjectComponent

An abstract component that is an object in this process.

The concept of a “component” covers anything that a component manager might manage, including

  • hardware

  • software services such as databases or compute servers

  • groups of Tango devices

  • software running in its own process or thread

  • software objects in the current process.

This class defines an interface for the last of these – a component that is simply a python object running in the current process. An example of such a component is a simple simulator or stub that pretends to be a more substantial component.

property faulty: bool

Return whether this component is faulty.

Detecting component faults is a shared responsibility between component and component manager. In some cases, a component may be able to ability to self-diagnose a fault. In other cases, it will be update to the component manager to diagnose a fault from the component behaviour.

This property is implemented here to return False. Thus, if a subclass does not override this method, it is assumed to have no self-diagnosis capability.

Returns:

whether this component is faulty; defaulting here to False.

off(task_callback=None)

Turn the component off.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Raises:

NotImplementedError – because this class is abstract.

Return type:

tuple[TaskStatus, str]

on(task_callback=None)

Turn the component on.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Raises:

NotImplementedError – because this class is abstract.

Return type:

tuple[TaskStatus, str]

property power_mode: PowerState

Return the power mode of the component.

Here we implement a default functionality for components that do not manage their own power mode. From their own point of view they are always-on devices, though there may be an upstream power supply device that supplies/denies them power.

Returns:

the power mode of the component.

reset(task_callback=None)

Reset the component (from fault state).

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Raises:

NotImplementedError – because this class is abstract.

Return type:

tuple[TaskStatus, str]

set_fault_callback(fault_callback)

Set the fault callback.

Here we implement a default functionality for components that lack the ability to detect and raise a fault. This method calls the callback once with False, and doesn’t register the callback, thus the fault status of the component will be False forevermore.

Parameters:

fault_callback (Optional[Callable[..., None]]) – the callback to be called when the component changes.

Return type:

None

set_power_mode_changed_callback(power_mode_changed_callback)

Set the callback to be called when the power mode of the component changes.

Here we implement a default functionality for components that do not manage their own power mode. From their own point of view they are always-on devices, though there may be an upstream power supply device that supplies/denies them power. Thus, this method calls the callback once with PowerState.ON, and doesn’t register the callback, so the power mode of the component will be ON forevermore.

Parameters:

power_mode_changed_callback (Optional[Callable[..., None]]) – the callback to be called when the component changes.

Return type:

None

standby(task_callback=None)

Put the component into low-power standby mode.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Raises:

NotImplementedError – because this class is abstract.

Return type:

tuple[TaskStatus, str]

class ObjectComponentManager(component, logger, communication_state_callback, component_state_callback)

An abstract component manager for a component that is an object in this process.

The base component manager is a very general class that allows for management of remote components to which communication may need to be established and maintained. In cases where the component is simply an object running in the same process as its component manager (for example, a simple simulator), such complexity is not needed. This class eliminates that complexity, providing a basic framework for these simple component managers.

__init__(component, logger, communication_state_callback, component_state_callback)

Initialise a new instance.

Parameters:
  • component (ObjectComponent) – the component managed by this component manager

  • logger (Logger) – a logger for this object to use

  • communication_state_callback (Callable[[CommunicationStatus], None]) – callback to be called when the status of the communications channel between the component manager and its component changes

  • component_state_callback (Callable[..., None]) – callback to be called when the component state changes.

off(task_callback=None)

Turn the component off.

Parameters:

task_callback (Optional[Callable]) – Update task state, defaults to None

Return type:

tuple[TaskStatus, str]

Returns:

a taskstatus and message.

on(task_callback=None)

Turn the component on.

Parameters:

task_callback (Optional[Callable]) – Update task state, defaults to None

Return type:

tuple[TaskStatus, str]

Returns:

a taskstatus and message

reset(task_callback=None)

Reset the component.

Parameters:

task_callback (Optional[Callable]) – Update task state, defaults to None

Return type:

tuple[TaskStatus, str]

Returns:

a taskstatus and message

simulate_communication_failure(fail_communicate)

Simulate (or stop simulating) a failure to communicate with the component.

Parameters:

fail_communicate (bool) – whether the connection to the component is failing

Return type:

None

standby(task_callback=None)

Put the component into low-power standby mode.

Parameters:

task_callback (Optional[Callable]) – Update task state, defaults to None

Return type:

tuple[TaskStatus, str]

Returns:

a taskstatus and message

start_communicating()

Establish communication with the component, then start monitoring.

Raises:

ConnectionError – if the attempt to establish communication with the channel fails.

Return type:

None

stop_communicating()

Cease monitoring the component, and break off all communication with it.

Return type:

None

class ObsDeviceComponentManager(fqdn, logger, max_workers, communication_state_callback, component_state_callback)

An abstract component manager for a Tango observation device component.

__init__(fqdn, logger, max_workers, communication_state_callback, component_state_callback)

Initialise a new instance.

Parameters:
  • fqdn (str) – the FQDN of the device.

  • logger (Logger) – the logger to be used by this object.

  • communication_state_callback (Callable[[CommunicationStatus], None]) – callback to be called when the status of the communications channel between the component manager and its component changes.

  • component_state_callback (Callable[..., None]) – callback to be called when the component’s state changes.

  • max_workers (int) – Maximum number of workers in thread pool.

class PowerSupplyProxySimulator(logger, communication_state_callback, component_state_callback, initial_power_state=PowerState.OFF, initial_fail=False, _simulator=None)

A component manager that simulates a proxy to an upstream power supply device.

MCCS manages numerous hardware devices that can’t turn turn themselves off and on directly. Rather, in order for a tango device to turn its hardware off or on, it needs to contact the tango device for an upstream device that supplies power to the hardware, and tell that tango device to supply/deny power to the hardware.

However this functionality is largely not implemented yet, so we need to “fake” it. Plus, even when it _is_ implemented, there will be a need to simulate this when in simulation mode. This class provides that simulation pattern.

__init__(logger, communication_state_callback, component_state_callback, initial_power_state=PowerState.OFF, initial_fail=False, _simulator=None)

Initialise a new instance.

Parameters:
  • logger (Logger) – a logger for this object to use

  • communication_state_callback (Optional[Callable]) – callback to be called when the status of communications between the component manager and its component changes.

  • component_state_callback (Optional[Callable]) – callback to be called when the state of the component changes.

  • initial_power_state (PowerState) – the initial power state of the simulated power supply

  • initial_fail (bool) – the initial failure condition of the simulated power supply. If True, the power supply will immediately simulate failure.

abort_commands(task_callback=None)

Abort all queued tasks.

This implementation does not abort tasks that have already been picked up and executed by the poller.

Parameters:

task_callback (Optional[Callable]) – callback to be called whenever the status of the task changes.

Return type:

tuple[TaskStatus, str]

Returns:

a task status and message.

get_request()

Return the reads and writes to be executed in the next poll.

In this implementation, this simply returns an optional boolean that indicates whether or not to turn the power supply on or off. If true, we are asking to turn on the power supply; if false, we are asking to turn off the power supply; if None, we aren’t asking for any action to be taken.

Return type:

tuple[Optional[bool]]

Returns:

reads and writes to be executed in the next poll.

off(task_callback=None)

Turn the power supply off.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

task status and message

on(task_callback=None)

Turn the power supply on.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Return type:

tuple[TaskStatus, str]

Returns:

task status and message

poll(poll_request)

Poll the power supply.

Parameters:

poll_request (tuple[Optional[bool]]) – specification of the reads and writes to be performed in this poll. In this implementation, this is simply an optional boolean that indicates whether or not to turn the power supply on or off. If True, this poll will turn on the power supply; if False, this poll will turn off the power supply; if None, no action will be taken.

Return type:

PowerState

Returns:

responses to queries in this poll. In this implementation, this is simply a boolean that tells whether the power supply is on. If True, the power supply is currently on. If False, it is currently off.

poll_failed(exception)

Respond to an exception being raised by a poll attempt.

This is a hook called by the poller when an exception occurs.

Parameters:

exception (Exception) – the exception that was raised by a recent poll attempt.

Return type:

None

poll_succeeded(poll_response)

Handle a successful poll, including any values received.

This is a hook called by the poller at the end of each successful poll.

Parameters:

poll_response (PowerState) – response to the poll, including any values received. In this implementation, this is simply a boolean indicating whether the power supply is on or not.

Return type:

None

reset(task_callback=None)

Reset the component.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Raises:

NotImplementedError – because reset has not been implemented yet

Return type:

tuple[TaskStatus, str]

standby(task_callback=None)

Raise an error indicating that standby mode is not supported.

Parameters:

task_callback (Optional[Callable]) – callback to be called when the status of the command changes

Raises:

NotImplementedError – because this simulator does not support standby mode.

Return type:

tuple[TaskStatus, str]

class SwitchingComponentManager(component_managers, initial_mode)

A base component manager that switches between underlying base component managers.

This class passes commands down to an underlying component manager. This underlying component manager is selected from multiple available component managers.

An example of its use would be a component manager for a device that monitors and controls either a hardware component, or a simulator of that hardware component, depending on its simulation mode. In such a case we could:

  • Implement a component manager for the hardware driver;

  • Implement a component manager for the simulator;

  • Use this SwitchingBaseComponentManager as a component manager that uses a simulation mode setting to switch between hardware driver and simulator.

The switching functionality is implemented in the Switcher class. This class is syntactic sugar that allows us to get the multiple inheritance right once and for all, and then hide it from other classes.

__init__(component_managers, initial_mode)

Initialise a new ComponentManager instance.

Parameters:
class WebHardwareClient(ip_address, port=80)

Implementation of the HardwareClient protocol using a HTTP-based interface.

connect()

Nominally establish a connection with the client.

However this implementation is based on HTTP, which is connectionless, so this method is essentially unimplemented. It always returned True.

Return type:

bool

Returns:

True

disconnect()

Nominally, disconnect from the client.

However this implementation is based on HTTP, which is connectionless, so this method is implemented to do nothing.

Return type:

None

execute_command(command, parameters='')

Execute a named command, with or without parameters.

Parameters:
  • command (str) – Name of command to be executed

  • parameters (str) – Parameters of the command

Return type:

CommandResponseType

Returns:

dictionary with command result

get_attribute(attribute)

Read the value associated to a named attribute.

Parameters:

attribute (str) – Name of attribute to be read

Return type:

AttributeResponseType

Returns:

result of the attribute command

set_attribute(attribute, value)

Set the value associated to a named attribute.

Parameters:
  • attribute (str) – Name of attribute to set

  • value (Any) – value to set

Return type:

AttributeResponseType

Returns:

result of the attribute command