MockMTRotatorController¶
- class lsst.ts.mtrotator.MockMTRotatorController(log: Logger, port: int = 0, initial_state: ControllerState = ControllerState.STANDBY)¶
Bases:
BaseMockController
Mock MT rotator controller that talks over TCP/IP.
- Parameters:
- log
logging.Logger
Logger.
- port
int
(optional) Port for telemetry and configuration; if nonzero then the command port will be one larger. Specify 0 to choose random values for both ports; this is recommended for unit tests, to avoid collision with other tests. Do not specify 0 with host=None (see Raises section).
- initial_state
ControllerState
(optional) Initial state of mock controller.
- log
- Raises:
- ValueError
If host=None and port=0. See
CommandTelemetryServer
for details.
Notes
To start the mock controller:
ctrl = MockRotatorController(…) await ctrl.connect_task
To stop the server:
await ctrl.stop()
Known Limitations
Constant-velocity motion is not supported.
The odometer resets to zero each time the mock controller is constructed.
The motor current and torque are scaled versions of current acceleration, with a wild guess as to scale.
Motor current and torque exactly match for motors A and B.
Many telemetry fields are not set at all.
Attributes Summary
Return True if self._reader and self._writer are connected.
Methods Summary
assert_state
(state[, enabled_substate])Check the state and, optionally, the substate.
Close the connected client socket, if any.
A client has connected or disconnected.
close
()Kill command and telemetry tasks and close the connections.
close_client
(**kwargs)Close the connected client (if any) and stop background tasks.
connect_callback
(server)Called when the server connection state changes.
do_clearError
(data)do_clear_error
(command)do_config_accel
(command)do_config_accel_emergency
(command)do_config_jerk
(command)do_config_jerk_emergency
(command)do_config_vel
(command)do_constant_velocity
(command)do_enable
(command)do_enable_drives
(command)do_fault
(command)do_move_point_to_point
(command)do_position_set
(command)do_set_constant_vel
(command)do_standby
(command)do_stop
(command)do_track
(command)do_track_vel_cmd
(command)end_run_command
(command, cmd_method)Called when run_command is done.
get_command_key
(command)Return the key to command_table.
read
(n)Read up to n bytes.
Read and execute one command.
read_into
(struct)Read binary data from a stream reader into a
ctypes.Structure
.Read JSON data.
Read incoming data and handle them.
read_str
()Read and decode a terminated str; strip the terminator.
readexactly
(n)Read exactly n bytes.
readline
()Read a sequence of bytes ending with
\n
.readuntil
([separator])Read one line, where “line” is a sequence of bytes ending with
separator
.run_command
(command)Run a command and wait for the reply.
set_state
(state)Set the current state and substates.
start
(**kwargs)Start the TCP/IP server.
Write configuration once, then telemetry at regular intervals.
If this times out then go into a FAULT state.
update_and_get_header
(frame_id)Update the config or telemetry header and return it and the time.
update_telemetry
(curr_tai)Update self.client.telemetry.
write
(data)Write data and call
drain
.write_command_status
(counter, status[, ...])Write a command status.
Write the current configuration.
write_from
(*structs)Write binary data from one or more
ctypes.Structure
s.write_json
(data)Write data in JSON format.
write_str
(line)Encode, terminate, and write a str.
writelines
(lines)Write an iterable of bytes and call
drain
.Attributes Documentation
- connected¶
Return True if self._reader and self._writer are connected.
Note: if the other end drops the connection and if you are not trying to read data (e.g. in a background loop), then it takes the operating system awhile to realize the connection is lost. So this can return true for some unknown time after the connection has been dropped.
- current_per_acceleration = 5¶
- enabled_substate¶
- state¶
- telemetry_interval = 0.1¶
- torque_per_acceleration = 0.002¶
Methods Documentation
- assert_state(state: int, enabled_substate: int | None = None) None ¶
Check the state and, optionally, the substate.
- Parameters:
- stateint
Required state.
- enabled_substateint or None, optional
Required enabled substate, or None to not check.
- Raises:
- CommandError
If the state is not as expected.
- async basic_close_client() None ¶
Close the connected client socket, if any.
Also:
Reset
self.connected_task
to a new Future.Call connect_callback, if a client was connected.
Unlike
close_client
, this does not touchself.should_be_connected
.Always safe to call.
- async close() None ¶
Kill command and telemetry tasks and close the connections.
Always safe to call.
- async close_client(**kwargs: dict[str, Any]) None ¶
Close the connected client (if any) and stop background tasks.
- async connect_callback(server: OneClientReadLoopServer) None ¶
Called when the server connection state changes.
If connected: start the command and telemetry loops. If not connected: stop the command and telemetry loops.
- async end_run_command(command: Command, cmd_method: Coroutine) None ¶
Called when run_command is done.
Can be used to clear the set position.
- async read(n: int) bytes ¶
Read up to n bytes.
- Parameters:
- n
int
The number of bytes to read. If -1 then block until the other end closes its writer, then return all data seen.
- n
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
- async read_into(struct: Structure) None ¶
Read binary data from a stream reader into a
ctypes.Structure
.- Parameters:
- struct
ctypes.Structure
Structure to set.
- struct
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
asyncio.IncompleteReadError
If EOF is reached before
n
bytes can be read. Use theIncompleteReadError.partial
attribute to get the partially read data.
- async read_json() Any ¶
Read JSON data.
Read the data with
read_str
and return the json-decoded result.- Returns:
- data
typing.Any
Data decoded from JSON.
- data
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
asyncio.IncompleteReadError
If EOF is reached before the complete separator is found and the internal buffer is reset.
LimitOverrunError
If the amount of data read exceeds the configured stream lmit. The data is left in the internal buffer and can be read again.
TypeError
If the data are of a type that cannot be decoded from JSON.
json.JSONDecodeError
If the data cannot be decoded from JSON.
- async read_loop() None ¶
Read incoming data and handle them.
The actual reading is deferred to the
read_and_dispatch
method and needs to be implemented by subclasses.
- async read_str() str ¶
Read and decode a terminated str; strip the terminator.
Read until
self.terminator
, strip the terminator, and decode the data asself.encoding
with strict error handling.- Returns:
- line
str
Line of data, as a str with the terminator stripped.
- line
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
asyncio.IncompleteReadError
If EOF is reached before the complete separator is found and the internal buffer is reset.
LimitOverrunError
If the amount of data read exceeds the configured stream lmit. The data is left in the internal buffer and can be read again.
UnicodeError
If decoding fails.
- async readexactly(n: int) bytes ¶
Read exactly n bytes.
- Parameters:
- n
int
The number of bytes to read.
- n
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
asyncio.IncompleteReadError
If EOF is reached before
n
bytes can be read. Use theIncompleteReadError.partial
attribute to get the partially read data.
- async readline() bytes ¶
Read a sequence of bytes ending with
\n
.If EOF is received and
\n
was not found, the method returns partially read data.- Raises:
ConnectionError
If the connection is lost before, or while, reading.
- async readuntil(separator: bytes = b'\n') bytes ¶
Read one line, where “line” is a sequence of bytes ending with
separator
.Read data from the stream until separator is found.
On success, the data and separator will be removed from the internal buffer (consumed). Returned data will include the separator at the end.
See also
read_str
, which is more convenient for most use cases.- Parameters:
- separator
bytes
The desired separator. The default matches the standard library, rather than using
terminator
.
- separator
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
asyncio.IncompleteReadError
If EOF is reached before the complete separator is found and the internal buffer is reset.
LimitOverrunError
If the amount of data read exceeds the configured stream lmit. The data is left in the internal buffer and can be read again.
- async run_command(command: Command) float | None ¶
Run a command and wait for the reply.
- Parameters:
- command
Command
The command to run. This method sets the commander and counter fields.
- command
- Returns:
- duration
float
or None Estimated duration (seconds) until the command is finished. 0 if the command is already done or almost already done.
- duration
- Raises:
- CommandError
If the command fails.
- set_state(state: Command) None ¶
Set the current state and substates.
- Parameters:
- state
lsst.ts.xml.enums.MTHexapod.ControllerState
orint
New state.
- state
Notes
Sets the substates as follows:
lsst.ts.xml.enums.MTHexapod.EnabledSubstate.STATIONARY
if state ==lsst.ts.xml.enums.MTHexapod.ControllerState.ENABLED
- async start(**kwargs: Any) None ¶
Start the TCP/IP server.
This is called automatically by the constructor, and is not intended to be called by the user. It is a public method so that subclasses can override it.
- Parameters:
- **kwargs
dict
[str
,typing.Any
] Additional keyword arguments for
asyncio.start_server
, beyond host and port.
- **kwargs
- Raises:
RuntimeError
If start has already been called and has successfully constructed a server.
- async tracking_timer() None ¶
If this times out then go into a FAULT state.
Used to make sure TRACK commands arrive often enough.
- update_and_get_header(frame_id: FrameId) tuple[lsst.ts.hexrotcomm.structs.Header, float] ¶
Update the config or telemetry header and return it and the time.
Call this prior to writing configuration or telemetry.
- Parameters:
- frame_id
FrameId
Frame ID of header to write.
- frame_id
- Returns:
- header
structs.Header
The header.
- curr_tai
float
Current time in header timestamp (TAI, unix seconds).
- header
- async update_telemetry(curr_tai: float) None ¶
Update self.client.telemetry.
- Parameters:
- curr_tai
float
Time at which to compute telemetry (TAI, unix seconds). This is the time in the header, which is (approximately) the current time.
- curr_tai
- async write(data: bytes) None ¶
Write data and call
drain
.- Parameters:
- data
bytes
The data to write.
- data
- Raises:
ConnectionError
If
self.connected
false before writing begins.
- async write_command_status(counter: int, status: CommandStatusCode, duration: float | None = 0.0, reason: str = '') None ¶
Write a command status.
- Parameters:
- Raises:
- ConnectionError
If not connected.
- async write_from(*structs: Structure) None ¶
Write binary data from one or more
ctypes.Structure
s.- Parameters:
- structs
list
[ctypes.Structure
] Structures to write.
- structs
- Raises:
ConnectionError
If
self.connected
false before writing begins.
- async write_json(data: Any) None ¶
Write data in JSON format.
Encode the data as json and write the result with
write_str
.- Parameters:
- data
any
The data to be written. Typically a dict, but any json-encodable data is acceptable.
- data
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
UnicodeError
If encoding fails.
json.JSONEncodeError
If the data cannot be json-encoded.
- async write_str(line: str) None ¶
Encode, terminate, and write a str.
Encode the str as
self.encoding
with strict error handling, and appendself.terminator
.- Parameters:
- line
str
The line of data to be written.
- line
- Raises:
ConnectionError
If the connection is lost before, or while, reading.
UnicodeError
If encoding fails.
- async writelines(lines: Iterable) None ¶
Write an iterable of bytes and call
drain
.- Parameters:
- lines
collections.abc.Iterable
[bytes
] The data to write, as an iterable collection of
bytes
.
- lines
- Raises:
ConnectionError
If
self.connected
false before writing begins.