diff --git a/src-tauri/src/commands/hardware.rs b/src-tauri/src/commands/hardware.rs index c3e8604..2f4cc2c 100644 --- a/src-tauri/src/commands/hardware.rs +++ b/src-tauri/src/commands/hardware.rs @@ -48,23 +48,27 @@ pub fn get_cpu_usage(state: tauri::State<'_, AppState>) -> i32 { pub struct SysInfo { pub cpu: system_info_service::CpuInfo, pub memory: system_info_service::MemoryInfo, - //pub gpu: GpuInfo, + pub gpus: Vec, } /// /// ## システム情報を取得 /// #[command] -pub fn get_hardware_info(state: tauri::State<'_, AppState>) -> Result { +pub async fn get_hardware_info( + state: tauri::State<'_, AppState>, +) -> Result { let cpu = system_info_service::get_cpu_info(state.system.lock().unwrap()); let memory = system_info_service::get_memory_info(); + let gpus = graphic_service::get_nvidia_gpu_info().await; - match (cpu, memory) { - (Ok(cpu_info), Ok(memory_info)) => Ok(SysInfo { + match (cpu, memory, gpus) { + (Ok(cpu_info), Ok(memory_info), Ok(gpu_info)) => Ok(SysInfo { cpu: cpu_info, memory: memory_info, + gpus: gpu_info, }), - (Err(e), _) | (_, Err(e)) => { + (Err(e), _, _) | (_, Err(e), _) | (_, _, Err(e)) => { log_error!( "get_sys_info_failed", "get_hardware_info", diff --git a/src-tauri/src/services/graphic_service.rs b/src-tauri/src/services/graphic_service.rs index a33ab86..91f2d0e 100644 --- a/src-tauri/src/services/graphic_service.rs +++ b/src-tauri/src/services/graphic_service.rs @@ -1,6 +1,8 @@ +use crate::utils::{self, unit}; use crate::{log_debug, log_error, log_info, log_internal, log_warn}; use nvapi; use nvapi::UtilizationDomain; +use serde::Serialize; use tokio::task::spawn_blocking; use tokio::task::JoinError; @@ -69,3 +71,101 @@ pub async fn get_nvidia_gpu_usage() -> Result { nvapi::Status::Error })? } + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct GraphicInfo { + name: String, + vendor_name: String, + clock: u64, + memory_size: String, + memory_size_dedicated: String, +} + +/// +/// GPU情報を取得する +/// +/// - [TODO] AMD GPU の情報も取得する +/// +pub async fn get_nvidia_gpu_info() -> Result, String> { + let handle = spawn_blocking(|| { + log_debug!("start", "get_nvidia_gpu_info", None::<&str>); + + let gpus = match nvapi::PhysicalGpu::enumerate() { + Ok(gpus) => gpus, + Err(e) => { + log_error!( + "enumerate_failed", + "get_nvidia_gpu_info", + Some(e.to_string()) + ); + return Err(e.to_string()); + } + }; + + if gpus.is_empty() { + log_warn!("not found", "get_nvidia_gpu_info", Some("gpu is not found")); + tracing::warn!("gpu is not found"); + } + + let mut gpu_info_list = Vec::new(); + + for gpu in gpus.iter() { + let name = gpu.full_name().unwrap_or("Unknown".to_string()); + + // クロック周波数 (MHz) の取得 + let clock_frequencies = + match gpu.clock_frequencies(nvapi::ClockFrequencyType::Current) { + Ok(freqs) => freqs, + Err(e) => { + log_error!("clock_failed", "get_nvidia_gpu_info", Some(e.to_string())); + continue; + } + }; + + let frequency = match clock_frequencies.get(&nvapi::ClockDomain::Graphics) { + Some(&nvapi::Kilohertz(freq)) => freq as u64, + None => { + log_warn!( + "clock_not_found", + "get_nvidia_gpu_info", + Some("Graphics clock not found") + ); + 0 // デフォルト値として 0 を設定 + } + }; + + // メモリサイズ (MB) の取得 + let memory_info = match gpu.memory_info() { + Ok(info) => info, + Err(e) => { + log_error!( + "memory_info_failed", + "get_nvidia_gpu_info", + Some(e.to_string()) + ); + continue; + } + }; + + let gpu_info = GraphicInfo { + name, + vendor_name: "NVIDIA".to_string(), + clock: frequency, + memory_size: memory_info.shared.to_string(), + memory_size_dedicated: memory_info.dedicated.to_string(), + }; + + gpu_info_list.push(gpu_info); + } + + log_debug!("end", "get_nvidia_gpu_info", None::<&str>); + + Ok(gpu_info_list) + }); + + handle.await.map_err(|e: JoinError| { + log_error!("join_error", "get_nvidia_gpu_info", Some(e.to_string())); + nvapi::Status::Error.to_string() + })? +} diff --git a/src/App.tsx b/src/App.tsx index cd0c942..924ab4c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,7 +20,8 @@ const Page = () => { useSettingsModalListener(); useErrorModalListener(); - useHardwareInfoAtom(); + const { hardwareInfo } = useHardwareInfoAtom(); + console.log(hardwareInfo); const handleShowData = () => { setButtonState(buttonState === "raw" ? "chart" : "raw"); diff --git a/src/atom/useHardwareInfoAtom.ts b/src/atom/useHardwareInfoAtom.ts index 637552f..809b221 100644 --- a/src/atom/useHardwareInfoAtom.ts +++ b/src/atom/useHardwareInfoAtom.ts @@ -6,7 +6,7 @@ import { useEffect } from "react"; const hardInfoAtom = atom(); export const useHardwareInfoAtom = () => { - const [hardware, setHardInfo] = useAtom(hardInfoAtom); + const [hardwareInfo, setHardInfo] = useAtom(hardInfoAtom); useEffect(() => { const init = async () => { @@ -19,12 +19,10 @@ export const useHardwareInfoAtom = () => { }; // データがなければ取得して更新 - if (!hardware) { + if (!hardwareInfo) { init(); } + }, [setHardInfo, hardwareInfo]); - console.log(hardware); - }, [setHardInfo, hardware]); - - return { hardware }; + return { hardwareInfo }; }; diff --git a/src/types/hardwareDataType.ts b/src/types/hardwareDataType.ts index 796b970..79646c0 100644 --- a/src/types/hardwareDataType.ts +++ b/src/types/hardwareDataType.ts @@ -6,7 +6,6 @@ export type CpuInfo = { clockUnit: string; vendor: string; coreCount: number; - frequency: number; cpuName: string; }; @@ -18,7 +17,16 @@ export type MemoryInfo = { memoryType: string; }; +export type GraphicInfo = { + clock: number; + name: string; + vendorName: string; + memorySize: string; + memorySizeDedicated: string; +}; + export type HardwareInfo = { cpu: CpuInfo; memory: MemoryInfo; + gpus: GraphicInfo[]; };