# Refactoring Plan: GUI as ARTOS API Client ## Problema Attuale La GUI attuale accede direttamente a `ConnectionManager` invece di usare `BusMonitorCore`: ```python # CURRENT (Wrong approach) from pybusmonitor1553.core.connection_manager import get_manager self.manager = get_manager() self.manager.init_library() self.manager.start() ``` **Problema**: Questa NON è l'API che userà ARTOS! Stiamo testando l'implementazione sbagliata. ## Soluzione: GUI Diventa Client del Modulo La GUI deve usare **esattamente** la stessa API BaseModule che userà ARTOS: ```python # NEW (Correct approach - same as ARTOS) from pybusmonitor1553.core import BusMonitorCore self.bus_monitor = BusMonitorCore() self.bus_monitor.initialize(config) self.bus_monitor.start_session() self.bus_monitor.stop_session() ``` ## Architettura Target ``` ┌──────────────────────────────────────────────────────────┐ │ ARTOS Collector │ │ ┌────────────────────────────────────────────────────┐ │ │ │ from pybusmonitor1553.core import BusMonitorCore │ │ │ │ monitor = BusMonitorCore() │ │ │ │ monitor.initialize({'ip': ..., 'port': ...}) │ │ │ │ monitor.start_session() │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────┘ ↕ SAME API ┌──────────────────────────────────────────────────────────┐ │ PyBusMonitor1553 GUI (Test Tool) │ │ ┌────────────────────────────────────────────────────┐ │ │ │ from pybusmonitor1553.core import BusMonitorCore │ │ │ │ monitor = BusMonitorCore() │ │ │ │ monitor.initialize({'ip': ..., 'port': ...}) │ │ │ │ monitor.start_session() │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────┘ ``` **Benefit**: Se la GUI funziona, ARTOS funzionerà. Zero sorprese! --- ## Modifiche Necessarie ### File da Modificare #### 1. `gui/monitor.py` **Prima (linea ~793)**: ```python from pybusmonitor1553.core.connection_manager import get_manager self.manager = get_manager() ``` **Dopo**: ```python from pybusmonitor1553.core import BusMonitorCore self.bus_monitor = BusMonitorCore() ``` **Cambio metodi (linea ~809)**: | Prima | Dopo | |------------------------------|-------------------------------------| | `self.manager.init_library()`| `self.bus_monitor.initialize(config)`| | `self.manager.start()` | `self.bus_monitor.start_session()` | | `self.manager.stop()` | `self.bus_monitor.stop_session()` | | `self.manager.is_running()` | `self.bus_monitor.get_status()['is_running']` | #### 2. `bus_monitor_core.py` - Aggiungere MessageDB Integration Attualmente `get_message()` ritorna `None`. Dobbiamo integrare il MessageDB: ```python def get_message(self, label: str) -> Optional[Any]: """Get message by label.""" # Import MessageDB lazily from ..Grifo_E_1553lib.messages import MessageDB # o dove si trova return MessageDB.get_message(label) def get_all_messages(self) -> List[Any]: """Get all registered messages.""" from ..Grifo_E_1553lib.messages import MessageDB return MessageDB.get_all_messages() ``` #### 3. Aggiungere Config Helper nella GUI La GUI deve costruire il dizionario di configurazione: ```python def get_config_from_gui(self) -> Dict[str, Any]: """Build config dict from GUI widgets (if any config UI exists).""" return { 'ip': os.getenv('PYBM_RX_IP', '127.0.0.1'), 'send_port': int(os.getenv('PYBM_TX_PORT', '5001')), 'recv_port': int(os.getenv('PYBM_RX_PORT', '5002')) } ``` --- ## Step-by-Step Implementation Plan ### Phase 1: Preparare BusMonitorCore (Completamento) **File**: `pybusmonitor1553/core/bus_monitor_core.py` 1. ✅ Interfaccia BaseModule (già fatto) 2. ✅ Recording system (già fatto) 3. ❌ **TODO**: Integrare MessageDB per `get_message()` e `get_all_messages()` 4. ❌ **TODO**: Assicurarsi che `initialize()` configuri correttamente ConnectionManager ### Phase 2: Refactorare GUI per Usare BusMonitorCore **File**: `pybusmonitor1553/gui/monitor.py` 1. Cambiare import da `connection_manager` a `BusMonitorCore` 2. Sostituire `self.manager` con `self.bus_monitor` 3. Mappare tutti i metodi vecchi ai nuovi: - `init_library()` → `initialize(config)` - `start()` → `start_session()` - `stop()` → `stop_session()` 4. Usare `get_status()` per verificare stato 5. Usare `get_message()` e `get_all_messages()` per accesso ai dati ### Phase 3: Registrare Callbacks per GUI Updates La GUI può usare il callback system per aggiornamenti real-time: ```python def on_message_received(self, label: str, message: Any): """Callback called when a message arrives.""" # Update GUI tree view self.refresh_single_message(label, message) # During initialization: self.bus_monitor.register_callback("msg_a2", lambda msg: self.on_message_received("msg_a2", msg)) ``` ### Phase 4: Testing & Validation 1. Verificare che la GUI funzioni come prima (comportamento invariato) 2. Verificare che i log mostrino lo stesso output 3. Testare Initialize → Start → Stop → Recording 4. **IMPORTANTE**: Creare un test automatico che usi lo stesso workflow della GUI --- ## Boundary Definition: Core Module vs GUI ### Core Module (Auto-contenuto, Esportabile) **Folder**: `pybusmonitor1553/core/` ``` pybusmonitor1553/ ├── core/ │ ├── __init__.py # Exports: BaseModule, BusMonitorCore, DataRecorder │ ├── base_module.py # ARTOS interface │ ├── bus_monitor_core.py # Business logic │ ├── data_recorder.py # Recording system │ └── connection_manager.py # Internal (non esposto!) └── Grifo_E_1553lib/ # Protocol layer (parte del core) ├── messages/ ├── udp_parser.py └── ... ``` **Public API** (quello che ARTOS importa): ```python from pybusmonitor1553.core import BusMonitorCore # That's it! Tutto il resto è internal. ``` ### GUI (Development/Test Tool) **Folder**: `pybusmonitor1553/gui/` ``` pybusmonitor1553/ └── gui/ ├── __init__.py ├── monitor.py # Main GUI - imports BusMonitorCore ├── details_pane.py # Helper widgets └── monitor_helpers.py # GUI utilities ``` **GUI è un CLIENT**, non parte del core module. ### Standalone Entry Point **File**: `pybusmonitor1553/__main__.py` ```python def main(): """Standalone mode: start GUI test tool.""" from pybusmonitor1553.gui.monitor import main as gui_main gui_main() ``` --- ## Package Structure for Distribution ### Scenario 1: Full Package (Development) ```bash pip install pybusmonitor1553[gui] python -m pybusmonitor1553 # Runs GUI test tool ``` ### Scenario 2: Core Only (ARTOS) ```bash pip install pybusmonitor1553 # No GUI dependencies ``` ```python # In ARTOS Collector from pybusmonitor1553.core import BusMonitorCore ``` ### setup.py Configuration ```python setup( name="pybusmonitor1553", packages=find_packages(), install_requires=[ # Core dependencies only "no external dependencies!" # Tutto built-in Python ], extras_require={ 'gui': [ 'tkinter', # Usually included in Python, but explicit here # Add other GUI-specific deps if needed ] } ) ``` --- ## Vantaggi di Questo Approccio ### ✅ API Consistency GUI e ARTOS usano **identica** API → zero discrepanze. ### ✅ True Test Harness Se la GUI funziona, ARTOS funzionerà. La GUI diventa lo strumento di test del modulo. ### ✅ Clean Separation - **Core**: Auto-contenuto, zero dipendenze esterne - **GUI**: Tool opzionale che dipende dal core ### ✅ Easy Distribution ```python # ARTOS project doesn't even know GUI exists: from pybusmonitor1553.core import BusMonitorCore ``` ### ✅ Future-Proof Domani puoi creare un CLI, un REST API server, o un altro client - tutti useranno lo stesso core! --- ## Next Steps ### Immediate (Completare BusMonitorCore) 1. Integrare MessageDB in `bus_monitor_core.py` 2. Verificare che `initialize()` configuri ConnectionManager correttamente 3. Testare recording/replay con messaggi reali ### Short-term (Refactorare GUI) 1. Modificare `gui/monitor.py` per usare BusMonitorCore 2. Rimuovere accessi diretti a ConnectionManager 3. Testare che la GUI funzioni come prima ### Mid-term (Packaging) 1. Configurare setup.py con extras_require 2. Documentare API pubblica 3. Creare esempi di utilizzo (GUI + ARTOS) Vuoi che proceda con l'implementazione del refactoring?