Communication Layer
Relevant source files
The following files were used as context for generating this wiki page:
The communication layer in the Pulsar Dome Driver is responsible for all interactions between the driver and the dome controller hardware, as well as optional external systems for status monitoring and notifications. It provides a robust, multi-channel architecture designed for reliability and observability.
The primary communication channel is a serial port connection to the dome controller, which is managed and protected to ensure thread-safe, sequential command execution. In addition to direct hardware control, the layer supports publishing status updates and alarms to an MQTT broker and sending notifications to the Goodnight System (GNS) via named pipes. This layered approach allows for both direct control and integration with broader observatory automation systems.
Core Components
The communication layer is composed of several key classes that work together to manage data flow.
This diagram shows the main classes involved in communication and their relationships. DomeDriver orchestrates the interactions, using SerialPortGuard for hardware commands, MqttPublisher for MQTT messages, and GNS for notifications.
Sources: Driver/Pulsar_DomeDriver.cs, Helper/SerialPortGuard.cs, MQTT/MqttPublisher.cs, GNS/GNS.cs
Serial Communication
Serial communication is the fundamental method for controlling the dome hardware. It involves sending text-based commands and parsing the responses.
Connection Management
The connection to the dome controller is established via a serial port. The configuration, including the port name (e.g., COM3), is stored in the ASCOM profile and managed by the ConfigManager.
The connection process is as follows:
- The
DomeDriveris instantiated, andInitializeSerialPortprepares aSerialPortobject with hardcoded settings (115200 baud, 8N1). - When
Connectedis set totrue, theConnectControllermethod is called. ConnectControlleropens the serial port.- A
SerialPortGuardinstance is created to manage access to the port. - The controller is pinged by sending the command
PULSAR. A successful connection is confirmed if the controller responds withY519. - If the ping is successful, the background polling loop is started.
Sources: Driver/Pulsar_DomeDriver.cs:165-285, Config/ConfigManager.cs:100-104
The following diagram illustrates the connection flow.
Sources: Driver/Pulsar_DomeDriver.cs:228-285
Command and Response Handling
All serial commands are sent through a SerialPortGuard instance. This class ensures thread safety by using a SemaphoreSlim to allow only one command to be processed at a time, preventing interleaved communication from different threads.
The SerialPortGuard.Send method:
- Waits to acquire the semaphore (
_gate). - Invokes a
_setBusycallback to flag that a command is in progress. - Flushes the serial input buffer to discard stale data.
- Writes the command string followed by a carriage return (
\r) to the port. - If a response is expected, it reads from the port until a terminator (
\ror\n) is seen or a 750ms timeout occurs. - Invokes a
_clearBusycallback and releases the semaphore.
The DomeDriver uses the SendAndVerify helper method, which wraps SerialPortGuard.Send and provides different modes for validating the controller's response.
Sources: Helper/SerialPortGuard.cs:27-96, Driver/Pulsar_DomeDriver.cs:1386-1469
Response Modes
The ResponseMode enum dictates how the driver interprets the controller's reply to a command.
| Mode | Description | Source File |
|---|---|---|
Blind | Sends the command and does not wait for or read any response. | Config/ConfigManager.cs:20 |
Raw | Sends the command and returns the raw string response without validation. | Config/ConfigManager.cs:21 |
MatchExact | The response must exactly match a single expected string. | Config/ConfigManager.cs:22 |
MatchAny | The response must match one of several possible expected strings. | Config/ConfigManager.cs:23 |
Sources: Config/ConfigManager.cs:19-24, Driver/Pulsar_DomeDriver.cs:1386-1469
Background Polling
Once connected, a background task (PollLoopAsync) continuously queries the dome's status at an interval defined by _config._pollingIntervalMs (default 500ms). This ensures the driver's state properties (e.g., Azimuth, ShutterStatus) are kept current.
The polling loop calls DomeStatus, which executes three serial commands:
V: Gets the main status block, including azimuth, dome state, and shutter state.HOME ?: Gets the home status (returns1if at home,0otherwise).PARK ?: Gets the park status (returns1if parked,0otherwise).
A system watchdog (StartWatchdog) monitors this polling loop. If the _lastPollTimestamp is not updated within a threshold (_pollingStallThreshold, 10 seconds), the watchdog will restart the polling task to prevent stalls.
The sequence diagram below shows the polling process.
External Communication
The driver can communicate with external systems for monitoring and notifications. This functionality is optional and can be enabled/disabled in the settings.
MQTT Communication
If enabled (UseMQTT is true), the driver will publish status updates to an MQTT broker. The MqttPublisher class handles the connection and publishing logic.
- Initialization:
StartMQTTAsynccreates anMqttPublisherinstance and callsInitializeAsyncto connect to the broker. - Publishing: The
TryMQTTPublishhelper method is used throughout the driver to send non-blocking messages. It checks if the publisher is connected before attempting to publish. - Topics: The driver publishes to several predefined topics to report its status.
| Topic | Description |
|---|---|
Dome/DriverStatus | Reports driver connection status (e.g., "Driver connected"). |
Dome/Dome/Status | Reports dome movement status (e.g., "Dome is parked."). |
Dome/Shutter/Status | Reports shutter status (e.g., "Shutter is open."). |
Dome/Alarm | Publishes critical failure messages. |
Dome/Watchdog | Publishes a periodic heartbeat with current status. |
Sources: Driver/Pulsar_DomeDriver.cs:91-96, 1313-1349, MQTT/MqttPublisher.cs:39-158, Config/ConfigManager.cs:234-245
GNS (Goodnight System) Communication
If enabled (UseGNS is true), the driver sends notifications to the Goodnight System, an external monitoring application.
- Mechanism: The
GNSclass uses aNamedPipeClientStreamto connect to a local named pipe calledGNSBridge. - Message Format: Messages are formatted as a pipe-delimited string:
action|message|timeout. TheGNSTypeenum determines theactionpart of the message.
| GNSType | Purpose | Example Formatted Message |
|---|---|---|
Message | A standard informational message. | message|Dome connected |
New | A new task with a timeout. | new|Slewing to home|180 |
Alarm | A critical alarm message. | alarm|Reset failed|0 |
Stop | Indicates a task has completed successfully. | stop|Dome homed|-1 |
Cease | Indicates a task was aborted. | cease|Abort succeeded|-2 |
Sources: GNS/GNS.cs, Config/ConfigManager.cs:247-258
Communication and Error Recovery
The communication layer is integral to the driver's error detection and recovery mechanisms. When a command that takes significant time is executed (e.g., SlewToAzimuth, OpenShutter), an ActionWatchdog is started.
This watchdog monitors the dome's state via the background polling data. If the dome does not reach its target state within a specified timeout, the watchdog assumes a failure and triggers the ResetRoutineAsync method. This routine attempts to recover the controller, first with a software "RESTART" command, and if that fails, by executing an external hardware reset script. This demonstrates a tight loop between command execution, status polling, and automated recovery driven by communication timeouts and failures.
Summary
The Pulsar Dome Driver's communication layer is a comprehensive system that handles not only the primary serial commands for hardware control but also provides extensive external visibility through MQTT and GNS. Its use of a SerialPortGuard ensures stable, thread-safe hardware interaction, while the background polling and watchdog mechanisms create a self-monitoring and self-healing system. This robust architecture is key to the driver's reliability, allowing it to detect communication stalls and automatically initiate recovery procedures.