-
Notifications
You must be signed in to change notification settings - Fork 0
/
powersaver.sh
executable file
·334 lines (282 loc) · 11.6 KB
/
powersaver.sh
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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
#!/bin/bash
#
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_URL="https://github.com/tomasmark79/powersaver"
# Get number of cpu cores
num_cores=$(nproc --all)
# -------------------------------------------------------------------------------------
# Functions pattern
# -------------------------------------------------------------------------------------
function update {
git_pull_status=0
# Check if the script is in a git repository
if [ -d .git ]; then
echo "Updating existing repository..."
# Restore deleted files
git restore --source=HEAD --staged --worktree .
if git pull origin main; then
echo "Update successful."
else
echo "Update failed. Attempting to clone a new..."
git_pull_status=1
fi
else
echo "Git repository not found. Cloning new one..."
git_pull_status=1
fi
# broken structure of git repository will cause to clone new one
if [ ! -d .git ] || [ $git_pull_status -ne 0 ]; then
# backup store to timestamp directory about one level up
cd ..
timestamp=$(date +"%Y%m%d_%H%M%S")
new_dir="$(dirname "$SCRIPT_DIR")/$timestamp"
mkdir -p "$new_dir"
mv "$SCRIPT_DIR" "$new_dir"
git clone "$REPO_URL" "$SCRIPT_DIR"
cd "$SCRIPT_DIR"
fi
echo "Update completed."
ls -la
}
# Check if script is called with --update argument
if [ "$1" = "--update" ]; then
update
exit 0
fi
function convert_to_mhz {
freq=$1
unit=$2
if [ "$unit" == "GHz" ]; then
# Tento prevod prevadi na MHz bez desetinnych hodnot
# freq=$(echo "$freq" | awk -F. '{print $1}')
# freq=$(( freq * 1000 ))
# Převod GHz na MHz s desetinnými hodnotami
freq=$(echo "$freq * 1000" | bc -l)
fi
# Zaokrouhlení na celé číslo (pokud potřebujete desetinná místa, upravte printf)
LC_NUMERIC=C printf "%.0f\n" "$freq"
# echo $freq
}
function get_cpu_info {
echo
echo "Getting cpu info ..."
model_name=$(cat /proc/cpuinfo | grep 'model name' | uniq | awk -F ': ' '{print $2}')
echo -e "$model_name" w "\e[31m$num_cores\e[0m cores"
}
function get_cpu_limits {
echo
echo "Getting factory cpu limits ..."
hwLimitsPattern="hardware limits:"
for ((i = 0; i < $num_cores; i++)); do
cpu_info=$(sudo cpupower -c $i frequency-info)
min_freqs[$i]=$(echo "$cpu_info" | grep "$hwLimitsPattern" | awk '{print $3}')
min_freq_units[$i]=$(echo "$cpu_info" | grep "$hwLimitsPattern" | awk '{print $4}')
max_freqs[$i]=$(echo "$cpu_info" | grep "$hwLimitsPattern" | awk '{print $6}')
max_freq_units[$i]=$(echo "$cpu_info" | grep "$hwLimitsPattern" | awk '{print $7}')
echo -e "\e[32mCore $i - min: ${min_freqs[$i]} ${min_freq_units[$i]} - max: ${max_freqs[$i]} ${max_freq_units[$i]}\e[0m"
done
echo
}
function get_cpu_policy {
policyPattern="policy"
echo "Getting current cpu policy ..."
for ((i = 0; i < $num_cores; i++)); do
cpu_info_policy=$(sudo cpupower -c $i frequency-info)
min_freqs_policy[$i]=$(echo "$cpu_info_policy" | grep "$policyPattern" | awk '{print $7}')
min_freq_units_policy[$i]=$(echo "$cpu_info_policy" | grep "$policyPattern" | awk '{print $8}')
max_freqs_policy[$i]=$(echo "$cpu_info_policy" | grep "$policyPattern" | awk '{print $10}')
max_freq_units_policy[$i]=$(echo "$cpu_info_policy" | grep "$policyPattern" | awk '{print $11}')
echo -e "\e[34mCore $i - min: ${min_freqs_policy[$i]} ${min_freq_units_policy[$i]} - max: ${max_freqs_policy[$i]} ${max_freq_units_policy[$i]}\e[0m"
done
}
function print_notify {
icon=$SCRIPT_DIR/cpu.png
if [ -z "$SUDO_USER" ]; then
notify-send -u low -i $icon "$1" "$2"
else
sudo -u $SUDO_USER DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u $SUDO_USER)/bus notify-send -u low -i $icon "$1" "$2"
fi
}
function check_and_set_max_limits {
if [[ "$1" == "max" ]]; then
echo "Setting maximal cpu limits ..."
for ((i = 0; i < $num_cores; i++)); do
echo -e -n "\e[33mForce to set core $i - min: ${min_freqs[$i]}${min_freq_units[$i]} - max: ${max_freqs[$i]}${max_freq_units[$i]}\e[0m "
sudo cpupower -c $i frequency-set -d ${min_freqs[$i]}${min_freq_units[$i]} -u ${max_freqs[$i]}${max_freq_units[$i]}
done
echo
notify_message="Maximum core limits successfully set.\n"
fi
}
function check_and_set_minusgiga_limits {
if [[ "$1" == "minusgiga" ]]; then
echo "Setting minus one gigahertz cpu limits ..."
for ((i = 0; i < $num_cores; i++)); do
max_freq=$(convert_to_mhz ${max_freqs[$i]} ${max_freq_units[$i]})
max_freq=$((max_freq - 1000))
max_freq_units="MHz"
echo -e -n "\e[33mAttempt to set core $i - min: ${min_freqs[$i]}${min_freq_units[$i]} - max: ${max_freq}${max_freq_units}\e[0m "
sudo cpupower -c $i frequency-set -d ${min_freqs[$i]}${min_freq_units[$i]} -u ${max_freq}${max_freq_units}
done
echo
notify_message="Minus giga core limits successfully set.\n"
fi
}
function check_and_set_half_limits {
if [[ "$1" == "half" ]]; then
echo "Setting half of maximum cpu limits ..."
for ((i = 0; i < $num_cores; i++)); do
max_freq=$(convert_to_mhz ${max_freqs[$i]} ${max_freq_units[$i]})
max_freq=$((max_freq / 2))
max_freq_units="MHz"
echo -e -n "\e[33mAttempt to set core $i - min: ${min_freqs[$i]}${min_freq_units[$i]} - max: ${max_freq}${max_freq_units}\e[0m "
sudo cpupower -c $i frequency-set -d ${min_freqs[$i]}${min_freq_units[$i]} -u ${max_freq}${max_freq_units}
done
echo
notify_message="Half core limits successfully set.\n"
fi
}
function check_and_set_min_limits {
if [[ "$1" == "min" ]]; then
echo "Setting minimal cpu limits ..."
for ((i = 0; i < $num_cores; i++)); do
echo -e -n "\e[33mAttempt to set core $i - min: ${min_freqs[$i]}${min_freq_units[$i]} - min: ${min_freqs[$i]}${min_freq_units[$i]}\e[0m "
sudo cpupower -c $i frequency-set -d ${min_freqs[$i]}${min_freq_units[$i]} -u ${min_freqs[$i]}${min_freq_units[$i]}
done
echo
notify_message="Minimal core limits successfully set.\n"
fi
}
function check_and_set_custom_limits {
# # params $2 - max frequency, $3 - unit
if [[ "$1" == "custom" ]]; then
echo "Setting custom cpu limits ..."
if [[ -z "$2" || -z "$3" ]]; then
echo -e "\e[31mMissing second or third param for max frequency and its unit.\e[0m"
echo -e "\e[31mExample: ./powermaster.sh custom_power_saver 1.6 Ghz\e[0m - space char required between freq number and unit!"
echo -e "\e[31mExample: ./powermaster.sh custom_power_saver 1600 Mhz\e[0m - space char required between freq number and unit!"
echo -e "\e[31mSettings Aborted!\e[0m"
return
fi
for ((i = 0; i < $num_cores; i++)); do
echo -e -n "\e[33mAttempt to set core $i - min: ${min_freqs[$i]}${min_freq_units[$i]} - max: $2$3\e[0m "
sudo cpupower -c $i frequency-set -d ${min_freqs[$i]}${min_freq_units[$i]} -u $2$3
done
echo
notify_message="Cores limits to $notify_message $2 $3 $4 successfully set.\n"
fi
}
function get_governor {
echo
echo "Getting current cpu governors ..."
for ((i = 0; i < $num_cores; i++)); do
echo -e "\e[36mCore $i $(cat /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor)\e[0m"
done
echo
}
function check_and_set_governor {
#echo $1 $2 $3 $4 $5 $6
for ((i = 0; i < $#; i++)); do
if [[ "${!i}" == "--governor" ]]; then
next_arg_index=$((i + 1))
valid_governons=("powersave" "performance")
for index_governor in "${valid_governons[@]}"; do
if [[ "${!next_arg_index}" == "$index_governor" ]]; then
echo "Setting governors ..."
for ((i = 0; i < $num_cores; i++)); do
echo -n ${!next_arg_index} | sudo tee /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor >/dev/null
echo -e "\e[36mCore $i setting governor to ${!next_arg_index}\e[0m"
done
notify_message="$notify_message governor ${!next_arg_index}"
fi
done
fi
done
}
# -------------------------------------------------------------------------------------
# Main entry point
# -------------------------------------------------------------------------------------
# Check if cpupower package is installed
if ! dpkg -l | grep cpupower >/dev/null; then
echo -e "\e[31mcpupower package is not installed. Please install it first.\e[0m"
echo -e "\e[31mRun: sudo apt install cpupower\e[0m"
exit 1
fi
declare -a min_freqs
declare -a min_freq_units
declare -a max_freqs
declare -a max_freq_units
declare -a min_freqs_policy
declare -a min_freq_units_policy
declare -a max_freqs_policy
declare -a max_freq_units_policy
usage="powersaver.sh [options]\n\
--user-profile [ fire | work | relax | ooo | timeisgold ]\n\
--cpu-profile [ max | minusgiga | half | min | custom [max_freq] [Mhz|GHz] ]\n\
--governor [ powersave | performance ]"
if [ "$#" -eq 0 ] || [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
echo -e "$usage"
echo
echo -e "\e[31mNo arguments provided.\e[0m"
get_cpu_info
get_cpu_limits
get_cpu_policy
get_governor
exit 1
fi
future_argument=""
notify_message=""
# $1 - --user-profile
# $2 - fire | work | relax | ooo | timeisgold
if [[ "$1" == "--user-profile" || "$1" == "-up" ]]; then
valid_user_profiles=("fire" "work" "relax" "ooo" "timeisgold")
for index_user_profile in "${valid_user_profiles[@]}"; do
if [[ "$2" == "$index_user_profile" ]]; then
print_notify "PowerSaver" "Setting $2 profile."
# fire
if [[ "$2" == "fire" ]]; then
future_argument="--cpu-profile max --governor performance"
# work
elif [[ "$2" == "work" ]]; then
future_argument="--cpu-profile custom 3.8 Ghz --governor performance"
# relax
elif [[ "$2" == "relax" ]]; then
future_argument="--cpu-profile custom 3.0 Ghz --governor powersave"
# out of office
elif [[ "$2" == "ooo" ]]; then
future_argument="--cpu-profile custom 1.8 Ghz --governor powersave"
# time is gold
elif [[ "$2" == "timeisgold" ]]; then
future_argument="--cpu-profile min --governor powersave"
fi
fi
done
fi
# ReRun script with new whole_argument if --user-profile is set
if [[ "$future_argument" != "" ]]; then
bash $0 $future_argument
exit 0
fi
# Second instance of script
get_cpu_info
get_cpu_limits
# $1 - --cpu-profile
# $2 - max | minusgiga | half | min | custom
# $3 - max_freq
# $4 - Mhz | GHz
if [[ "$1" == "--cpu-profile" || "$1" == "-cp" ]]; then
valid_cpu_profiles=("max" "minusgiga" "half" "min" "custom")
for index_cpu_profile in "${valid_cpu_profiles[@]}"; do
if [[ "$2" == "$index_cpu_profile" ]]; then
check_and_set_max_limits $2
check_and_set_minusgiga_limits $2
check_and_set_half_limits $2
check_and_set_min_limits $2
check_and_set_custom_limits $2 $3 $4
get_cpu_policy
fi
done
fi
get_governor
check_and_set_governor $@
print_notify "PowerSaver" "$notify_message"