Skip to content

Commit b5b4931

Browse files
committed
Fixed screen dimming when changing power profiles & new config with legal values for fan lower limits + tests
1 parent 7248e78 commit b5b4931

File tree

7 files changed

+307
-171
lines changed

7 files changed

+307
-171
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,5 @@ fabric.properties
228228
random/
229229
starto.ps1
230230
.vscode/launch.json
231+
config.DAT
232+
testing files/brightnesstest.py

G14Control.pyw

Lines changed: 160 additions & 132 deletions
Large diffs are not rendered by default.

G14ControlThreads.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ def kill(self):
5151
if res > 1:
5252
ctypes.pythonapi.PyThreadState_SetAsyncExc(self.ident, 0)
5353
print('Exception raise failure')
54+
55+
56+
fans = psutil.sensors_fans()
57+
print(fans.values())

G14RunCommands.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ def __init__(self, config, G14dir, app_GUID, dpp_GUID, notify, windows_plans, ac
2222
def set_windows_and_active_plans(self, winplns, activeplns):
2323
self.active_plan_map = activeplns
2424
self.windows_plans = winplns
25-
2625
# noinspection PyBroadException
2726

2827
# Small utility to convert windows HEX format to a boolean.
@@ -70,25 +69,16 @@ def do_boost(self, state):
7069
creationflags=subprocess.CREATE_NO_WINDOW)
7170
subprocess.Popen(SET_DC_VAL, shell=True,
7271
creationflags=subprocess.CREATE_NO_WINDOW)
73-
print(SET_AC_VAL)
74-
print(SET_DC_VAL)
72+
self.finalize_powercfg_chg(pwr_guid)
73+
if self.config['debug']:
74+
print(SET_AC_VAL)
75+
print(SET_DC_VAL)
7576

7677
def set_boost(self, state, notification=True):
77-
current_boost_mode = state
78-
win_plans = self.windows_plans
79-
active_plans = self.active_plan_map
80-
windows_plan_map = self.windows_plan_map
8178
CURRENT_SCHEME = os.popen("powercfg /GETACTIVESCHEME")
8279
pwr_guid = CURRENT_SCHEME.readlines()[0].rsplit(": ")[1].rsplit(
8380
" (")[0].lstrip("\n").replace(" ", "") # Parse the GUID
84-
switch_to = list(
85-
{val for key, val in windows_plan_map.items() if val != pwr_guid})[0]
86-
print(switch_to, "switch to guid")
8781
print(pwr_guid, "power guid")
88-
print(self.active_plan_map)
89-
self.set_power_plan(switch_to)
90-
time.sleep(.25)
91-
self.set_power_plan(pwr_guid)
9282
if state is True: # Activate boost
9383
self.do_boost(state)
9484
if notification is True:
@@ -104,15 +94,11 @@ def set_boost(self, state, notification=True):
10494
elif state == 4:
10595
self.do_boost(state)
10696
if notification is True:
107-
# Inform the user
108-
self.notify("Boost set to Efficient Aggressive")
97+
self.notify("Boost: Efficient Aggressive") # Inform the user
10998
elif state == 2:
11099
self.do_boost(state)
111100
if notification is True:
112-
self.notify("Boost set to Aggressive") # Inform the user
113-
self.set_power_plan(switch_to)
114-
time.sleep(0.25)
115-
self.set_power_plan(pwr_guid)
101+
self.notify("Boost: Aggressive") # Inform the user
116102

117103
def get_dgpu(self):
118104
# I know, it's ugly, but no other way to do that from py.
@@ -132,7 +118,6 @@ def get_dgpu(self):
132118
return True
133119

134120
def set_dgpu(self, state, notification=True):
135-
config = self.config
136121
G14dir = self.G14dir
137122
# Just to be safe, let's get the current power scheme
138123
current_pwr = os.popen("powercfg /GETACTIVESCHEME")
@@ -235,6 +220,11 @@ def set_power_plan(self, GUID):
235220
if self.config['debug']:
236221
print('Set power result (good if nothing): ', result)
237222

223+
def finalize_powercfg_chg(self, GUID):
224+
time.sleep(.25)
225+
subprocess.Popen(['powercfg', '-setactive', GUID], shell=True,
226+
creationflags=subprocess.CREATE_NO_WINDOW, stderr=STDOUT)
227+
238228
def apply_plan(self, plan):
239229
current_plan = plan['name']
240230
self.set_atrofac(plan['plan'], plan['cpu_curve'], plan['gpu_curve'])

data/config.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ plans:
3333
screen_hz: 120
3434
- name: Silent (low-speed fan)
3535
plan: windows
36-
cpu_curve: "30c:0%,40c:5%,50c:5%,60c:10%,70c:31%,80c:49%,90c:56%,100c:56%"
37-
gpu_curve: "30c:0%,40c:5%,50c:5%,60c:10%,70c:34%,80c:51%,90c:61%,100c:61%"
36+
cpu_curve: "30c:0%,40c:0%,50c:20%,60c:20%,70c:31%,80c:49%,90c:56%,100c:56%"
37+
gpu_curve: "30c:0%,40c:0%,50c:20%,60c:20%,70c:34%,80c:51%,90c:61%,100c:61%"
3838
cpu_tdp: 35000
3939
boost: 0
4040
dgpu_enabled: true
@@ -49,16 +49,16 @@ plans:
4949
screen_hz: 120
5050
- name: Performance
5151
plan: performance
52-
cpu_curve: "30c:0%,40c:5%,50c:8%,60c:10%,70c:31%,80c:49%,90c:56%,100c:56%"
53-
gpu_curve: "30c:0%,40c:5%,50c:8%,60c:10%,70c:34%,80c:51%,90c:61%,100c:61%"
52+
cpu_curve: "30c:0%,40c:20%,50c:20%,60c:20%,70c:31%,80c:49%,90c:56%,100c:56%"
53+
gpu_curve: "30c:0%,40c:20%,50c:20%,60c:20%,70c:34%,80c:51%,90c:61%,100c:61%"
5454
cpu_tdp: 38000
5555
boost: 4
5656
dgpu_enabled: true
5757
screen_hz: 120
5858
- name: Performance Plus
5959
plan: performance
60-
cpu_curve: "30c:0%,40c:5%,50c:15%,60c:24%,70c:31%,80c:49%,90c:56%,100c:56%"
61-
gpu_curve: "30c:0%,40c:5%,50c:15%,60c:24%,70c:34%,80c:51%,90c:61%,100c:61%"
60+
cpu_curve: "30c:0%,40c:20%,50c:20%,60c:24%,70c:31%,80c:49%,90c:56%,100c:56%"
61+
gpu_curve: "30c:0%,40c:20%,50c:20%,60c:24%,70c:34%,80c:51%,90c:61%,100c:61%"
6262
cpu_tdp: 40000
6363
boost: 4
6464
dgpu_enabled: true

testing files/threadtest.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import ctypes
55

66

7-
8-
97
class PowerThreadTest(threading.Thread):
108
def __init__(self):
119
threading.Thread.__init__(self)
@@ -15,25 +13,23 @@ def run(self):
1513
print('running')
1614
time.sleep(1)
1715

18-
def murder(self):
16+
def kill(self):
1917
print('trying to kill')
20-
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(self.ident,
21-
ctypes.py_object(SystemExit))
22-
if res > 1:
23-
ctypes.pythonapi.PyThreadState_SetAsyncExc(self.ident, 0)
24-
print('Exception raise failure')
25-
26-
18+
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(self.ident,
19+
ctypes.py_object(SystemExit))
20+
if res > 1:
21+
ctypes.pythonapi.PyThreadState_SetAsyncExc(self.ident, 0)
22+
print('Exception raise failure')
2723

2824

2925
def starto():
3026
thd = PowerThreadTest()
3127
thd.start()
3228
time.sleep(6)
33-
thd.murder()
29+
thd.kill()
3430
thd.join()
3531
print("ded")
36-
print(thd,thd.is_alive())
32+
print(thd, thd.is_alive())
3733

3834

3935
starto()

tests.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import unittest
2+
import os
3+
import re
4+
from G14RunCommands import RunCommands
5+
import yaml
6+
import pathlib
7+
import subprocess as sp
8+
import subprocess
9+
import sys
10+
11+
config = {}
12+
windows_plans = []
13+
current_windows_plan = ""
14+
app_GUID = ""
15+
dpp_GUID = ""
16+
active_plan_map = dict()
17+
G14dir = ""
18+
19+
20+
def get_power_plans():
21+
global dpp_GUID, app_GUID
22+
all_plans = subprocess.check_output(["powercfg", "/l"])
23+
for i in str(all_plans).split('\\n'):
24+
print(i)
25+
if i.find(config['default_power_plan']) != -1:
26+
dpp_GUID = i.split(' ')[3]
27+
if i.find(config['alt_power_plan']) != -1:
28+
app_GUID = i.split(' ')[3]
29+
30+
31+
def get_windows_plans():
32+
global config, active_plan_map, current_windows_plan
33+
windows_power_options = re.findall(
34+
r"([0-9a-f\-]{36}) *\((.*)\) *\*?\n", os.popen("powercfg /l").read())
35+
active_plan_map = {x[1]: False for x in windows_power_options}
36+
active_plan_map[current_windows_plan] = True
37+
return windows_power_options
38+
39+
40+
"""
41+
Cannot be run before @get_windows_plans()
42+
"""
43+
44+
45+
def get_active_plan_map():
46+
global windows_plans, active_plan_map
47+
try:
48+
active_plan_map["Balanced"]
49+
return active_plan_map
50+
except Exception:
51+
active_plan_map = {x[1]: False for x in windows_plans}
52+
active_plan_map[current_windows_plan] = True
53+
return active_plan_map
54+
55+
56+
def get_app_path():
57+
global G14dir
58+
G14Dir = ""
59+
# Sets the path accordingly whether it is a python script or a frozen .exe
60+
if getattr(sys, 'frozen', False):
61+
G14dir = os.path.dirname(os.path.realpath(sys.executable))
62+
elif __file__:
63+
G14dir = os.path.dirname(os.path.realpath(__file__))
64+
65+
66+
def loadConfig():
67+
config = {}
68+
with open('data/config.yml') as file:
69+
config = yaml.load(file.read())
70+
return config
71+
72+
73+
class RunCommandsTests(unittest.TestCase):
74+
75+
def setUp(self):
76+
global config, windows_plans, active_plan_map, config, dpp_GUID, app_GUID, G14dir
77+
self.config = loadConfig()
78+
config = self.config
79+
get_power_plans()
80+
get_app_path()
81+
get_windows_plans()
82+
get_active_plan_map()
83+
self.main_cmds = RunCommands(self.config,
84+
G14dir=G14dir,
85+
app_GUID=app_GUID,
86+
dpp_GUID=dpp_GUID,
87+
notify=lambda x: print(x),
88+
windows_plans=windows_plans,
89+
active_plan_map=active_plan_map)
90+
91+
def boost_test(self):
92+
startboost = self.main_cmds.get_boost()
93+
self.main_cmds.do_boost(2)
94+
boost = self.main_cmds.get_boost()
95+
self.assertEqual(
96+
2, int(boost, 16), "Boost not equal to boost that was set (2)")
97+
self.main_cmds.do_boost(4)
98+
boost = self.main_cmds.get_boost()
99+
self.assertEqual(4, int(boost, 16))
100+
101+
self.main_cmds.do_boost(0)
102+
boost = self.main_cmds.get_boost()
103+
self.assertEqual(0, int(boost, 16))
104+
105+
self.main_cmds.do_boost(int(startboost, 16))
106+
107+
108+
def suite():
109+
suite = unittest.TestSuite()
110+
suite.addTest(RunCommandsTests('boost_test'))
111+
return suite
112+
113+
114+
if __name__ == '__main__':
115+
runner = unittest.TextTestRunner()
116+
runner.run(suite())

0 commit comments

Comments
 (0)