#! /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()