Skip to content

Commit e74c871

Browse files
committed
consistency mode 2
1 parent c62f88d commit e74c871

File tree

11 files changed

+277
-3
lines changed

11 files changed

+277
-3
lines changed

LenovoFanManagementApp/ConsistencyModeHandlers/ConsistencyModeHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,7 @@ public ConsistencyModeHandler(Core core, State state, FanController fanControlle
3939
/// Logic for a particular consistency mode implementation.
4040
/// </summary>
4141
public abstract void RunConsistencyModeLogic();
42+
43+
public abstract void RunConsistencyModeLogic2();
4244
}
4345
}

LenovoFanManagementApp/ConsistencyModeHandlers/LegacyConsistencyModeHandler.cs

Lines changed: 219 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
using DellFanManagement.App.FanControllers;
22
using DellFanManagement.App.TemperatureReaders;
3+
using Salaros.Configuration;
34
using System;
45
using System.Collections.Generic;
6+
using System.IO;
7+
using DellFanManagement.DellSmbiozBzhLib;
8+
using System.Threading;
59

610
namespace DellFanManagement.App.ConsistencyModeHandlers
711
{
@@ -10,6 +14,13 @@ namespace DellFanManagement.App.ConsistencyModeHandlers
1014
/// </summary>
1115
public class LegacyConsistencyModeHandler : ConsistencyModeHandler
1216
{
17+
protected Dictionary<int, int[]> fanDict = new();
18+
FileSystemWatcher watcher;
19+
/// <summary>
20+
/// Semaphore for protecting access to fanDict changes.
21+
/// </summary>
22+
private readonly Semaphore _semaphore = new Semaphore(1,1);
23+
1324
/// <summary>
1425
/// Constructor.
1526
/// </summary>
@@ -18,7 +29,113 @@ public class LegacyConsistencyModeHandler : ConsistencyModeHandler
1829
/// <param name="fanController">The fan controller currently in use.</param>
1930
public LegacyConsistencyModeHandler(Core core, State state, FanController fanController) : base(core, state, fanController)
2031
{
21-
// No action here.
32+
// Init Fan info.
33+
InitFanInfo();
34+
35+
// Monitor fan.ini if changed.
36+
string curDir = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
37+
watcher = new FileSystemWatcher(curDir);
38+
39+
watcher.NotifyFilter = NotifyFilters.Attributes
40+
| NotifyFilters.CreationTime
41+
| NotifyFilters.DirectoryName
42+
| NotifyFilters.FileName
43+
| NotifyFilters.LastAccess
44+
| NotifyFilters.LastWrite
45+
| NotifyFilters.Security
46+
| NotifyFilters.Size;
47+
48+
watcher.Changed += new FileSystemEventHandler(OnFanInfoChanged);
49+
watcher.Created += new FileSystemEventHandler(OnFanInfoCreated);
50+
watcher.Renamed += new RenamedEventHandler(OnFanInfoRenamed);
51+
watcher.Filter = "fan.ini";
52+
watcher.IncludeSubdirectories = true;
53+
watcher.EnableRaisingEvents = true;
54+
}
55+
56+
private void InitFanInfo()
57+
{
58+
fanDict.Clear();
59+
string curDir = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
60+
string iniPath = string.Format("{0}{1}{2}", Directory.GetCurrentDirectory(), Path.DirectorySeparatorChar, "fan.ini");
61+
if (!File.Exists(iniPath))
62+
{
63+
return;
64+
}
65+
66+
_semaphore.WaitOne();
67+
var config = new ConfigParser(iniPath);
68+
List<int> validLevel = new List<int>()
69+
{
70+
0,1,2,3,4,5,6,7,64
71+
};
72+
foreach (ConfigSection section in config.Sections)
73+
{
74+
/*
75+
if (section.SectionName == "RPM_DELAY")
76+
{
77+
foreach (IConfigKeyValue item in section.Keys)
78+
{
79+
80+
}
81+
}
82+
*/
83+
84+
if (section.SectionName == "RPM_TEMP")
85+
{
86+
foreach (IConfigKeyValue item in section.Keys)
87+
{
88+
try
89+
{
90+
string[] arr = item.ValueRaw.ToString().Split("-");
91+
int[] arr2 = new int[]
92+
{
93+
int.Parse(arr[0]),
94+
int.Parse(arr[1])
95+
};
96+
if (item.Name.ToLower() == "auto")
97+
{
98+
fanDict.Add(AUTO_LEVEL, arr2);
99+
}
100+
else
101+
{
102+
int level = int.Parse(item.Name);
103+
if (validLevel.IndexOf(level) >= 0)
104+
{
105+
fanDict.Add(level, arr2);
106+
}
107+
}
108+
}
109+
catch (Exception expt)
110+
{
111+
// Do nothing
112+
113+
}
114+
}
115+
}
116+
}
117+
_semaphore.Release();
118+
}
119+
120+
private void OnFanInfoCreated(object sender, FileSystemEventArgs e)
121+
{
122+
InitFanInfo();
123+
string value = $"Created: {e.FullPath}";
124+
Console.WriteLine(value);
125+
}
126+
private void OnFanInfoRenamed(object sender, FileSystemEventArgs e)
127+
{
128+
InitFanInfo();
129+
Console.WriteLine($"Renamed:");
130+
}
131+
private void OnFanInfoChanged(object sender, FileSystemEventArgs e)
132+
{
133+
if (e.ChangeType != WatcherChangeTypes.Changed)
134+
{
135+
return;
136+
}
137+
InitFanInfo();
138+
Console.WriteLine($"Changed: {e.FullPath}");
22139
}
23140

24141
/// <summary>
@@ -322,5 +439,106 @@ public override void RunConsistencyModeLogic()
322439
}
323440
}
324441
}
442+
443+
private class ClosestFanLevel
444+
{
445+
public int level;
446+
public int absDiff;
447+
}
448+
public static int AUTO_LEVEL = 99;
449+
public static int FAN_LEVEL_DELAY = 3; // in seconds
450+
public static int _fan_level_loops = 0;
451+
public static int _cur_fan_level = -1; // current fan level
452+
453+
public override void RunConsistencyModeLogic2()
454+
{
455+
if (fanDict.Count == 0)
456+
{
457+
_fanController.EnableAutomaticFanControl();
458+
_cur_fan_level = AUTO_LEVEL;
459+
return;
460+
}
461+
462+
int cur_temp = 0;
463+
foreach (TemperatureComponent component in _state.Temperatures.Keys)
464+
{
465+
foreach (KeyValuePair<string, int> temperature in _state.Temperatures[component])
466+
{
467+
//if (component == TemperatureComponent.CPU &&
468+
// temperature.Key.ToLower().IndexOf("package") >= 0) continue; // Ignore CPU Package temperature
469+
cur_temp = Math.Max(temperature.Value, cur_temp);
470+
}
471+
}
472+
473+
// Look up the Fan level on fanDict
474+
_semaphore.WaitOne();
475+
int fanLevel = -1; // Invalid level
476+
bool bFound = false;
477+
List<ClosestFanLevel> rpmList = new List<ClosestFanLevel>();
478+
foreach (KeyValuePair<int, int[]> item in fanDict)
479+
{
480+
int configLevel = item.Key;
481+
int min_val = item.Value[0];
482+
int max_val = item.Value[1];
483+
484+
if (cur_temp >= min_val && cur_temp <= max_val)
485+
{
486+
fanLevel = configLevel;
487+
bFound = true;
488+
break;
489+
}
490+
else
491+
{
492+
int absDiff = Math.Min(Math.Abs(cur_temp - min_val), Math.Abs(cur_temp - max_val));
493+
if (absDiff <= 5) // For safely, we don't allow that difference is greater than 5 degree that would damage CPU/GPU
494+
{
495+
rpmList.Add(new ClosestFanLevel() { level = configLevel, absDiff = absDiff});
496+
}
497+
}
498+
}
499+
_semaphore.Release();
500+
501+
if (!bFound && rpmList.Count > 0)
502+
{
503+
rpmList.Sort((item1, item2) => (item1.absDiff > item2.absDiff ? 1 : -1));
504+
fanLevel = (int)rpmList[0].level;
505+
}
506+
507+
if (fanLevel == -1 || fanLevel == AUTO_LEVEL)
508+
{
509+
_fanController.EnableAutomaticFanControl();
510+
_cur_fan_level = AUTO_LEVEL;
511+
_state.ConsistencyModeStatus = "EC自动调节...";
512+
_core.TrayIconColor = TrayIconColor.Gray;
513+
return;
514+
}
515+
516+
if (_fan_level_loops > FAN_LEVEL_DELAY)
517+
_fan_level_loops = 0;
518+
if (_fan_level_loops == 0)
519+
{
520+
_fanController.SetFanLevelSpecific((BzhFanLevel)fanLevel, FanIndex.AllFans);
521+
_cur_fan_level = fanLevel;
522+
if (fanLevel == 0)
523+
{
524+
_state.ConsistencyModeStatus = "关闭风扇";
525+
_core.TrayIconColor = TrayIconColor.Gray;
526+
}
527+
else
528+
{
529+
if (fanLevel < 7)
530+
{
531+
_state.ConsistencyModeStatus = string.Format("风扇转速: {0} 档", fanLevel);
532+
_core.TrayIconColor = TrayIconColor.Blue;
533+
}
534+
else
535+
{
536+
_state.ConsistencyModeStatus = string.Format("风扇转速: {0} 档", fanLevel);
537+
_core.TrayIconColor = TrayIconColor.Red;
538+
}
539+
}
540+
}
541+
_fan_level_loops += 1;
542+
}
325543
}
326544
}

LenovoFanManagementApp/ConsistencyModeHandlers/SimpleConsistencyModeHandler.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,5 +184,10 @@ private void BackgroundWork(int threadId, int cpu)
184184
/// <see cref="https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadid"/>
185185
[DllImport("kernel32.dll")]
186186
static extern uint GetCurrentThreadId();
187+
188+
public override void RunConsistencyModeLogic2()
189+
{
190+
// Do nothing
191+
}
187192
}
188193
}

LenovoFanManagementApp/FanControllers/BzhFanController.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,30 @@ public override bool SetFanLevel(FanLevel level, FanIndex fanIndex)
116116
}
117117
}
118118

119+
public override bool SetFanLevelSpecific(BzhFanLevel level, FanIndex fanIndex)
120+
{
121+
if (DellSmbiosBzh.IsInitialized)
122+
{
123+
bool result1 = true;
124+
bool result2 = true;
125+
126+
if (fanIndex == FanIndex.Fan1 || fanIndex == FanIndex.AllFans)
127+
{
128+
result1 = DellSmbiosBzh.SetFanLevel(BzhFanIndex.Fan1, level);
129+
}
130+
131+
if (fanIndex == FanIndex.Fan2 || fanIndex == FanIndex.AllFans)
132+
{
133+
result2 = DellSmbiosBzh.SetFanLevel(BzhFanIndex.Fan2, level);
134+
}
135+
136+
return result1 && result2;
137+
}
138+
else
139+
{
140+
return false;
141+
}
142+
}
119143
/// <summary>
120144
/// Unload the BZH driver.
121145
/// </summary>

LenovoFanManagementApp/FanControllers/FanController.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace DellFanManagement.App.FanControllers
1+
using DellFanManagement.DellSmbiozBzhLib;
2+
3+
namespace DellFanManagement.App.FanControllers
24
{
35
/// <summary>
46
/// Interface for fan speed controller implementations.
@@ -40,6 +42,8 @@ public abstract class FanController
4042
/// <returns>True on succes, false on failure.</returns>
4143
public abstract bool SetFanLevel(FanLevel level, FanIndex fanIndex);
4244

45+
public abstract bool SetFanLevelSpecific(BzhFanLevel level, FanIndex fanIndex);
46+
4347
/// <summary>
4448
/// Perform any steps needed to "clean up" as the program is terminating.
4549
/// </summary>

LenovoFanManagementApp/FanControllers/NullFanController.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace DellFanManagement.App.FanControllers
1+
using DellFanManagement.DellSmbiozBzhLib;
2+
3+
namespace DellFanManagement.App.FanControllers
24
{
35
/// <summary>
46
/// This fan controller can't actually control the fans.
@@ -44,6 +46,11 @@ public override bool SetFanLevel(FanLevel level, FanIndex fanIndex)
4446
return false;
4547
}
4648

49+
public override bool SetFanLevelSpecific(BzhFanLevel level, FanIndex fanIndex)
50+
{
51+
return false;
52+
}
53+
4754
/// <summary>
4855
/// No shutdown method is needed for this fan controller.
4956
/// </summary>

LenovoFanManagementApp/FanControllers/SmiFanController.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using DellFanManagement.DellSmbiosSmiLib;
2+
using DellFanManagement.DellSmbiozBzhLib;
23

34
namespace DellFanManagement.App.FanControllers
45
{
@@ -68,6 +69,11 @@ public override bool SetFanLevel(FanLevel level, FanIndex fanIndex)
6869
return DellSmbiosSmi.SetFanLevel(smiLevel);
6970
}
7071

72+
public override bool SetFanLevelSpecific(BzhFanLevel level, FanIndex fanIndex)
73+
{
74+
return DellSmbiosBzh.SetFanLevel((fanIndex == FanIndex.Fan1) ? BzhFanIndex.Fan1 : BzhFanIndex.Fan2, level);
75+
}
76+
7177
/// <summary>
7278
/// No shutdown method is needed for this fan controller.
7379
/// </summary>

LenovoFanManagementApp/TemperatureReaders/CpuTemperatureReader.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using LibreHardwareMonitor.Hardware;
2+
using System;
3+
using System.Windows.Forms;
24

35
namespace DellFanManagement.App.TemperatureReaders
46
{
@@ -18,6 +20,8 @@ public CpuTemperatureReader()
1820
};
1921

2022
_computer.Open();
23+
//string report = _computer.GetReport();
24+
Log.WriteToFile(string.Format("CPU report\r\n:{0}", _computer.GetReport()));
2125
}
2226
}
2327
}

LenovoFanManagementApp/TemperatureReaders/GenericGpuTemperatureReader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public GenericGpuTemperatureReader()
1515
};
1616

1717
_computer.Open();
18+
Log.WriteToFile(string.Format("Generic Gpu report:\r\n{0}", _computer.GetReport()));
1819
}
1920
}
2021
}

LenovoFanManagementApp/TemperatureReaders/LibreHardwareMonitorTemperatureReader.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using LibreHardwareMonitor.Hardware;
22
using System;
33
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Windows.Forms;
46

57
namespace DellFanManagement.App.TemperatureReaders
68
{

0 commit comments

Comments
 (0)