-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsnoris.py
More file actions
94 lines (76 loc) · 3.23 KB
/
snoris.py
File metadata and controls
94 lines (76 loc) · 3.23 KB
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
import json
import os
import time
import traceback
from math import degrees, floor
version = 1.0
def readInline(path: str) -> str:
content = ""
with open(path, "r") as f:
content = f.read()
return content
def writeInline(path: str, content: str) -> None:
with open(path, "w") as f:
f.write(str(content))
def highestRelativeTemp(config) -> int:
highest = 0
for sensor in config["temp_sensors"]:
current_temp = int(readInline(sensor["path"])) / 1000 # temps are in millidegrees
relative_temp = current_temp - sensor["baseline"]
if relative_temp > highest:
highest = relative_temp
return highest
def main():
print(f"Snoris Fan Controller Daemon v{version} 💤")
config = None
config_path = os.getenv("SNORIS_CONFIG_PATH")
print(f"Loading config from {config_path} (envvar SNORIS_CONFIG_PATH)")
with open(config_path, "r") as config_file:
config = json.load(config_file)
if config is None:
print("⛔️ Config not found! You MUST run snoris_setup first!")
exit(1)
settings = config["user_options"]
lowest_number_of_steps = 256 # how many different fan speeds are supported
for fan in config["fan_calibration"]:
if len(fan["pwm_to_rpm"]) < lowest_number_of_steps:
lowest_number_of_steps = len(fan["pwm_to_rpm"])
# Let's say our fan supports three speeds: 0, 150, and 255
# and degrees_til_max_fan is 40
# The step map should be:
# [ (5, 1), (40, -1) ]
# which means that 5 degrees above baseline, we will use medium speed
# then above 40 degrees we will use the maximum speed
step_map = []
if settings["degrees_til_max_fan"] > 5 and lowest_number_of_steps > 2:
degrees_above = 5
for i in range(1, lowest_number_of_steps - 1):
step_map.append((floor(degrees_above), i))
degrees_above += (settings["degrees_til_max_fan"] - 5) / (lowest_number_of_steps - 2)
step_map.append((settings["degrees_til_max_fan"], -1))
print("Fan \"curve\", each tuple is (temp above baseline, fan speed")
print(step_map)
current_setting = None
while True:
try:
time.sleep(1)
new_setting = None
highest_relative_temp = highestRelativeTemp(config)
if highest_relative_temp <= step_map[0][0]:
new_setting = 0
else:
for step in step_map:
if highest_relative_temp > step[0]:
new_setting = step[1]
# TODO: should also check fan RPM to make sure they are reaching targets and not dead
if current_setting is None or new_setting != current_setting:
current_setting = new_setting
print(f"🌡️ Temperature is {highest_relative_temp} above baseline. Changing fans to setting {current_setting} (remember, -1 = max speed)")
for fan in config["fan_calibration"]:
pwm_to_set = fan["pwm_to_rpm"][current_setting]["pwm"]
writeInline(fan["pwm_path"], pwm_to_set)
except Exception as e:
print(traceback.format_exc())
print("This may result in an overheat!")
if __name__ == "__main__":
main()