-
Notifications
You must be signed in to change notification settings - Fork 4
/
G14RunCommands.py
315 lines (293 loc) · 12.2 KB
/
G14RunCommands.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
from G14Utils import get_active_windows_plan
import os
import subprocess as sp
import sys
import time
import re
from subprocess import STDOUT
class RunCommands:
def __init__(
self, config, G14dir, app_GUID, dpp_GUID, notify, windows_plans, active_plan_map
):
self.config = config
self.G14dir = G14dir
self.app_GUID = app_GUID
self.dpp_GUID = dpp_GUID
self.notify = notify
self.windows_plans = windows_plans
self.active_plan_map = active_plan_map
self.windows_plan_map = {name: guid for guid, name in iter(windows_plans)}
self.reverse_windows_plan_map = {
guid: name for guid, name in iter(windows_plans)
}
def set_windows_and_active_plans(self, winplns, activeplns):
self.active_plan_map = activeplns
self.windows_plans = winplns
# noinspection PyBroadException
# Small utility to convert windows HEX format to a boolean.
def parse_boolean(self, parse_string):
try:
if parse_string == "0x00000000": # We will consider this as False
return False
else: # We will consider this as True
return True
except Exception:
return None # Just in case™
def get_boost(self):
# I know, it's ugly, but no other way to do that from py.
pwr_guid = list(get_active_windows_plan().values())[0] # Parse the GUID
SUB_PROCESSOR = " 54533251-82be-4824-96c1-47b60b740d00"
PERFBOOSTMODE = " be337238-0d82-4146-a960-4f3749d470c7"
# Let's get the boost option in the currently active power scheme
pwr_settings = os.popen(
"powercfg /Q " + pwr_guid + SUB_PROCESSOR + PERFBOOSTMODE
)
output = pwr_settings.readlines() # We save the output to parse it afterwards
# Parsing AC, assuming the DC is the same setting
ac_boost = output[-3].rsplit(": ")[1].strip("\n")
# battery_boost = parse_boolean(output[-2].rsplit(": ")[1].strip("\n")) # currently unused, we will set both
return ac_boost
def do_boost(self, state):
# Just to be safe, let's get the current power scheme
SUB_PROCESSOR = "54533251-82be-4824-96c1-47b60b740d00"
PERFBOOSTMODE = "be337238-0d82-4146-a960-4f3749d470c7"
set_ac = "powercfg /setacvalueindex"
set_dc = "powercfg /setdcvalueindex"
pwr_guid = list(get_active_windows_plan().values())[0]
if state is False:
state = 0
SET_AC_VAL = "{0} {1} {2} {3} {4}".format(
set_ac, pwr_guid, SUB_PROCESSOR, PERFBOOSTMODE, str(state)
)
SET_DC_VAL = "{0} {1} {2} {3} {4}".format(
set_dc, pwr_guid, SUB_PROCESSOR, PERFBOOSTMODE, str(state)
)
sp.Popen(SET_AC_VAL, shell=True, creationflags=sp.CREATE_NO_WINDOW)
sp.Popen(SET_DC_VAL, shell=True, creationflags=sp.CREATE_NO_WINDOW)
if self.config["debug"]:
print(SET_AC_VAL)
print(SET_DC_VAL)
def set_boost(self, state, notification=True):
"""
Takes boost state as a boolean or integer value and modifies the boost
parameter of the current windows plan by modifying and then activating
the windows plan. The current hackish solution is to switch to another
windows plan and then switch back.
By default set_boost will cause a windows notification to appear
indicating the boost value after it is set, you can silence the
notification with the parameter notification=False.
"""
windows_plan_map = self.windows_plan_map
pwr_guid = list(get_active_windows_plan().values())[0]
switch_to = list(
{val for key, val in windows_plan_map.items() if val != pwr_guid}
)[0]
print(switch_to, "switch to guid")
print(pwr_guid, "power guid")
self.set_power_plan(switch_to)
time.sleep(0.25)
self.set_power_plan(pwr_guid)
if state is True: # Activate boost
self.do_boost(state)
if notification is True:
self.notify("Boost ENABLED") # Inform the user
elif state is False or state == 0: # Deactivate boost
self.do_boost(False)
if notification is True:
self.notify("Boost DISABLED") # Inform the user
elif state == 4:
self.do_boost(state)
if notification is True:
# Inform the user
self.notify("Boost Efficient Aggressive")
elif state == 2:
self.do_boost(state)
if notification is True:
self.notify("Boost Aggressive") # Inform the user
self.set_power_plan(switch_to)
time.sleep(0.25)
self.set_power_plan(pwr_guid)
def get_dgpu(self):
# Get active windows power scheme
pwr_guid = list(get_active_windows_plan().values())[0] # Parse the GUID
SW_DYNAMC_GRAPHICS = "e276e160-7cb0-43c6-b20b-73f5dce39954"
GLOBAL_SETTINGS = "a1662ab2-9d34-4e53-ba8b-2639b9e20857"
pwr_settings = os.popen(
" ".join(["powercfg", "/q", pwr_guid, SW_DYNAMC_GRAPHICS, GLOBAL_SETTINGS])
) # Let's get the dGPU status in the current power scheme
output = pwr_settings.readlines() # We save the output to parse it afterwards
# Convert to boolean for "On/Off"
dgpu_ac = self.parse_boolean(output[-3].rsplit(": ")[1].strip("\n"))
if dgpu_ac is None:
return False
else:
return dgpu_ac
def set_dgpu(self, state, notification=True):
G14dir = self.G14dir
# Just to be safe, let's get the current power scheme
pwr_guid = list(get_active_windows_plan().values())[0]
SW_DYNAMC_GRAPHICS = "e276e160-7cb0-43c6-b20b-73f5dce39954"
GLOBAL_SETTINGS = "a1662ab2-9d34-4e53-ba8b-2639b9e20857"
AC = "/setacvalueindex"
DC = "/setdcvalueindex"
def _set_dgpu(SETTING, AC_DC):
return os.popen(
" ".join(
[
"powercfg",
AC_DC,
pwr_guid,
SW_DYNAMC_GRAPHICS,
GLOBAL_SETTINGS,
str(SETTING),
]
)
)
if state is True: # Activate dGPU
_set_dgpu(2, AC)
_set_dgpu(2, DC)
time.sleep(0.25)
if notification is True:
self.notify("dGPU set to performance.") # Inform the user
elif state is False: # Deactivate dGPU
_set_dgpu(0, AC)
_set_dgpu(0, DC)
time.sleep(0.25)
os.system('"' + str(G14dir) + "\\restartGPUcmd.bat" + '"')
if notification is True:
self.notify("dGPU set to force power saver.") # Inform the user
def check_screen(
self,
): # Checks to see if the G14 has a 120Hz capable screen or not
config = self.config
check_screen_ref = str(
os.path.join(config["temp_dir"] + "ChangeScreenResolution.exe")
)
# /m lists all possible resolutions & refresh rates
screen = os.popen(check_screen_ref + " /m /d=0")
output = screen.readlines()
for line in output:
if re.search("@120Hz", line):
return True
else:
return False
def get_screen(self): # Gets the current screen resolution
config = self.config
get_screen_ref = str(
os.path.join(config["temp_dir"] + "ChangeScreenResolution.exe")
)
# /l lists current resolution & refresh rate
screen = os.popen(get_screen_ref + " /l /d=0")
output = screen.readlines()
for line in output:
if re.search("@120Hz", line):
return True
else:
return False
def set_screen(self, refresh: str or int, notification=True):
config = self.config
if (
self.check_screen()
): # Before trying to change resolution, check that G14 is capable of 120Hz resolution
if refresh is None:
# If screen refresh rate is null (not set), set to default refresh rate of 120Hz
self.set_screen(120)
check_screen_ref = str(
os.path.join(config["temp_dir"] + "ChangeScreenResolution.exe")
)
os.popen(check_screen_ref + " /d=0 /f=" + str(refresh))
if notification is True:
self.notify("Screen refresh rate set to: " + str(refresh) + "Hz")
else:
return
def set_atrofac(self, asus_plan, cpu_curve=None, gpu_curve=None):
config = self.config
atrofac = str(os.path.join(config["temp_dir"] + "atrofac-cli.exe"))
if cpu_curve is not None and gpu_curve is not None:
cmdargs = (
atrofac
+ " fan --cpu "
+ cpu_curve
+ " --gpu "
+ gpu_curve
+ " --plan "
+ asus_plan
)
elif cpu_curve is not None and gpu_curve is None:
cmdargs = atrofac + " fan --cpu " + cpu_curve + " --plan " + asus_plan
elif cpu_curve is None and gpu_curve is not None:
cmdargs = atrofac + " fan --gpu " + gpu_curve + " --plan " + asus_plan
else:
cmdargs = atrofac + " --plan " + asus_plan
try:
result = sp.check_output(
cmdargs, shell=True, creationflags=sp.CREATE_NO_WINDOW
)
if self.config["debug"]:
print(result)
except Exception:
if self.config["debug"]:
print("Error setting fan speeds.")
def set_ryzenadj(self, tdp, attempts=3):
config = self.config
ryzenadj = str(os.path.join(config["temp_dir"] + "ryzenadj.exe"))
if tdp is None:
pass
else:
try:
result = sp.check_output(
ryzenadj + " -a " + str(tdp) + " -b " + str(tdp),
shell=True,
creationflags=sp.CREATE_NO_WINDOW,
)
if self.config["debug"]:
print(result.decode("utf-8"))
except Exception:
print("There was an error applying ryzenadj\n Attempt #" + attempts)
if attempts == 0:
self.notify(
"There was an error apply ryzenadj TDP power settings...\n"
+ "This is relatively normal."
)
else:
self.set_ryzenadj(tdp, attempts - 1)
def set_power_plan(self, GUID, do_notify=False):
print("setting power plan GUID to: ", GUID)
result = sp.check_output(
["powercfg", "/s", GUID],
shell=True,
creationflags=sp.CREATE_NO_WINDOW,
stderr=STDOUT,
)
if self.config["debug"]:
print(result.decode("utf-8"))
if do_notify:
self.notify(
"Switched windows plan to:\n" + self.reverse_windows_plan_map[GUID]
)
def finalize_powercfg_chg(self, GUID):
time.sleep(0.25)
sp.Popen(
["powercfg", "-setactive", GUID],
shell=True,
creationflags=sp.CREATE_NO_WINDOW,
stderr=STDOUT,
)
def edit_config(self):
config_loc = ""
if getattr(sys, "frozen", False):
# Set absolute path for config.yaml
config_loc = os.path.join(str(self.G14dir), "config.yml")
elif __file__:
# Set absolute path for config.yaml
config_loc = os.path.join(str(self.G14dir), "data/config.yml")
sp.Popen(["notepad", config_loc], shell=True, creationflags=sp.CREATE_NO_WINDOW)
def apply_plan(self, plan):
current_plan = plan["name"]
self.set_atrofac(plan["plan"], plan["cpu_curve"], plan["gpu_curve"])
self.set_boost(plan["boost"], False)
self.set_dgpu(plan["dgpu_enabled"], False)
self.set_screen(plan["screen_hz"], False)
self.set_ryzenadj(plan["cpu_tdp"])
self.notify("Applied plan " + plan["name"])
return current_plan