Files
chromebox-fan-control-win/ChromeboxFanControl/FanCurve.cs
2026-03-21 05:47:58 +08:00

42 lines
1.5 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.
namespace ChromeboxFanControl;
/// <summary>
/// Fan curve: 14 control points at 0 °C and 40100 °C every 5 °C, linear interpolation.
/// </summary>
public static class FanCurve
{
private const int PointCount = 14;
/// <summary>Temperature breakpoints (°C): 0, 40, 45, 50, …, 100.</summary>
public static readonly int[] TempBreakpoints = [0, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
/// <param name="tempC">CPU temperature in °C.</param>
/// <param name="curve">Exactly 14 values 0100 (fan duty).</param>
public static byte CalculateFanPercent(double tempC, ReadOnlySpan<int> curve)
{
if (curve.Length != PointCount)
throw new ArgumentException($"Curve must contain exactly {PointCount} points.", nameof(curve));
var t = Math.Clamp(tempC, 0, 100);
if (t <= TempBreakpoints[0])
return (byte)Math.Clamp(curve[0], 0, 100);
if (t >= TempBreakpoints[PointCount - 1])
return (byte)Math.Clamp(curve[PointCount - 1], 0, 100);
for (var i = 0; i < PointCount - 1; i++)
{
var t0 = TempBreakpoints[i];
var t1 = TempBreakpoints[i + 1];
if (t >= t0 && t <= t1)
{
var d0 = Math.Clamp(curve[i], 0, 100);
var d1 = Math.Clamp(curve[i + 1], 0, 100);
var frac = (t - t0) / (t1 - t0);
return (byte)Math.Round(d0 + (d1 - d0) * frac);
}
}
return (byte)Math.Clamp(curve[PointCount - 1], 0, 100);
}
}