Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions AsusFanControl/AsusControl.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using AsusSystemAnalysis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace AsusFanControl
{
Expand Down Expand Up @@ -32,13 +30,15 @@ public void SetFanSpeed(int percent, byte fanIndex = 0)
SetFanSpeed(value, fanIndex);
}

public async void SetFanSpeeds(byte value)
public void SetFanSpeeds(byte value)
{
var fanCount = AsusWinIO64.HealthyTable_FanCounts();
for(byte fanIndex = 0; fanIndex < fanCount; fanIndex++)
for (byte fanIndex = 0; fanIndex < fanCount; fanIndex++)
{
SetFanSpeed(value, fanIndex);
await Task.Delay(20);

if (fanIndex + 1 < fanCount)
Thread.Sleep(20);
}
Comment on lines +33 to 42
}

Expand Down
5 changes: 5 additions & 0 deletions AsusFanControl/AsusFanControl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net472" Version="1.0.3">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
4 changes: 2 additions & 2 deletions AsusFanControl/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.2.0.0")]
[assembly: AssemblyFileVersion("1.2.0.0")]
9 changes: 9 additions & 0 deletions AsusFanControlGUI/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<setting name="fanSpeed" serializeAs="String">
<value>90</value>
</setting>
<setting name="fanControlEnabled" serializeAs="String">
<value>False</value>
</setting>
<setting name="turnOffControlOnExit" serializeAs="String">
<value>True</value>
</setting>
Expand All @@ -25,6 +28,12 @@
<setting name="autoRefreshStats" serializeAs="String">
<value>False</value>
</setting>
<setting name="temperatureCurveEnabled" serializeAs="String">
<value>False</value>
</setting>
<setting name="temperatureCurve" serializeAs="String">
<value>45:40;60:55;70:70;80:85;90:99</value>
</setting>
</AsusFanControlGUI.Properties.Settings>
</userSettings>
</configuration>
12 changes: 12 additions & 0 deletions AsusFanControlGUI/AsusFanControlGUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="FanCurve.cs" />
<Compile Include="FanCurveGraphControl.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
Expand All @@ -77,6 +79,7 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StartupRegistration.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
<SubType>Designer</SubType>
Expand All @@ -102,6 +105,10 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<Content Include="..\run.bat">
<Link>run.bat</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AsusFanControl\AsusFanControl.csproj">
Expand All @@ -112,5 +119,10 @@
<ItemGroup>
<Content Include="propeller.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net472" Version="1.0.3">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
167 changes: 167 additions & 0 deletions AsusFanControlGUI/FanCurve.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace AsusFanControlGUI
{
internal sealed class FanCurve
{
public static FanCurve Default => new FanCurve(new[]
{
new FanCurvePoint(45, 40),
new FanCurvePoint(60, 55),
new FanCurvePoint(70, 70),
new FanCurvePoint(80, 85),
new FanCurvePoint(90, 99),
});

public FanCurve(IEnumerable<FanCurvePoint> points)
{
if (points == null)
throw new ArgumentNullException(nameof(points));

var orderedPoints = points.OrderBy(point => point.Temperature).ToList();
if (orderedPoints.Count < 2)
throw new ArgumentException("A fan curve needs at least two points.", nameof(points));

for (var index = 0; index < orderedPoints.Count; index++)
{
var point = orderedPoints[index];
if (point.Temperature < 0 || point.Temperature > 120)
throw new ArgumentOutOfRangeException(nameof(points), "Curve temperatures must be between 0 and 120 C.");

if (point.FanSpeed < 0 || point.FanSpeed > 100)
throw new ArgumentOutOfRangeException(nameof(points), "Curve fan speeds must be between 0 and 100 percent.");

if (index > 0 && point.Temperature <= orderedPoints[index - 1].Temperature)
throw new ArgumentException("Curve temperatures must be strictly increasing.", nameof(points));
}

Points = orderedPoints;
}

public IReadOnlyList<FanCurvePoint> Points { get; }

public int GetFanSpeed(int temperature)
{
if (temperature <= Points[0].Temperature)
return Points[0].FanSpeed;

for (var index = 1; index < Points.Count; index++)
{
var lowerPoint = Points[index - 1];
var upperPoint = Points[index];
if (temperature <= upperPoint.Temperature)
{
var temperatureDelta = upperPoint.Temperature - lowerPoint.Temperature;
if (temperatureDelta <= 0)
return upperPoint.FanSpeed;

var progress = (temperature - lowerPoint.Temperature) / (double)temperatureDelta;
var interpolatedSpeed = lowerPoint.FanSpeed + ((upperPoint.FanSpeed - lowerPoint.FanSpeed) * progress);
return (int)Math.Round(interpolatedSpeed, MidpointRounding.AwayFromZero);
}
}

return Points[Points.Count - 1].FanSpeed;
}

public int GetFanSpeed(int temperature, int minimumTemperature, int maximumTemperature, int minimumFanSpeed, int maximumFanSpeed)
{
var normalizedMinimumTemperature = Math.Max(0, minimumTemperature);
var normalizedMaximumTemperature = Math.Max(normalizedMinimumTemperature, maximumTemperature);
var normalizedMinimumFanSpeed = Math.Max(0, Math.Min(100, minimumFanSpeed));
var normalizedMaximumFanSpeed = Math.Max(normalizedMinimumFanSpeed, Math.Min(100, maximumFanSpeed));

var curvePoints = new List<FanCurvePoint>
{
new FanCurvePoint(normalizedMinimumTemperature, normalizedMinimumFanSpeed)
};
curvePoints.AddRange(Points);
curvePoints.Add(new FanCurvePoint(normalizedMaximumTemperature, normalizedMaximumFanSpeed));

if (temperature <= curvePoints[0].Temperature)
return curvePoints[0].FanSpeed;

for (var index = 1; index < curvePoints.Count; index++)
{
var lowerPoint = curvePoints[index - 1];
var upperPoint = curvePoints[index];
if (temperature <= upperPoint.Temperature)
{
var temperatureDelta = upperPoint.Temperature - lowerPoint.Temperature;
if (temperatureDelta <= 0)
return upperPoint.FanSpeed;

var progress = (temperature - lowerPoint.Temperature) / (double)temperatureDelta;
var interpolatedSpeed = lowerPoint.FanSpeed + ((upperPoint.FanSpeed - lowerPoint.FanSpeed) * progress);
return (int)Math.Round(interpolatedSpeed, MidpointRounding.AwayFromZero);
}
}

return curvePoints[curvePoints.Count - 1].FanSpeed;
}

public string Serialize()
{
return string.Join(";", Points.Select(point =>
string.Format(CultureInfo.InvariantCulture, "{0}:{1}", point.Temperature, point.FanSpeed)));
}

public static FanCurve ParseOrDefault(string serializedCurve)
{
if (TryParse(serializedCurve, out var fanCurve))
return fanCurve;

return Default;
}

public static bool TryParse(string serializedCurve, out FanCurve fanCurve)
{
fanCurve = null;

if (string.IsNullOrWhiteSpace(serializedCurve))
return false;

var points = new List<FanCurvePoint>();
foreach (var rawPoint in serializedCurve.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
var segments = rawPoint.Split(':');
if (segments.Length != 2)
return false;

if (!int.TryParse(segments[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var temperature))
return false;

if (!int.TryParse(segments[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var fanSpeed))
return false;

points.Add(new FanCurvePoint(temperature, fanSpeed));
}

try
{
fanCurve = new FanCurve(points);
return true;
}
catch (ArgumentException)
{
return false;
}
Comment on lines +143 to +151
}
}

internal sealed class FanCurvePoint
{
public FanCurvePoint(int temperature, int fanSpeed)
{
Temperature = temperature;
FanSpeed = fanSpeed;
}

public int Temperature { get; }

public int FanSpeed { get; }
}
}
Loading
Loading