SXXXXXXX_PyBusMonitor1553/doc/Refactoring-Plan-GUI-as-Client.md
2025-12-22 10:44:32 +01:00

301 lines
9.6 KiB
Markdown

# 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?