Skip to content

Commit 2b50f08

Browse files
committed
Implement fan set points
1 parent 1fc4b94 commit 2b50f08

File tree

6 files changed

+113
-30
lines changed

6 files changed

+113
-30
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description = "Yet Another Framework Interface"
88
readme = "README.md"
99
requires-python = ">=3.10"
1010
dependencies = [
11-
"cros_ec_python >= 0.2.0",
11+
"cros_ec_python >= 0.3.0",
1212
"PyGObject"
1313
]
1414
classifiers = [

python3-cros_ec_python.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
"sources": [
88
{
99
"type": "file",
10-
"url": "https://files.pythonhosted.org/packages/33/11/c23a7acaa333589921a2f524517eb719dfb72628153ae22fcdf2e9052ac6/cros_ec_python-0.2.0-py3-none-any.whl",
11-
"sha256": "d38e493fbcaf23bc4b613d1342a036cecc6506284afc74f37013a3eac85a01b9"
10+
"url": "https://files.pythonhosted.org/packages/6c/7a/10d978a02bbe37530490cfd14e0994c433dc29c81b3afcdbde453d512528/cros_ec_python-0.3.0-py3-none-any.whl",
11+
"sha256": "aeb14ebdbd60ec6d6a4b11df1482a295466da4a908a468d168efd4cc141e7e3d"
1212
}
1313
]
1414
}

yafi/thermals.py

Lines changed: 101 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@
2727
class ThermalsPage(Gtk.Box):
2828
__gtype_name__ = 'ThermalsPage'
2929

30+
first_run = True
31+
3032
fan_rpm = Gtk.Template.Child()
3133
fan_mode = Gtk.Template.Child()
3234
fan_set_rpm = Gtk.Template.Child()
3335
fan_set_percent = Gtk.Template.Child()
3436
fan_percent_scale = Gtk.Template.Child()
37+
fan_set_points = Gtk.Template.Child()
38+
set_points = []
39+
ec_set_points_supported = False
40+
ec_set_points = []
3541

3642
temperatures = Gtk.Template.Child()
3743
temp_items = []
@@ -40,24 +46,59 @@ def __init__(self, **kwargs):
4046
super().__init__(**kwargs)
4147

4248
def setup(self, app):
49+
# Temperature sensors
50+
while temp_child := self.temperatures.get_last_child():
51+
self.temperatures.remove(temp_child)
52+
self.temp_items.clear()
53+
54+
try:
55+
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
56+
except ec_exceptions.ECError as e:
57+
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
58+
# Generate some labels if the command is not supported
59+
ec_temp_sensors = {}
60+
temps = ec_commands.memmap.get_temps(app.cros_ec)
61+
for i, temp in enumerate(temps):
62+
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
63+
else:
64+
raise e
65+
66+
for key, value in ec_temp_sensors.items():
67+
off_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C")
68+
off_row.add_css_class("property")
69+
self.temperatures.append(off_row)
70+
self.temp_items.append(off_row)
71+
72+
self._update_thermals(app)
73+
4374
# Don't let the user change the fans if they can't get back to auto
4475
if ec_commands.general.get_cmd_versions(
4576
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_AUTO_FAN_CTRL
4677
):
78+
self.ec_set_points_supported = ec_commands.general.check_cmd_version(
79+
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_GET_THRESHOLD, 1
80+
) and ec_commands.general.check_cmd_version(
81+
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_SET_THRESHOLD, 1
82+
)
4783

4884
def handle_fan_mode(mode):
4985
match mode:
5086
case 0: # Auto
5187
self.fan_set_rpm.set_visible(False)
5288
self.fan_set_percent.set_visible(False)
5389
ec_commands.thermal.thermal_auto_fan_ctrl(app.cros_ec)
90+
self.fan_set_points.set_visible(self.ec_set_points_supported)
5491
case 1: # Percent
92+
self.fan_set_points.set_visible(False)
5593
self.fan_set_rpm.set_visible(False)
5694
self.fan_set_percent.set_visible(True)
5795
case 2: # RPM
96+
self.fan_set_points.set_visible(False)
5897
self.fan_set_rpm.set_visible(True)
5998
self.fan_set_percent.set_visible(False)
6099

100+
handle_fan_mode(self.fan_mode.get_selected())
101+
61102
self.fan_mode.connect(
62103
"notify::selected",
63104
lambda combo, _: handle_fan_mode(combo.get_selected()),
@@ -81,41 +122,77 @@ def handle_fan_percent(scale):
81122
):
82123

83124
def handle_fan_rpm(entry):
84-
rpm = int(entry.get_text())
125+
rpm = int(entry.get_value())
85126
ec_commands.pwm.pwm_set_fan_rpm(app.cros_ec, rpm)
86127

87128
self.fan_set_rpm.connect(
88-
"notify::text", lambda entry, _: handle_fan_rpm(entry)
129+
"notify::value", lambda entry, _: handle_fan_rpm(entry)
89130
)
90131
else:
91132
self.fan_set_rpm.set_sensitive(False)
92133
else:
93134
self.fan_mode.set_sensitive(False)
94135

95-
# Temperature sensors
96-
while temp_child := self.temperatures.get_last_child():
97-
self.temperatures.remove(temp_child)
98-
self.temp_items.clear()
99-
100-
try:
101-
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
102-
except ec_exceptions.ECError as e:
103-
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
104-
# Generate some labels if the command is not supported
105-
ec_temp_sensors = {}
106-
temps = ec_commands.memmap.get_temps(app.cros_ec)
107-
for i, temp in enumerate(temps):
108-
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
109-
else:
110-
raise e
136+
# Set points
137+
if self.ec_set_points_supported and self.first_run:
138+
def handle_set_point(entry, key):
139+
index = entry.ec_index
140+
temp = int(entry.get_value())
141+
# Don't allow an off temp higher than max temp and vice versa
142+
match key:
143+
case "temp_fan_off":
144+
if temp > self.ec_set_points[index]["temp_fan_max"]:
145+
entry.set_value(self.ec_set_points[index]["temp_fan_off"])
146+
return
147+
case "temp_fan_max":
148+
if temp < self.ec_set_points[index]["temp_fan_off"]:
149+
entry.set_value(self.ec_set_points[index]["temp_fan_max"])
150+
return
151+
self.ec_set_points[entry.ec_index][key] = temp
152+
ec_commands.thermal.thermal_set_thresholds(
153+
app.cros_ec, index,
154+
self.ec_set_points[index]
155+
)
111156

112-
for key, value in ec_temp_sensors.items():
113-
new_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C")
114-
new_row.add_css_class("property")
115-
self.temperatures.append(new_row)
116-
self.temp_items.append(new_row)
157+
for i, sensor in enumerate(ec_temp_sensors):
158+
ec_set_point = ec_commands.thermal.thermal_get_thresholds(app.cros_ec, i)
159+
self.ec_set_points.append(ec_set_point)
160+
off_row = Adw.SpinRow(
161+
title=f"Fan On - {sensor}",
162+
subtitle=f"Turn fan on when above temp (°C)",
163+
)
164+
off_row.ec_index = i
165+
# 0K to 65535K for 16bit unsigned range
166+
# Actually the EC takes 32bits, but let's keep it like this for sanity
167+
off_row.set_adjustment(Gtk.Adjustment(
168+
lower=-273,
169+
upper=65_262,
170+
page_increment=10,
171+
step_increment=1,
172+
value=ec_set_point["temp_fan_off"],
173+
))
174+
off_row.connect(
175+
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_off")
176+
)
177+
max_row = Adw.SpinRow(
178+
title=f"Fan Max - {sensor}",
179+
subtitle=f"Max fan speed when above temp (°C)",
180+
)
181+
max_row.ec_index = i
182+
max_row.set_adjustment(Gtk.Adjustment(
183+
lower=-273,
184+
upper=65_262,
185+
page_increment=10,
186+
step_increment=1,
187+
value=ec_set_point["temp_fan_max"],
188+
))
189+
max_row.connect(
190+
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_max")
191+
)
192+
self.fan_set_points.add_row(off_row)
193+
self.fan_set_points.add_row(max_row)
117194

118-
self._update_thermals(app)
195+
self.first_run = False
119196

120197
# Schedule _update_thermals to run every second
121198
GLib.timeout_add_seconds(1, self._update_thermals, app)

yafi/ui/thermals.ui

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version='1.0' encoding='UTF-8'?>
2-
<!-- Created with Cambalache 0.96.1 -->
2+
<!-- Created with Cambalache 0.96.3 -->
33
<interface>
44
<!-- interface-name thermals.ui -->
55
<!-- interface-description The Thermals page for YAFI -->
@@ -92,6 +92,12 @@
9292
<property name="visible">False</property>
9393
</object>
9494
</child>
95+
<child>
96+
<object class="AdwExpanderRow" id="fan_set_points">
97+
<property name="selectable">False</property>
98+
<property name="title">Fan Set Points</property>
99+
</object>
100+
</child>
95101
<style>
96102
<class name="boxed-list"/>
97103
</style>

yafi/ui/yafi.cmb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
22
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
3-
<!-- Created with Cambalache 0.96.1 -->
3+
<!-- Created with Cambalache 0.96.3 -->
44
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
55
<ui template-class="YafiWindow" filename="yafi.ui" sha256="9d1b2f030e4a816eb0b1aa53ae1d80c5b50a2f4646e32c7a64803eb6f6ed3947"/>
6-
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="e301e65649005315ff60d250b60a47f6250ad6feb27db104051fcf0143cde173"/>
6+
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="89f5b68da04abad587d8b949d18357cd956313680e663b10e5d42697f9bfbf6e"/>
77
<ui template-class="LedsPage" filename="leds.ui" sha256="abc3ee759974a5c92feb48cc258dbe7271d0402facf71fd5e779f2bb1a277e16"/>
88
<ui template-class="BatteryLimiterPage" filename="battery-limiter.ui" sha256="b5d41b19cb1fb7ca5b4bcfae43244e54111f5e8d8c51d95448d6a92b5185d2c4"/>
99
<ui template-class="HardwarePage" filename="hardware.ui" sha256="37ea282198d9f60435f80e4adf8256cd2249e590dcad4b63af634d828673f1bf"/>

yafi/yafi.gresource

168 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)