import time
import os
import math

import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008

import RPi.GPIO as GPIO

import board
import busio
import numpy as np
import math
import cv2
from threading import Thread

class Heater(object):
    def __init__(self,pwm_pin,target_temp):
        self.target_temp = target_temp
        self.pin = pwm_pin
        self.last_temp = 0.0
        self.isOpened = False
        self.thread = Thread(target=self.job)
    # Convert data to voltage level
    def ReadVolts(self,data,deci,input_volts=3.3):
        volts = (data * input_volts) / float(1023)
        volts = round(volts,deci)
        return volts
    def GetTemperature(self,data,input_volts=3.3):
        Rp=10000
        T2=273.15+25
        Bx=3950
        Ka=273.15
        vol = (data * input_volts) / float(1023)
        Rt=vol*1000/(input_volts-vol)
        if((Rt/Rp)<0):
            return -1
        else:
            return 1/(1/T2+math.log(Rt/Rp)/Bx)-Ka+0.5
    def job(self):
        SPI_PORT   = 0
        SPI_DEVICE = 0

        SIGNAL_CHANNEL = 0

        mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))

        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.pin,GPIO.OUT)

        p = GPIO.PWM(self.pin,1000)
        
        duty_cycle = 100.0
        alpha = 1.0
        p.start(duty_cycle)
        while self.isOpened:
            data = mcp.read_adc(SIGNAL_CHANNEL)
            if(data!=0 and data!= 1023):
                volts = (data * 5.0) / float(1023)
                temp = self.GetTemperature(data,5.0)
                self.last_temp = temp
#                 print(data,volts,temp,duty_cycle)
                duty_cycle-=alpha*(temp-self.target_temp)
                duty_cycle = 100.0 if duty_cycle > 100.0 else duty_cycle
                duty_cycle = 0.0 if duty_cycle < 0.0 else duty_cycle

                p.ChangeDutyCycle(duty_cycle)        

                time.sleep(0.1)
        p.stop()
    def start(self):
        self.isOpened = True
        self.thread.start()
    def stop(self):
        self.isOpened = False
#         self.thread.stop()