11using DellFanManagement . App . FanControllers ;
22using DellFanManagement . App . TemperatureReaders ;
3+ using Salaros . Configuration ;
34using System ;
45using System . Collections . Generic ;
6+ using System . IO ;
7+ using DellFanManagement . DellSmbiozBzhLib ;
8+ using System . Threading ;
59
610namespace 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}
0 commit comments