class lsst.ts.salobj.Remote(domain: Domain, name: str, index: int | None = None, *, readonly: bool = False, include:[str] | None = None, exclude:[str] | None = None, evt_max_history: int = 1, start: bool = True)

Bases: object

A class that issues commands to a SAL component and receives telemetry and events from that component.

If a SAL component listens to or commands other SAL components then it will have one Remote for each such component.


DDS Domain. If you have a Controller then use its domain attribute. Otherwise create your own Domain and close it when you are done, for example:

async with Domain() as domain:
    dome = Remote(domain=domain, name="ATDome", index=0)

Name of SAL component.

indexint or None, optional

SAL component index, or 0 or None if the component is not indexed. A value is required if the component is indexed.


If True then do not provide commands.

includeiterable of str, optional

Names of topics (telemetry or events) to support, for example [“FilterChangeInPosition”, “TrackingTarget”] If None then all are included except those in exclude.

excludeiterable of str, optional

Names of topics (telemetry or events) to not support. Topic names must not have a tel_ or evt_ prefix. If None or empty then no topics are excluded.

evt_max_historyint, optional

Maximum number of historical items to read for events. Set to 0 if your remote is not interested in “late joiner” data.

startbool, optional

Automatically start the read loop when constructed? Normally this should be True, but if you are adding topics piecemeal after constructing the remote then specify False and call start manually after you have added all topics. Warning: if False then self.start_task will not exist and the remote cannot be used as an async context manager.


If include and exclude are both iterables (one or both must be None).


Here is an example that makes a Test remote and displays the topic-related attributes:

include salobj
# the index is arbitrary, but a remote must use the same index
# as the controller or CSC in order to communicate
index = 5
test_remote = salobj.Remote("Test", index)


You should see the following topic-related attributes:

  • Commands, each an instance of topics.RemoteCommand:

    • cmd_standby

    • cmd_start

    • … and so on for all other standard CSC commands

    • cmd_setArrays

    • cmd_setScalars

  • Events, each an instance of topics.RemoteEvent:

    • evt_authList

    • evt_configurationApplied

    • … and so on for all other standard CSC log events

    • evt_arrays

    • evt_scalars

  • Telemetry, each an instance of topics.RemoteTelemetry:

    • tel_arrays

    • tel_scalars


Has the start method been called? The instance is fully started when start_task is done.


Remote command topic for each command supported by the component. Omitted if readonly true.


Remote event for each event supported by the component, as specified by include and the exclude arguments.


Remote telemetry topic for each telemetry topic supported by the component, as specified by the include and exclude arguments.

Methods Summary


Shut down and clean up resources.


Start the read loop by starting the contained SalInfo.

Methods Documentation

async close() None

Shut down and clean up resources.

Close the contained SalInfo, but not the Domain, because that may be used by other objects.

May be called multiple times. The first call closes the SalInfo; subsequent calls wait until the Remote is closed.

async start() None

Start the read loop by starting the contained SalInfo.


If the SalInfo is already started, closing or closed.