using System; using System.Collections.Generic; using LibreHardwareMonitor.Hardware; namespace PCPalConfigurator.Core { /// /// Manages hardware sensors and provides access to sensor data /// public class SensorManager : IDisposable { private readonly Computer computer; private readonly Dictionary sensorValues = new Dictionary(); private bool isDisposed = false; public SensorManager() { computer = new Computer { IsCpuEnabled = true, IsGpuEnabled = true, IsMemoryEnabled = true, IsMotherboardEnabled = true, IsControllerEnabled = true, IsStorageEnabled = true }; computer.Open(); } /// /// Updates all sensor values from hardware /// public void UpdateSensorValues() { foreach (var hardware in computer.Hardware) { hardware.Update(); foreach (var sensor in hardware.Sensors) { if (sensor.Value.HasValue) { string sensorId = GetSensorVariableName(hardware.Name, sensor.Name); sensorValues[sensorId] = sensor.Value.Value; } } } } /// /// Gets a dictionary of all current sensor values /// public Dictionary GetAllSensorValues() { return new Dictionary(sensorValues); } /// /// Gets the value of a specific sensor /// public float? GetSensorValue(string sensorId) { if (sensorValues.TryGetValue(sensorId, out float value)) { return value; } return null; } /// /// Finds the first available sensor of a specific type /// public string FindFirstSensorOfType(HardwareType hardwareType, SensorType sensorType) { foreach (var hardware in computer.Hardware) { if (hardware.HardwareType == hardwareType) { foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == sensorType && sensor.Value.HasValue) { return GetSensorVariableName(hardware.Name, sensor.Name); } } } } return string.Empty; } /// /// Creates a variable name for a sensor that's safe to use in markup /// public static string GetSensorVariableName(string hardwareName, string sensorName) { string name = $"{hardwareName}_{sensorName}" .Replace(" ", "_") .Replace("%", "Percent") .Replace("#", "Num") .Replace("/", "_") .Replace("\\", "_") .Replace("(", "") .Replace(")", "") .Replace(",", ""); return name; } /// /// Gets the appropriate unit for a sensor type /// public static string GetSensorUnit(SensorType sensorType) { return sensorType switch { SensorType.Temperature => "°C", SensorType.Load => "%", SensorType.Clock => "MHz", SensorType.Power => "W", SensorType.Fan => "RPM", SensorType.Flow => "L/h", SensorType.Control => "%", SensorType.Level => "%", _ => "" }; } /// /// Formats a sensor value according to its type /// public static string FormatSensorValue(float value, SensorType sensorType) { return sensorType switch { SensorType.Temperature => value.ToString("F1"), SensorType.Clock => value.ToString("F0"), SensorType.Load => value.ToString("F1"), SensorType.Fan => value.ToString("F0"), SensorType.Power => value.ToString("F1"), SensorType.Data => (value > 1024) ? (value / 1024).ToString("F1") : value.ToString("F1"), _ => value.ToString("F1") }; } /// /// Gets all hardware sensors grouped by type /// public Dictionary> GetAllSensorsGroupedByType() { var result = new Dictionary>(); foreach (var hardware in computer.Hardware) { hardware.Update(); foreach (var sensor in hardware.Sensors) { if (sensor.Value.HasValue) { var sensorType = sensor.SensorType; if (!result.ContainsKey(sensorType)) { result[sensorType] = new List(); } string sensorId = GetSensorVariableName(hardware.Name, sensor.Name); result[sensorType].Add(new SensorInfo { Id = sensorId, Name = $"{hardware.Name} {sensor.Name}", Value = sensor.Value.Value, SensorType = sensorType }); } } } return result; } /// /// Gets all hardware for populating dropdown lists /// public List GetSensorOptionsForDropdown() { var options = new List(); foreach (var hardware in computer.Hardware) { hardware.Update(); foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Load || sensor.SensorType == SensorType.Temperature || sensor.SensorType == SensorType.Data || sensor.SensorType == SensorType.Fan) { string option = $"{hardware.HardwareType}: {sensor.Name} ({sensor.SensorType})"; options.Add(option); } } } options.Add("Custom Text"); return options; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!isDisposed) { if (disposing) { computer.Close(); } isDisposed = true; } } } /// /// Represents information about a sensor /// public class SensorInfo { public string Id { get; set; } public string Name { get; set; } public float Value { get; set; } public SensorType SensorType { get; set; } } }