Skip to content

Commit b61de36

Browse files
committed
feat: support rule-based hwmon blacklist matching
1 parent 790e715 commit b61de36

3 files changed

Lines changed: 132 additions & 4 deletions

File tree

py_modules/fan.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import os
3+
import re
34
from typing import List
45

56
from conf_manager import confManager
@@ -26,6 +27,7 @@ def __init__(self):
2627
self.hwmon_curve_paths = [] # 风扇曲线写入路径
2728

2829
self.hwmon_black_list = [] # 风扇hwmon黑名单
30+
self.hwmon_black_list_rules = [] # 风扇hwmon黑名单规则
2931

3032
# EC配置变量
3133
self.is_ec_configured = False # 是否配置好风扇ec
@@ -122,6 +124,14 @@ def __parse_fan_configuration_HWMON(self, name_path_map):
122124
)
123125
else []
124126
)
127+
fc.hwmon_black_list_rules = (
128+
hwmon_config["black_list_rules"]
129+
if (
130+
"black_list_rules" in hwmon_config
131+
and hwmon_config["black_list_rules"] is not None
132+
)
133+
else []
134+
)
125135

126136
fan_pwm_write = hwmon_config["pwm_write"]
127137
pwm_write_max = fan_pwm_write["pwm_write_max"]
@@ -229,6 +239,75 @@ def __parse_fan_configuration_HWMON(self, name_path_map):
229239
except Exception:
230240
logger.error(f"获取风扇({hwmon_name})hwmon信息失败:", exc_info=True)
231241

242+
def __match_hwmon_black_list_value(self, target_value, rule_value, match_mode):
243+
def _match_string(single_rule_value: str):
244+
if match_mode == "contains":
245+
return single_rule_value in target_value
246+
if match_mode == "regex":
247+
try:
248+
return re.search(single_rule_value, target_value) is not None
249+
except re.error:
250+
logger.error(
251+
f"Invalid hwmon black_list_rules regex: {single_rule_value}",
252+
exc_info=True,
253+
)
254+
return False
255+
return target_value == single_rule_value
256+
257+
if isinstance(rule_value, str):
258+
return _match_string(rule_value)
259+
if isinstance(rule_value, list):
260+
return any(
261+
isinstance(single_rule_value, str)
262+
and _match_string(single_rule_value)
263+
for single_rule_value in rule_value
264+
)
265+
return False
266+
267+
def __is_hwmon_blacklisted(self, fan_config: FanConfig):
268+
if PRODUCT_NAME in fan_config.hwmon_black_list:
269+
logger.info(
270+
f"hwmon black_list matched: product_name={PRODUCT_NAME}, hwmon={fan_config.hwmon_name}"
271+
)
272+
return True
273+
274+
for rule in fan_config.hwmon_black_list_rules:
275+
if not isinstance(rule, dict):
276+
continue
277+
278+
match_mode = rule.get("match", "exact")
279+
if not isinstance(match_mode, str):
280+
match_mode = "exact"
281+
match_mode = match_mode.lower()
282+
if match_mode not in ("exact", "contains", "regex"):
283+
logger.error(
284+
f"Invalid hwmon black_list_rules match mode: {match_mode}, fallback to exact"
285+
)
286+
match_mode = "exact"
287+
288+
has_match_item = False
289+
is_matched = True
290+
291+
if "product_name" in rule:
292+
has_match_item = True
293+
is_matched = is_matched and self.__match_hwmon_black_list_value(
294+
PRODUCT_NAME, rule["product_name"], match_mode
295+
)
296+
297+
if "product_version" in rule:
298+
has_match_item = True
299+
is_matched = is_matched and self.__match_hwmon_black_list_value(
300+
PRODUCT_VERSION, rule["product_version"], match_mode
301+
)
302+
303+
if has_match_item and is_matched:
304+
logger.info(
305+
f"hwmon black_list_rules matched: product_name={PRODUCT_NAME}, product_version={PRODUCT_VERSION}, hwmon={fan_config.hwmon_name}, rule={rule}"
306+
)
307+
return True
308+
309+
return False
310+
232311
# 获取配置值,支持直接数值或按机型字典格式
233312
def __get_value_for_product(self, config_value, default=0):
234313
"""获取配置值,支持直接数值或按机型字典格式"""
@@ -361,9 +440,7 @@ def parse_fan_configuration(self):
361440

362441
# self.fan_config_list 筛选, 去除黑名单
363442
self.fan_config_list = list(
364-
filter(
365-
lambda x: PRODUCT_NAME not in x.hwmon_black_list, self.fan_config_list
366-
)
443+
filter(lambda x: not self.__is_hwmon_blacklisted(x), self.fan_config_list)
367444
)
368445
# self.fan_config_list = [
369446
# config

py_modules/fan_config/hwmon/gpdfan.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ fans:
55
- fan_name: Fan
66
pwm_mode: 0
77
black_list:
8-
- G1618-04
98
- G1618-05
109
# - G1617-01
10+
black_list_rules:
11+
- product_name: G1618-04
12+
product_version:
13+
- Version 1.0
1114

1215
pwm_enable:
1316
manual_value: 1

py_modules/fan_config/schema/hwmon.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
},
4444
"description": "黑名单, 匹配 /sys/devices/virtual/dmi/id/product_name. 不使用该配置"
4545
},
46+
"black_list_rules": {
47+
"type": "array",
48+
"items": {
49+
"$ref": "#/definitions/BlackListRule"
50+
},
51+
"description": "黑名单规则, 支持 product_name 和 product_version 的组合匹配"
52+
},
4653
"temp_mode": {
4754
"type": "number",
4855
"enum": [0, 1],
@@ -185,6 +192,47 @@
185192
}
186193
},
187194
"required": ["temp_write", "pwm_write"]
195+
},
196+
"BlackListRule": {
197+
"title": "BlackListRule",
198+
"type": "object",
199+
"additionalProperties": false,
200+
"properties": {
201+
"product_name": {
202+
"oneOf": [
203+
{
204+
"type": "string"
205+
},
206+
{
207+
"type": "array",
208+
"items": {
209+
"type": "string"
210+
}
211+
}
212+
],
213+
"description": "匹配 /sys/devices/virtual/dmi/id/product_name"
214+
},
215+
"product_version": {
216+
"oneOf": [
217+
{
218+
"type": "string"
219+
},
220+
{
221+
"type": "array",
222+
"items": {
223+
"type": "string"
224+
}
225+
}
226+
],
227+
"description": "匹配 /sys/devices/virtual/dmi/id/product_version"
228+
},
229+
"match": {
230+
"type": "string",
231+
"enum": ["exact", "contains", "regex"],
232+
"description": "匹配方式, 默认 exact"
233+
}
234+
},
235+
"required": []
188236
}
189237
}
190238
}

0 commit comments

Comments
 (0)