From 8bf8d60f081c85cbfbfc6993c2630c9044c441ea Mon Sep 17 00:00:00 2001 From: Gawah <1026892284@qq.com> Date: Thu, 14 Dec 2023 23:16:23 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E9=A3=8E=E6=89=87=E7=9A=84?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=B9=E5=BC=8F=E4=BB=A5=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=A4=9A=E9=A3=8E=E6=89=87=E5=92=8Crogally=202.=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=89=8D=E7=AB=AF=E4=BB=A3=E7=A0=81=E9=80=82=E9=85=8D?= =?UTF-8?q?=E5=A4=9A=E9=A3=8E=E6=89=87=203.=E5=9C=A8=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=99=90=E5=88=B6=E6=8E=A7=E5=88=B6=E5=92=8C=E8=BD=AC=E9=80=9F?= =?UTF-8?q?=E7=9A=84=E5=86=99=E5=85=A5=E9=A1=BA=E5=BA=8F=EF=BC=8C=E5=85=88?= =?UTF-8?q?=E5=86=99=E5=85=A5=E8=BD=AC=E9=80=9F=E5=86=8D=E5=86=99=E5=85=A5?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E3=80=82=204.=E5=BD=93=E8=BD=AC=E9=80=9F?= =?UTF-8?q?=E5=8F=98=E5=8C=96=E8=B6=85=E8=BF=873%=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E6=89=8D=E8=AE=BE=E7=BD=AE=E4=B8=80=E6=AC=A1=E8=BD=AC=E9=80=9F?= =?UTF-8?q?=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E6=AF=8F=E7=A7=92=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E4=B8=80=E6=AC=A1=EF=BC=8C=E5=87=8F=E5=B0=91=E9=A3=8E?= =?UTF-8?q?=E6=89=87=E7=9A=84=E5=86=99=E5=85=A5=E6=AC=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/config.py | 416 ++++++++++++++++++----------- backend/fan.py | 592 ++++++++++++++++++++++++++--------------- backend/sysInfo.py | 30 +-- main.py | 40 ++- src/components/fan.tsx | 136 +++++----- src/util/backend.ts | 154 +++++++---- src/util/pluginMain.ts | 166 +++++++----- src/util/settings.ts | 59 ++-- 8 files changed, 963 insertions(+), 630 deletions(-) diff --git a/backend/config.py b/backend/config.py index b57e237..fb02337 100755 --- a/backend/config.py +++ b/backend/config.py @@ -2,24 +2,21 @@ import subprocess import glob import os -from helpers import get_homebrew_path,get_home_path,get_user +from helpers import get_homebrew_path +from enum import Enum #日志配置 -try: - LOG_LOCATION = "/tmp/PowerControl_py.log" - logging.basicConfig( - level = logging.INFO, - filename = LOG_LOCATION, - format="[%(asctime)s | %(filename)s:%(lineno)s:%(funcName)s] %(levelname)s: %(message)s", - filemode = 'w', - force = True) -except Exception as e: - logging.error(f"日志配置异常|{e}") +LOG_LOCATION = "/tmp/PowerControl_py.log" +logging.basicConfig( + level = logging.INFO, + filename = LOG_LOCATION, + format="[%(asctime)s | %(filename)s:%(lineno)s:%(funcName)s] %(levelname)s: %(message)s", + filemode = 'w', + force = True) #路径配置 try: - HOMEBREW_PATH = get_homebrew_path() - logging.info(f"HOMEBREW_PATH: {HOMEBREW_PATH}") + HOMEBREW_PATH = get_homebrew_path() SH_PATH="{}/plugins/PowerControl/backend/sh_tools.sh".format(HOMEBREW_PATH) RYZENADJ_PATH="{}/plugins/PowerControl/bin/ryzenadj".format(HOMEBREW_PATH) GPU_DEVICE_PATH = glob.glob("/sys/class/drm/card?/device")[0] @@ -79,189 +76,298 @@ #风扇配置 try: - + ''' + #风扇hwmon配置示范 + "hwmon目录下name文件内容":[{ + "fan_name":"Fan", #显示在风扇中的名字 + "pwm_mode":0, #写入的模式 0.普通模式(对单个文件写入) 1.rog掌机特殊模式(对多个文件写入同样的数值) + "pwm_enable":{ + "manual_value": 1, #手动控制时写入的数值 + "auto_value": 0, #自动控制时写入的数值 + "pwm_enable_path":"pwm1_enable" #写入数值的文件路径(数值模式) + }, + "pwm_write":{ + "pwm_write_max":100, #写入转速最大值 + "pwm_write_path":"pwm1", #写入转速路径 + "pwm_mode1_write_path":[ + {"pwm_write":"xxxxxxxxxx","temp_write":"xxxxxxxx"}, #写入转速和温度的文件名 + {"pwm_write":"xxxxxxxxx","temp_write":"xxxxxxxx"} + ..... + ] #模式1写入转速曲线的路径 + "pwm_mode1_default_value":[ + {"pwm_write_value":"3","temp_write_value":"39"}, + {"pwm_write_value":"3","temp_write_value":"40"} + ] #模式1处于auto时写入的值 + }, + "pwm_input":{ + "hwmon_label":"oxpec", #读转速的hwmon标签(读取转速和写入转速可能不在同一个hwmon) + "pwm_read_path":"fan1_input" #读取转速的文件名 + } + "temp_mode":0 #温度使用哪个数据 0.cpu温度(不可用时切换到gpu温度) 1.gpu温度(不可用时切换到cpu温度) + },{第二个风扇..},{.....} + ], + ''' #风扇驱动配置 FAN_HWMON_LIST={ - "oxpec":{ - "pwm_enable":"pwm1_enable", - "pwm":"pwm1", - "fan_input":"fan1_input" - }, - "asus_custom_fan_curve":{ - "manual_value": 1, - "auto_value": 2, - "pwm_enable_list":["pwm1_enable","pwm2_enable"], - "temp_first_list":["pwm1_auto_point1_temp","pwm2_auto_point1_temp"], - "pwm_list":[ - "pwm1_auto_point1_pwm", - "pwm1_auto_point2_pwm", - "pwm1_auto_point3_pwm", - "pwm1_auto_point4_pwm", - "pwm1_auto_point5_pwm", - "pwm1_auto_point6_pwm", - "pwm1_auto_point7_pwm", - "pwm1_auto_point8_pwm", - "pwm2_auto_point1_pwm", - "pwm2_auto_point2_pwm", - "pwm2_auto_point3_pwm", - "pwm2_auto_point4_pwm", - "pwm2_auto_point5_pwm", - "pwm2_auto_point6_pwm", - "pwm2_auto_point7_pwm", - "pwm2_auto_point8_pwm" + "oxpec":[{ + "fan_name":"Fan", + "pwm_mode":0, + "pwm_enable":{ + "manual_value": 1, + "auto_value": 0, + "pwm_enable_path":"pwm1_enable" + }, + "pwm_write":{ + "pwm_write_max":100, + "pwm_write_path":"pwm1" + }, + "pwm_input":{ + "hwmon_label":"oxpec", + "pwm_read_path":"fan1_input" + }, + "temp_mode":0 + }], + + "asus_custom_fan_curve":[{ + "fan_name":"CPU Fan", + "pwm_mode":1, + "pwm_enable":{ + "manual_value": 1, + "auto_value": 2, + "pwm_enable_path":"pwm1_enable" + }, + "pwm_write":{ + "pwm_write_max":255, + "pwm_mode1_write_path":[ + {"pwm_write":"pwm1_auto_point1_pwm","temp_write":"pwm1_auto_point1_temp"}, + {"pwm_write":"pwm1_auto_point2_pwm","temp_write":"pwm1_auto_point2_temp"}, + {"pwm_write":"pwm1_auto_point3_pwm","temp_write":"pwm1_auto_point3_temp"}, + {"pwm_write":"pwm1_auto_point4_pwm","temp_write":"pwm1_auto_point4_temp"}, + {"pwm_write":"pwm1_auto_point5_pwm","temp_write":"pwm1_auto_point5_temp"}, + {"pwm_write":"pwm1_auto_point6_pwm","temp_write":"pwm1_auto_point6_temp"}, + {"pwm_write":"pwm1_auto_point7_pwm","temp_write":"pwm1_auto_point7_temp"}, + {"pwm_write":"pwm1_auto_point1_pwm","temp_write":"pwm1_auto_point8_temp"} ], - "fan_input":"../hwmon6/fan1_input" - }, - "steamdeck_hwmon":{ - "pwm_enable":"fan1_target", - "pwm":"fan1_target", - "fan_input":"fan1_input" - }} + "pwm_mode1_auto_value":[ + {"pwm_write_value":3,"temp_write_value":39}, + {"pwm_write_value":3,"temp_write_value":40}, + {"pwm_write_value":3,"temp_write_value":50}, + {"pwm_write_value":3,"temp_write_value":60}, + {"pwm_write_value":10,"temp_write_value":70}, + {"pwm_write_value":38,"temp_write_value":80}, + {"pwm_write_value":77,"temp_write_value":90}, + {"pwm_write_value":115,"temp_write_value":100} + ] + }, + "pwm_input":{ + "hwmon_label":"asus", + "pwm_read_path":"fan1_input", + "pwm_read_max":8200 + }, + "temp_mode":0 + },{ + "fan_name":"GPU Fan", + "pwm_mode":1, + "pwm_enable":{ + "manual_value": 1, + "auto_value": 2, + "pwm_enable_path":"pwm2_enable" + }, + "pwm_write":{ + "pwm_write_max":255, + "pwm_mode1_write_path":[ + {"pwm_write":"pwm2_auto_point1_pwm","temp_write":"pwm2_auto_point1_temp"}, + {"pwm_write":"pwm2_auto_point2_pwm","temp_write":"pwm2_auto_point2_temp"}, + {"pwm_write":"pwm2_auto_point3_pwm","temp_write":"pwm2_auto_point3_temp"}, + {"pwm_write":"pwm2_auto_point4_pwm","temp_write":"pwm2_auto_point4_temp"}, + {"pwm_write":"pwm2_auto_point5_pwm","temp_write":"pwm2_auto_point5_temp"}, + {"pwm_write":"pwm2_auto_point6_pwm","temp_write":"pwm2_auto_point6_temp"}, + {"pwm_write":"pwm2_auto_point7_pwm","temp_write":"pwm2_auto_point7_temp"}, + {"pwm_write":"pwm2_auto_point1_pwm","temp_write":"pwm2_auto_point8_temp"} + ], + "pwm_mode1_auto_value":[ + {"pwm_write_value":3,"temp_write_value":39}, + {"pwm_write_value":3,"temp_write_value":40}, + {"pwm_write_value":3,"temp_write_value":50}, + {"pwm_write_value":3,"temp_write_value":60}, + {"pwm_write_value":10,"temp_write_value":70}, + {"pwm_write_value":38,"temp_write_value":80}, + {"pwm_write_value":77,"temp_write_value":90}, + {"pwm_write_value":115,"temp_write_value":100} + ] + }, + "pwm_input":{ + "hwmon_label":"asus", + "pwm_read_path":"fan2_input", + "pwm_read_max":8200 + }, + "temp_mode":0 + }], - #风扇ec配置 - FAN_MANUAL_OFFSET=0 #风扇自动控制ec地址 - FAN_RPMWRITE_OFFSET=0 #风扇写入转速ec地址 - FAN_RPMREAD_OFFSET=0 #风扇读取转速ec地址 - FAN_RAM_REG_ADDR=0 #风扇ecRam寄存器地址 - FAN_RAM_REG_DATA=0 #风扇ecRam寄存器数据 - FAN_RAM_MANUAL_OFFSET=0 #风扇自动控制ecRam地址 - FAN_RAM_RPMWRITE_OFFSET=0 #风扇写入转速ecRam地址 - FAN_RAM_RPMREAD_OFFSET=0 #风扇读取转速ecRam地址 - FAN_RAM_RPMREAD_LENGTH=0 #风扇实际转速值长度 0为需要通过计算获得转速 - FAN_IS_ADAPTED=False #风扇是否适配 + "steamdeck_hwmon":[{ + "fan_name":"Fan", + "pwm_mode":0, #0.写入数值 1.写入曲线 + "pwm_enable":{ + "manual_value": 1, #手动控制写入的数值 + "auto_value": 0, #自动控制写入的数值 + "pwm_enable_path":"fan1_target" #写入数值的文件路径 + }, + "pwm_write":{ + "pwm_write_max":7300, + "pwm_write_path":"fan1_target" + }, + "pwm_input":{ + "hwmon_label":"steamdeck_hwmon", + "pwm_read_path":"fan1_input", + "pwm_read_max":7309 + }, + "temp_mode":0 + }] + } + ''' + #风扇ec配置示范 + if PRODUCT_NAME in ( + "ONEXPLAYER 2 ARP23", #/sys/devices/virtual/dmi/id/product_name 内容 + ): + FAN_EC_CONFIG=[{ + "FAN_MANUAL_OFFSET":0x4a, #风扇自动控制ec地址 + "FAN_RPMWRITE_OFFSET":0x4b, #风扇写入转速ec地址 + "FAN_RPMREAD_OFFSET":0x58, #风扇读取转速ec地址 + + "FAN_RAM_REG_ADDR":0x4E, #风扇ecRam寄存器地址 + "FAN_RAM_REG_DATA":0x4F, #风扇ecRam寄存器数据 + "FAN_RAM_MANUAL_OFFSET":0x44a, #风扇自动控制ecRam地址 + "FAN_RAM_RPMWRITE_OFFSET":0x44b, #风扇写入转速ecRam地址 + "FAN_RAM_RPMREAD_OFFSET":0x1809, #风扇读取转速ecRam地址 + "FAN_RAM_RPMREAD_LENGTH":0, #风扇实际转速值长度 0为需要通过计算获得转速 + + "FAN_RPMWRITE_MAX":184, #风扇最大转速ec写入值 + "FAN_RPMVALUE_MAX":5000 #风扇最大转速数值 + },{第二个风扇},{....}] + + ''' + #风扇ec配置 + FAN_EC_CONFIG=[] - #FAN_MAXTEMP=0 #风扇图表最大温度 - #FAN_MINTEMP=0 #风扇图表最小温度 - #FAN_MAXRPM_PERCENT=0 #风扇图表最大转速百分比 - #FAN_MINRPM_PERCENT=0 #风扇图表最小转速百分比 - FAN_RPMWRITE_MAX=0 #风扇最大转速ec写入值 - FAN_RPMVALUE_MAX=0 #风扇最大转速数值 - FAN_CPUTEMP_PATH="" #CPU温度路径 - FAN_GPUTEMP_PATH="" #GPU温度路径 - if PRODUCT_NAME in ( "ONEXPLAYER 2 ARP23", ): - FAN_MANUAL_OFFSET=0x4a - FAN_RPMWRITE_OFFSET=0x4b - FAN_RPMREAD_OFFSET=0x58 + FAN_EC_CONFIG=[{ + "FAN_MANUAL_OFFSET":0x4a, + "FAN_RPMWRITE_OFFSET":0x4b, + "FAN_RPMREAD_OFFSET":0x58, - FAN_RAM_REG_ADDR=0x4E - FAN_RAM_REG_DATA=0x4F - FAN_RAM_MANUAL_OFFSET=0x44a - FAN_RAM_RPMWRITE_OFFSET=0x44b - FAN_RAM_RPMREAD_OFFSET=0x1809 - FAN_RAM_RPMREAD_LENGTH=0 + "FAN_RAM_REG_ADDR":0x4E, + "FAN_RAM_REG_DATA":0x4F, + "FAN_RAM_MANUAL_OFFSET":0x44a, + "FAN_RAM_RPMWRITE_OFFSET":0x44b, + "FAN_RAM_RPMREAD_OFFSET":0x1809, + "FAN_RAM_RPMREAD_LENGTH":0, - FAN_RPMWRITE_MAX=184 - FAN_RPMVALUE_MAX=5000 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":184, + "FAN_RPMVALUE_MAX":5000 + }] elif PRODUCT_NAME in ( "AIR", "AIR Pro", ): - FAN_MANUAL_OFFSET=0x4a - FAN_RPMWRITE_OFFSET=0x4b - FAN_RPMREAD_OFFSET=0x76 + FAN_EC_CONFIG=[{ + "FAN_MANUAL_OFFSET":0x4a, + "FAN_RPMWRITE_OFFSET":0x4b, + "FAN_RPMREAD_OFFSET":0x76, - FAN_RAM_REG_ADDR=0x4E - FAN_RAM_REG_DATA=0x4F - FAN_RAM_MANUAL_OFFSET=0x44a - FAN_RAM_RPMWRITE_OFFSET=0x44b - FAN_RAM_RPMREAD_OFFSET=0x1809 - FAN_RAM_RPMREAD_LENGTH=0 + "FAN_RAM_REG_ADDR":0x4E, + "FAN_RAM_REG_DATA":0x4F, + "FAN_RAM_MANUAL_OFFSET":0x44a, + "FAN_RAM_RPMWRITE_OFFSET":0x44b, + "FAN_RAM_RPMREAD_OFFSET":0x1809, + "FAN_RAM_RPMREAD_LENGTH":0, - FAN_RPMWRITE_MAX=255 - FAN_RPMVALUE_MAX=5811 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":255, + "FAN_RPMVALUE_MAX":5811 + }] elif PRODUCT_NAME in ( "AYANEO 2", "AYANEO 2S", "GEEK", "GEEK 1S", ): - FAN_MANUAL_OFFSET=0x4a - FAN_RPMWRITE_OFFSET=0x4b - FAN_RPMREAD_OFFSET=0x76 + FAN_EC_CONFIG=[{ + "FAN_MANUAL_OFFSET":0x4a, + "FAN_RPMWRITE_OFFSET":0x4b, + "FAN_RPMREAD_OFFSET":0x76, - FAN_RAM_REG_ADDR=0x4E - FAN_RAM_REG_DATA=0x4F - FAN_RAM_MANUAL_OFFSET=0x44a - FAN_RAM_RPMWRITE_OFFSET=0x44b - FAN_RAM_RPMREAD_OFFSET=0x1809 - FAN_RAM_RPMREAD_LENGTH=0 + "FAN_RAM_REG_ADDR":0x4E, + "FAN_RAM_REG_DATA":0x4F, + "FAN_RAM_MANUAL_OFFSET":0x44a, + "FAN_RAM_RPMWRITE_OFFSET":0x44b, + "FAN_RAM_RPMREAD_OFFSET":0x1809, + "FAN_RAM_RPMREAD_LENGTH":0, - FAN_RPMWRITE_MAX=200 - FAN_RPMVALUE_MAX=5530 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":200, + "FAN_RPMVALUE_MAX":5530 + }] elif PRODUCT_NAME in ( "ONEXPLAYER Mini Pro", "AOKZOE A1 AR07", ): - FAN_MANUAL_OFFSET=0x4a - FAN_RPMWRITE_OFFSET=0x4b - FAN_RPMREAD_OFFSET=0x76 + FAN_EC_CONFIG=[{ + "FAN_MANUAL_OFFSET":0x4a, + "FAN_RPMWRITE_OFFSET":0x4b, + "FAN_RPMREAD_OFFSET":0x76, - FAN_RAM_REG_ADDR=0x4E - FAN_RAM_REG_DATA=0x4F - FAN_RAM_MANUAL_OFFSET=0x44a - FAN_RAM_RPMWRITE_OFFSET=0x44b - FAN_RAM_RPMREAD_OFFSET=0x1809 - FAN_RAM_RPMREAD_LENGTH=0 + "FAN_RAM_REG_ADDR":0x4E, + "FAN_RAM_REG_DATA":0x4F, + "FAN_RAM_MANUAL_OFFSET":0x44a, + "FAN_RAM_RPMWRITE_OFFSET":0x44b, + "FAN_RAM_RPMREAD_OFFSET":0x1809, + "FAN_RAM_RPMREAD_LENGTH":0, - FAN_RPMWRITE_MAX=255 - FAN_RPMVALUE_MAX=4968 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":255, + "FAN_RPMVALUE_MAX":4968 + }] elif PRODUCT_NAME in ( "G1618-04", ): - FAN_RAM_REG_ADDR=0x2E - FAN_RAM_REG_DATA=0x2F - FAN_RAM_MANUAL_OFFSET=0xC311 - FAN_RAM_RPMWRITE_OFFSET=0xC311 - FAN_RAM_RPMREAD_OFFSET=0x880 - FAN_RAM_RPMREAD_LENGTH=2 + FAN_EC_CONFIG=[{ + "FAN_RAM_REG_ADDR":0x2E, + "FAN_RAM_REG_DATA":0x2F, + "FAN_RAM_MANUAL_OFFSET":0xC311, + "FAN_RAM_RPMWRITE_OFFSET":0xC311, + "FAN_RAM_RPMREAD_OFFSET":0x880, + "FAN_RAM_RPMREAD_LENGTH":2, - FAN_RPMWRITE_MAX=127 - FAN_RPMVALUE_MAX=4968 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":127, + "FAN_RPMVALUE_MAX":4968 + }] elif PRODUCT_NAME in ( "G1619-04", ): - FAN_RAM_REG_ADDR=0x4E - FAN_RAM_REG_DATA=0x4F - FAN_RAM_MANUAL_OFFSET=0x275 - FAN_RAM_RPMWRITE_OFFSET=0x1809 - FAN_RAM_RPMREAD_OFFSET=0x218 - FAN_RAM_RPMREAD_LENGTH=2 + FAN_EC_CONFIG=[{ + "FAN_RAM_REG_ADDR":0x4E, + "FAN_RAM_REG_DATA":0x4F, + "FAN_RAM_MANUAL_OFFSET":0x275, + "FAN_RAM_RPMWRITE_OFFSET":0x1809, + "FAN_RAM_RPMREAD_OFFSET":0x218, + "FAN_RAM_RPMREAD_LENGTH":2, - FAN_RPMWRITE_MAX=184 - FAN_RPMVALUE_MAX=4968 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":184, + "FAN_RPMVALUE_MAX":4968 + }] elif PRODUCT_NAME in ( "G1617-01", ): - FAN_RAM_REG_ADDR=0x4E - FAN_RAM_REG_DATA=0x4F - FAN_RAM_MANUAL_OFFSET=0x47A - FAN_RAM_RPMWRITE_OFFSET=0x47A - FAN_RAM_RPMREAD_OFFSET=0x478 - FAN_RAM_RPMREAD_LENGTH=2 + FAN_EC_CONFIG=[{ + "FAN_RAM_REG_ADDR":0x4E, + "FAN_RAM_REG_DATA":0x4F, + "FAN_RAM_MANUAL_OFFSET":0x47A, + "FAN_RAM_RPMWRITE_OFFSET":0x47A, + "FAN_RAM_RPMREAD_OFFSET":0x478, + "FAN_RAM_RPMREAD_LENGTH":2, - FAN_RPMWRITE_MAX=244 - FAN_RPMVALUE_MAX=6500 - FAN_IS_ADAPTED=True - elif PRODUCT_NAME in ( - "Jupiter", - ): - FAN_RPMWRITE_MAX=7300 - FAN_RPMVALUE_MAX=7309 - FAN_IS_ADAPTED=True - elif PRODUCT_NAME in ( - "ROG Ally RC71L_RC71L", - ): - FAN_RPMWRITE_MAX=255 - FAN_RPMVALUE_MAX=8000 - FAN_IS_ADAPTED=True + "FAN_RPMWRITE_MAX":244, + "FAN_RPMVALUE_MAX":6500 + }] + except Exception as e: logging.error(f"风扇配置异常|{e}") diff --git a/backend/fan.py b/backend/fan.py index 538f498..2a16588 100755 --- a/backend/fan.py +++ b/backend/fan.py @@ -2,290 +2,464 @@ import os import time from ec import EC -from config import logging,SH_PATH,RYZENADJ_PATH,PRODUCT_NAME,FAN_IS_ADAPTED -from config import FAN_HWMON_LIST,FAN_MANUAL_OFFSET,FAN_RPMREAD_OFFSET,FAN_RPMWRITE_MAX,FAN_RPMWRITE_OFFSET,FAN_RPMVALUE_MAX -from config import FAN_RAM_REG_ADDR,FAN_RAM_REG_DATA,FAN_RAM_MANUAL_OFFSET,FAN_RAM_RPMWRITE_OFFSET,FAN_RAM_RPMREAD_OFFSET,FAN_RAM_RPMREAD_LENGTH +from config import logging,PRODUCT_NAME +from config import FAN_HWMON_LIST,FAN_EC_CONFIG -class FanManager (): + +class FanConfig (): def __init__(self): + #HWMON配置变量 self.FAN_ISFIND_HWMON=False #是否找到风扇hwmon - self.FAN_HWMON_NAME="" #风扇hwmon名字 - self.FAN_HWMON_PWMENABLE_PATH="" #风扇自动控制hwmon地址 - self.FAN_HWMON_PWM_PATH="" #风扇写入转速hwmon地址 - self.FAN_HWMON_INPUT_PATH="" #风扇读取转速hwmon地址 - self.FAN_HWMON_PWMENABLE_PATH_LIST=[] #风扇自动控制hwmon地址列表 - self.FAN_HWMON_PWM_PATH_LIST=[] #风扇写入转速hwmon地址列表 - self.FAN_HWMON_IS_MULTI_PWM=False #风扇是否有多个PWM - self.FAN_HWMON_MANUAL_VALUE=1 #风扇手动控制值 - self.FAN_HWMON_AUTO_VALUE=0 #风扇自动控制值 - self.FAN_HWMON_TEMP_FIRST_LIST=[] #风扇自动控制温度初始点列表 - hwmon_path="/sys/class/hwmon" - hwmon_files=os.listdir(hwmon_path) - for file in hwmon_files: - try: - path=hwmon_path+"/"+file - name = open(path+"/name").read().strip() - if(name=="amdgpu"): - temp=int(open(path+"/temp1_input").read().strip()) - FAN_GPUTEMP_PATH=path+"/temp1_input" - if(name=="k10temp"): - temp=int(open(path+"/temp1_input").read().strip()) - FAN_CPUTEMP_PATH=path+"/temp1_input" - if(name in FAN_HWMON_LIST): - self.FAN_HWMON_NAME=name - self.FAN_ISFIND_HWMON=True - pwm_enable_list=FAN_HWMON_LIST[name]["pwm_enable_list"] - pwm_list=FAN_HWMON_LIST[name]["pwm_list"] - temp_first_list=FAN_HWMON_LIST[name]["temp_first_list"] + self.FAN_NAME="FAN" #风扇在图表中显示的名字 + self.FAN_HWMON_NAME=None #风扇hwmon名字 + self.FAN_HWMON_MODE=0 #风扇模式 + self.FAN_HWMON_PWMENABLE_PATH=None #风扇自动控制hwmon地址 - self.FAN_HWMON_PRECENT_VALUE = FAN_HWMON_LIST[name]["percent_value"] if "percent_value" in FAN_HWMON_LIST[name] else False + self.FAN_ENABLE_MANUAL_VALUE = 1 #手动模式写到自动控制hwmon地址的数值 + self.FAN_ENABLE_AUTO_VALUE = 0 #自动模式写到自动控制hwmon地址的数值 + self.FAN_HWMON_PWM_PATH=None #风扇写入转速hwmon地址 + self.FAN_HWMON_MODE1_PWM_PATH=[] #风扇写入转速和对应温度hwmon地址列表(模式1) + self.FAN_HWMON_MODE1_AUTO_VALUE=[] #风扇写入转速和对应温度hwmon地址列表(模式1) - self.FAN_HWMON_MANUAL_VALUE = FAN_HWMON_LIST[name]["manual_value"] if "manual_value" in FAN_HWMON_LIST[name] else 1 - self.FAN_HWMON_AUTO_VALUE = FAN_HWMON_LIST[name]["auto_value"] if "auto_value" in FAN_HWMON_LIST[name] else 0 + self.FAN_HWMON_INPUT_PATH=None #风扇读取转速hwmon地址 - # for each temp_first_list item, check if it exists, if it does, add it to the list - for temp_first in temp_first_list: - temp_first_path = path+"/"+temp_first - if os.path.exists(temp_first_path): - logging.debug(f"找到风扇自动控制温度初始点 当前机型:{PRODUCT_NAME} hwmon地址:{temp_first_path}") - self.FAN_HWMON_TEMP_FIRST_LIST.append(temp_first_path) + #EC配置变量 + self.FAN_IS_EC_CONFIGURED=False #是否配置好风扇ec + self.FAN_MANUAL_OFFSET=None #风扇自动控制ec地址 + self.FAN_RPMWRITE_OFFSET=None #风扇写入转速ec地址 + self.FAN_RPMREAD_OFFSET=None #风扇读取转速ec地址 + #ECRAM配置变量 + self.FAN_RAM_REG_ADDR=None #风扇ecRam寄存器地址 + self.FAN_RAM_REG_DATA=None #风扇ecRam寄存器数据 + self.FAN_RAM_MANUAL_OFFSET=None #风扇自动控制ecRam地址 + self.FAN_RAM_RPMWRITE_OFFSET=None #风扇写入转速ecRam地址 + self.FAN_RAM_RPMREAD_OFFSET=None #风扇读取转速ecRam地址 + self.FAN_RAM_RPMREAD_LENGTH=0 #风扇实际转速值长度 0为需要通过计算获得转速 + #其他变量 + self.FAN_RPMWRITE_MAX=0 #风扇最大转速写入值 + self.FAN_RPMVALUE_MAX=0 #风扇最大转速读取数值 + self.TEMP_MODE=0 #使用cpu或者gpu温度 - # for each pwm_enable_list item, check if it exists, if it does, add it to the list - for pwm_enable in pwm_enable_list: - pwm_enable_path = path+"/"+pwm_enable - if os.path.exists(pwm_enable_path): - logging.debug(f"找到风扇自动控制hwmon 当前机型:{PRODUCT_NAME} hwmon地址:{pwm_enable_path}") - self.FAN_HWMON_PWMENABLE_PATH_LIST.append(pwm_enable_path) - # for each pwm_list item, check if it exists, if it does, add it to the list - for pwm in pwm_list: - pwm_path = path+"/"+pwm - if os.path.exists(pwm_path): - logging.debug(f"找到风扇写入转速hwmon 当前机型:{PRODUCT_NAME} hwmon地址:{pwm_path}") - self.FAN_HWMON_PWM_PATH_LIST.append(pwm_path) - if len(self.FAN_HWMON_PWM_PATH_LIST) > 1: - self.FAN_HWMON_IS_MULTI_PWM=True - - self.FAN_HWMON_PWMENABLE_PATH=path+"/"+FAN_HWMON_LIST[name]["pwm_enable"] if "pwm_enable" in FAN_HWMON_LIST[name] else "" - self.FAN_HWMON_PWM_PATH=path+"/"+FAN_HWMON_LIST[name]["pwm"] if "pwm" in FAN_HWMON_LIST[name] else "" - self.FAN_HWMON_INPUT_PATH=path+"/"+FAN_HWMON_LIST[name]["fan_input"] if "fan_input" in FAN_HWMON_LIST[name] else "" - logging.debug(f"FAN_HWMON_NAME={self.FAN_HWMON_NAME}") - logging.debug(f"FAN_ISFIND_HWMON={self.FAN_ISFIND_HWMON}") - logging.debug(f"FAN_HWMON_PWMENABLE_PATH={self.FAN_HWMON_PWMENABLE_PATH}") - logging.debug(f"FAN_HWMON_PWM_PATH={self.FAN_HWMON_PWM_PATH}") - logging.debug(f"FAN_HWMON_INPUT_PATH={self.FAN_HWMON_INPUT_PATH}") +class FanManager (): + def __init__(self): + self.fan_config_list=[] #记录每一个风扇的配置 + self.FAN_CPUTEMP_PATH="" #CPU温度路径 + self.FAN_GPUTEMP_PATH="" #GPU温度路径 + self.parse_fan_configuration() ##转化风扇配置 + self.device_init_quirks() #设备特殊初始化 + + #转化风扇配置 + def parse_fan_configuration(self): + hwmon_path="/sys/class/hwmon" + hwmon_files=os.listdir(hwmon_path) + name_path_map={} - except Exception as e: - logging.error(e) + #转化hwmon信息 + for file in hwmon_files: + path=hwmon_path+"/"+file + name = open(path+"/name").read().strip() + name_path_map[name]=path + if(name=="amdgpu"): + self.FAN_GPUTEMP_PATH=path+"/temp1_input" + if(name=="k10temp" or name == "acpitz"): + self.FAN_CPUTEMP_PATH=path+"/temp1_input" - if PRODUCT_NAME == "G1618-04": - # Initialize GPD WIN4 EC - ec_chip_id = EC.RamRead(FAN_RAM_REG_ADDR, FAN_RAM_REG_DATA, 0x2000) - if ec_chip_id == 0x55: - ec_chip_ver = EC.RamRead(FAN_RAM_REG_ADDR, FAN_RAM_REG_DATA, 0x1060) - ec_chip_ver |= 0x80 - EC.RamWrite(FAN_RAM_REG_ADDR, FAN_RAM_REG_DATA, 0x1060, ec_chip_ver) + for hwmon_name in FAN_HWMON_LIST: + if hwmon_name not in name_path_map: + continue + for hwmon_config in FAN_HWMON_LIST[hwmon_name]: + try: + fan_config = FanConfig() + fan_config.FAN_ISFIND_HWMON = True + fan_config.FAN_HWMON_NAME = hwmon_name + fan_config.FAN_NAME = hwmon_config["fan_name"] + fan_config.FAN_HWMON_MODE = hwmon_config["pwm_mode"] + + fan_pwm_enable = hwmon_config["pwm_enable"] + fan_config.FAN_ENABLE_MANUAL_VALUE = fan_pwm_enable["manual_value"] + fan_config.FAN_ENABLE_AUTO_VALUE = fan_pwm_enable["auto_value"] + fan_config.FAN_HWMON_PWMENABLE_PATH = name_path_map[hwmon_name]+"/"+fan_pwm_enable["pwm_enable_path"] + + fan_pwm_write = hwmon_config["pwm_write"] + fan_config.FAN_RPMWRITE_MAX = fan_pwm_write["pwm_write_max"] + if fan_config.FAN_HWMON_MODE == 0: + fan_config.FAN_HWMON_PWM_PATH = name_path_map[hwmon_name]+"/"+fan_pwm_write["pwm_write_path"] if "pwm_write_path" in fan_pwm_write and fan_pwm_write["pwm_write_path"] != "" else None + elif fan_config.FAN_HWMON_MODE == 1: + pwm_mode1_write_path = fan_pwm_write["pwm_mode1_write_path"] if "pwm_mode1_write_path" in fan_pwm_write else [] + for point in pwm_mode1_write_path: + point_info = {"pwm_write":name_path_map[hwmon_name]+"/"+point["pwm_write"],"temp_write":name_path_map[hwmon_name]+"/"+point["temp_write"]} + if os.path.exists(point_info["pwm_write"]) and os.path.exists(point_info["temp_write"]): + fan_config.FAN_HWMON_MODE1_PWM_PATH.append(point_info) + pwm_mode1_auto_value = fan_pwm_write["pwm_mode1_auto_value"] if "pwm_mode1_auto_value" in fan_pwm_write else [] + for value in pwm_mode1_auto_value: + value_info = {"pwm_write_value":value["pwm_write_value"],"temp_write_value":value["temp_write_value"]} + fan_config.FAN_HWMON_MODE1_AUTO_VALUE.append(value_info) + + fan_pwm_input = hwmon_config["pwm_input"] + fan_hwmon_label_input = fan_pwm_input["hwmon_label"] + fan_config.FAN_HWMON_INPUT_PATH = name_path_map[fan_hwmon_label_input]+"/"+fan_pwm_input["pwm_read_path"] + fan_config.FAN_RPMVALUE_MAX = fan_pwm_input["pwm_read_max"] + fan_config.TEMP_MODE = hwmon_config["temp_mode"] + self.fan_config_list.append(fan_config) + except: + logging.error(f"获取风扇({hwmon_name})hwmon信息失败:",exc_info=True) + + #转化ec信息 + for ec_info in FAN_EC_CONFIG: + try: + fan_config = FanConfig() + #EC配置变量 + fan_config.FAN_MANUAL_OFFSET = ec_info["FAN_MANUAL_OFFSET"] if "FAN_MANUAL_OFFSET" in ec_info else None #风扇自动控制ec地址 + fan_config.FAN_RPMWRITE_OFFSET = ec_info["FAN_RPMWRITE_OFFSET"] if "FAN_RPMWRITE_OFFSET" in ec_info else None #风扇写入转速ec地址 + fan_config.FAN_RPMREAD_OFFSET = ec_info["FAN_RPMREAD_OFFSET"] if "FAN_RPMREAD_OFFSET" in ec_info else None #风扇读取转速ec地址 + #ECRAM配置变量 + fan_config.FAN_RAM_REG_ADDR = ec_info["FAN_RAM_REG_ADDR"] if "FAN_RAM_REG_ADDR" in ec_info else None #风扇ecRam寄存器地址 + fan_config.FAN_RAM_REG_DATA = ec_info["FAN_RAM_REG_DATA"] if "FAN_RAM_REG_DATA" in ec_info else None #风扇ecRam寄存器数据 + fan_config.FAN_RAM_MANUAL_OFFSET = ec_info["FAN_RAM_MANUAL_OFFSET"] if "FAN_RAM_MANUAL_OFFSET" in ec_info else None #风扇自动控制ecRam地址 + fan_config.FAN_RAM_RPMWRITE_OFFSET = ec_info["FAN_RAM_RPMWRITE_OFFSET"] if "FAN_RAM_RPMWRITE_OFFSET" in ec_info else None #风扇写入转速ecRam地址 + fan_config.FAN_RAM_RPMREAD_OFFSET = ec_info["FAN_RAM_RPMREAD_OFFSET"] if "FAN_RAM_RPMREAD_OFFSET" in ec_info else None #风扇读取转速ecRam地址 + fan_config.FAN_RAM_RPMREAD_LENGTH = ec_info["FAN_RAM_RPMREAD_LENGTH"] if "FAN_RAM_RPMREAD_LENGTH" in ec_info else 0 #风扇实际转速值长度 0为需要通过计算获得转速 + #其他变量 + fan_config.FAN_RPMWRITE_MAX = ec_info["FAN_RPMWRITE_MAX"] if "FAN_RPMWRITE_MAX" in ec_info else 0 #风扇最大转速写入值 + fan_config.FAN_RPMVALUE_MAX = ec_info["FAN_RPMVALUE_MAX"] if "FAN_RPMVALUE_MAX" in ec_info else 0 #风扇最大转速读取数值 + fan_config.FAN_ENABLE_MANUAL_VALUE = 1 + fan_config.FAN_ENABLE_AUTO_VALUE = 0 + fan_config.TEMP_MODE = 0 + #判断是否配置好ec(控制地址、读和写至少各有一种方法,最大写入和最大读取必须有配置数值) + fan_config.FAN_IS_EC_CONFIGURED = (fan_config.FAN_MANUAL_OFFSET!=None or fan_config.FAN_RAM_MANUAL_OFFSET!=None)\ + and (fan_config.FAN_RPMWRITE_OFFSET!=None or fan_config.FAN_RAM_RPMWRITE_OFFSET!=None)\ + and (fan_config.FAN_RPMREAD_OFFSET!=None or fan_config.FAN_RAM_RPMREAD_OFFSET!=None)\ + and (fan_config.FAN_RPMWRITE_MAX!=0 and fan_config.FAN_RPMVALUE_MAX!=0) + if fan_config.FAN_IS_EC_CONFIGURED: + self.fan_config_list.append(fan_config) + except: + logging.error(f"获取风扇({hwmon_name})ec信息失败:",exc_info=True) + #设备特殊初始化 + def device_init_quirks(self): + #遍历所有风扇配置 + for fan_config in self.fan_config_list: + try: + #ecram配置 + FAN_IS_EC_CONFIGURED = fan_config.FAN_IS_EC_CONFIGURED + FAN_RAM_REG_ADDR = fan_config.FAN_RAM_REG_ADDR + FAN_RAM_REG_DATA = fan_config.FAN_RAM_REG_DATA + #有配置ec并且是win4 + if FAN_IS_EC_CONFIGURED and PRODUCT_NAME == "G1618-04": + # Initialize GPD WIN4 EC + ec_chip_id = EC.RamRead(FAN_RAM_REG_ADDR, FAN_RAM_REG_DATA, 0x2000) + if ec_chip_id == 0x55: + ec_chip_ver = EC.RamRead(FAN_RAM_REG_ADDR, FAN_RAM_REG_DATA, 0x1060) + ec_chip_ver |= 0x80 + EC.RamWrite(FAN_RAM_REG_ADDR, FAN_RAM_REG_DATA, 0x1060, ec_chip_ver) + except: + logging.error("设备特殊初始化失败:",exc_info=True) - def get_fanRPM(self): + def get_fanRPM(self,index): try: - if FAN_IS_ADAPTED: + if index < len(self.fan_config_list): + is_find_hwmon = self.fan_config_list[index].FAN_ISFIND_HWMON + hwmon_mode = self.fan_config_list[index].FAN_HWMON_MODE + hwmon_input_path = self.fan_config_list[index].FAN_HWMON_INPUT_PATH try: - if self.FAN_ISFIND_HWMON: - fanRPM=int(open(self.FAN_HWMON_INPUT_PATH).read().strip()) - logging.debug(f"使用hwmon数据 当前机型:{PRODUCT_NAME} hwmon地址:{self.FAN_HWMON_INPUT_PATH} 风扇转速:{fanRPM}") + if is_find_hwmon: + fanRPM=int(open(hwmon_input_path).read().strip()) + logging.debug(f"使用hwmon数据 当前机型:{PRODUCT_NAME} hwmon地址:{hwmon_input_path} 风扇转速:{fanRPM}") return fanRPM - except Exception as e: - logging.error(f"使用hwmon获取风扇转速异常:{e}") + except: + logging.error(f"使用hwmon获取风扇转速异常:",exc_info=True) + rpm_read_offset = self.fan_config_list[index].FAN_RPMREAD_OFFSET try: - if FAN_RPMREAD_OFFSET: - fanRPM=EC.ReadLonger(FAN_RPMREAD_OFFSET,2) - logging.debug(f"使用ECIO数据 当前机型:{PRODUCT_NAME} EC地址:{hex(FAN_RPMREAD_OFFSET)} 风扇转速:{fanRPM}") + if rpm_read_offset: + fanRPM=EC.ReadLonger(rpm_read_offset,2) + logging.debug(f"使用ECIO数据 当前机型:{PRODUCT_NAME} EC地址:{hex(rpm_read_offset)} 风扇转速:{fanRPM}") return fanRPM - except Exception as e: - logging.error(f"使用ECIO获取风扇转速异常:{e}") + except: + logging.error(f"使用ECIO获取风扇转速异常:",exc_info=True) + ram_read_offset = self.fan_config_list[index].FAN_RAM_RPMREAD_OFFSET + ram_reg_addr = self.fan_config_list[index].FAN_RAM_REG_ADDR + ram_reg_data = self.fan_config_list[index].FAN_RAM_REG_DATA + ram_rpm_read_length = self.fan_config_list[index].FAN_RAM_RPMREAD_LENGTH + rpm_write_max = self.fan_config_list[index].FAN_RPMWRITE_MAX + rpm_value_max = self.fan_config_list[index].FAN_RPMVALUE_MAX try: - if FAN_RAM_RPMREAD_OFFSET: - if FAN_RAM_RPMREAD_LENGTH > 0: - fanRPM=EC.RamReadLonger(FAN_RAM_REG_ADDR,FAN_RAM_REG_DATA,FAN_RAM_RPMREAD_OFFSET,FAN_RAM_RPMREAD_LENGTH) + if ram_read_offset: + if ram_rpm_read_length > 0: + fanRPM=EC.RamReadLonger(ram_reg_addr,ram_reg_data,ram_read_offset,ram_rpm_read_length) else: - fanRPM=int(EC.RamRead(FAN_RAM_REG_ADDR,FAN_RAM_REG_DATA,FAN_RAM_RPMREAD_OFFSET) * FAN_RPMVALUE_MAX / FAN_RPMWRITE_MAX) - logging.debug(f"使用ECRAM数据 当前机型:{PRODUCT_NAME} EC_ADDR:{hex(FAN_RAM_REG_ADDR)} EC_DATA={hex(FAN_RAM_REG_DATA)} EC地址:{hex(FAN_RAM_RPMREAD_OFFSET)} 风扇转速:{fanRPM}") + fanRPM=int(EC.RamRead(ram_reg_addr,ram_reg_data,ram_read_offset) * rpm_value_max / rpm_write_max) + logging.debug(f"使用ECRAM数据 当前机型:{PRODUCT_NAME} EC_ADDR:{hex(ram_reg_addr)} EC_DATA={hex(ram_reg_data)} EC地址:{hex(ram_read_offset)} 风扇转速:{fanRPM}") return fanRPM - except Exception as e: - logging.error(f"使用ECRAM获取风扇转速异常:{e}") - - + except: + logging.error(f"使用ECRAM获取风扇转速异常:",exc_info=True) return 0 else: - logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") + logging.debug(f"风扇下标越界 index:{index} len:{len(self.fan_config_list)}") return 0 - except Exception as e: - logging.error(f"获取风扇转速异常:{e}") + except: + logging.error(f"获取风扇转速异常:",exc_info=True) return 0 - def get_fanIsAuto(self): + def get_fanIsAuto(self,index): try: - if FAN_IS_ADAPTED: + if index < len(self.fan_config_list): + is_find_hwmon = self.fan_config_list[index].FAN_ISFIND_HWMON + hwmon_mode = self.fan_config_list[index].FAN_HWMON_MODE + hwmon_pwm_enable_path = self.fan_config_list[index].FAN_HWMON_PWMENABLE_PATH + enable_auto_value = self.fan_config_list[index].FAN_ENABLE_AUTO_VALUE try: - if self.FAN_ISFIND_HWMON: - fanIsManual=int(open(self.FAN_HWMON_PWMENABLE_PATH).read().strip()) - logging.debug(f"使用hwmon数据 当前机型:{PRODUCT_NAME} 读取hwmon地址:{self.FAN_HWMON_INPUT_PATH} 风扇是否控制:{fanIsManual}") + if is_find_hwmon and hwmon_mode == 0: + fanIsManual=int(open(hwmon_pwm_enable_path).read().strip()) + logging.debug(f"使用hwmon数据 读取hwmon地址:{hwmon_pwm_enable_path} 风扇是否控制:{fanIsManual == enable_auto_value}") # return not fanIsManual - return fanIsManual == self.FAN_HWMON_AUTO_VALUE - except Exception as e: - logging.error(f"使用hwmon获取风扇状态异常:{e}") + return fanIsManual == enable_auto_value + except: + logging.error(f"使用hwmon获取风扇状态异常:",exc_info=True) + ram_manual_offset = self.fan_config_list[index].FAN_RAM_MANUAL_OFFSET + ram_reg_addr = self.fan_config_list[index].FAN_RAM_REG_ADDR + ram_reg_data = self.fan_config_list[index].FAN_RAM_REG_DATA try: - if FAN_RAM_MANUAL_OFFSET: - fanIsManual=EC.RamRead(FAN_RAM_REG_ADDR,FAN_RAM_REG_DATA,FAN_RAM_MANUAL_OFFSET) - logging.debug(f"使用ECRAM数据 当前机型:{PRODUCT_NAME} 读取EC地址:{hex(FAN_RAM_MANUAL_OFFSET)} 风扇是否控制:{fanIsManual}") - return not fanIsManual - except Exception as e: - logging.error(f"使用ECRAM获取风扇状态异常:{e}") + if ram_manual_offset: + fanIsManual=EC.RamRead(ram_reg_addr,ram_reg_data,ram_manual_offset) + logging.debug(f"使用ECRAM数据 读取EC地址:{hex(ram_manual_offset)} 风扇是否控制:{fanIsManual == enable_auto_value}") + return fanIsManual == enable_auto_value + except: + logging.error(f"使用ECRAM获取风扇状态异常:",exc_info=True) + manual_offset = self.fan_config_list[index].FAN_RAM_MANUAL_OFFSET try: - if FAN_MANUAL_OFFSET: - fanIsManual=EC.Read(FAN_MANUAL_OFFSET) - logging.debug(f"使用ECIO数据 当前机型:{PRODUCT_NAME} 读取EC地址:{hex(FAN_MANUAL_OFFSET)} 风扇是否控制:{fanIsManual}") - return not fanIsManual - except Exception as e: - logging.error(f"使用ECIO获取风扇状态异常:{e}") + if manual_offset: + fanIsManual=EC.Read(manual_offset) + logging.debug(f"使用ECIO数据 读取EC地址:{hex(manual_offset)} 风扇是否控制:{fanIsManual == enable_auto_value}") + return fanIsManual == enable_auto_value + except: + logging.error(f"使用ECIO获取风扇状态异常:",exc_info=True) return False else: - logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") + logging.debug(f"风扇下标越界 index:{index} len:{len(self.fan_config_list)}") return False - except Exception as e: - logging.error(f"获取风扇状态异常:{e}") + except: + logging.error(f"获取风扇状态异常:",exc_info=True) return False - def set_fanAuto(self, value:bool): + def set_fanAuto(self, index:int, value:bool): try: - if FAN_IS_ADAPTED: + if index < len(self.fan_config_list): + is_find_hwmon = self.fan_config_list[index].FAN_ISFIND_HWMON + hwmon_mode = self.fan_config_list[index].FAN_HWMON_MODE + hwmon_pwm_enable_path = self.fan_config_list[index].FAN_HWMON_PWMENABLE_PATH + hwmon_pwm_path = self.fan_config_list[index].FAN_HWMON_PWM_PATH + hwmon_mode1_pwm_path = self.fan_config_list[index].FAN_HWMON_MODE1_PWM_PATH + enable_manual_value = self.fan_config_list[index].FAN_ENABLE_MANUAL_VALUE + enable_auto_value = self.fan_config_list[index].FAN_ENABLE_AUTO_VALUE + mode1_auto_value = self.fan_config_list[index].FAN_HWMON_MODE1_AUTO_VALUE try: - if self.FAN_ISFIND_HWMON and not self.FAN_HWMON_IS_MULTI_PWM: - fanIsManual = int(not value) - open(self.FAN_HWMON_PWMENABLE_PATH,'w').write(str(fanIsManual)) - logging.debug(f"写入hwmon数据 当前机型:{PRODUCT_NAME} 写入hwmon地址:{self.FAN_HWMON_PWMENABLE_PATH} 写入风扇是否控制:{fanIsManual}") + if is_find_hwmon and hwmon_mode == 0: + if value: + fanIsManual = enable_auto_value if value else enable_manual_value + elif not value and hwmon_pwm_path == hwmon_pwm_enable_path: #手动模式且控制位地址和写风扇转速的地址一样,跳过控制位写入,防止覆盖风扇转速 + logging.debug(f"写入hwmon_eanble地址:{hwmon_pwm_enable_path} 写入hwmon_pwm地址:{hwmon_pwm_enable_path} 地址相同跳过写入控制位") + return False + else: + fanIsManual = enable_manual_value + open(hwmon_pwm_enable_path,'w').write(str(fanIsManual)) + logging.debug(f"写入hwmon数据 写入hwmon地址:{hwmon_pwm_enable_path} 写入风扇是否控制:{fanIsManual}") return True - except Exception as e: - logging.error(f"使用hwmon写入风扇状态异常:{e}") - - try: - if self.FAN_HWMON_IS_MULTI_PWM and self.FAN_HWMON_PWMENABLE_PATH_LIST: - # 设置风扇自动控制温度初始点 10度, 温度写入要在风扇自动控制之前。因为写入后控制位会复位 - if self.FAN_HWMON_TEMP_FIRST_LIST: - temp = 10; - for temp_first in self.FAN_HWMON_TEMP_FIRST_LIST: - open(temp_first,'w').write(str(temp)) - logging.debug(f"写入hwmon数据 当前机型:{PRODUCT_NAME} 写入hwmon地址:{temp_first} 写入值:{temp}") - - # fanIsManual = int(not value) - fanIsManual = self.FAN_HWMON_MANUAL_VALUE if not value else self.FAN_HWMON_AUTO_VALUE - for pwm_enable_path in self.FAN_HWMON_PWMENABLE_PATH_LIST: - open(pwm_enable_path,'w').write(str(fanIsManual)) - logging.debug(f"写入hwmon数据 当前机型:{PRODUCT_NAME} 写入hwmon地址:{pwm_enable_path} 写入风扇是否控制:{fanIsManual}") + elif is_find_hwmon and hwmon_mode == 1 and value: + fanIsManual = enable_manual_value + for index,mode1_pwm_path in enumerate(hwmon_mode1_pwm_path): + if index >= len(mode1_auto_value): + break + #写入转速 + fanWriteValue = mode1_auto_value[index]["pwm_write_value"] + pwm_path = mode1_pwm_path["pwm_write"] + open(pwm_path,'w').write(str(fanWriteValue)) + #写入温度 + temp = mode1_auto_value[index]["temp_write_value"] + temp_path = mode1_pwm_path["temp_write"] + open(temp_path,'w').write(str(temp)) + logging.debug(f"写入hwmon数据 写入hwmon转速地址:{pwm_path} 风扇转速写入值:{fanWriteValue} 温度地址:{temp_path} 温度大小:{temp}") + open(hwmon_pwm_enable_path,'w').write(str(fanIsManual)) + logging.debug(f"写入hwmon数据 写入hwmon地址:{hwmon_pwm_enable_path} 写入风扇是否控制:{fanIsManual}") return True - except Exception as e: - logging.error(f"使用hwmon写入风扇状态异常:{e}") + return False + except: + logging.error(f"使用hwmon写入风扇状态异常:",exc_info=True) + ram_manual_offset = self.fan_config_list[index].FAN_RAM_MANUAL_OFFSET + ram_rpm_write_offset = self.fan_config_list[index].FAN_RAM_RPMWRITE_OFFSET + ram_reg_addr = self.fan_config_list[index].FAN_RAM_REG_ADDR + ram_reg_data = self.fan_config_list[index].FAN_RAM_REG_DATA try: - if FAN_RAM_MANUAL_OFFSET: - fanIsManual = int(not value) - EC.RamWrite(FAN_RAM_REG_ADDR,FAN_RAM_REG_DATA,FAN_RAM_MANUAL_OFFSET,fanIsManual) - logging.debug(f"写入ECRAM数据 当前机型:{PRODUCT_NAME} 写入EC地址:{hex(FAN_RAM_MANUAL_OFFSET)} 写入风扇是否控制:{fanIsManual}") + if ram_manual_offset: + if not value and ram_manual_offset == ram_rpm_write_offset:#手动模式且控制位地址和写风扇转速的地址一样,跳过控制位写入,防止覆盖风扇转速 + return False + fanIsManual = enable_auto_value if value else enable_manual_value + EC.RamWrite(ram_reg_addr,ram_reg_data,ram_manual_offset,fanIsManual) + logging.debug(f"写入ECRAM数据 写入EC地址:{hex(ram_manual_offset)} 写入风扇是否控制:{fanIsManual}") return True - except Exception as e: - logging.error(f"使用ECRAM写入风扇状态异常:{e}") + except: + logging.error(f"使用ECRAM写入风扇状态异常:",exc_info=True) + manual_offset = self.fan_config_list[index].FAN_RAM_MANUAL_OFFSET + rpm_write_offset = self.fan_config_list[index].FAN_RPMWRITE_OFFSET try: - if FAN_MANUAL_OFFSET: - fanIsManual = int(not value) - EC.Write(FAN_MANUAL_OFFSET,fanIsManual) - logging.debug(f"写入ECIO数据 当前机型:{PRODUCT_NAME} 写入EC地址:{hex(FAN_MANUAL_OFFSET)} 写入风扇是否控制:{fanIsManual}") + if manual_offset: + if not value and manual_offset == rpm_write_offset:#手动模式且控制位地址和写风扇转速的地址一样,跳过控制位写入,防止覆盖风扇转速 + return False + fanIsManual = enable_auto_value if value else enable_manual_value + EC.Write(manual_offset,fanIsManual) + logging.debug(f"写入ECIO数据 写入EC地址:{hex(manual_offset)} 写入风扇是否控制:{fanIsManual}") return True - except Exception as e: - logging.error(f"使用ECIO写入风扇状态异常:{e}") + except: + logging.error(f"使用ECIO写入风扇状态异常:",exc_info=True) else: - logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") - return False - except Exception as e: - logging.error(f"写入风扇状态异常:{e}") + logging.debug(f"风扇下标越界 index:{index} len:{len(self.fan_config_list)}") + return False + except: + logging.error(f"写入风扇状态异常:",exc_info=True) return False - def set_fanPercent(self, value:int): + def set_fanPercent(self, index:int,value:int): try: - if FAN_IS_ADAPTED: + if index < len(self.fan_config_list): + is_find_hwmon = self.fan_config_list[index].FAN_ISFIND_HWMON + hwmon_mode = self.fan_config_list[index].FAN_HWMON_MODE + rpm_write_max = self.fan_config_list[index].FAN_RPMWRITE_MAX + hwmon_pwm_path = self.fan_config_list[index].FAN_HWMON_PWM_PATH + hwmon_mode1_pwm_path = self.fan_config_list[index].FAN_HWMON_MODE1_PWM_PATH + enable_manual_value = self.fan_config_list[index].FAN_ENABLE_MANUAL_VALUE + hwmon_pwm_enable_path = self.fan_config_list[index].FAN_HWMON_PWMENABLE_PATH try: - if self.FAN_ISFIND_HWMON and not self.FAN_HWMON_IS_MULTI_PWM: - fanWriteValue = max(min(int(value/100*FAN_RPMWRITE_MAX),FAN_RPMWRITE_MAX),0) - open(self.FAN_HWMON_PWM_PATH,'w').write(str(fanWriteValue)) - logging.debug(f"写入hwmon数据 写入hwmon地址:{self.FAN_HWMON_PWM_PATH} 风扇转速百分比{value} 风扇最大值{FAN_RPMWRITE_MAX} 风扇转速写入值:{fanWriteValue}") + if is_find_hwmon and hwmon_mode == 0: + fanWriteValue = max(min(int(value/100*rpm_write_max),rpm_write_max),0) + open(hwmon_pwm_path,'w').write(str(fanWriteValue)) + logging.debug(f"写入hwmon数据 写入hwmon地址:{hwmon_pwm_path} 风扇转速百分比{value} 风扇最大值{rpm_write_max} 风扇转速写入值:{fanWriteValue}") return True - except Exception as e: - logging.error(f"使用hwmon写入风扇转速异常:{e}") - - try: - if self.FAN_HWMON_IS_MULTI_PWM and self.FAN_HWMON_PWM_PATH_LIST: - fanWriteValue = max(min(int(value/100*FAN_RPMWRITE_MAX),FAN_RPMWRITE_MAX),0) - for pwm_path in self.FAN_HWMON_PWM_PATH_LIST: - open(pwm_path,'w').write(str(fanWriteValue)) - logging.debug(f"写入hwmon数据 写入hwmon地址:{pwm_path} 风扇转速百分比{value} 风扇最大值{FAN_RPMWRITE_MAX} 风扇转速写入值:{fanWriteValue}") - self.set_fanAuto(False) + if is_find_hwmon and hwmon_mode == 1: + fanWriteValue = max(min(int(value/100*rpm_write_max),rpm_write_max),0) + temp = 10 + addTemp = int(100 / len(hwmon_mode1_pwm_path)) + if hwmon_mode1_pwm_path: + for mode1_pwm_path in hwmon_mode1_pwm_path: + #写入转速 + pwm_path = mode1_pwm_path["pwm_write"] + open(pwm_path,'w').write(str(fanWriteValue)) + #写入温度 + temp = temp + addTemp + temp_path = mode1_pwm_path["temp_write"] + open(temp_path,'w').write(str(temp)) + logging.debug(f"写入hwmon数据 写入hwmon转速地址:{pwm_path} 风扇转速百分比{value} 风扇最大值{rpm_write_max} 风扇转速写入值:{fanWriteValue} 温度地址:{temp_path} 温度大小:{temp}") + fanIsManual = enable_manual_value + open(hwmon_pwm_enable_path,'w').write(str(fanIsManual)) + logging.debug(f"写入hwmon数据 写入hwmon地址:{hwmon_pwm_enable_path} 写入风扇是否控制:{fanIsManual}") return True - except Exception as e: - logging.error(f"使用hwmon写入风扇转速异常:{e}") + except: + logging.error("使用hwmon写入风扇转速异常:",exc_info=True) + ram_reg_addr = self.fan_config_list[index].FAN_RAM_REG_ADDR + ram_reg_data = self.fan_config_list[index].FAN_RAM_REG_DATA + ram_rpm_write_offset = self.fan_config_list[index].FAN_RAM_RPMWRITE_OFFSET try: - if FAN_RAM_RPMWRITE_OFFSET: - fanWriteValue = max(min(int(value/100*FAN_RPMWRITE_MAX),FAN_RPMWRITE_MAX),0) - EC.RamWrite(FAN_RAM_REG_ADDR,FAN_RAM_REG_DATA,FAN_RAM_RPMWRITE_OFFSET,fanWriteValue) - logging.debug(f"写入ECRAM数据 写入EC地址:{hex(FAN_RAM_RPMWRITE_OFFSET)} 风扇转速百分比{value} 风扇最大值{FAN_RPMWRITE_MAX} 风扇转速写入值:{fanWriteValue}") + if ram_rpm_write_offset: + fanWriteValue = max(min(int(value/100*rpm_write_max),rpm_write_max),0) + EC.RamWrite(ram_reg_addr,ram_reg_data,ram_rpm_write_offset,fanWriteValue) + logging.debug(f"写入ECRAM数据 写入EC地址:{hex(ram_rpm_write_offset)} 风扇转速百分比{value} 风扇最大值{rpm_write_max} 风扇转速写入值:{fanWriteValue}") return True - except Exception as e: - logging.error(f"使用ECRAM写入风扇转速异常:{e}") - + except: + logging.error("使用ECRAM写入风扇转速异常:",exc_info=True) + + rpm_write_offset = self.fan_config_list[index].FAN_RPMWRITE_OFFSET try: - if FAN_RPMWRITE_OFFSET: - fanWriteValue = max(min(int(value/100*FAN_RPMWRITE_MAX),FAN_RPMWRITE_MAX),0) - EC.Write(FAN_RPMWRITE_OFFSET,fanWriteValue) - logging.debug(f"写入ECIO数据 写入EC地址:{hex(FAN_RPMWRITE_OFFSET)} 风扇转速百分比{value} 风扇最大值{FAN_RPMWRITE_MAX} 风扇转速写入值:{fanWriteValue}") + if rpm_write_offset: + fanWriteValue = max(min(int(value/100*rpm_write_max),rpm_write_max),0) + EC.Write(rpm_write_offset,fanWriteValue) + logging.debug(f"写入ECIO数据 写入EC地址:{hex(rpm_write_offset)} 风扇转速百分比{value} 风扇最大值{rpm_write_max} 风扇转速写入值:{fanWriteValue}") return True - except Exception as e: - logging.error(f"使用ECIO写入风扇转速异常:{e}") + except: + logging.error("使用ECIO写入风扇转速异常:",exc_info=True) else: - logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") + logging.debug(f"风扇下标越界 index:{index} len:{len(self.fan_config_list)}") return False - except Exception as e: - logging.error(f"写入风扇转速异常:{e}") + except: + logging.error(f"写入风扇转速异常:",exc_info=True) return False - def get_fanMAXRPM(self): + def get_fanTemp(self,index): try: - if FAN_IS_ADAPTED: - logging.debug(f"机型已适配fan 最大风扇转速:{FAN_RPMVALUE_MAX}") - return FAN_RPMVALUE_MAX + if index < len(self.fan_config_list): + if self.fan_config_list[index].TEMP_MODE == 0: + cpu_temp = self.get_cpuTemp() + if cpu_temp == -1: + gpu_temp = self.get_gpuTemp() + return gpu_temp + return cpu_temp + elif self.fan_config_list[index].TEMP_MODE == 1: + gpu_temp = self.get_gpuTemp() + if gpu_temp == -1: + cpu_temp = self.get_gpuTemp() + return cpu_temp + return gpu_temp + else: + logging.error(f"未知的温度来源配置:",exc_info=True) else: - logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") - return 0 - except Exception as e: - logging.error(f"获取风扇最大转速异常:{e}") + logging.debug(f"风扇下标越界 index:{index} len:{len(self.fan_config_list)}") + return 0 + except: + logging.error(f"获取温度异常:",exc_info=True) return 0 - def get_fanIsAdapted(self): + def get_gpuTemp(self): + try: + if(self.FAN_GPUTEMP_PATH==""): + hwmon_path="/sys/class/hwmon" + hwmon_files=os.listdir(hwmon_path) + for file in hwmon_files: + path=hwmon_path+"/"+file + name = open(path+"/name").read().strip() + if(name=="amdgpu"): + self.FAN_GPUTEMP_PATH=path+"/temp1_input" + temp = int(open(self.FAN_GPUTEMP_PATH).read().strip()) + logging.debug(f"获取gpu温度:{temp}") + return temp + except Exception as e: + logging.error(f"获取gpu温度异常:{e}") + return -1 + + def get_cpuTemp(self): try: - if FAN_IS_ADAPTED: + if os.path.exists(self.FAN_CPUTEMP_PATH): + temp = int(open(self.FAN_CPUTEMP_PATH).read().strip()) + else: + temp = -1 + logging.debug(f"获取cpu温度:{temp}") + return temp + except Exception as e: + logging.error(f"获取cpu温度异常:{e}") + return -1 + + def get_fanConfigList(self): + try: + if len(self.fan_config_list)>0: logging.debug(f"机型已适配fan 当前机型:{PRODUCT_NAME}") - return True + config_list = [] + for config in self.fan_config_list: + fan_name = config.FAN_NAME + fan_max_rpm = config.FAN_RPMVALUE_MAX + fan_hwmon_mode = config.FAN_HWMON_MODE + config_list.append({"fan_name":fan_name,"fan_max_rpm":fan_max_rpm,"fan_hwmon_mode":fan_hwmon_mode}) + return config_list else: - logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") - return False + logging.debug(f"机型未适配fan 当前机型:{PRODUCT_NAME}") + return [] except Exception as e: logging.error(f"获取机型适配异常:{e}") - return 0 + return [] fanManager = FanManager() diff --git a/backend/sysInfo.py b/backend/sysInfo.py index 8756591..8983a82 100755 --- a/backend/sysInfo.py +++ b/backend/sysInfo.py @@ -6,7 +6,7 @@ import asyncio from ec import EC from config import logging,SH_PATH,PRODUCT_NAME -from config import FAN_GPUTEMP_PATH,FAN_CPUTEMP_PATH,GPU_DEVICE_PATH +from config import GPU_DEVICE_PATH from helpers import get_user cpu_busyPercent = 0 @@ -120,34 +120,6 @@ def get_language(self): logging.error(e) return self._language - - def get_gpuTemp(self): - try: - global FAN_GPUTEMP_PATH - if(FAN_GPUTEMP_PATH==""): - hwmon_path="/sys/class/hwmon" - hwmon_files=os.listdir(hwmon_path) - for file in hwmon_files: - path=hwmon_path+"/"+file - name = open(path+"/name").read().strip() - if(name=="amdgpu"): - FAN_GPUTEMP_PATH=path+"/temp1_input" - temp = int(open(FAN_GPUTEMP_PATH).read().strip()) - logging.debug(f"获取gpu温度:{temp}") - return temp - except Exception as e: - logging.error(f"获取gpu温度异常:{e}") - return -1 - - def get_cpuTemp(self): - try: - temp = int(open(FAN_CPUTEMP_PATH).read().strip()) - logging.debug(f"获取cpu温度:{temp}") - return temp - except Exception as e: - logging.error(f"获取cpu温度异常:{e}") - return -1 - def updateCpuData(self): global cpu_DataErrCnt global cpu_busyPercent diff --git a/main.py b/main.py index ab4d952..c61c02d 100755 --- a/main.py +++ b/main.py @@ -67,61 +67,51 @@ async def get_language(self): logging.error(e) return "" - async def get_fanRPM(self): + async def get_fanRPM(self,index): try: - return fanManager.get_fanRPM() + return fanManager.get_fanRPM(index) except Exception as e: logging.error(e) return 0 - async def get_fanRPMPercent(self): + async def get_fanRPMPercent(self,index): try: - return fanManager.get_fanRPMPercent() + return fanManager.get_fanRPMPercent(index) except Exception as e: logging.error(e) return 0 - async def get_fanTemp(self): + async def get_fanTemp(self,index): try: - gpuTemp = sysInfoManager.get_gpuTemp() - if gpuTemp!=-1: - return gpuTemp - return sysInfoManager.get_cpuTemp() + return fanManager.get_fanTemp(index) except Exception as e: logging.error(e) return 0 - async def get_fanIsAuto(self): + async def get_fanIsAuto(self,index): try: - return fanManager.get_fanIsAuto() + return fanManager.get_fanIsAuto(index) except Exception as e: logging.error(e) return 0 - async def get_fanMAXRPM(self): + async def get_fanConfigList(self): try: - return fanManager.get_fanMAXRPM() + return fanManager.get_fanConfigList() except Exception as e: logging.error(e) - return 0 - - async def get_fanIsAdapted(self): - try: - return fanManager.get_fanIsAdapted() - except Exception as e: - logging.error(e) - return 0 + return [] - def set_fanAuto(self, value:bool): + def set_fanAuto(self, index:int, value:bool): try: - return fanManager.set_fanAuto(value) + return fanManager.set_fanAuto(index,value) except Exception as e: logging.error(e) return False - def set_fanPercent(self, value:int): + def set_fanPercent(self,index:int, value:int): try: - return fanManager.set_fanPercent(value) + return fanManager.set_fanPercent(index,value) except Exception as e: logging.error(e) return False diff --git a/src/components/fan.tsx b/src/components/fan.tsx index 4ac01d2..cbe783f 100755 --- a/src/components/fan.tsx +++ b/src/components/fan.tsx @@ -7,17 +7,15 @@ import { DialogButton, TextField, SliderField, - Dropdown, DropdownOption, Focusable, + DropdownItem, } from "decky-frontend-lib"; import { useEffect, useState,useRef,VFC} from "react"; import { FiPlusCircle }from "react-icons/fi" -import { Settings, PluginManager,ComponentName, UpdateType, FANMODE, getTextPosByCanvasPos, fanPosition, FanSetting, FANPROFILEACTION, FanControl} from "../util"; +import { Settings, PluginManager,ComponentName, UpdateType, FANMODE, getTextPosByCanvasPos, fanPosition, FanSetting, FANPROFILEACTION, FanControl, Backend} from "../util"; import { localizeStrEnum,localizationManager } from "../i18n"; import {FanCanvas} from "./fanCanvas"; -var fanRPMIntervalID:any; -var fanDisplayIntervalID:any; const totalLines = 9; const pointBlockDis = 5; const pointColor = "#1A9FFF"; @@ -27,12 +25,12 @@ const lineColor = "#1E90FF"; const setPointColor = "#00BFFF"; //选择配置文件下拉框 -const FANSelectProfileComponent: VFC = () =>{ +const FANSelectProfileComponent:VFC<{fanIndex:number}> = ({fanIndex}) =>{ //@ts-ignore const [items, setItems] = useState( Object.entries(Settings.getFanSettings()).map(([profileName, fanSetting]) => { var useOption = {label:localizationManager.getString(localizeStrEnum.USE),data:{profileName:profileName,type:FANPROFILEACTION.USE,setting:fanSetting}}; - if (profileName==Settings.appFanSettingName()) { + if (profileName==Settings.appFanSettingNameList()?.[fanIndex]) { useOption ={label:localizationManager.getString(localizeStrEnum.CANCEL),data:{profileName:profileName,type:FANPROFILEACTION.CANCEL,setting:fanSetting}}; } return { @@ -47,12 +45,12 @@ const FANSelectProfileComponent: VFC = () =>{ ); //@ts-ignore const [selectedItem,setSelectedItem] = useState(items.find((item)=>{ - return item.label==Settings.appFanSettingName(); + return item.label==Settings.appFanSettingNameList()?.[fanIndex]; })); return ( +
- { ]} strDefaultLabel={selectedItem?selectedItem.label?.toString():(items.length==0?localizationManager.getString(localizeStrEnum.CREATE_FAN_PROFILE_TIP):localizationManager.getString(localizeStrEnum.SELECT_FAN_PROFILE_TIP))} selectedOption={selectedItem} + bottomSeparator={"none"} onChange={(item:DropdownOption)=>{ if(item.data==FANPROFILEACTION.ADD){ // @ts-ignore @@ -82,57 +81,42 @@ const FANSelectProfileComponent: VFC = () =>{ } //setSelectedItem(item); if(item.data.type==FANPROFILEACTION.USE){ - Settings.setAppFanSettingName(item.data.profileName) + Settings.setAppFanSettingName(item.data.profileName,fanIndex) }else if(item.data.type==FANPROFILEACTION.DELETE){ Settings.removeFanSetting(item.data.profileName) }else if(item.data.type==FANPROFILEACTION.EDIT){ // @ts-ignore showModal(); }else if(item.data.type==FANPROFILEACTION.CANCEL){ - Settings.setAppFanSettingName(undefined); + Settings.setAppFanSettingName(undefined,fanIndex); } }} /> - + +
); } //显示当前风扇配置和温度转速信息 -const FANDisplayComponent: VFC = () =>{ +const FANDisplayComponent: VFC<{fanIndex:number}> = ({fanIndex}) =>{ const canvasRef: any = useRef(null); const curvePoints : any = useRef([]); const initDraw=(ref:any)=>{ canvasRef.current=ref; - curvePoints.current=Settings.appFanSetting()?.curvePoints; + curvePoints.current=Settings.appFanSettings()?.[fanIndex]?.curvePoints; } const refresh = () => { refreshCanvas(); }; - const dismount = () =>{ - if(fanDisplayIntervalID!=null){ - clearInterval(fanDisplayIntervalID); - } - } useEffect(() => { refresh(); - if(fanDisplayIntervalID!=null){ - clearInterval(fanDisplayIntervalID); - } - fanDisplayIntervalID=setInterval(()=>{ + + const fanDisplayIntervalID=setInterval(()=>{ refresh(); },1000) - PluginManager.listenUpdateComponent(ComponentName.FAN_DISPLAY,[ComponentName.FAN_DISPLAY],(_ComponentName,updateType)=>{ - switch(updateType){ - case(UpdateType.UPDATE):{ - refresh(); - break; - } - case(UpdateType.DISMOUNT):{ - dismount(); - break; - } - } - }) + return ()=>{ + clearInterval(fanDisplayIntervalID); + } }, []); const refreshCanvas=()=>{ const canvas = canvasRef.current; @@ -164,7 +148,7 @@ const FANDisplayComponent: VFC = () =>{ ctx.fillText(fanText, 2, height-lineDistance * i * height + 10); } ctx.stroke();*/ - switch(Settings.appFanSetting()?.fanMode){ + switch(Settings.appFanSettings()?.[fanIndex]?.fanMode){ case(FANMODE.NOCONTROL):{ drawNoControlMode(); break; @@ -192,9 +176,9 @@ const FANDisplayComponent: VFC = () =>{ ctx.fill(); //绘制实际点 ctx.fillStyle = setPointColor; - var nowPointCanPos=FanControl.nowPoint.getCanvasPos(width,height); + var nowPointCanPos=FanControl.fanInfo[fanIndex].nowPoint.getCanvasPos(width,height); var textPos = getTextPosByCanvasPos(nowPointCanPos[0],nowPointCanPos[1],width,height) - ctx.fillText(`(${Math.trunc(FanControl.nowPoint.temperature!!)}°C,${Math.trunc(FanControl.nowPoint.fanRPMpercent!!)}%)`, textPos[0],textPos[1]); + ctx.fillText(`(${Math.trunc(FanControl.fanInfo[fanIndex].nowPoint.temperature!!)}°C,${Math.trunc(FanControl.fanInfo[fanIndex].nowPoint.fanRPMpercent!!)}%)`, textPos[0],textPos[1]); ctx.arc(nowPointCanPos[0],nowPointCanPos[1],5, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); @@ -204,7 +188,7 @@ const FANDisplayComponent: VFC = () =>{ const ctx = canvas?.getContext('2d'); const width: number = ctx.canvas.width; const height: number = ctx.canvas.height; - const anchorPoint = new fanPosition(fanPosition.tempMax/2,Settings.appFanSetting()?.fixSpeed!!).getCanvasPos(width,height); + const anchorPoint = new fanPosition(fanPosition.tempMax/2,Settings.appFanSettings()?.[fanIndex].fixSpeed!!).getCanvasPos(width,height); //说明绘制 ctx.beginPath(); ctx.fillStyle = setPointColor; @@ -225,9 +209,9 @@ const FANDisplayComponent: VFC = () =>{ //绘制设置点 ctx.beginPath(); ctx.fillStyle = setPointColor; - var setPointCanPos=FanControl.setPoint.getCanvasPos(width,height); + var setPointCanPos=FanControl.fanInfo[fanIndex].setPoint.getCanvasPos(width,height); var textPos = getTextPosByCanvasPos(setPointCanPos[0],setPointCanPos[1],width,height) - ctx.fillText(`(${Math.trunc(FanControl.setPoint.temperature!!)}°C,${Math.trunc(FanControl.setPoint.fanRPMpercent!!)}%)`, textPos[0],textPos[1]); + ctx.fillText(`(${Math.trunc(FanControl.fanInfo[fanIndex].setPoint.temperature!!)}°C,${Math.trunc(FanControl.fanInfo[fanIndex].setPoint.fanRPMpercent!!)}%)`, textPos[0],textPos[1]); ctx.arc(setPointCanPos[0],setPointCanPos[1],5, 0, Math.PI * 2); ctx.fill(); } @@ -262,9 +246,9 @@ const FANDisplayComponent: VFC = () =>{ //绘制实际点和设置点 ctx.beginPath(); ctx.fillStyle = setPointColor; - var setPointCanPos=FanControl.setPoint.getCanvasPos(width,height); + var setPointCanPos=FanControl.fanInfo[fanIndex].setPoint.getCanvasPos(width,height); var textPos = getTextPosByCanvasPos(setPointCanPos[0],setPointCanPos[1],width,height) - ctx.fillText(`(${Math.trunc(FanControl.setPoint.temperature!!)}°C,${Math.trunc(FanControl.setPoint.fanRPMpercent!!)}%)`, textPos[0],textPos[1]); + ctx.fillText(`(${Math.trunc(FanControl.fanInfo[fanIndex].setPoint.temperature!!)}°C,${Math.trunc(FanControl.fanInfo[fanIndex].setPoint.fanRPMpercent!!)}%)`, textPos[0],textPos[1]); ctx.arc(setPointCanPos[0],setPointCanPos[1],5, 0, Math.PI * 2); ctx.fill(); //绘制点和坐标 @@ -305,35 +289,23 @@ const FANDisplayComponent: VFC = () =>{ //FANRPM模块 -const FANRPMComponent: VFC = () => { +const FANRPMComponent: VFC<{fanIndex:number}> = ({fanIndex}) =>{ const [fanrpm, setFanRPM] = useState(0); const refresh = async() => { - setFanRPM(FanControl.fanRPM); + setFanRPM(FanControl.fanInfo[fanIndex].fanRPM); }; - const dismount = () =>{ - if(fanRPMIntervalID!=null){ - clearInterval(fanRPMIntervalID); - } - } + useEffect(() => { - if(fanRPMIntervalID!=null){ - clearInterval(fanRPMIntervalID); - } - fanRPMIntervalID=setInterval(()=>{ + const fanRPMIntervalID=setInterval(()=>{ refresh(); },1000) - PluginManager.listenUpdateComponent(ComponentName.FAN_RPM,[ComponentName.FAN_RPM],(_ComponentName,updateType)=>{ - switch(updateType){ - case(UpdateType.DISMOUNT):{ - dismount() - break; - } - } - }) + return ()=>{ + clearInterval(fanRPMIntervalID); + } }, []); return ( - {fanrpm + " RPM"} @@ -782,9 +754,12 @@ function FANCretateProfileModelComponent({ ); } + export function FANComponent(){ const [show,setShow] = useState(Settings.ensureEnable()); + const [index,setIndex] = useState(0); const fanEnable = useRef(FanControl.fanIsEnable); + const fanCount = useRef(Backend.data.getFanCount()); const hide = (ishide:boolean) => { setShow(!ishide); }; @@ -806,10 +781,37 @@ export function FANComponent(){ // return (
- {show&&fanEnable.current&& - - - + {show&&fanEnable.current&&fanCount.current>=0&& + { + fanCount.current==1&&(
+ + + +
) + } + { + fanCount.current==2&&(
+ + { + return {notchIndex:index,label:config.fan_name,value:index} + }) + } onChange={(value)=>{ + setIndex(value); + }}> + + + + {Backend.data.getFanConfigs().map((_config,configIndex) => { + return index==configIndex&&(
+ + + +
) + })} +
) + } +
}
); diff --git a/src/util/backend.ts b/src/util/backend.ts index 3ccb684..dfaf35c 100755 --- a/src/util/backend.ts +++ b/src/util/backend.ts @@ -3,8 +3,6 @@ import { APPLYTYPE, FANMODE, GPUMODE, Patch} from "./enum"; import { FanControl, PluginManager} from "./pluginMain"; import { Settings } from "./settings"; - - export class BackendData{ private serverAPI:ServerAPI | undefined; private cpuMaxNum = 0; @@ -15,9 +13,8 @@ export class BackendData{ private has_gpuMax = false; private gpuMin = 0; private has_gpuMin = false; - private fanMaxRPM = 0; - private has_fanMaxRPM = false; - private fanIsAdapted = false; + private fanConfigs:any[] = []; + private has_fanConfigs = false; public async init(serverAPI:ServerAPI){ this.serverAPI=serverAPI; await serverAPI!.callPluginMethod<{},number>("get_cpuMaxNum",{}).then(res=>{ @@ -43,19 +40,13 @@ export class BackendData{ this.has_gpuMax = true; } }) - await this.serverAPI!.callPluginMethod<{},number>("get_fanMAXRPM",{}).then(res=>{ - if (res.success){ - this.fanMaxRPM=res.result; - this.has_fanMaxRPM=true; - }else{ - this.fanMaxRPM=1; - } - }) - await this.serverAPI!.callPluginMethod<{},boolean>("get_fanIsAdapted",{}).then(res=>{ + await this.serverAPI!.callPluginMethod<{},[]>("get_fanConfigList",{}).then(res=>{ if (res.success){ - this.fanIsAdapted=res.result; + console.info("fanConfigList",res.result) + this.fanConfigs = res.result; + this.has_fanConfigs=true; }else{ - this.fanIsAdapted=false; + this.has_fanConfigs=false; } }) } @@ -91,21 +82,46 @@ export class BackendData{ return this.has_tdpMax; } - public getFanMAXPRM(){ - return this.fanMaxRPM; + public getFanMAXPRM(index:number){ + if (this.has_fanConfigs){ + return this.fanConfigs?.[index]?.fan_max_rpm??0; + } + return 0; + } + + public getFanCount(){ + if (this.has_fanConfigs){ + return this.fanConfigs?.length??0; + } + return 0; + } + + public getFanName(index:number){ + if (this.has_fanConfigs){ + return this.fanConfigs?.[index]?.fan_name??"Fan"; + } + return "Fan"; } - public HasFanMAXPRM(){ - return this.has_fanMaxRPM; + public getFanConfigs(){ + if (this.has_fanConfigs){ + return this.fanConfigs; + } + return []; } - public getFanIsAdapt(){ - return this.fanIsAdapted; + public getFanHwmonMode(index:number){ + if (this.has_fanConfigs){ + return this.fanConfigs?.[index]?.fan_hwmon_mode??0; + } + return 0; } - public async getFanRPM(){ + + public async getFanRPM(index:number){ var fanPRM:number; - await this.serverAPI!.callPluginMethod<{},number>("get_fanRPM",{}).then(res=>{ + await this.serverAPI!.callPluginMethod<{"index":number},number>("get_fanRPM",{"index":index}).then(res=>{ + //console.log("get_fanRPM res=",res,"index=",index) if (res.success){ fanPRM=res.result; }else{ @@ -115,9 +131,9 @@ export class BackendData{ return fanPRM!!; } - public async getFanTemp(){ + public async getFanTemp(index:number){ var fanTemp:number; - await this.serverAPI!.callPluginMethod<{},number>("get_fanTemp",{}).then(res=>{ + await this.serverAPI!.callPluginMethod<{"index":number},number>("get_fanTemp",{"index":index}).then(res=>{ if (res.success){ fanTemp=res.result/1000; }else{ @@ -127,9 +143,9 @@ export class BackendData{ return fanTemp!!; } - public async getFanIsAuto(){ + public async getFanIsAuto(index:number){ var fanIsAuto:boolean; - await this.serverAPI!.callPluginMethod<{},boolean>("get_fanIsAuto",{}).then(res=>{ + await this.serverAPI!.callPluginMethod<{"index":number},boolean>("get_fanIsAuto",{"index":index}).then(res=>{ if (res.success){ fanIsAuto=res.result; }else{ @@ -190,12 +206,12 @@ export class Backend { this.serverAPI!.callPluginMethod("set_gpuAutoFreqRange", {"min":minAutoFreq,"max":maxAutoFreq}); } - private static applyFanAuto(auto:boolean){ - this.serverAPI!.callPluginMethod("set_fanAuto", {"value":auto}); + private static applyFanAuto(index:number,auto:boolean){ + this.serverAPI!.callPluginMethod("set_fanAuto", {"index":index,"value":auto}); } - private static applyFanPercent(percent:number){ - this.serverAPI!.callPluginMethod("set_fanPercent", {"value":percent}); + private static applyFanPercent(index:number,percent:number){ + this.serverAPI!.callPluginMethod("set_fanPercent", {"index":index,"value":percent}); } public static throwSuspendEvt(){ console.log("throwSuspendEvt"); @@ -252,42 +268,66 @@ export class Backend { Backend.applyGPUFreq(0); } } + /* if (applyTarget == APPLYTYPE.SET_ALL || applyTarget == APPLYTYPE.SET_FANMODE){ if(!FanControl.fanIsEnable){ return; } - const fanSetting = Settings.appFanSetting(); - const fanMode = fanSetting?.fanMode; - if (fanMode == FANMODE.NOCONTROL) { - Backend.applyFanAuto(true); - } else if (fanMode == FANMODE.FIX) { - Backend.applyFanAuto(false); - } else if (fanMode == FANMODE.CURVE) { - Backend.applyFanAuto(false); - } else { - Backend.applyFanAuto(true); - console.log(`出现意外的FanMode = ${fanMode}`) - }; - } + const fanSettings = Settings.appFanSettings(); + fanSettings?.forEach((fanSetting,index)=>{ + const fanMode = fanSetting?.fanMode; + if (fanMode == FANMODE.NOCONTROL) { + Backend.applyFanAuto(index,true); + } else if (fanMode == FANMODE.FIX) { + Backend.applyFanAuto(index,false); + } else if (fanMode == FANMODE.CURVE) { + Backend.applyFanAuto(index,false); + } else { + Backend.applyFanAuto(index,true); + console.log(`出现意外的FanMode = ${fanMode}`) + }; + }) + + }*/ + if (applyTarget == APPLYTYPE.SET_ALL || applyTarget == APPLYTYPE.SET_FANRPM){ if(!FanControl.fanIsEnable){ return; } - const fanSetting = Settings.appFanSetting(); - const fanMode = fanSetting?.fanMode; - if (fanMode == FANMODE.NOCONTROL) { - } else if (fanMode == FANMODE.FIX) { - Backend.applyFanPercent(FanControl.setPoint.fanRPMpercent!!); - } else if (fanMode == FANMODE.CURVE) { - Backend.applyFanPercent(FanControl.setPoint.fanRPMpercent!!); - } else { - console.log(`出现意外的FanMode = ${fanMode}`) + const fanSettings = Settings.appFanSettings(); + for(var index=0;index{ - Backend.applyFanAuto(true); + FanControl.fanInfo.forEach((_value,index)=>{ + Backend.applyFanAuto(index,true); + }) + } public static resetSettings = () => { @@ -297,6 +337,8 @@ export class Backend { Backend.applyCpuBoost(true); Backend.applyTDP(Backend.data.getTDPMax()); Backend.applyGPUFreq(0); - Backend.applyFanAuto(true); + FanControl.fanInfo.forEach((_value,index)=>{ + Backend.applyFanAuto(index,true); + }) }; } diff --git a/src/util/pluginMain.ts b/src/util/pluginMain.ts index ebb865e..ef9341b 100755 --- a/src/util/pluginMain.ts +++ b/src/util/pluginMain.ts @@ -19,7 +19,7 @@ export class RunningApps { private static pollActive() { const newApp = RunningApps.active(); if (this.lastAppId != newApp) { - this.listeners.forEach((h) => h(newApp, this.lastAppId)); + this.listeners?.forEach((h) => h(newApp, this.lastAppId)); } this.lastAppId = newApp; } @@ -54,94 +54,126 @@ export class RunningApps { export class FanControl{ private static intervalId: any; - public static nowPoint:fanPosition=new fanPosition(0,0); - public static setPoint:fanPosition=new fanPosition(0,0); - public static fanMode:FANMODE; - public static fanRPM:number=0; public static fanIsEnable:boolean=false; + public static fanInfo:{nowPoint:fanPosition,setPoint:fanPosition,lastSetPoint:fanPosition,fanMode:FANMODE,fanRPM:number,bFanNotSet:Boolean}[]=[]; + static async register() { - if(!Backend.data.getFanIsAdapt()){ + if(Backend.data.getFanCount()==0){ this.disableFan(); return; } + for(var index = 0;index this.updateFan(), 1000); this.fanIsEnable=true; } static async updateFan(){ - FanControl.updateFanMode(); + //FanControl.updateFanMode(); FanControl.updateFanInfo(); - PluginManager.updateComponent(ComponentName.FAN_DISPLAY,UpdateType.UPDATE); } + /* static async updateFanMode(){ - const fanSetting = Settings.appFanSetting(); - const fanMode = fanSetting?.fanMode; - if(FanControl.fanMode==undefined||FanControl.fanMode!=fanMode) - { - FanControl.fanMode = fanMode!!; - Backend.applySettings(APPLYTYPE.SET_FANMODE); + var settings = Settings.appFanSettings() + for(var index=0;index<=settings.length;index++){ + var fanSetting = Settings.appFanSettings()?.[index]; + console.log("index = ",index,"fanSetiing = ",fanSetting) + if(!fanSetting){ + //未设置 + if(!FanControl.fanInfo[index].bFanNotSet){ + FanControl.fanInfo[index].bFanNotSet = true; + Backend.applySettings(APPLYTYPE.SET_FANMODE); + } + }else{ + const fanMode = fanSetting?.fanMode; + if(FanControl.fanInfo[index].fanMode==undefined||FanControl.fanInfo[index].fanMode!=fanMode) + { + FanControl.fanInfo[index].fanMode = fanMode!!; + Backend.applySettings(APPLYTYPE.SET_FANMODE); + } + } + } - } + }*/ static async updateFanInfo(){ - await Backend.data.getFanRPM().then((value)=>{ - this.fanRPM=value; - FanControl.nowPoint.fanRPMpercent=Backend.data.HasFanMAXPRM()?value/Backend.data.getFanMAXPRM()*100:-273; - }); - await Backend.data.getFanTemp().then((value)=>{ - FanControl.nowPoint.temperature=value; - }); - const fanSetting = Settings.appFanSetting(); - const fanMode = fanSetting?.fanMode; - switch(fanMode){ - case(FANMODE.NOCONTROL):{ - break; - } - case(FANMODE.FIX):{ - var fixSpeed = fanSetting?.fixSpeed; - FanControl.setPoint.temperature=FanControl.nowPoint.temperature; - FanControl.setPoint.fanRPMpercent=fixSpeed; - break; - } - case(FANMODE.CURVE):{ - var curvePoints = fanSetting?.curvePoints!!.sort((a:fanPosition,b:fanPosition)=>{ - return a.temperature==b.temperature?a.fanRPMpercent!!-b.fanRPMpercent!!:a.temperature!!-b.temperature!! - }); - //每俩点判断是否在这俩点之间 - var lineStart = new fanPosition(fanPosition.tempMin,fanPosition.fanMin); - if(curvePoints?.length!!>0){ - //初始点到第一个点 - var lineEnd = curvePoints!![0]; - if(FanControl.nowPoint.temperature!!>lineStart.temperature!!&&FanControl.nowPoint.temperature!!<=lineEnd.temperature!!){ - FanControl.setPoint = calPointInLine(lineStart,lineEnd,FanControl.nowPoint.temperature!!)!!; - } + Backend.data.getFanConfigs()?.forEach(async (_config,index)=>{ + await Backend.data.getFanRPM(index).then((value)=>{ + FanControl.fanInfo[index].fanRPM=value; + FanControl.fanInfo[index].nowPoint.fanRPMpercent=value/Backend.data.getFanMAXPRM(index)*100; + }); + }) + Settings.appFanSettings()?.forEach(async (fanSetting,index)=>{ + await Backend.data.getFanTemp(index).then((value)=>{ + FanControl.fanInfo[index].nowPoint.temperature=value; + }); + const fanMode = fanSetting?.fanMode; + switch(fanMode){ + case(FANMODE.NOCONTROL):{ + FanControl.fanInfo[index].setPoint.fanRPMpercent = 0; + FanControl.fanInfo[index].setPoint.temperature = -10; + break; + } + case(FANMODE.FIX):{ + var fixSpeed = fanSetting?.fixSpeed; + FanControl.fanInfo[index].setPoint.temperature=FanControl.fanInfo[index].nowPoint.temperature; + FanControl.fanInfo[index].setPoint.fanRPMpercent=fixSpeed; + break; + } + case(FANMODE.CURVE):{ + var curvePoints = fanSetting?.curvePoints!!.sort((a:fanPosition,b:fanPosition)=>{ + return a.temperature==b.temperature?a.fanRPMpercent!!-b.fanRPMpercent!!:a.temperature!!-b.temperature!! + }); + //每俩点判断是否在这俩点之间 + var lineStart = new fanPosition(fanPosition.tempMin,fanPosition.fanMin); + if(curvePoints?.length!!>0){ + //初始点到第一个点 + var lineEnd = curvePoints!![0]; + if(FanControl.fanInfo[index].nowPoint.temperature!!>lineStart.temperature!!&&FanControl.fanInfo[index].nowPoint.temperature!!<=lineEnd.temperature!!){ + FanControl.fanInfo[index].setPoint = calPointInLine(lineStart,lineEnd,FanControl.fanInfo[index].nowPoint.temperature!!)!!; + } - curvePoints?.forEach((value,index)=>{ - if(index>curvePoints?.length!!-1) - return; - lineStart = value; - lineEnd = index == curvePoints?.length!!-1?new fanPosition(fanPosition.tempMax,fanPosition.fanMax):curvePoints!![index+1]; - if(FanControl.nowPoint.temperature!!>lineStart.temperature!!&&FanControl.nowPoint.temperature!!<=lineEnd.temperature!!){ - FanControl.setPoint = calPointInLine(lineStart,lineEnd,FanControl.nowPoint.temperature!!)!!; - return; + curvePoints?.forEach((value,pointIndex)=>{ + if(pointIndex>curvePoints?.length!!-1) + return; + lineStart = value; + lineEnd = pointIndex == curvePoints?.length!!-1?new fanPosition(fanPosition.tempMax,fanPosition.fanMax):curvePoints!![pointIndex+1]; + if(FanControl.fanInfo[index].nowPoint.temperature!!>lineStart.temperature!!&&FanControl.fanInfo[index].nowPoint.temperature!!<=lineEnd.temperature!!){ + FanControl.fanInfo[index].setPoint = calPointInLine(lineStart,lineEnd,FanControl.fanInfo[index].nowPoint.temperature!!)!!; + return; + } + }) + }else{ + var lineEnd = new fanPosition(fanPosition.tempMax,fanPosition.fanMax); + if(FanControl.fanInfo[index].nowPoint.temperature!!>lineStart.temperature!!&&FanControl.fanInfo[index].nowPoint.temperature!!<=lineEnd.temperature!!){ + FanControl.fanInfo[index].setPoint = calPointInLine(lineStart,lineEnd,FanControl.fanInfo[index].nowPoint.temperature!!)!!; + break; } - }) - }else{ - var lineEnd = new fanPosition(fanPosition.tempMax,fanPosition.fanMax); - if(FanControl.nowPoint.temperature!!>lineStart.temperature!!&&FanControl.nowPoint.temperature!!<=lineEnd.temperature!!){ - FanControl.setPoint = calPointInLine(lineStart,lineEnd,FanControl.nowPoint.temperature!!)!!; - break; } + + break; } - break; } - default:{ - console.error(`错误的fanmode = ${fanMode}`) + + }) + const fanSettings = Settings.appFanSettings(); + for(var index=0;index