Support for reading fan speeds from NZXT Smart Device v2

Hi everyone,
NZXT's H510i and H510 Elite cases include an Fan & RGB controller, which is named "Smart Device 2" in NZXT CAM.
The device doesn't show up in HWiNFO, even if HWiNFO is started before NZXT CAM.

It features 3x FAN connectors, each connector is individually controllable in NZXT CAM. I don't want to control the fans via HWiNFO (I know it's not in scope), but I would like to monitor their speed RPM.

1669650763710.png

I've made a search changelog/version history but I haven't found support for this device. Would it be possible to support this?
Thank you & best regards

P.s. the device has been "Designed in Los Angles, California" :D
 
Is NZXT CAM also able to monitor those fan speeds, not just the setting? That would require some dedicated connection to mainboard or USB which I don't think is available.
 
Yes, NZXT CAM is able to monitor fan speeds, and I see those values slightly changing every second.
Indeed, the NZXT Smart Device v2 has a connection to the mainboard, via a dedicated cable with a 9-pin USB header.

1669900932570.png
 
I'm sorry but we don't have information about protocol used by this device so currently it can't be supported.
 
@Martin I would vote for this feature request, Martin, as a yearly subscriber.

Please include the fan speeds of the NZXT fan controllers as you already are detecting the NZXT AIO coolers.

I asked the AI for a sample Rust code on how to read these values, it came up with this:

Code:
use rusb::{Context, Device, DeviceDescriptor, UsbContext};
use std::time::Duration;

fn main() {
    let context = Context::new().unwrap();
    let devices = context.devices().unwrap();

    for device in devices.iter() {
        let desc = device.device_descriptor().unwrap();

        // Check for NZXT vendor ID
        if desc.vendor_id() == 0x1e71 {
            let product_name = match desc.product_id() {
                0x170e => "Smart Device v1",
                0x2007 => "Smart Device v2 / RGB & Fan Controller",
                0x3006 => "Kraken X3 Series",
                0x3008 => "Kraken Z-Series",
                _ => "Unknown NZXT Device",
            };

            if let Some(info) = get_device_info(&device, &desc) {
                println!("Detected: {} -> {}", product_name, info);
            }
        }
    }
}

fn get_device_info<T: UsbContext>(
    device: &Device<T>,
    descriptor: &DeviceDescriptor,
) -> Option<String> {
    let handle = device.open().ok()?;
    let lang = handle.read_languages(Duration::from_secs(1)).ok()?.get(0).cloned()?;
    let manufacturer = handle.read_manufacturer_string(lang, descriptor, Duration::from_secs(1)).ok();
    let product = handle.read_product_string(lang, descriptor, Duration::from_secs(1)).ok();

    Some(format!(
        "{} {} (VID: {:04x}, PID: {:04x})",
        manufacturer.unwrap_or("Unknown".to_string()),
        product.unwrap_or("Unknown".to_string()),
        descriptor.vendor_id(),
        descriptor.product_id()
    ))
}

Unfortunately I am not a systems programmer and cannot help more than point you to out to more projects doing this:

https://github.com/liquidctl/liquidctl (python)
https://github.com/LibreHardwareMonitor/LibreHardwareMonitor (C#) with sample code :
 
Back
Top