Last active
January 1, 2021 13:16
-
-
Save xxmatyuk/5f37b719b8ba76bb6e5ce06e431b015d to your computer and use it in GitHub Desktop.
The first draft of a small Flask app running on Raspberry Pi to read DH-22 sensors temperature and to operate Noctua fans (A6 and A12) via GPIO PWM.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import board | |
import atexit | |
import json | |
import adafruit_dht | |
import RPi.GPIO as GPIO | |
from flask import Flask | |
# Fans | |
FANS_PIN = 21 | |
PWM_DEFAULT_FREQ = 100 | |
PWM_DEFAULT_DUTY = 75 | |
DEFAULT_RPM_A6 = 3000 | |
DEFAULT_RPM_A12 = 2000 | |
# Sensors | |
DHT_PIN_16 = 16 | |
DHT_PIN_20 = 20 | |
DHT_DEVICES = { | |
DHT_PIN_20: adafruit_dht.DHT22(board.D20), | |
DHT_PIN_16: adafruit_dht.DHT22(board.D16) | |
} | |
# Flask stuff | |
app = Flask(__name__) | |
# Global vars | |
fans = None | |
current_pwm_duty = None | |
current_pwm_frequency = None | |
def _init_pwm(): | |
"""Inits PWM fans controls""" | |
GPIO.setmode(GPIO.BCM) | |
GPIO.setwarnings(False) | |
GPIO.setup(FANS_PIN, GPIO.OUT, initial=GPIO.LOW) | |
global fans | |
fans = GPIO.PWM(FANS_PIN, PWM_DEFAULT_FREQ) | |
def _stop_fans(): | |
"""Stops fans without loosing controls""" | |
global fans, current_pwm_duty | |
if fans: | |
fans.stop() | |
current_pwm_duty = 0 | |
def _stop_pwm_fans_control(): | |
"""Stops fans and does cleanup""" | |
global fans | |
_stop_fans() | |
GPIO.cleanup() | |
fans = None | |
def _set_fans_pwm_duty_cycle(percent): | |
"""Sets fans' duty cycle""" | |
global fans, current_pwm_duty | |
if fans: | |
fans.ChangeDutyCycle(percent) | |
current_pwm_duty = percent | |
def _set_fans_pwm_frequency(freq): | |
"""Sets fans' frequency""" | |
global fans, current_pwm_frequency | |
if fans: | |
fans.ChangeFrequency(freq) | |
current_pwm_frequency = freq | |
def _get_current_rpm(): | |
"""Returns RPM values based on PWM status and its values of duty and frequency""" | |
global fans, current_pwm_duty | |
if not fans: | |
return DEFAULT_RPM_A6, DEFAULT_RPM_A12 | |
elif fans and current_pwm_duty == 0: | |
return 0, 0 | |
elif fans and current_pwm_duty == 100: | |
return DEFAULT_RPM_A6, DEFAULT_RPM_A12 | |
else: | |
return (current_pwm_duty*DEFAULT_RPM_A6)/100, (current_pwm_duty*DEFAULT_RPM_A12)/100 | |
def _get_sensor_temperature(pin): | |
"""Gets tempreature mesure of a given sensor""" | |
try: | |
d = DHT_DEVICES.get(pin, None) | |
if d: | |
return d.temperature | |
except Exception: | |
return -100 | |
def _get_average_temperature(): | |
"""Gets average temperature from two available sensors""" | |
t1 = _get_sensor_temperature(DHT_PIN_16) | |
t2 = _get_sensor_temperature(DHT_PIN_20) | |
if t1 and t2: | |
return (t1 + t2)/2 | |
@app.route("/get-sensor-temperature/<int:pin>") | |
def get_sensor_temp(pin): | |
return str(_get_sensor_temperature(pin)) | |
@app.route("/get-average-temperature") | |
def get_avg_temp(): | |
return str(_get_average_temperature()) | |
@app.route("/pwm/start") | |
def pwm_start(): | |
msg = "No action taken" | |
try: | |
global fans, current_pwm_duty, current_pwm_frequency | |
_init_pwm() | |
fans.start(PWM_DEFAULT_DUTY) | |
current_pwm_duty = PWM_DEFAULT_DUTY | |
current_pwm_frequency = PWM_DEFAULT_FREQ | |
return "Started." | |
except RuntimeError: | |
return msg | |
return msg | |
@app.route("/pwm/set-duty/<int:percent>") | |
def pwm_set_duty(percent): | |
global fans | |
if fans: | |
_set_fans_pwm_duty_cycle(percent) | |
return "Duty is set to: %s" % percent | |
return "No action taken." | |
@app.route("/pwm/set-frequency/<int:freq>") | |
def pwm_set_frequency(freq): | |
global fans | |
if fans: | |
_set_fans_pwm_frequency(freq) | |
return "Frequency is set to: %s" % freq | |
return "No action taken." | |
@app.route("/pwm/stop") | |
def pwm_stop(): | |
global fans | |
if fans: | |
_stop_fans() | |
return "Stopped." | |
return "No action taken." | |
@app.route("/pwm/cleanup") | |
def pwm_cleanup(): | |
global fans | |
if fans: | |
_stop_pwm_fans_control() | |
return "Contols stopped." | |
return "No action taken." | |
@app.route("/stats") | |
def stats(): | |
global fans, current_pwm_duty, current_pwm_frequency | |
rpm_a6, rpm_a12 = _get_current_rpm() | |
stats = { | |
"pwm_enabled": True if fans else False, | |
"t1_temperature": _get_sensor_temperature(DHT_PIN_16), | |
"t2_temperature":_get_sensor_temperature(DHT_PIN_20), | |
"pwm_duty_cycle": current_pwm_duty if fans else 0, | |
"pwm_frequency": current_pwm_frequency if fans else 0, | |
"rpm_a6": rpm_a6, | |
"rpm_a12": rpm_a12, | |
} | |
return json.dumps(stats, indent=4) | |
atexit.register(_stop_pwm_fans_control) | |
if __name__ == "__main__": | |
app.run(host='0.0.0.0') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment