Files
Analog_System_Monitor/analog_system_monitor_dotnet/Telemetry.cs

223 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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();
// Prepare 8 floats (futureproof)
float[] packet =
{
cpu,
cpuTemp,
mem,
gpu3d,
gpuTemp,
vram,
0f, // reserved for future use
0f // reserved for future use
};
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();
}
}