-
Notifications
You must be signed in to change notification settings - Fork 0
/
temperature_pwm_controller.py
145 lines (124 loc) · 6.06 KB
/
temperature_pwm_controller.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python3
import configparser
from rpi_hardware_pwm import HardwarePWM
import psutil
import time
import sys
import atexit
import syslog
import os
import signal
#Inicializa las variables
canal_pwm = 0
frecuencia = 25000
ciclo_de_trabajo_anterior = 0
temperatura_anterior = 0
tiempo = 6
ciclo_de_trabajo = 0
pwm = HardwarePWM(canal_pwm, frecuencia)
def print_debug(mensaje):
if debug and not as_a_service:
print(mensaje)
if debug and as_a_service:
syslog.syslog(syslog.LOG_INFO, mensaje)
def inicializar_configuracion():
# Valores predeterminados
defaults = {
'intervalo_de_prueba': 5,
'canal_pwm': 0,
'frecuencia': 25000,
'temp_min': 45,
'temp_max': 65,
'ciclo_min': 60,
'ciclo_max': 100,
'histeresis': 2,
'debug': False,
'as_a_service': True
}
try:
# Cargar configuración desde el archivo INI
config = configparser.ConfigParser()
config.read("temperature_pwm_controller.ini")
# Desempaquetar la configuración o usar valores predeterminados
intervalo_de_prueba = config.getint("config", "intervalo_de_prueba", fallback=defaults['intervalo_de_prueba'])
canal_pwm = config.getint("config", "canal_pwm", fallback=defaults['canal_pwm'])
frecuencia = config.getint("config", "frecuencia", fallback=defaults['frecuencia'])
temp_min = config.getint("config", "temp_min", fallback=defaults['temp_min'])
temp_max = config.getint("config", "temp_max", fallback=defaults['temp_max'])
ciclo_min = config.getint("config", "ciclo_min", fallback=defaults['ciclo_min'])
ciclo_max = config.getint("config", "ciclo_max", fallback=defaults['ciclo_max'])
histeresis = config.getint("config", "histeresis", fallback=defaults['histeresis'])
debug = config.getboolean("config", "debug", fallback=defaults['debug'])
as_a_service = config.getboolean("config", "as_a_service", fallback=defaults['as_a_service'])
return (intervalo_de_prueba, canal_pwm, frecuencia, temp_min, temp_max, ciclo_min, ciclo_max, histeresis, debug, as_a_service)
except Exception as e:
print(f"Error al cargar la configuración: {str(e)}")
syslog.syslog(syslog.LOG_ERR, f"Error al cargar la configuración: {str(e)}")
# Utiliza los valores predeterminados si hay un error al cargar la configuración
return tuple(defaults.values())
def calcular_ciclo_de_trabajo(temp, temp_min, temp_max, ciclo_min, ciclo_max, ciclo_actual, hysteresis):
try:
if temp < temp_min:
return 0
elif temp > temp_max:
return 100
elif temp_min <= temp:
if (temp > (temperatura_anterior + hysteresis)) or (temp < (temperatura_anterior - hysteresis)):
print_debug(f"***Superada histéresis. Nueva temperatura: {temp:.2f}ºC. Nuevo ciclo de trabajo: {ciclo_de_trabajo:.0f}%. La temperatura anterior era {temperatura_anterior:.2f} °C. El ciclo anterior era de {ciclo_de_trabajo_anterior:.0f}%")
ciclo = (temp - temp_min) * (ciclo_max - ciclo_min) / (temp_max - temp_min) + ciclo_min
ciclo = max(ciclo_min, min(ciclo, ciclo_max))
return round(ciclo)
return round(ciclo_actual)
except Exception as e:
print_debug(f"Error al calcular el ciclo de trabajo: {str(e)}")
return round(ciclo_actual)
def parar_ventilador(signum, frame):
try:
syslog.syslog(syslog.LOG_INFO, "Parando salida PWM")
pwm.stop();
time.sleep(1)
# Asegurarse de que todos los buffers estén vacíos antes de salir
sys.stdout.flush()
sys.stderr.flush()
sys.exit(0)
except Exception as e:
print_debug(f"Error al parar el servicio: {str(e)}")
try:
# Llama a la función para inicializar la configuración
(intervalo_de_prueba, canal_pwm, frecuencia, temp_min, temp_max, ciclo_min, ciclo_max, histeresis, debug, as_a_service) = inicializar_configuracion()
script_name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
syslog.openlog(ident=script_name, facility=syslog.LOG_USER)
syslog.syslog(syslog.LOG_INFO, f"El servicio {script_name} se está ejecutando.")
# Para que se detenga el ventilador al para el script
signal.signal(signal.SIGTERM, parar_ventilador)
pwm.start(100)
time.sleep(1)
pwm.change_duty_cycle(0)
while True:
temp = psutil.sensors_temperatures()['cpu_thermal'][0].current
ciclo_de_trabajo = calcular_ciclo_de_trabajo(temp, temp_min, temp_max, ciclo_min, ciclo_max, ciclo_de_trabajo, histeresis)
if tiempo >= intervalo_de_prueba and debug is True:
mensaje = f"La temperatura de la CPU es {temp:.2f} °C. El ciclo de trabajo es de {ciclo_de_trabajo:.0f}%"
print_debug(mensaje)
mensaje = f"La temperatura anterior era {temperatura_anterior:.2f} °C. El ciclo anterior era de {ciclo_de_trabajo_anterior:.0f}%"
print_debug(mensaje)
mensaje = f"--------------------------------------------------------------------------------------------"
print_debug(mensaje)
tiempo = 0
else:
tiempo += 1
if ciclo_de_trabajo_anterior == 0 and ciclo_de_trabajo != 0:
print_debug(f"Arrancando ventilador... (temperatura {temp:.2f}ºC)")
pwm.change_duty_cycle(100)
ciclo_de_trabajo_anterior = 100
time.sleep(1)
if ciclo_de_trabajo != ciclo_de_trabajo_anterior:
pwm.change_duty_cycle(ciclo_de_trabajo)
print_debug(f"Nueva temperatura: {temp:.2f}ºC. Nuevo ciclo de trabajo: {ciclo_de_trabajo:.0f}%")
print_debug(f"Temperatura cambio anterior: {temperatura_anterior:.2f}ºC. Ciclo de trabajo anterior: {ciclo_de_trabajo_anterior:.0f}%")
ciclo_de_trabajo_anterior = ciclo_de_trabajo
temperatura_anterior = temp
time.sleep(intervalo_de_prueba)
except Exception as e:
print(f"Error general: {str(e)}")
syslog.syslog(syslog.LOG_ERR, f"Error general: {str(e)}")