Obsidean_VM/01-Documentation/Dispositivos - Manuales/Maselli/Maselli - Utility/Instrument Communication Se...

129 lines
10 KiB
Markdown

# 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<ClassStrumentoMaselli>`) 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<ComandoSeriale>`) 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.