using LibreHardwareMonitor.Hardware; namespace ChromeboxFanControl; public enum CpuTempAggregation { AverageCore, MaxCore } /// /// CPU temperature via LibreHardwareMonitor only (no fan sensors). /// public sealed class CpuTempReader : IDisposable { private readonly Computer _computer = new() { IsCpuEnabled = true, IsMotherboardEnabled = true }; private bool _open; public CpuTempReader() { _computer.Open(); _open = true; } public void Dispose() { if (!_open) return; _computer.Close(); _open = false; } /// Returns null if no reading available. public double? ReadCpuTemp(CpuTempAggregation mode) { foreach (var hw in _computer.Hardware) { hw.Update(); foreach (var sh in hw.SubHardware) sh.Update(); } var coreTemps = new List(); foreach (var hw in _computer.Hardware) { CollectCoreTemps(hw, coreTemps); foreach (var sh in hw.SubHardware) CollectCoreTemps(sh, coreTemps); } if (coreTemps.Count > 0) { return mode == CpuTempAggregation.MaxCore ? coreTemps.Max() : coreTemps.Average(); } // Fallback: any CPU temperature sensor var any = new List(); foreach (var hw in _computer.Hardware) { CollectAnyCpuTemp(hw, any); foreach (var sh in hw.SubHardware) CollectAnyCpuTemp(sh, any); } if (any.Count == 0) return null; return mode == CpuTempAggregation.MaxCore ? any.Max() : any.Average(); } private static readonly string[] CoreTempPatterns = [ "Core", "Package", "Tctl", "Tdie", "CCD", "CPU Package", "Core Average", "Core Max", "Core #" ]; private static void CollectCoreTemps(IHardware hw, List list) { foreach (var s in hw.Sensors) { if (s.SensorType != SensorType.Temperature || !s.Value.HasValue) continue; var name = s.Name; if (CoreTempPatterns.Any(p => name.Contains(p, StringComparison.OrdinalIgnoreCase))) list.Add(s.Value.Value); } } private static void CollectAnyCpuTemp(IHardware hw, List list) { foreach (var s in hw.Sensors) { if (s.SensorType == SensorType.Temperature && s.Value.HasValue) list.Add(s.Value.Value); } } }