301 lines
9.6 KiB
Markdown
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?
|