mirror of
https://github.com/lkddi/dell-fans-controller-docker.git
synced 2026-04-24 03:53:18 +08:00
init commit
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
from controller.logger import logger
|
||||
|
||||
from controller.ipmi import IpmiTool
|
||||
|
||||
|
||||
class FanController:
|
||||
|
||||
def __init__(self, host: str, username: str, password: str):
|
||||
self.host = host
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
self.ipmi = IpmiTool(self.host, self.username, self.password)
|
||||
|
||||
def set_fan_speed(self, speed: int):
|
||||
logger.info(f'Set fan speed: {speed}%')
|
||||
self.ipmi.set_fan_speed(speed)
|
||||
|
||||
def run(self):
|
||||
temperature: int = max(self.ipmi.temperature())
|
||||
logger.info(f'Current maximum temperature: {temperature}')
|
||||
|
||||
if 0 < temperature < 50:
|
||||
self.set_fan_speed(10)
|
||||
elif 50 < temperature < 55:
|
||||
self.set_fan_speed(20)
|
||||
elif 55 < temperature < 60:
|
||||
self.set_fan_speed(30)
|
||||
elif 60 < temperature < 65:
|
||||
self.set_fan_speed(40)
|
||||
else:
|
||||
logger.info(f'Switch fan control to auto mode')
|
||||
self.ipmi.switch_fan_mode(auto=True)
|
||||
@@ -0,0 +1,74 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
class IpmiTool:
|
||||
|
||||
def __init__(self, host: str, username: str, password: str):
|
||||
self.host = host
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def run_cmd(self, cmd: str) -> str:
|
||||
basecmd = f'ipmitool -H {self.host} -I lanplus -U {self.username} -P {self.password}'
|
||||
command = f'{basecmd} {cmd}'
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(
|
||||
f'execute command {cmd} failed:{result.stderr}'
|
||||
)
|
||||
|
||||
return result.stdout
|
||||
|
||||
def mc_info(self) -> str:
|
||||
"""
|
||||
execute ipmitool command mc info
|
||||
:return:
|
||||
"""
|
||||
return self.run_cmd(cmd='mc info')
|
||||
|
||||
def sensor(self) -> str:
|
||||
"""
|
||||
execute ipmitool command sensor
|
||||
:return:
|
||||
"""
|
||||
return self.run_cmd(cmd='sensor')
|
||||
|
||||
def temperature(self) -> list:
|
||||
"""
|
||||
get current temperature
|
||||
:return:
|
||||
"""
|
||||
data = self.sensor()
|
||||
temperatures = []
|
||||
|
||||
for line in data.splitlines():
|
||||
if 'Temp' in line:
|
||||
temperatures.append(float(line.split('|')[1].strip()))
|
||||
|
||||
return temperatures
|
||||
|
||||
def switch_fan_mode(self, auto: bool):
|
||||
"""
|
||||
switch the fan mode
|
||||
:param auto:
|
||||
:return:
|
||||
"""
|
||||
manual_cmd = 'raw 0x30 0x30 0x01 0x00'
|
||||
auto_cmd = 'raw 0x30 0x30 0x01 0x01'
|
||||
return self.run_cmd(cmd=auto_cmd) if auto else self.run_cmd(cmd=manual_cmd)
|
||||
|
||||
def set_fan_speed(self, speed: int):
|
||||
"""
|
||||
set fan speed
|
||||
:param speed:
|
||||
:return:
|
||||
"""
|
||||
if speed < 10 or speed > 100:
|
||||
raise ValueError(
|
||||
'speed must be between 10 and 100'
|
||||
)
|
||||
|
||||
self.switch_fan_mode(auto=False)
|
||||
base_cmd = 'raw 0x30 0x30 0x02 0xff'
|
||||
return self.run_cmd(cmd=f'{base_cmd} {hex(speed)}')
|
||||
@@ -0,0 +1,18 @@
|
||||
import logging
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
class CustomFormatter(logging.Formatter):
|
||||
def format(self, record):
|
||||
desired_timezone = timezone(timedelta(hours=8))
|
||||
current_time = datetime.now(desired_timezone).strftime('%Y-%m-%d %H:%M:%S')
|
||||
record.customtime = current_time
|
||||
return super().format(record)
|
||||
|
||||
|
||||
stream_handler = logging.StreamHandler()
|
||||
stream_handler.setFormatter(CustomFormatter(' %(customtime)s [%(levelname)s] %(message)s'))
|
||||
logger.addHandler(stream_handler)
|
||||
Reference in New Issue
Block a user