Skip to content

Instantly share code, notes, and snippets.

@supersonictw
Last active April 26, 2024 12:21
Show Gist options
  • Save supersonictw/046e10024038c18ccb46cbf3f1a88b79 to your computer and use it in GitHub Desktop.
Save supersonictw/046e10024038c18ccb46cbf3f1a88b79 to your computer and use it in GitHub Desktop.
Cold down the temperature of OPi automatically.
#!/usr/bin/python3
# opi_fan - Cold down the temperature of OPi automatically.
# License: MIT (https://ncurl.xyz/s/RD0Yl5fSg)
# https://gist.github.com/supersonictw/046e10024038c18ccb46cbf3f1a88b79
from sys import argv
from time import sleep
from gpiod import (
request_lines,
LineSettings
)
from gpiod.line import (
Direction,
Value,
)
""" /usr/local/sbin/opi_fan
#!/bin/sh
BASE_DIR="/opt/opi_fan"
INTERPRETER="$BASE_DIR/venv/bin/python"
CONTROLLER="$BASE_DIR/main.py"
"$INTERPRETER" "$CONTROLLER" $1
"""
""" /lib/systemd/system/opi_fan.service
[Unit]
Description=Cold down the temperature of OPi automatically.
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/sbin/opi_fan daemon
[Install]
WantedBy=multi-user.target
"""
CHECK_TIME_GAP = 60
FAN_CONTROL_PIN = 6
FAN_ENABLE_TEMPERATURE = 60
COLD_TEMPERATURE_GAP = 10
SYS_GPIO_CHIP_FILE = "/dev/gpiochip0"
SYS_TEMPERATURE_FILE = "/sys/devices/virtual/thermal/thermal_zone0/temp"
class Fan:
def __init__(self) -> None:
self.request = request_lines(
SYS_GPIO_CHIP_FILE,
consumer="opi_fan",
config={
FAN_CONTROL_PIN: LineSettings(
direction=Direction.OUTPUT,
output_value=Value.INACTIVE
)
},
)
def enable(self):
self.request.set_value(
FAN_CONTROL_PIN,
Value.ACTIVE,
)
def disable(self):
self.request.set_value(
FAN_CONTROL_PIN,
Value.INACTIVE,
)
def cleanup(self):
self.disable()
self.request.release()
def temperature_read():
with open(SYS_TEMPERATURE_FILE, "r") as f:
temperature = f.read()
return int(temperature) / 1000
def temperature_loop():
while temperature_read() > (FAN_ENABLE_TEMPERATURE - COLD_TEMPERATURE_GAP):
sleep(CHECK_TIME_GAP)
def task_cold():
fan = Fan()
try:
fan.enable()
while True:
sleep(CHECK_TIME_GAP)
except KeyboardInterrupt:
print("Task interrupted.")
finally:
fan.cleanup()
def task_daemon():
fan = Fan()
while True:
if temperature_read() < FAN_ENABLE_TEMPERATURE:
sleep(CHECK_TIME_GAP)
continue
fan.enable()
temperature_loop()
fan.disable()
def task_temp():
temperature = temperature_read()
print(f"{temperature:.1f}°C")
if __name__ == '__main__':
command_tasks = {
"cold": task_cold,
"daemon": task_daemon,
"temp": task_temp,
}
if len(argv) > 1 and argv[1] in command_tasks:
command_tasks[argv[1]]()
else:
print("No task specified.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment