diff --git a/AppImage/components/hardware.tsx b/AppImage/components/hardware.tsx index fc209e3..383a514 100644 --- a/AppImage/components/hardware.tsx +++ b/AppImage/components/hardware.tsx @@ -18,7 +18,7 @@ import { Cpu as Gpu, } from "lucide-react" import useSWR from "swr" -import { useState, useEffect } from "react" +import { useState } from "react" import { type HardwareData, type GPU, type PCIDevice, type StorageDevice, fetcher } from "../types/hardware" const getDeviceTypeColor = (type: string): string => { @@ -59,30 +59,34 @@ export default function Hardware() { }) const [selectedGPU, setSelectedGPU] = useState(null) + const [realtimeGPUData, setRealtimeGPUData] = useState(null) + const [loadingRealtimeData, setLoadingRealtimeData] = useState(false) const [selectedPCIDevice, setSelectedPCIDevice] = useState(null) const [selectedDisk, setSelectedDisk] = useState(null) const [selectedNetwork, setSelectedNetwork] = useState(null) - useEffect(() => { - if (hardwareData?.gpus) { - console.log("[v0] ===== GPU DATA DEBUG =====") - console.log("[v0] Total GPUs:", hardwareData.gpus.length) - console.log("[v0] Full GPU data:", JSON.stringify(hardwareData.gpus, null, 2)) + const handleGPUClick = async (gpu: GPU) => { + setSelectedGPU(gpu) + setLoadingRealtimeData(true) + setRealtimeGPUData(null) - hardwareData.gpus.forEach((gpu, index) => { - console.log(`[v0] ----- GPU ${index}: ${gpu.name} -----`) - console.log(`[v0] GPU ${index} vendor:`, gpu.vendor) - console.log(`[v0] GPU ${index} has_monitoring_tool:`, gpu.has_monitoring_tool) - console.log(`[v0] GPU ${index} temperature:`, gpu.temperature) - console.log(`[v0] GPU ${index} utilization_gpu:`, gpu.utilization_gpu) - console.log(`[v0] GPU ${index} memory_total:`, gpu.memory_total) - console.log(`[v0] GPU ${index} power_draw:`, gpu.power_draw) - console.log(`[v0] GPU ${index} hasRealtimeData:`, hasRealtimeData(gpu)) - console.log(`[v0] GPU ${index} will show modal:`, hasRealtimeData(gpu) ? "ADVANCED" : "BASIC") - }) - console.log("[v0] ===== END GPU DATA DEBUG =====") + try { + const response = await fetch(`http://localhost:8008/api/gpu/${gpu.slot}/realtime`) + if (response.ok) { + const data = await response.json() + console.log("[v0] Real-time GPU data received:", data) + setRealtimeGPUData(data) + } else { + console.log("[v0] Failed to fetch real-time GPU data:", response.status) + setRealtimeGPUData({ has_monitoring_tool: false }) + } + } catch (error) { + console.error("[v0] Error fetching real-time GPU data:", error) + setRealtimeGPUData({ has_monitoring_tool: false }) + } finally { + setLoadingRealtimeData(false) } - }, [hardwareData]) + } const findPCIDeviceForGPU = (gpu: GPU): PCIDevice | null => { if (!hardwareData?.pci_devices || !gpu.slot) return null @@ -104,20 +108,22 @@ export default function Hardware() { return pciDevice || null } - const hasRealtimeData = (gpu: GPU): boolean => { + const hasRealtimeData = (): boolean => { + if (!realtimeGPUData) return false + const result = !!( - (gpu.temperature !== undefined && gpu.temperature > 0) || - (gpu.utilization_gpu !== undefined && gpu.utilization_gpu > 0) || - gpu.memory_total || - gpu.power_draw || - gpu.engine_render !== undefined || - gpu.engine_blitter !== undefined || - gpu.engine_video !== undefined || - gpu.engine_video_enhance !== undefined || - gpu.clock_graphics || - gpu.clock_memory || - gpu.utilization_memory !== undefined || - (gpu.processes !== undefined && gpu.processes.length > 0) + (realtimeGPUData.temperature !== undefined && realtimeGPUData.temperature > 0) || + (realtimeGPUData.utilization_gpu !== undefined && realtimeGPUData.utilization_gpu > 0) || + realtimeGPUData.memory_total || + realtimeGPUData.power_draw || + realtimeGPUData.engine_render !== undefined || + realtimeGPUData.engine_blitter !== undefined || + realtimeGPUData.engine_video !== undefined || + realtimeGPUData.engine_video_enhance !== undefined || + realtimeGPUData.clock_graphics || + realtimeGPUData.clock_memory || + realtimeGPUData.utilization_memory !== undefined || + (realtimeGPUData.processes !== undefined && realtimeGPUData.processes.length > 0) ) return result } @@ -311,7 +317,7 @@ export default function Hardware() { )} - {/* GPU Information - Enhanced with modal */} + {/* GPU Information - Enhanced with on-demand data fetching */} {hardwareData?.gpus && hardwareData.gpus.length > 0 && (
@@ -326,12 +332,11 @@ export default function Hardware() { {hardwareData.gpus.map((gpu, index) => { const pciDevice = findPCIDeviceForGPU(gpu) const fullSlot = pciDevice?.slot || gpu.slot - const isClickable = true return (
setSelectedGPU(gpu)} + onClick={() => handleGPUClick(gpu)} className="cursor-pointer rounded-lg border border-border/30 bg-background/50 p-4 transition-colors hover:bg-background/80" >
@@ -365,59 +370,6 @@ export default function Hardware() { {gpu.pci_kernel_module}
)} - - {gpu.driver_version && ( -
- Driver Version - {gpu.driver_version} -
- )} - - {gpu.temperature !== undefined && gpu.temperature > 0 && ( -
-
- Temperature - {gpu.temperature}°C -
-
-
-
-
- )} - - {gpu.memory_total && ( -
- Memory - - {gpu.memory_used} / {gpu.memory_total} - -
- )} - - {gpu.utilization_gpu !== undefined && ( -
-
- GPU Usage - {gpu.utilization_gpu}% -
-
-
-
-
- )} - - {gpu.power_draw && gpu.power_draw !== "N/A" && ( -
- Power - {gpu.power_draw} -
- )}
) @@ -426,301 +378,325 @@ export default function Hardware() { )} - setSelectedGPU(null)}> + { + setSelectedGPU(null) + setRealtimeGPUData(null) + }} + > - {selectedGPU && - hasRealtimeData(selectedGPU) && - (() => { - const pciDevice = findPCIDeviceForGPU(selectedGPU) - - return ( + {selectedGPU && ( + <> + {loadingRealtimeData ? ( <> {selectedGPU.name} - Real-Time GPU Monitoring + Loading GPU data... +
+
+
+ + ) : hasRealtimeData() ? ( + // Advanced modal with real-time data + (() => { + const pciDevice = findPCIDeviceForGPU(selectedGPU) -
- {/* Basic Information */} -
-

Basic Information

-
-
- Vendor - {selectedGPU.vendor} + return ( + <> + + {selectedGPU.name} + Real-Time GPU Monitoring + + +
+ {/* Basic Information */} +
+

Basic Information

+
+
+ Vendor + {selectedGPU.vendor} +
+
+ Type + {selectedGPU.type} +
+
+ PCI Slot + {pciDevice?.slot || selectedGPU.slot} +
+ {(pciDevice?.driver || selectedGPU.pci_driver) && ( +
+ Driver + + {pciDevice?.driver || selectedGPU.pci_driver} + +
+ )} + {(pciDevice?.kernel_module || selectedGPU.pci_kernel_module) && ( +
+ Kernel Module + + {pciDevice?.kernel_module || selectedGPU.pci_kernel_module} + +
+ )} +
-
- Type - {selectedGPU.type} + + {/* Real-Time Metrics */} +
+

Real-Time Metrics

+
+ {realtimeGPUData.temperature !== undefined && realtimeGPUData.temperature > 0 && ( +
+
+ Temperature + + {realtimeGPUData.temperature}°C + +
+ +
+ )} + {realtimeGPUData.utilization_gpu !== undefined && ( +
+
+ GPU Utilization + {realtimeGPUData.utilization_gpu}% +
+ +
+ )} + {realtimeGPUData.clock_graphics && ( +
+ Graphics Clock + {realtimeGPUData.clock_graphics} +
+ )} + {realtimeGPUData.clock_memory && ( +
+ Memory Clock + {realtimeGPUData.clock_memory} +
+ )} + {realtimeGPUData.power_draw && realtimeGPUData.power_draw !== "N/A" && ( +
+ Power Draw + {realtimeGPUData.power_draw} +
+ )} + {realtimeGPUData.power_limit && ( +
+ Power Limit + {realtimeGPUData.power_limit} +
+ )} +
+ + {/* Engine Utilization (Intel/AMD) */} + {(realtimeGPUData.engine_render !== undefined || + realtimeGPUData.engine_blitter !== undefined || + realtimeGPUData.engine_video !== undefined || + realtimeGPUData.engine_video_enhance !== undefined) && ( +
+

Engine Utilization

+
+ {realtimeGPUData.engine_render !== undefined && ( +
+
+ Render/3D + + {realtimeGPUData.engine_render.toFixed(2)}% + +
+ +
+ )} + {realtimeGPUData.engine_blitter !== undefined && ( +
+
+ Blitter + + {realtimeGPUData.engine_blitter.toFixed(2)}% + +
+ +
+ )} + {realtimeGPUData.engine_video !== undefined && ( +
+
+ Video + + {realtimeGPUData.engine_video.toFixed(2)}% + +
+ +
+ )} + {realtimeGPUData.engine_video_enhance !== undefined && ( +
+
+ VideoEnhance + + {realtimeGPUData.engine_video_enhance.toFixed(2)}% + +
+ +
+ )} +
+
+ )} + + {/* Memory Info */} + {realtimeGPUData.memory_total && ( +
+

Memory

+
+
+ Total + {realtimeGPUData.memory_total} +
+
+ Used + {realtimeGPUData.memory_used} +
+
+ Free + {realtimeGPUData.memory_free} +
+ {realtimeGPUData.utilization_memory !== undefined && ( +
+
+ Memory Utilization + {realtimeGPUData.utilization_memory}% +
+ +
+ )} +
+
+ )} + + {/* Running Processes (NVIDIA) */} + {realtimeGPUData.processes && realtimeGPUData.processes.length > 0 && ( +
+

Running Processes

+
+ {realtimeGPUData.processes.map((proc: any, idx: number) => ( +
+
+ PID: {proc.pid} + {proc.memory} +
+

{proc.name}

+
+ ))} +
+
+ )} +
+ + ) + })() + ) : ( + // Basic modal without real-time data + (() => { + const pciDevice = findPCIDeviceForGPU(selectedGPU) + + return ( + <> + + {selectedGPU.name} + PCI Device Information + + +
- PCI Slot + Device Type + Graphics Card +
+ +
+ PCI Slot {pciDevice?.slot || selectedGPU.slot}
+ +
+ Device Name + {selectedGPU.name} +
+ +
+ Vendor + {selectedGPU.vendor} +
+ + {(pciDevice?.class || selectedGPU.pci_class) && ( +
+ Class + {pciDevice?.class || selectedGPU.pci_class} +
+ )} + {(pciDevice?.driver || selectedGPU.pci_driver) && (
- Driver + Driver {pciDevice?.driver || selectedGPU.pci_driver}
)} + {(pciDevice?.kernel_module || selectedGPU.pci_kernel_module) && (
- Kernel Module + Kernel Module {pciDevice?.kernel_module || selectedGPU.pci_kernel_module}
)} -
-
- {/* Real-Time Metrics */} -
-

Real-Time Metrics

-
- {selectedGPU.temperature !== undefined && selectedGPU.temperature > 0 && ( -
-
- Temperature - {selectedGPU.temperature}°C -
- -
- )} - {selectedGPU.utilization_gpu !== undefined && ( -
-
- GPU Utilization - {selectedGPU.utilization_gpu}% -
- -
- )} - {selectedGPU.clock_graphics && ( -
- Graphics Clock - {selectedGPU.clock_graphics} -
- )} - {selectedGPU.clock_memory && ( -
- Memory Clock - {selectedGPU.clock_memory} -
- )} - {selectedGPU.power_draw && selectedGPU.power_draw !== "N/A" && ( -
- Power Draw - {selectedGPU.power_draw} -
- )} - {selectedGPU.power_limit && ( -
- Power Limit - {selectedGPU.power_limit} -
- )} -
-
- - {/* Engine Utilization (Intel/AMD) */} - {(selectedGPU.engine_render !== undefined || - selectedGPU.engine_blitter !== undefined || - selectedGPU.engine_video !== undefined || - selectedGPU.engine_video_enhance !== undefined) && ( -
-

Engine Utilization

-
- {selectedGPU.engine_render !== undefined && ( -
-
- Render/3D - {selectedGPU.engine_render.toFixed(2)}% -
- -
- )} - {selectedGPU.engine_blitter !== undefined && ( -
-
- Blitter - {selectedGPU.engine_blitter.toFixed(2)}% -
- -
- )} - {selectedGPU.engine_video !== undefined && ( -
-
- Video - {selectedGPU.engine_video.toFixed(2)}% -
- -
- )} - {selectedGPU.engine_video_enhance !== undefined && ( -
-
- VideoEnhance - - {selectedGPU.engine_video_enhance.toFixed(2)}% - -
- -
- )} +
+ Type + {selectedGPU.type}
-
- )} - {/* Memory Info */} - {selectedGPU.memory_total && ( -
-

Memory

-
-
- Total - {selectedGPU.memory_total} -
-
- Used - {selectedGPU.memory_used} -
-
- Free - {selectedGPU.memory_free} -
- {selectedGPU.utilization_memory !== undefined && ( -
-
- Memory Utilization - {selectedGPU.utilization_memory}% + {realtimeGPUData?.has_monitoring_tool === false && ( +
+
+
+ + +
- -
- )} -
-
- )} - - {/* Running Processes (NVIDIA) */} - {selectedGPU.processes && selectedGPU.processes.length > 0 && ( -
-

Running Processes

-
- {selectedGPU.processes.map((proc: any, idx: number) => ( -
-
- PID: {proc.pid} - {proc.memory} +
+

+ Extended Monitoring Not Available +

+

+ {getMonitoringToolRecommendation(selectedGPU.vendor)} +

-

{proc.name}

- ))} -
-
- )} -
- - ) - })()} - -
- - setSelectedGPU(null)}> - - {selectedGPU && - !hasRealtimeData(selectedGPU) && - (() => { - const pciDevice = findPCIDeviceForGPU(selectedGPU) - - return ( - <> - - {selectedGPU.name} - PCI Device Information - - -
-
- Device Type - Graphics Card -
- -
- PCI Slot - {pciDevice?.slot || selectedGPU.slot} -
- -
- Device Name - {selectedGPU.name} -
- -
- Vendor - {selectedGPU.vendor} -
- - {(pciDevice?.class || selectedGPU.pci_class) && ( -
- Class - {pciDevice?.class || selectedGPU.pci_class} -
- )} - - {(pciDevice?.driver || selectedGPU.pci_driver) && ( -
- Driver - - {pciDevice?.driver || selectedGPU.pci_driver} - -
- )} - - {(pciDevice?.kernel_module || selectedGPU.pci_kernel_module) && ( -
- Kernel Module - - {pciDevice?.kernel_module || selectedGPU.pci_kernel_module} - -
- )} - -
- Type - {selectedGPU.type} -
- - {selectedGPU.has_monitoring_tool === false && ( -
-
-
- - -
-
-

- Extended Monitoring Not Available -

-

- {getMonitoringToolRecommendation(selectedGPU.vendor)} -

-
-
+ )}
- )} -
- - ) - })()} + + ) + })() + )} + + )}
diff --git a/AppImage/scripts/flask_server.py b/AppImage/scripts/flask_server.py index e812dfe..483efc2 100644 --- a/AppImage/scripts/flask_server.py +++ b/AppImage/scripts/flask_server.py @@ -1567,8 +1567,6 @@ def identify_fan(fan_name, adapter): return "CPU Fan" if "fan2" in fan_lower and "isa" in adapter_lower: return "Chassis Fan" - if "fan3" in fan_lower and "isa" in adapter_lower: - return "Chassis Fan" if "sys" in fan_lower or "chassis" in fan_lower: return "Chassis Fan" @@ -1587,14 +1585,22 @@ def get_detailed_gpu_info(gpu): detailed_info['has_monitoring_tool'] = False print(f"[v0] intel_gpu_top not found for Intel GPU") return detailed_info + else: + print(f"[v0] intel_gpu_top found for Intel GPU") - import os - if not os.path.exists('/dev/dri/card0'): + gpu_device = '/dev/dri/card0' + if not os.path.exists(gpu_device): + print(f"[v0] GPU device {gpu_device} not found - marking tool as unavailable") detailed_info['has_monitoring_tool'] = False - print(f"[v0] /dev/dri/card0 not accessible - intel_gpu_top cannot run") return detailed_info - print(f"[v0] intel_gpu_top found and /dev/dri/card0 accessible") + if not os.access(gpu_device, os.R_OK): + print(f"[v0] GPU device {gpu_device} not accessible - marking tool as unavailable") + detailed_info['has_monitoring_tool'] = False + return detailed_info + + print(f"[v0] GPU device {gpu_device} is accessible") + except Exception as e: print(f"[v0] Error checking for intel_gpu_top: {e}") detailed_info['has_monitoring_tool'] = False @@ -1606,14 +1612,13 @@ def get_detailed_gpu_info(gpu): ['intel_gpu_top', '-J', '-s', '500', '-o', '-'], capture_output=True, text=True, - timeout=1.5 # Reduced from 2 seconds + timeout=1.5 ) output = result.stdout.strip() if output and result.returncode == 0: print(f"[v0] intel_gpu_top output received ({len(output)} chars)") - print(f"[v0] First 500 chars: {output[:500]}") # Try to parse as JSON try: @@ -1632,7 +1637,6 @@ def get_detailed_gpu_info(gpu): if json_end > 0: json_str = output[:json_end] json_data = json.loads(json_str) - print(f"[v0] Parsed JSON successfully with keys: {list(json_data.keys())}") # Parse frequency data if 'frequency' in json_data: @@ -1681,32 +1685,28 @@ def get_detailed_gpu_info(gpu): detailed_info[key] = float(busy_value) data_retrieved = True - print(f"[v0] Intel GPU data retrieved successfully") + print(f"[v0] Intel GPU data retrieved successfully via JSON") except (json.JSONDecodeError, ValueError) as e: - print(f"[v0] JSON parsing failed: {e}") + print(f"[v0] JSON parsing failed, trying text parsing: {e}") # Fallback to text parsing - # Parse frequency: "0/ 0 MHz" freq_match = re.search(r'(\d+)/\s*(\d+)\s*MHz', output) if freq_match: detailed_info['clock_graphics'] = f"{freq_match.group(1)} MHz" detailed_info['clock_max'] = f"{freq_match.group(2)} MHz" data_retrieved = True - # Parse power: "0.00/ 7.23 W" power_match = re.search(r'([\d.]+)/\s*([\d.]+)\s*W', output) if power_match: detailed_info['power_draw'] = f"{power_match.group(1)} W" detailed_info['power_limit'] = f"{power_match.group(2)} W" data_retrieved = True - # Parse RC6 (power saving state): "100% RC6" rc6_match = re.search(r'(\d+)%\s*RC6', output) if rc6_match: detailed_info['power_state'] = f"RC6: {rc6_match.group(1)}%" data_retrieved = True - # Parse engine utilization engines = { 'Render/3D': 'engine_render', 'Blitter': 'engine_blitter', @@ -1720,13 +1720,15 @@ def get_detailed_gpu_info(gpu): detailed_info[key] = float(match.group(1)) data_retrieved = True - # Parse IRQ rate irq_match = re.search(r'(\d+)\s*irqs/s', output) if irq_match: detailed_info['irq_rate'] = int(irq_match.group(1)) data_retrieved = True + + if data_retrieved: + print(f"[v0] Intel GPU data retrieved successfully via text parsing") else: - print(f"[v0] No output received from intel_gpu_top (return code: {result.returncode})") + print(f"[v0] No output from intel_gpu_top (return code: {result.returncode})") if data_retrieved: detailed_info['has_monitoring_tool'] = True @@ -1740,8 +1742,6 @@ def get_detailed_gpu_info(gpu): detailed_info['has_monitoring_tool'] = False except Exception as e: print(f"[v0] Error getting Intel GPU details: {e}") - import traceback - traceback.print_exc() detailed_info['has_monitoring_tool'] = False elif vendor == 'NVIDIA': @@ -2676,7 +2676,7 @@ def api_hardware(): 'cpu': hardware_info.get('cpu', {}), 'motherboard': hardware_info.get('motherboard', {}), 'memory_modules': hardware_info.get('memory_modules', []), - 'storage_devices': hardware_data.get('storage_devices', []), # Corrected variable name + 'storage_devices': hardware_info.get('storage_devices', []), 'pci_devices': hardware_info.get('pci_devices', []), 'temperatures': hardware_info.get('sensors', {}).get('temperatures', []), 'fans': hardware_info.get('sensors', {}).get('fans', []), # Use sensors fans @@ -2871,3 +2871,4 @@ if __name__ == '__main__': print("API endpoints available at: /api/system, /api/storage, /api/network, /api/vms, /api/logs, /api/health, /api/hardware") app.run(host='0.0.0.0', port=8008, debug=False) + port=8008, debug=False)