Object-oriented Python interface to Service Abstraction Layer (SAL) components that uses asyncio for asynchronous communication. ts_salobj SAL communication uses the dds Python library, which is part of Vortex OpenSplice. You may use the free community edition or the licensed edition of OpenSplice.

Using lsst.ts.salobj

Important Classes

  • BaseCsc and ConfigurableCsc are subclasses of Controller that supports the standard CSC summary states and state transition commands. The latter also supports configuration via yaml files that are validated against a schema. See Writing a CSC for more information. It is important to call BaseCsc.close when done with the CSC; BaseCsc.amain does this automatically, but in other cases see Cleanup for more information.
  • Controller provides the capability to output SAL telemetry and event topics and receive SAL commands. Every Python SAL component that is not a Commandable SAL Component (CSC) should be a subclass of Controller. See Writing a Controller for more information. Note that it is important to close the Controller when you are finished. See Cleanup for more information.
  • Remote supports listening to other SAL components; it can receive events and telemetry and issue commands. If your SAL component needs to do this then it should create one Remote for each SAL component it wants to interact with. See the example above.
  • Domain contains the dds domain participant (which includes a cache of topic data) and quality of service objects for the various categories. There should be only one Domain per process or unit test method, if practical, though some unit tests create a few more. Controller creates and manages a Domain, but if you have no controller and wish to construct one or more Remotes then you will have to create and manage a Domain yourself. See Cleanup for more information.
  • BaseScript is a base class for Python SAL Scripts.
  • AsyncS3Bucket is a class for asynchronously uploading and downloading files to/from s3 buckets.


  • TestCsc is an example of a fairly simple SAL CSC, though it is slightly unusual because it is intended for use in unit tests. In particular, it does not output telemetry at regular intervals.
  • TestScript is an example of a trivial Python SAL Script.


It is important to call Controller.close or Domain.close when done with any controller or domain you construct, unless your process is exiting. Note that closing a Domain automatically cleans up the resources used by all Remotes constructed using that domain.

Both Controller and Domain can be used as asynchronous context managers to call close automatically. For example:

# If you have a controller or CSC:
async with TestCsc(index=1) as csc:
    dome = Remote(domain=csc.domain, name="Test", index=0)

# If you don't have a controller or CSC:
async with Domain() as domain:
    dome = Remote(domain=domain, name="Test", index=1)


lsst.ts.salobj is developed at You can find Jira issues for this module using labels=ts_salobj.

Python API reference

lsst.ts.salobj Package


angle_diff(angle1, angle2) Return angle1 - angle2 wrapped into the range [-180, 180) deg.
angle_wrap_center(angle) Return an angle wrapped into the range [-180, 180) deg.
angle_wrap_nonnegative(angle) Return an angle wrapped into the range [0, 360) deg.
as_salRetCode(value) Convert an int (or SalRetCode) to a SalRetCode.
as_state(value) Convert an int (or State) to a State.
assertAnglesAlmostEqual(angle1, angle2[, …]) Raise AssertionError if angle1 and angle2 are too different, ignoring wrap.
assertRaisesAckError([ack, error, …]) Assert that code raises a salobj.AckError
assertRaisesAckTimeoutError([ack, error]) Assert that code raises a salobj.AckTimeoutError
assert_black_formatted(dirpath) Assert that all Python files in a directory, or any subdirectory of that directory, are formatted with black.
astropy_time_from_tai_unix(tai_unix) Get astropy time from TAI in unix seconds.
current_tai() Return the current TAI in unix seconds, using tai_from_utc.
get_dds_version([dds_file]) Get the version of OpenSplice dds library.
get_opensplice_version() Get the version of OpenSplice as a string.
get_user_host() Get the username and host as user@host
index_generator([imin, imax, i0]) Sequential index generator.
name_to_name_index(name) Parse a SAL component name of the form name[:index].
parse_idl(name, idl_path) Parse the SAL-generated IDL file.
set_random_lsst_dds_domain() Deprecated version of set_random_lsst_dds_partition_prefix.
set_random_lsst_dds_partition_prefix() Set a random value for environment variable LSST_DDS_PARTITION_PREFIX
set_summary_state(remote, state[, …]) Put a CSC into the specified summary state.
stream_as_generator(stream[, encoding]) Await lines of text from stdin or another input stream.
tai_from_utc(utc[, format]) Return TAI in unix seconds, given UTC or any astropy.time.Time.
tai_from_utc_unix(utc_unix) Return TAI in unix seconds, given UTC in unix seconds.


AckError(msg, ackcmd) Exception raised if a command fails.
AckTimeoutError(msg, ackcmd) Exception raised if waiting for a command acknowledgement times out.
AsyncS3Bucket(name, *[, create, profile, domock]) Asynchronous interface to an Amazon Web Services s3 bucket.
BaseConfigTestCase Base class for testing configuration files.
BaseCsc(name[, index, initial_state, …]) Base class for a Commandable SAL Component (CSC)
BaseCscTestCase Base class for CSC tests.
BaseScript(index, descr) Abstract base class for SAL Scripts.
ConfigurableCsc(name, index, schema_path[, …]) Base class for a configurable Commandable SAL Component (CSC)
Controller(name[, index, do_callbacks]) A class that receives commands for a SAL component and sends telemetry and events from that component.
CscCommander(name[, index, enable, exclude, …]) Command a CSC from the command line.
DefaultingValidator(schema[, ValidatorClass]) A wrapper for jsonschema validators that applies default values.
Domain() dds domain participant and quality of service information.
ExpectedError Report an error that does not benefit from a traceback.
FieldMetadata(name, description, units, …) Information about a field.
IdlMetadata(name, idl_path, sal_version, …) Information about SAL topics in an IDL file.
Remote(domain, name[, index, readonly, …]) A class that issues commands to a SAL component and receives telemetry and events from that component.
SalInfo(domain, name[, index]) DDS information for one SAL component and its DDS partition
SalLogHandler(controller) Log handler that outputs an event topic.
SalRetCode SAL return codes.
State CSC summaryState constants.
TestCsc(index[, config_dir, initial_state, …]) A simple CSC intended for unit testing.
TestCscCommander(index[, enable, exclude, …]) Control a Test CSC from the command line.
TestScript(index[, descr]) Test script to allow testing BaseScript.
TopicMetadata(sal_name, description) Metadata about a topic.

Class Inheritance Diagram

Inheritance diagram of lsst.ts.salobj.base.AckError, lsst.ts.salobj.base.AckTimeoutError, lsst.ts.salobj.async_s3_bucket.AsyncS3Bucket, lsst.ts.salobj.base_config_test_case.BaseConfigTestCase, lsst.ts.salobj.base_csc.BaseCsc, lsst.ts.salobj.base_csc_test_case.BaseCscTestCase, lsst.ts.salobj.base_script.BaseScript, lsst.ts.salobj.configurable_csc.ConfigurableCsc, lsst.ts.salobj.controller.Controller, lsst.ts.salobj.csc_commander.CscCommander, lsst.ts.salobj.validator.DefaultingValidator, lsst.ts.salobj.domain.Domain, lsst.ts.salobj.base.ExpectedError, lsst.ts.salobj.sal_info.FieldMetadata, lsst.ts.salobj.idl_metadata.IdlMetadata, lsst.ts.salobj.remote.Remote, lsst.ts.salobj.sal_info.SalInfo, lsst.ts.salobj.sal_log_handler.SalLogHandler, lsst.ts.salobj.sal_enums.SalRetCode, lsst.ts.salobj.sal_enums.State, lsst.ts.salobj.testcsc.TestCsc, lsst.ts.salobj.testcsccommander.TestCscCommander, lsst.ts.salobj.testscript.TestScript, lsst.ts.salobj.sal_info.TopicMetadata

lsst.ts.salobj.topics Package


AckCmdReader(salinfo[, queue_len]) Read the ackcmd command acknowledgement topic.
AckCmdWriter(salinfo) Command Acknowledgement writer.
BaseTopic(*, salinfo, name, sal_prefix) Base class for topics.
ControllerCommand(salinfo, name[, queue_len]) Read a specified command topic.
ControllerEvent(salinfo, name) Write a specific event topic.
ControllerTelemetry(salinfo, name) Write a specific telemetry topic.
QueueCapacityChecker(descr, log, queue_len) Log warnings for a fixed-length queue that should contain no more than one item.
ReadTopic(*, salinfo, name, sal_prefix, …) Base class for reading a topic.
RemoteCommand(salinfo, name) Issue a specific command topic and wait for acknowldgement.
RemoteEvent(salinfo, name[, max_history, …]) Read a specific event topic.
RemoteTelemetry(salinfo, name[, …]) Read a specific telemetry topic.
WriteTopic(*, salinfo, name, sal_prefix[, …]) Base class for topics that are output.

Class Inheritance Diagram

Inheritance diagram of lsst.ts.salobj.topics.remote_command.AckCmdReader, lsst.ts.salobj.topics.controller_command.AckCmdWriter, lsst.ts.salobj.topics.base_topic.BaseTopic, lsst.ts.salobj.topics.controller_command.ControllerCommand, lsst.ts.salobj.topics.controller_event.ControllerEvent, lsst.ts.salobj.topics.controller_telemetry.ControllerTelemetry, lsst.ts.salobj.topics.read_topic.QueueCapacityChecker, lsst.ts.salobj.topics.read_topic.ReadTopic, lsst.ts.salobj.topics.remote_command.RemoteCommand, lsst.ts.salobj.topics.remote_event.RemoteEvent, lsst.ts.salobj.topics.remote_telemetry.RemoteTelemetry, lsst.ts.salobj.topics.write_topic.WriteTopic

Version History