Files
Analog_System_Monitor/analog_system_monitor_dotnet/Telemetry.cs

222 lines
5.7 KiB
C#

#nullable enable
using System;
using System.Globalization;
using LibreHardwareMonitor.Hardware;
public class Telemetry : IDisposable
{
private const int UpdateRateDefaultMs = 1000;
public int UpdateRateMs => UpdateRateDefaultMs;
private readonly UdpSender udp = new UdpSender();
private readonly Computer computer = new Computer();
private IHardware? cpuHw;
private IHardware? gpuHw;
private IHardware? memHw;
private ISensor[] cpuLoadSensors = Array.Empty<ISensor>();
private ISensor? cpuTempSensor;
private ISensor? gpu3DLoadSensor;
private ISensor? gpuTempSensor;
private ISensor? gpuVramUsedSensor;
private ISensor? gpuVramTotalSensor;
private ISensor? memUsedSensor;
private ISensor? memAvailSensor;
private static readonly CultureInfo CI = CultureInfo.InvariantCulture;
public void Initialize()
{
computer.IsCpuEnabled = true;
computer.IsGpuEnabled = true;
computer.IsMemoryEnabled = true;
computer.Open();
CacheHardwareAndSensors();
}
private void CacheHardwareAndSensors()
{
foreach (var hw in computer.Hardware)
{
hw.Update();
switch (hw.HardwareType)
{
case HardwareType.Cpu:
cpuHw = hw;
CacheCpuSensors(hw);
break;
case HardwareType.GpuNvidia:
case HardwareType.GpuAmd:
case HardwareType.GpuIntel:
gpuHw = hw;
CacheGpuSensors(hw);
break;
case HardwareType.Memory:
memHw = hw;
CacheMemorySensors(hw);
break;
}
}
}
private void CacheCpuSensors(IHardware hw)
{
var loads = new System.Collections.Generic.List<ISensor>();
foreach (var s in hw.Sensors)
{
if (s.SensorType == SensorType.Load &&
s.Name.Contains("CPU Core"))
loads.Add(s);
if (s.SensorType == SensorType.Temperature)
{
if (s.Name == "Core (Tctl/Tdie)")
cpuTempSensor = s;
else if (cpuTempSensor == null)
cpuTempSensor = s;
}
}
cpuLoadSensors = loads.ToArray();
}
private void CacheGpuSensors(IHardware hw)
{
foreach (var s in hw.Sensors)
{
if (s.SensorType == SensorType.Load)
{
if (s.Name == "D3D 3D")
gpu3DLoadSensor = s;
else if (gpu3DLoadSensor == null && s.Name == "GPU Core")
gpu3DLoadSensor = s;
}
if (s.SensorType == SensorType.Temperature)
{
if (s.Name == "GPU Core")
gpuTempSensor = s;
else if (gpuTempSensor == null)
gpuTempSensor = s;
}
if (s.SensorType == SensorType.SmallData)
{
if (s.Name == "GPU Memory Used")
gpuVramUsedSensor = s;
if (s.Name == "GPU Memory Total")
gpuVramTotalSensor = s;
}
}
}
private void CacheMemorySensors(IHardware hw)
{
foreach (var s in hw.Sensors)
{
if (s.SensorType == SensorType.Data && s.Name == "Memory Used")
memUsedSensor = s;
if (s.SensorType == SensorType.Data && s.Name == "Memory Available")
memAvailSensor = s;
}
}
public void UpdateAndSend()
{
cpuHw?.Update();
gpuHw?.Update();
memHw?.Update();
float cpu = GetCpuLoadPercent();
float cpuTemp = GetCpuTemperaturePercent();
float mem = GetMemoryUsagePercent();
float gpu3d = GetGpu3DLoad();
float gpuTemp = GetGpuTemperaturePercent();
float vram = GetGpuVramPercent();
float[] packet =
{
cpu,
cpuTemp,
mem,
gpu3d,
gpuTemp,
vram,
0f,
0f
};
udp.SendFloats(packet);
}
private float GetCpuLoadPercent()
{
if (cpuLoadSensors.Length == 0) return 0;
float total = 0;
int count = 0;
foreach (var s in cpuLoadSensors)
{
total += s.Value ?? 0;
count++;
}
return count == 0 ? 0 : total / count;
}
private float GetCpuTemperaturePercent()
{
float t = cpuTempSensor?.Value ?? 0;
return Math.Clamp(t, 0, 100);
}
private float GetGpu3DLoad()
{
return gpu3DLoadSensor?.Value ?? 0;
}
private float GetGpuTemperaturePercent()
{
float t = gpuTempSensor?.Value ?? 0;
return Math.Clamp(t, 0, 100);
}
private float GetGpuVramPercent()
{
float used = gpuVramUsedSensor?.Value ?? 0;
float total = gpuVramTotalSensor?.Value ?? 0;
if (total <= 0) return 0;
return (used / total) * 100f;
}
private float GetMemoryUsagePercent()
{
float used = memUsedSensor?.Value ?? 0;
float avail = memAvailSensor?.Value ?? 0;
float total = used + avail;
if (total <= 0) return 0;
return (used / total) * 100f;
}
public void Dispose()
{
udp.Dispose();
computer.Close();
}
}