This repository has been archived on 2025-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
Files
salt-master/hardware/raspberrypi/fan/files/fan_ctrl.py
2020-09-21 11:41:26 +02:00

97 lines
3.6 KiB
Python

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
from datetime import date
from os import path
from os import getenv
import time
import sys
# Configuration
FAN_PIN = getenv('RPI_FAN_PIN', 21) # BCM pin used to drive transistor's base
WAIT_TIME = getenv('RPI_FAN_WAITTIME', 10) # [s] Time to wait between each refresh
FAN_MIN = getenv('RPI_FAN_MIN', 80) # [%] Fan minimum speed.
PWM_FREQ = getenv('RPI_FAN_PWMFREQ', 25000) # [Hz] Change this value if fan has strange behavior
# Fan speed will change only of the difference of temperature is higher than hysteresis
hyst = getenv('RPI_FAN_HYST', 1)
debug = bool(getenv('RPI_FAN_DEBUG', 'False'))
prom_collect_dir = getenv('RPI_PROM_COLLECTDIR','/tmp/textfile-collector')
prom_collect_file = prom_collect_dir + '/rpi_fan.prom'
# Configurable temperature and fan speed steps
tempSteps = [60, 70, 75, 80] # [°C]
speedSteps = [0, 80, 90, 100] # [%]
# tempSteps = [40, 45]
# speedSteps = [0, 100]
# Setup GPIO pin
GPIO.setmode(GPIO.BCM)
GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW)
fan = GPIO.PWM(FAN_PIN, PWM_FREQ)
fan.start(0)
i = 0
cpuTemp = 0
fanSpeed = 0
cpuTempOld = 0
fanSpeedOld = 0
if debug:
print('%s Temp: %s, Fan: %s' % (date.today(), cpuTemp, fanSpeed))
# We must set a speed value for each temperature step
if len(speedSteps) != len(tempSteps):
print('Numbers of temp steps and speed steps are different')
exit(0)
try:
while 1:
# Read CPU temperature
cpuTempFile = open('/sys/class/thermal/thermal_zone0/temp', 'r')
cpuTemp = float(cpuTempFile.read()) / 1000
cpuTempFile.close()
if debug:
print('%s Temp: %s, Fan: %s' % (date.today(), cpuTemp, fanSpeed))
# Calculate desired fan speed
if abs(cpuTemp - cpuTempOld) > hyst:
# Below first value, fan will run at min speed.
if cpuTemp < tempSteps[0]:
fanSpeed = speedSteps[0]
# Above last value, fan will run at max speed
elif cpuTemp >= tempSteps[len(tempSteps) - 1]:
fanSpeed = speedSteps[len(tempSteps) - 1]
# If temperature is between 2 steps, fan speed is calculated by linear interpolation
else:
for i in range(0, len(tempSteps) - 1):
if (cpuTemp >= tempSteps[i]) and (cpuTemp < tempSteps[i + 1]):
fanSpeed = round((speedSteps[i + 1] - speedSteps[i])
/ (tempSteps[i + 1] - tempSteps[i])
* (cpuTemp - tempSteps[i])
+speedSteps[i], 1)
if fanSpeed != fanSpeedOld:
if (fanSpeed != fanSpeedOld
and (fanSpeed >= FAN_MIN or fanSpeed == 0)):
fan.ChangeDutyCycle(fanSpeed)
fanSpeedOld = fanSpeed
if path.isdir(prom_collect_dir):
with open(prom_collect_file, 'w') as f:
str = '#HELP rpi_fan fan running at percent duty cycle\n'
str += '#TYPE rpi_fan gauge\n'
str += 'rpi_fan{component="sys"} %s\n' % fanSpeed
f.write(str)
if debug:
print('%s Temp: %s, Fan: %s' % (date.today(), cpuTemp, fanSpeed))
cpuTempOld = cpuTemp
# Wait until next refresh
time.sleep(WAIT_TIME)
except Exception as exception:
print('Exception: {}'.format(type(exception).__name__))
print('Exception message: {}'.format(exception))
GPIO.cleanup()
sys.exit()