import RPi.GPIO as GPIO
from datetime import datetime


class Sensors:
    """Class for communicate with sensors through MCP3008"""

    def __init__(self, config):
        self.mosi = int(config.get('adc', 'MOSI'))
        self.miso = int(config.get('adc', 'MISO'))
        self.clk = int(config.get('adc', 'CLK'))
        self.cs = int(config.get('adc', 'CS'))
        self.channel = 0
        self.config = config

        GPIO.setup(self.mosi, GPIO.OUT)
        GPIO.setup(self.miso, GPIO.IN)
        GPIO.setup(self.clk, GPIO.OUT)
        GPIO.setup(self.cs, GPIO.OUT)

    # read SPI data from MCP3008(or MCP3204) chip,8 possible adc's (0 thru 7)
    def readadc(self):
        adcnum = self.getChannel()

        if ((adcnum > 7) or (adcnum < 0)):
            return -1

        GPIO.output(self.cs, True)
        GPIO.output(self.clk, False)  # start clock low
        GPIO.output(self.cs, False)     # bring CS low

        commandout = adcnum
        commandout |= 0x18  # start bit + single-ended bit
        commandout <<= 3    # we only need to send 5 bits here
        for i in range(5):
            if (commandout & 0x80):
                GPIO.output(self.mosi, True)
            else:
                GPIO.output(self.mosi, False)

            commandout <<= 1
            GPIO.output(self.clk, True)
            GPIO.output(self.clk, False)

        adcout = 0

        # read in one empty bit, one null bit and 10 ADC bits
        for i in range(12):
            GPIO.output(self.clk, True)
            GPIO.output(self.clk, False)
            adcout <<= 1
            if (GPIO.input(self.miso)):
                adcout |= 0x1

        GPIO.output(self.cs, True)

        return adcout

    # Convert value to volt
    def convertToVoltage(self, value):
        correction = 1
        if (self.getChannelModel() == "arceli"):
            correction = 2

        return value * (3.3 / 1024) * 5 / correction

    # Convert volt to celcius value
    def convertToCelcius(self, value):
        value /= 2
        return (value * (3300.0/1024.0) - 100.0) / 10.0 - 40.0

    def convertToPrintableValue(self, value):
        if (self.getChannelType() == 'voltage'):
            return self.convertToVoltage(value)
        else:
            return self.convertToCelcius(value)

    def getChannelType(self):
        return self.config.get(
                'sensors',
                'SENSOR_' + str(self.channel) + '_TYPE'
        )

    def getChannelModel(self):
        return self.config.get(
                'sensors',
                'SENSOR_' + str(self.channel) + '_MODEL'
        )

    def getChannel(self):
        return self.channel

    def setChannel(self, channel):
        self.channel = channel

    def getValue(self):
        if (self.channel == 8):
            now = datetime.now()
            return now.strftime("%H:%M")
        else:
            raw_value = self.readadc()
            value = self.convertToPrintableValue(raw_value)

            return f"{value:.02f}"

    def main(self):
        print('MAIN')
