joularcore 0.1.0

Joular Core is a platform to measure power and energy across all systems, OSes and devices
Documentation
/*
 * Copyright (c) 2025-2026, Adel Noureddine.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the
 * GNU Lesser General Public License v3.0 only (LGPL-3.0-only)
 * which accompanies this distribution, and is available at
 * https://www.gnu.org/licenses/lgpl-3.0.en.html
 *
 * Author : Adel Noureddine
 */

#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
use std::process::Command;
use std::str;
use std::sync::OnceLock;

#[cfg(target_os = "windows")]
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
static NVIDIA_SUPPORTED: OnceLock<bool> = OnceLock::new();

fn nvidia_smi_output() -> std::io::Result<std::process::Output> {
    let mut cmd = Command::new("nvidia-smi");
    cmd.args(["--format=csv,noheader,nounits", "--query-gpu=power.draw"]);

    #[cfg(target_os = "windows")]
    {
        // Prevent transient console windows when running from the GUI binary.
        cmd.creation_flags(CREATE_NO_WINDOW);
    }

    cmd.output()
}

/// Returns the total power drawn by NVIDIA GPUs (same as before)
pub fn get_nvidia_power() -> f64 {
    let output = nvidia_smi_output();

    match output {
        Ok(output) => {
            let response = match str::from_utf8(&output.stdout) {
                Ok(s) => s.trim(),
                Err(e) => {
                    crate::logging::print_warning(&format!(
                        "Failed to read NVIDIA SMI output: {}",
                        e
                    ));
                    return 0.0;
                }
            };

            if response == "[N/A]" {
                0.0
            } else {
                response
                    .lines()
                    .filter_map(|line| line.trim().parse::<f64>().ok())
                    .sum()
            }
        }
        Err(e) => {
            crate::logging::print_warning(&format!("Failed to execute NVIDIA SMI command: {}", e));
            0.0
        }
    }
}

/// Checks if NVIDIA GPUs are supported on this system
pub fn is_nvidia_supported() -> bool {
    *NVIDIA_SUPPORTED.get_or_init(|| match nvidia_smi_output() {
        Ok(output) => {
            if !output.status.success() {
                return false;
            }
            if let Ok(s) = str::from_utf8(&output.stdout) {
                let trimmed = s.trim();
                !trimmed.is_empty() && trimmed != "[N/A]"
            } else {
                false
            }
        }
        Err(_) => false,
    })
}