ControllerCommand¶
- class lsst.ts.salobj.topics.ControllerCommand(salinfo: SalInfo, name: str, queue_len: int = 100)¶
Bases:
ReadTopic
Read a specified command topic.
- Parameters:
- salinfo
SalInfo
SAL component information.
- name
str
Command name, with no prefix, e.g. “start”.
- queue_len
int
, optional Number of elements that can be queued for
get_oldest
.
- salinfo
Notes
Each command must be acknowledged by writing an appropriate
ackcmd
message. If you use a callback function to process the command then this happens automatically, as follows:If the callback function returns
None
then send a final acknowledgement withack=SalRetCode.CMD_COMPLETE
.If the callback function returns an acknowledgement (instance of
SalInfo.AckCmdType
) instead ofNone
, then send that as the final acknowledgement. This is very unusual, but might be useful if the callback wants to exit early and leave some background task or thread processing the rest of the command.If the callback function raises
asyncio.TimeoutError
then send a final acknowledgement withack=SalRetCode.CMD_TIMEOUT
.If the callback function raises
asyncio.CancelledError
then send a final acknowledgement withack=SalRetCode.CMD_ABORTED
.If the callback function raises
ExpectedError
then send a final acknowledgement withack=SalRetCode.CMD_FAILED
andresult=f"Failed: {exception}"
.If the callback function raises any other
Exception
then do the same asExpectedError
and also log a traceback.
Attributes Summary
The type (class) for a message of this topic.
Can callbacks can run simultaneously?
Asynchronous callback function, or None if there is not one.
Return True if there is a callback function.
Has any data ever been seen for this topic?
Get topic metadata as a
TopicMetadata
, if available,else None.Return the number of messages in the Python queue.
Does this topic have volatile durability?
Methods Summary
ack
(data, ackcmd)Acknowledge a command by writing a new state.
ack_in_progress
(data, timeout[, result])Ackowledge this command as "in progress".
aget
([timeout])Get the most recently seen message (with no delay), or wait for data if no data has ever been seen (
has_data
False).A synchronous and possibly less thorough version of
close
.close
()Shut down and release resources.
flush
()Flush the queue used by
get_oldest
andnext
.get
()Get the most recent message, or
None
if no data has ever been seen (has_data
False).Pop and return the oldest message from the queue, or
None
if the queue is empty.next
(*[, timeout])Wait for data, returning old data if found.
Attributes Documentation
- DataType¶
The type (class) for a message of this topic.
When you read or write a message for this topic you are reading or writing an instance of
DataType
.Notes
The preferred way to write a message for a topic is:
RemoteCommand.start
to start a command.CommandEvent.write
to write an event.CommandTelemetry.write
to write a telemetry message.
- allow_multiple_callbacks¶
Can callbacks can run simultaneously?
Notes
Ignored for synchronous callbacks because those block while running. In particular, if the callback is synchronous but launches one or more background jobs then the number of those jobs cannot be limited by this class.
- callback¶
Asynchronous callback function, or None if there is not one.
Synchronous callback functions are deprecated.
The callback function is called when a new message is received; it receives one argument: the message (an object of type
topics.BaseTopic.DataType
).- Raises:
- TypeError
When setting a new callback if the callback is not None and is not callable.
Notes
Setting a callback flushes the queue, and it will remain empty as long as there is a callback.
get_oldest
andnext
are prohibited if there is a callback function. Technically they could both work, butget_oldest
would always returnNone
andnext
would miss messages if they arrived while waiting for something else. It seems safer to raise an exception.
- has_callback¶
Return True if there is a callback function.
- has_data¶
Has any data ever been seen for this topic?
- Raises:
- RuntimeError
If the
salinfo
has not started reading.
- max_history¶
- metadata¶
Get topic metadata as a
TopicMetadata
, if available,else None.
- nqueued¶
Return the number of messages in the Python queue.
- volatile¶
Does this topic have volatile durability?
Methods Documentation
- async ack(data: BaseMsgType, ackcmd: AckCmdDataType) None ¶
Acknowledge a command by writing a new state.
- Parameters:
- data
DataType
Data for the command being acknowledged.
- ackcmd
salobj.AckCmdType
Command acknowledgement data.
- data
- async ack_in_progress(data: BaseMsgType, timeout: float, result: str = '') None ¶
Ackowledge this command as “in progress”.
- async aget(timeout: float | None = None) BaseMsgType ¶
Get the most recently seen message (with no delay), or wait for data if no data has ever been seen (
has_data
False).This is almost exactly like
get
. The only difference: if no data has ever been received by this topic it will wait for data. Once the topic has received any data, callingaget
is identical to callingget
(except for the need to useawait
) and the call will return almost instantly.Please avoid
aget
, if possible, because it tends to confuse users. Useget
to get the current data ornext
to wait for new data (you will almost never need both for the same topic).- Parameters:
- timeout
float
, optional Time limit, in seconds. If None then no time limit.
- timeout
- Returns:
- data
DataType
The current or next message.
- data
- Raises:
- asyncio.TimeoutError
If no message is available within the specified time limit.
- RuntimeError
If a callback function is present, or if the
salinfo
has not started reading.
Notes
This method does not remove data from the queue, so it does not change which data is returned by
next
. In that respect it is not quite identical to this snippet, which otherwise does the same thing asaget
:data = self.get() if data is None: data = await self.next(flush=False, timeout=timeout) return data
Do not modify the returned data. To make a copy that you can safely modify, use
copy.copy(data)
.
- basic_close() None ¶
A synchronous and possibly less thorough version of
close
.Intended for exit handlers and constructor error handlers.
- async close() None ¶
Shut down and release resources.
Intended to be called by SalInfo.close(), since that tracks all topics.
- flush() None ¶
Flush the queue used by
get_oldest
andnext
.This makes
get_oldest
returnNone
andnext
wait, until a new message arrives. It does not change which message will be returned byaget
orget
.- Raises:
- RuntimeError
If a callback function is present.
- get() lsst.ts.salobj.type_hints.BaseMsgType | None ¶
Get the most recent message, or
None
if no data has ever been seen (has_data
False).This method does not change which message will be returned by
aget
,get_oldest
, andnext
.
- get_oldest() lsst.ts.salobj.type_hints.BaseMsgType | None ¶
Pop and return the oldest message from the queue, or
None
if the queue is empty.This is a variant of
next
that does not wait for a new message. This method affects which message will be returned bynext
, but not which message will be returned byaget
orget
.- Returns:
- Raises:
- RuntimeError
If a callback function is present, or if the
salinfo
has not started reading.
Notes
Use with caution when mixing with
next
, since that also consumes data from the queue.
- async next(*, timeout: float | None = None) BaseMsgType ¶
Wait for data, returning old data if found.
Unlike
RemoteEvent.next
andRemoteTelemetry.next
, the flush argument is not allowed; the only way to flush old commands is to callflush
.- Parameters:
- timeout
float
, optional Time limit, in seconds. If None then no time limit.
- timeout
- Returns:
- data
DataType
Command data.
- data
- Raises:
- asyncio.TimeoutError
If no message is available within the specified time limit.
- RuntimeError
If a callback function is present.
Notes
Do not modify the data or assume that it will be static. If you need a private copy, then copy it yourself.