109 lines
2.6 KiB
Python
109 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
import os.path
|
|
import time
|
|
import traceback
|
|
import threading
|
|
|
|
import gpiod
|
|
|
|
import misc
|
|
|
|
pin = None
|
|
|
|
|
|
class Pwm:
|
|
def __init__(self, chip):
|
|
self.period_value = None
|
|
try:
|
|
int(chip)
|
|
chip = f'pwmchip{chip}'
|
|
except ValueError:
|
|
pass
|
|
self.filepath = f"/sys/class/pwm/{chip}/pwm0/"
|
|
try:
|
|
with open(f"/sys/class/pwm/{chip}/export", 'w') as f:
|
|
f.write('0')
|
|
except OSError:
|
|
print("Waring: init pwm error")
|
|
traceback.print_exc()
|
|
|
|
def period(self, ns: int):
|
|
self.period_value = ns
|
|
with open(os.path.join(self.filepath, 'period'), 'w') as f:
|
|
f.write(str(ns))
|
|
|
|
def period_us(self, us: int):
|
|
self.period(us * 1000)
|
|
|
|
def enable(self, t: bool):
|
|
with open(os.path.join(self.filepath, 'enable'), 'w') as f:
|
|
f.write(f"{int(t)}")
|
|
|
|
def write(self, duty: float):
|
|
assert self.period_value, "The Period is not set."
|
|
with open(os.path.join(self.filepath, 'duty_cycle'), 'w') as f:
|
|
f.write(f"{int(self.period_value * duty)}")
|
|
|
|
|
|
class Gpio:
|
|
|
|
def tr(self):
|
|
while True:
|
|
self.line.set_value(1)
|
|
time.sleep(self.value[0])
|
|
self.line.set_value(0)
|
|
time.sleep(self.value[1])
|
|
|
|
def __init__(self, period_s):
|
|
self.line = gpiod.Chip(os.environ['FAN_CHIP']).get_line(int(os.environ['FAN_LINE']))
|
|
self.line.request(consumer='fan', type=gpiod.LINE_REQ_DIR_OUT)
|
|
self.value = [period_s / 2, period_s / 2]
|
|
self.period_s = period_s
|
|
self.thread = threading.Thread(target=self.tr, daemon=True)
|
|
self.thread.start()
|
|
|
|
def write(self, duty):
|
|
self.value[1] = duty * self.period_s
|
|
self.value[0] = self.period_s - self.value[1]
|
|
|
|
|
|
def read_temp():
|
|
with open('/sys/class/thermal/thermal_zone0/temp') as f:
|
|
t = int(f.read().strip()) / 1000.0
|
|
return t
|
|
|
|
|
|
def get_dc(cache={}):
|
|
if misc.conf['run'].value == 0:
|
|
return 0.999
|
|
|
|
if time.time() - cache.get('time', 0) > 60:
|
|
cache['time'] = time.time()
|
|
cache['dc'] = misc.fan_temp2dc(read_temp())
|
|
|
|
return cache['dc']
|
|
|
|
|
|
def change_dc(dc, cache={}):
|
|
if dc != cache.get('dc'):
|
|
cache['dc'] = dc
|
|
pin.write(dc)
|
|
|
|
|
|
def running():
|
|
global pin
|
|
if os.environ['HARDWARE_PWM'] == '1':
|
|
chip = os.environ['PWMCHIP']
|
|
pin = Pwm(chip)
|
|
pin.period_us(40)
|
|
pin.enable(True)
|
|
else:
|
|
pin = Gpio(0.025)
|
|
while True:
|
|
change_dc(get_dc())
|
|
time.sleep(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
running()
|