# Instrument Communication Service This document describes the Instrument Communication Service, a core component of the software responsible for managing all aspects of communication with connected Maselli instruments. The primary class implementing this service is `Uc09_Utility.ClassSerialeStrumenti`. ## 1. Overview and Purpose The Instrument Communication Service acts as a central hub for bi-directional data exchange between the software application and one or more Maselli instruments. Its main purpose is to abstract the complexities of low-level communication protocols and hardware interfaces, providing a consistent way for other parts of the application to interact with instruments. **Key Responsibilities:** * **Multi-Instrument Management:** Handles communication with multiple instruments, potentially on different lines or addresses. * **Command Queuing and Dispatch:** Manages a queue of commands to be sent to instruments, ensuring orderly and timely execution. * **Protocol Implementation:** Encodes outgoing commands and decodes incoming responses according to the Maselli Proprietary Serial/Socket Protocol. * **Transport Layer Abstraction:** Supports communication over both direct serial (RS-232/RS-485) connections and TCP/IP sockets (Ethernet Bridge). * **Instrument Lifecycle Management:** Handles instrument detection, recognition, initialization, active communication, and graceful disconnection. * **Data Synchronization:** Updates shared data structures (e.g., `UtilityMaselli.Variabili`) with values read from instruments. * **Event Notification:** Provides callbacks or events for significant communication occurrences (e.g., data received, protocol change). * **Error Handling and Logging:** Detects communication errors, retries commands, and logs relevant information. ## 2. Core Class: `Uc09_Utility.ClassSerialeStrumenti` This class is the heart of the Instrument Communication Service. **Key Internal Components and Mechanisms:** * **Instrument Registry (`ListaStrumenti`)**: * A list (`List`) that holds instances of all instruments the service is configured to manage. * Each `ClassStrumentoMaselli` object contains instrument-specific details like address, function numbers, and communication state (`InstrumentSerial`). * **Command Queue (`QueueComandiSeriali`)**: * A thread-safe queue (`ConcurrentQueue`) that stores commands submitted from various parts of the application. * Commands are processed in a FIFO (First-In, First-Out) manner, though the service prioritizes commands for instruments that are actively communicating. * **Main Processing Loop (driven by `_timerSerialeUtility`)**: * A `System.Timers.Timer` periodically triggers the main logic of the service. * This loop iterates through the `ListaStrumenti`, processing each instrument based on its current communication phase (`InstrumentSerial.FaseComunicazione`). * It handles sending commands from the queue, managing timeouts, processing received data, and transitioning instruments through different communication states. * **Physical Communication Layer:** * **Serial Port (`_serialPortUtility`):** An instance of `System.IO.Ports.SerialPort` used for direct serial communication. Configured based on settings in `UtilityMaselli.Setup` (COM port, baud rate, etc.). * **Socket Communication (`_maselliSocketUtility`):** An instance of `MaselliSocket.ClassMaselliSocket` used when the Ethernet bridge is enabled (`UtilityMaselli.Setup.EnableEthernetBridge`). This class encapsulates TCP/IP client socket operations. * The service seamlessly switches between these layers based on configuration. * **Protocol Encoding/Decoding Engine:** * `PreparaComando()`: Constructs the full command string according to the Maselli protocol, including address, command type, function number, value, length, and checksum. * `CalcolaChecksum()`: Calculates the checksum for outgoing commands. * `GestioneComandoRicevuto()`: The primary method for parsing incoming responses. It checks for protocol errors (e.g., `NOxx`), identifies response types (data, image, acknowledgment), and routes data for further processing. * `DecoderProtocolloMaselli()`: Extracts values from standard data responses (`!VALUE`) and updates the corresponding `ClassVariabile` objects in `UtilityMaselli.Variabili`. * `DecodificaImmagine()`: Handles the more complex task of parsing and assembling image data received from instruments. * **Communication State Machine (`InstrumentSerial.FaseComunicazione`)**: * Each instrument managed by the service has an associated communication phase. The service transitions instruments through these phases: * Initial connection attempts. * Sending "super commands" for recognition or protocol forcing. * Instrument recognition (matching response with `Identifier.RecognizingStrings`). * Sending instrument-specific startup commands. * `LINKED` state for active data exchange. * Handling image requests and multi-part responses. * Closing communication and sending exit commands. * **Error Handling and Retries:** * The service checks for protocol errors (`NOxx`) in responses. * Commands can have a retry count (`ComandoSeriale.NumeroRipetizioni`). If a command fails (timeout or error response), it can be re-queued for a limited number of retries. * The `CommunicationHandlerLoggerService` (an implementation of `ILoggerService`) is used to log communication errors and significant events. ## 3. Service Operations and Flow ### 3.1. Initialization and Instrument Addition 1. The `ClassSerialeStrumenti` service is typically initialized once at application startup. 2. Instruments (instances of `ClassStrumentoMaselli` derivatives) are added to the service using the `AddStrumento()` method. This registers them for management. 3. The service attempts to open the configured communication port (serial or socket) via `ApriPortaComunicazione()`. ### 3.2. Submitting Commands 1. Other parts of the application (e.g., UI event handlers, automated processes) submit commands to instruments by calling `InserisciComandoSeriale()`. 2. This method populates a `ComandoSeriale` object with the necessary details (instrument address, command type, function number, value, etc.) and adds it to the `QueueComandiSeriali`. ### 3.3. Command Processing Cycle (Timer Tick) 1. The `_timerSerialeUtility_Elapsed` event handler executes periodically. 2. **Command Sending:** * The service checks if the communication line is free (`_statoComunicazione == StatiComunicazione.LIBERO`). * It iterates through `ListaStrumenti`. For each instrument, it checks its `FaseComunicazione`. * If an instrument is in a state to send commands (e.g., `SEND_SUPER_COMMAND_RECOGNIZE_EQUIPMENT`, `LINKED`), the service dequeues the next relevant command (either a special command or from `QueueComandiSeriali`). * The command is formatted using `PreparaComando()`. * The formatted command is sent via `_serialPortUtility.Write()` or `_maselliSocketUtility.Send()`. * The service transitions to a `WAIT_RX` state and sets a timeout for the response. 3. **Response Handling:** * Data received on the serial port (`_serialPortUtility_DataReceived`) or socket (`_maselliSocketUtility.eventoResponseEthBridge`) triggers processing. * The received data is passed to `GestioneComandoRicevuto()`. * This method parses the response, checks for errors, and determines the response type. * If it's a data response, `DecoderProtocolloMaselli()` updates the global `UtilityMaselli.Variabili`. * If it's an image response, `DecodificaImmagine()` processes the image data. * The command status (`ComandoSeriale.Stato`) is updated (e.g., `OK_COMMAND`, `ERROR_COMMAND`). * Relevant callbacks/events like `ReceiveCallback` or `ModifiedReceived` are invoked. 4. **State Transitions:** * Based on successful command execution or received data, the instrument's `FaseComunicazione` is updated (e.g., from `RECOGNIZE_EQUIPMENT` to `SEND_STARTUP_COMMANDS`, then to `LINKED`). ### 3.4. Instrument Recognition * During initial phases, the service sends "super commands" (e.g., requesting instrument memory name). * The response is compared against `Identifier.RecognizingStrings` for each configured instrument. * Once a match is found, `Identifier.EquipmentRecognized` is set to true, and the instrument model may be further refined (e.g., differentiating UC07 from UC08 based on the memory name). * The `ProtocolChangedToMaselli` event can be raised if the instrument confirms it's in Maselli mode. ### 3.5. Data Synchronization * When `DecoderProtocolloMaselli()` successfully parses a response to a read command (`V`), it finds the corresponding `ClassVariabile` in `UtilityMaselli.Variabili` (based on instrument and function number) and updates its `Valore` property. * This makes the latest instrument data available to the rest of the application. ## 4. Interaction with Other System Components * **`UtilityMaselli.Setup`**: Provides configuration parameters for the communication channel (port, speed, bridge settings). * **`UtilityMaselli.Variabili`**: The global list of `ClassVariabile` objects that this service reads from (for "M" commands, using the current value in the variable if not explicitly provided in `ComandoSeriale`) and writes to (after "V" commands). * **`ClassStrumentoMaselli` (and derivatives)**: Provide instrument-specific information like address, function number definitions, startup/exit commands, and recognizing strings. * **Application Logic/UI**: Submits commands via `InserisciComandoSeriale()` and consumes data from `UtilityMaselli.Variabili`. Listens to events from the service for UI updates. * **`MaselliSocket.ClassMaselliSocket`**: Used as the transport layer when Ethernet bridge is active. * **`CommunicationHandlerLoggerService`**: Used for logging errors and important communication events. ## 5. Service Robustness * **Timeouts:** Manages timeouts for responses to prevent indefinite blocking. * **Retries:** Failed commands can be retried a configurable number of times. * **Checksums:** Validates command integrity for serial transmission. * **Error Logging:** Provides diagnostic information for troubleshooting. * **Concurrent Queue:** Ensures thread-safe command submission. The Instrument Communication Service is thus a critical and complex component, orchestrating the entire flow of information between the software and the physical Maselli instruments.