temp-fan-control/scripts/mvp.py

135 lines
5.1 KiB
Python
Raw Normal View History

#! /usr/bin/env python3
#import RPIO
import RPi.GPIO as GPIO
import time
import sys
import spidev
import yaml
import os
from decimal import *
from datetime import datetime
from datetime import timedelta
class MVP:
def __init__(self):
print("Initialization...")
dirname = os.path.dirname(os.path.realpath(__file__))
self.config = None
with open(os.path.join(dirname, "config.yml"), "r") as stream:
self.config = yaml.safe_load(stream)
self.spi = None
self.fan = None
self.ufan = None
self.spi = spidev.SpiDev()
self.spi.open(0,0)
self.spi.mode = self.config.get("defaults").get("spi").get("mode")
self.spi.max_speed_hz = self.config.get("defaults").get("spi").get("hz")
GPIO.setmode(GPIO.BCM)
for k, v in self.config.get("fan_output").items():
if v.get("switch", None):
GPIO.setup(v.get("switch"), GPIO.OUT)
if v.get("pwm", None):
GPIO.setup(v.get("pwm"), GPIO.OUT)
self.fan = GPIO.PWM(self.config["fan_output"]["in"]["pwm"], 25000)
self.ufan = GPIO.PWM(self.config["fan_output"]["out"]["pwm"],25000)
for k, v in self.config.get("temp_input").items():
GPIO.setup(v.get("switch"), GPIO.OUT)
GPIO.output(v.get("switch"), False)
self.fan.start(self.config.get("defaults").get("pwm").get("start_c"))
self.ufan.start(self.config.get("defaults").get("pwm").get("start_c"))
print("...done")
def read_spiADC(self, sensor):
bcm_pin = self.config.get("temp_input").get(sensor).get("switch")
channel = self.config.get("temp_input").get(sensor).get("channel")
GPIO.output(bcm_pin, True)
hchbit=channel >> 2
lchbits = channel & 0x03
to_send = [ hchbit | 0x06, lchbits << 6, 0x00 ]
self.spi.cshigh=True
# time.sleep(0.01)
self.spi.cshigh = False
r=self.spi.xfer(to_send)
self.spi.cshigh = True
GPIO.output(bcm_pin, False)
# time.sleep(0.01)
highbyte = r[1]
lowbyte = r[2]
value = (highbyte << 8) | lowbyte
return value
def calc_temp(self, adc_reading, channel = 0):
rser = self.config.get("temp_input").get(channel).get("Rk", None)
tnom = self.config.get("defaults").get("tnom")
rnom = self.config.get("defaults").get("rnom")
corr = self.config.get("defaults").get("corr")
if not rser:
rser = rnom
r = (rser/(4095/adc_reading - 1))
r = r - corr
t = r/rnom
if t < 0:
t = t * -1
t = float(Decimal(t).ln()) / 4050 + 1.0/(tnom + 273.15)
t = 1/t
t = t - 273.15
return t
def set_duty(self, fan, percent):
if percent == 0:
GPIO.output(self.config["fan_output"][fan]["switch"], False)
else:
GPIO.output(self.config["fan_output"][fan]["switch"], True)
self.fan.ChangeDutyCycle(100 - percent)
print("Duty: {fan}: {pwm}".format(fan=fan, pwm=percent))
def run(self):
print("Starting...")
try:
last_th = -1
while True:
# read temperatures
inner = self.read_spiADC("inside")
outer = self.read_spiADC("outside")
if inner != 0 and outer != 0:
# inner_R = rnom/(4095/ inner - 1)
inner_T = self.calc_temp(inner, "inside")
# outer_R = rnom/(4095/ outer - 1)
outer_T = self.calc_temp(outer, "outside")
# activate/deactivate and pwm
difference = inner_T - outer_T
operation = self.config.get("operation")
for elem in operation:
greater = elem.get("greater")
if (
difference > greater and
last_th != greater
):
hyst = self.config["defaults"]["hysterese"]
in_pwm = elem.get("in_pwm")
out_pwm = elem.get("out_pwm")
if (
difference + hyst > greater and greater > last_th or
difference - hyst < greater and greater < last_th
):
self.set_duty("in", in_pwm)
self.set_duty("out", out_pwm)
last_th = greater
print("Inner temp: {:.2f} - outer temp: {:.2f} || difference: {:.2f}".format(inner_T, outer_T, difference))
break
if int(time.time()) % 10 == 0:
print("Inner temp: {:.2f} - outer temp: {:.2f} || difference: {:.2f}\n".format(inner_T, outer_T, difference))
time.sleep(0.5)
except Exception as e:
raise e
finally:
GPIO.cleanup()
self.spi.close()
mvp = MVP()
mvp.run()