273 lines
7.9 KiB
Markdown
273 lines
7.9 KiB
Markdown
# Session 2026-01-05 - Améliorations de l'import PCI
|
|
|
|
## Contexte
|
|
|
|
Suite à l'implémentation de l'import PCI, l'utilisateur a testé avec ses périphériques réels:
|
|
- **NVMe SSD**: Micron/Crucial Technology P2/P3/P3 Plus NVMe PCIe SSD
|
|
- **Carte graphique**: NVIDIA GeForce RTX 3060 Lite Hash Rate (Gigabyte)
|
|
|
|
## Problèmes identifiés
|
|
|
|
### 1. Parsing incorrect du vendor/device name
|
|
|
|
**Problème initial:**
|
|
```
|
|
Description: "Micron/Crucial Technology P2 [Nick P2] / P3 / P3 Plus NVMe PCIe SSD"
|
|
├─ Vendor: "Micron/Crucial" ❌ (incomplet)
|
|
└─ Device: "Technology P2 [Nick P2] / P3 / P3 Plus NVMe PCIe SSD" ❌ (incorrect)
|
|
|
|
Description: "NVIDIA Corporation GA106 [GeForce RTX 3060 Lite Hash Rate]"
|
|
├─ Vendor: "NVIDIA" ❌ (incomplet)
|
|
└─ Device: "Corporation GA106 [GeForce RTX 3060 Lite Hash Rate]" ❌ (incorrect)
|
|
```
|
|
|
|
Le parser divisait simplement sur le premier espace, ce qui ne fonctionnait pas avec les vendor names multi-mots.
|
|
|
|
**Solution implémentée:**
|
|
|
|
Nouvelle fonction `_split_vendor_device()` dans `lspci_parser.py` qui détecte les suffixes de vendor:
|
|
- Corporation
|
|
- Technology
|
|
- Semiconductor
|
|
- Co., Ltd.
|
|
- Inc.
|
|
- GmbH
|
|
- AG
|
|
|
|
```python
|
|
def _split_vendor_device(description: str) -> Tuple[str, str]:
|
|
vendor_suffixes = [
|
|
r'\bCo\.,?\s*Ltd\.?',
|
|
r'\bCorporation\b',
|
|
r'\bTechnology\b',
|
|
r'\bSemiconductor\b',
|
|
# ... autres patterns
|
|
]
|
|
# Trouve le suffixe et divise à sa fin
|
|
```
|
|
|
|
**Résultat:**
|
|
```
|
|
✅ NVMe:
|
|
Vendor: "Micron/Crucial Technology"
|
|
Device: "P2 [Nick P2] / P3 / P3 Plus NVMe PCIe SSD (DRAM-less)"
|
|
|
|
✅ GPU:
|
|
Vendor: "NVIDIA Corporation"
|
|
Device: "GA106 [GeForce RTX 3060 Lite Hash Rate]"
|
|
```
|
|
|
|
### 2. Device name contenait prog-if et revision
|
|
|
|
**Problème:**
|
|
```
|
|
Device: "P2 [Nick P2] / P3 Plus NVMe PCIe SSD (prog-if 02 [NVM Express])"
|
|
```
|
|
|
|
**Solution:**
|
|
Nettoyage du device_name après extraction:
|
|
```python
|
|
# Clean prog-if from device_name
|
|
result["device_name"] = re.sub(r'\s*\(prog-if\s+[0-9a-fA-F]+\s*\[[^\]]+\]\)', '', result["device_name"])
|
|
```
|
|
|
|
**Résultat:**
|
|
```
|
|
✅ Device: "P2 [Nick P2] / P3 / P3 Plus NVMe PCIe SSD (DRAM-less)"
|
|
```
|
|
|
|
### 3. Extraction incorrecte de la marque et du modèle
|
|
|
|
**Problème:**
|
|
- Marque: vendor name complet au lieu du premier mot
|
|
- Modèle: device name complet au lieu du nom commercial
|
|
|
|
**Solution:**
|
|
|
|
Nouvelle fonction `extract_brand_model()` dans `lspci_parser.py`:
|
|
|
|
```python
|
|
def extract_brand_model(vendor_name: str, device_name: str, device_class: str) -> Tuple[str, str]:
|
|
# Extract brand (first word of vendor, before /)
|
|
brand = vendor_name.split()[0] if vendor_name else ""
|
|
if '/' in brand:
|
|
brand = brand.split('/')[0] # "Micron/Crucial" -> "Micron"
|
|
|
|
# For GPUs: use bracket content
|
|
if 'vga' in device_class.lower():
|
|
# "GA106 [GeForce RTX 3060]" -> "GeForce RTX 3060"
|
|
bracket_content = extract_from_brackets(device_name)
|
|
model = bracket_content
|
|
|
|
# For NVMe: clean brackets and combine
|
|
elif 'nvme' in device_class.lower():
|
|
# "P2 [Nick P2] / P3 / P3 Plus NVMe SSD"
|
|
# -> "P2/P3/P3 Plus NVMe PCIe SSD"
|
|
cleaned = remove_brackets(device_name)
|
|
model = cleaned
|
|
```
|
|
|
|
**Résultats:**
|
|
|
|
```
|
|
✅ NVMe:
|
|
Marque: "Micron"
|
|
Modèle: "P2/P3/P3 Plus NVMe PCIe SSD (DRAM-less)"
|
|
Nom: "Micron P2/P3/P3 Plus NVMe PCIe SSD (DRAM-less)"
|
|
|
|
✅ GPU:
|
|
Marque: "NVIDIA"
|
|
Modèle: "GeForce RTX 3060 Lite Hash Rate"
|
|
Nom: "NVIDIA GeForce RTX 3060 Lite Hash Rate"
|
|
```
|
|
|
|
### 4. Fabricant de la carte graphique non extrait
|
|
|
|
**Problème:**
|
|
Pour les GPU, le subsystem contient le fabricant de la carte (Gigabyte, ASUS, MSI, etc.) mais n'était pas extrait.
|
|
|
|
**Solution:**
|
|
|
|
Ajout dans l'endpoint `/import/pci/extract`:
|
|
```python
|
|
# For GPUs, extract card manufacturer from subsystem
|
|
if sous_type == "Carte graphique" and device_info.get("subsystem"):
|
|
subsystem_parts = device_info["subsystem"].split()
|
|
if subsystem_parts:
|
|
card_manufacturer = subsystem_parts[0]
|
|
if card_manufacturer.lower() not in ["device", "subsystem"]:
|
|
suggested["fabricant"] = card_manufacturer
|
|
```
|
|
|
|
**Résultat:**
|
|
```
|
|
✅ GPU:
|
|
Marque: "NVIDIA" (chipset manufacturer)
|
|
Fabricant: "Gigabyte" (card manufacturer)
|
|
Modèle: "GeForce RTX 3060 Lite Hash Rate"
|
|
```
|
|
|
|
## Fichiers modifiés
|
|
|
|
### 1. `/backend/app/utils/lspci_parser.py`
|
|
|
|
**Nouvelles fonctions:**
|
|
- `extract_brand_model()` - Extraction intelligente marque/modèle
|
|
- `_split_vendor_device()` - Division vendor/device basée sur suffixes
|
|
|
|
**Améliorations:**
|
|
- Nettoyage du `prog-if` dans device_name
|
|
- Meilleure extraction du vendor name
|
|
|
|
### 2. `/backend/app/api/endpoints/peripherals.py`
|
|
|
|
**Import ajouté:**
|
|
```python
|
|
from app.utils.lspci_parser import extract_brand_model
|
|
```
|
|
|
|
**Amélioration de la construction du peripheral suggéré:**
|
|
```python
|
|
# Extract brand and model
|
|
brand, model = extract_brand_model(
|
|
device_info.get("vendor_name", ""),
|
|
device_info.get("device_name", ""),
|
|
device_info.get("device_class", "")
|
|
)
|
|
|
|
# Build name
|
|
nom = f"{brand} {model}".strip()
|
|
|
|
suggested = {
|
|
"nom": nom,
|
|
"marque": brand,
|
|
"modele": model,
|
|
# ... autres champs
|
|
}
|
|
|
|
# For GPUs, add card manufacturer
|
|
if sous_type == "Carte graphique":
|
|
suggested["fabricant"] = extract_from_subsystem()
|
|
```
|
|
|
|
## Résultats des tests
|
|
|
|
### Test NVMe - Micron/Crucial P2/P3
|
|
|
|
```json
|
|
{
|
|
"nom": "Micron P2/P3/P3 Plus NVMe PCIe SSD (DRAM-less)",
|
|
"type_principal": "PCI",
|
|
"sous_type": "SSD NVMe",
|
|
"marque": "Micron",
|
|
"modele": "P2/P3/P3 Plus NVMe PCIe SSD (DRAM-less)",
|
|
"pci_device_id": "c0a9:5407",
|
|
"caracteristiques_specifiques": {
|
|
"slot": "01:00.0",
|
|
"device_class": "Non-Volatile memory controller",
|
|
"vendor_name": "Micron/Crucial Technology",
|
|
"subsystem": "Micron/Crucial Technology P2 [Nick P2] / P3 / P3 Plus NVMe PCIe SSD (DRAM-less)",
|
|
"driver": "nvme",
|
|
"iommu_group": "14",
|
|
"revision": "01",
|
|
"modules": "nvme"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Test GPU - NVIDIA RTX 3060
|
|
|
|
```json
|
|
{
|
|
"nom": "NVIDIA GeForce RTX 3060 Lite Hash Rate",
|
|
"type_principal": "PCI",
|
|
"sous_type": "Carte graphique",
|
|
"marque": "NVIDIA",
|
|
"modele": "GeForce RTX 3060 Lite Hash Rate",
|
|
"pci_device_id": "10de:2504",
|
|
"fabricant": "Gigabyte",
|
|
"caracteristiques_specifiques": {
|
|
"slot": "08:00.0",
|
|
"device_class": "VGA compatible controller",
|
|
"vendor_name": "NVIDIA Corporation",
|
|
"subsystem": "Gigabyte Technology Co., Ltd Device 4074",
|
|
"driver": "nvidia",
|
|
"iommu_group": "16",
|
|
"revision": "a1",
|
|
"modules": "nvidia"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Workflow complet de l'import PCI
|
|
|
|
1. **Détection**: Utilisateur colle `lspci -v` et `lspci -n` dans la modale
|
|
2. **Parsing**: Backend détecte tous les périphériques avec slots
|
|
3. **Sélection**: Frontend affiche les périphériques avec checkboxes
|
|
4. **Queue**: Périphériques sélectionnés ajoutés à `window.pciImportQueue`
|
|
5. **Import séquentiel**: Pour chaque périphérique:
|
|
- Backend extrait et classifie
|
|
- Détecte les doublons
|
|
- Construit le peripheral suggéré avec marque/modèle
|
|
- Frontend ouvre la modale d'ajout pré-remplie
|
|
- Utilisateur valide/modifie
|
|
- Sauvegarde et passe au suivant automatiquement
|
|
|
|
## Améliorations futures possibles
|
|
|
|
1. **Base de données PCI IDs**: Intégrer une base pour résoudre les vendor:device IDs en noms
|
|
2. **Photos automatiques**: Rechercher des photos de produits via API (Google Images, etc.)
|
|
3. **Détection de specs**: Extraire RAM pour GPU, capacité pour NVMe depuis autres sources
|
|
4. **Import groupé**: Option pour importer tous les périphériques sélectionnés sans validation individuelle
|
|
|
|
## Conclusion
|
|
|
|
✅ Le parsing PCI est maintenant intelligent et extrait correctement:
|
|
- Vendor names multi-mots (Corporation, Technology, Co., Ltd.)
|
|
- Device names nettoyés (sans prog-if, rev)
|
|
- Marques commerciales (premier mot du vendor)
|
|
- Modèles commerciaux (contenu des brackets pour GPU, nettoyé pour storage)
|
|
- Fabricant de carte (pour GPU, depuis subsystem)
|
|
|
|
Les périphériques importés auront des noms propres et exploitables pour l'inventaire.
|