| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- """
- System Status Panel
- Displays the status of cameras, AI models, and hardware.
- Allows manual refresh of status information.
- """
- from typing import Optional, Dict, Any, Callable
- from PyQt5.QtWidgets import QGroupBox, QVBoxLayout, QHBoxLayout, QLabel, QPushButton
- from PyQt5.QtGui import QFont
- from PyQt5.QtCore import Qt
- from ui.widgets.status_indicator import StatusIndicator
- from resources.styles import GROUP_BOX_STYLE, HEADER_LABEL_STYLE, INFO_LABEL_STYLE, STANDARD_BUTTON_STYLE
- from utils.config import MODEL_VERSIONS
- from utils.system_monitor import get_full_system_status
- class SystemStatusPanel(QGroupBox):
- """
- Panel displaying real-time system status information.
-
- Shows:
- - Camera systems (RGB, Multispectral, Thermal, Audio)
- - AI models (Ripeness, Quality, Defect Detection, Maturity, Shape)
- - Hardware information (GPU, RAM)
-
- Includes manual refresh button to update all statuses on demand.
- """
-
- def __init__(self):
- """Initialize the system status panel."""
- super().__init__("System Status")
- self.setStyleSheet(GROUP_BOX_STYLE)
-
- # Store status update callback
- self.models = None
-
- # Store references to all status widgets for updates
- self.camera_status_indicators = {}
- self.camera_info_labels = {}
-
- self.model_status_indicators = {}
- self.model_info_labels = {}
-
- self.gpu_info_label = None
- self.ram_info_label = None
-
- self.init_ui()
-
- def init_ui(self):
- """Initialize the UI components."""
- layout = QVBoxLayout()
-
- # Camera Systems Section
- self._add_camera_systems(layout)
-
- # AI Models Section
- self._add_ai_models(layout)
-
- # Hardware Section
- self._add_hardware_info(layout)
-
- # Refresh Button
- refresh_btn = QPushButton("🔄 Refresh Status")
- refresh_btn.setStyleSheet(STANDARD_BUTTON_STYLE)
- refresh_btn.clicked.connect(self.refresh_status)
- layout.addWidget(refresh_btn)
-
- layout.addStretch()
- self.setLayout(layout)
-
- def _add_camera_systems(self, layout: QVBoxLayout):
- """Add camera systems section to layout."""
- # Section header
- camera_label = QLabel("Camera Systems:")
- camera_label.setFont(QFont("Arial", 16, QFont.Bold))
- camera_label.setStyleSheet(HEADER_LABEL_STYLE + " margin-top: 10px;")
- layout.addWidget(camera_label)
-
- camera_names = ["EOS Utility", "2nd Look", "AnalyzIR", "Audio System"]
-
- for camera_name in camera_names:
- camera_layout = QHBoxLayout()
-
- # Status indicator
- status_indicator = StatusIndicator("offline")
- camera_layout.addWidget(status_indicator)
- self.camera_status_indicators[camera_name] = status_indicator
-
- # Camera name
- name_label = QLabel(camera_name)
- name_label.setFont(QFont("Arial", 12))
- camera_layout.addWidget(name_label)
-
- camera_layout.addStretch()
-
- # Info label (specs or DISCONNECTED)
- info_label = QLabel("Initializing...")
- info_label.setStyleSheet(INFO_LABEL_STYLE)
- camera_layout.addWidget(info_label)
- self.camera_info_labels[camera_name] = info_label
-
- layout.addLayout(camera_layout)
-
- def _add_ai_models(self, layout: QVBoxLayout):
- """Add AI models section to layout."""
- # Section header
- ai_label = QLabel("AI Models:")
- ai_label.setFont(QFont("Arial", 16, QFont.Bold))
- ai_label.setStyleSheet(HEADER_LABEL_STYLE + " margin-top: 15px;")
- layout.addWidget(ai_label)
-
- model_info = [
- ('Ripeness', MODEL_VERSIONS.get('ripeness', '')),
- ('Quality', MODEL_VERSIONS.get('quality', '')),
- ('Defect', MODEL_VERSIONS.get('defect', '')),
- ('Maturity', MODEL_VERSIONS.get('maturity', '')),
- ('Shape', MODEL_VERSIONS.get('shape', '')),
- ]
-
- for model_display_name, version in model_info:
- model_layout = QHBoxLayout()
-
- # Status indicator
- status_indicator = StatusIndicator("offline")
- model_layout.addWidget(status_indicator)
- self.model_status_indicators[model_display_name] = status_indicator
-
- # Model name with version
- model_text = QLabel(f"{model_display_name} Model {version}")
- model_text.setFont(QFont("Arial", 12))
- model_layout.addWidget(model_text)
-
- model_layout.addStretch()
-
- # Info label
- info_label = QLabel("Initializing...")
- info_label.setStyleSheet(INFO_LABEL_STYLE)
- model_layout.addWidget(info_label)
- self.model_info_labels[model_display_name] = info_label
-
- layout.addLayout(model_layout)
-
- def _add_hardware_info(self, layout: QVBoxLayout):
- """Add hardware information section to layout."""
- # Section header
- hardware_label = QLabel("Hardware:")
- hardware_label.setFont(QFont("Arial", 16, QFont.Bold))
- hardware_label.setStyleSheet(HEADER_LABEL_STYLE + " margin-top: 15px;")
- layout.addWidget(hardware_label)
-
- # GPU info
- self.gpu_info_label = QLabel("GPU: Initializing...")
- self.gpu_info_label.setStyleSheet("color: #2c3e50; font-size: 12px;")
- layout.addWidget(self.gpu_info_label)
-
- # RAM info
- self.ram_info_label = QLabel("RAM: Initializing...")
- self.ram_info_label.setStyleSheet("color: #2c3e50; font-size: 12px;")
- layout.addWidget(self.ram_info_label)
-
- def set_models_reference(self, models: Dict[str, Any]):
- """
- Set reference to loaded models for status checking.
-
- Args:
- models: Dictionary of model instances from main_window
- """
- self.models = models
-
- def refresh_status(self):
- """Refresh all system status information."""
- try:
- print("\n🔄 ============= REFRESH STATUS =============")
- print("🔄 Refreshing system status...")
- print(f" Available camera_status_indicators: {list(self.camera_status_indicators.keys())}")
- print(f" Available model_status_indicators: {list(self.model_status_indicators.keys())}")
-
- # Get complete system status
- system_status = get_full_system_status(self.models)
-
- # Update camera status
- cameras_status = system_status['cameras']
- print(f"\n📷 Camera status returned: {cameras_status}")
- for camera_name, camera_info in cameras_status.items():
- print(f" Processing camera: {camera_name}")
- if camera_name in self.camera_status_indicators:
- # Update indicator
- status = 'online' if camera_info['running'] else 'offline'
- self.camera_status_indicators[camera_name].set_status(status)
- print(f" ✓ Updated status to: {status}")
-
- # Update info label
- info_text = camera_info['spec']
- self.camera_info_labels[camera_name].setText(info_text)
- print(f" ✓ Updated info to: {info_text}")
-
- # Update color for disconnected
- if not camera_info['running']:
- self.camera_info_labels[camera_name].setStyleSheet(
- "color: #e74c3c; font-size: 12px; font-weight: bold;"
- )
- else:
- self.camera_info_labels[camera_name].setStyleSheet(INFO_LABEL_STYLE)
- else:
- print(f" ✗ WARNING: Not found in camera_status_indicators!")
-
- # Update model status
- models_status = system_status['models']
- print(f"\n🤖 Model status returned: {models_status}")
- for model_name, model_info in models_status.items():
- print(f" Processing model: {model_name}")
- if model_name in self.model_status_indicators:
- # Update indicator
- self.model_status_indicators[model_name].set_status(model_info['status'])
- print(f" ✓ Updated status to: {model_info['status']}")
-
- # Update info label
- self.model_info_labels[model_name].setText(model_info['info'])
- print(f" ✓ Updated info to: {model_info['info']}")
- else:
- print(f" ✗ WARNING: Not found in model_status_indicators!")
-
- # Update GPU info
- gpu_info = system_status['gpu']
- print(f"\n💾 GPU info: {gpu_info['display']}")
- self.gpu_info_label.setText(gpu_info['display'])
-
- # Update RAM info
- ram_info = system_status['ram']
- print(f"💾 RAM info: {ram_info['display']}")
- self.ram_info_label.setText(ram_info['display'])
-
- print("✓ System status refresh complete\n")
-
- except Exception as e:
- print(f"❌ Error refreshing system status: {e}")
- import traceback
- traceback.print_exc()
-
- def update_model_status(self, model_name: str, status: str, info_text: str = ""):
- """
- Update the status of a specific model (for backward compatibility).
-
- Args:
- model_name: Name of the model ('ripeness', 'quality', or 'defect')
- status: Status ('online', 'offline', or 'updating')
- info_text: Optional info text to display
- """
- # Map old model names to new display names
- model_map = {
- 'ripeness': 'Ripeness',
- 'quality': 'Quality',
- 'defect': 'Defect',
- 'maturity': 'Maturity',
- 'shape': 'Shape'
- }
-
- display_name = model_map.get(model_name, model_name)
-
- if display_name in self.model_status_indicators:
- self.model_status_indicators[display_name].set_status(status)
- if info_text:
- self.model_info_labels[display_name].setText(info_text)
|