import queue
import zmq
import math
import MAX11270 as adc
import MCP4822 as dac

import globalvars

def adc2T(dU):
    #constants
    #VREF = (REF+) – (REF–)
    #Vref = 2.5
    #wheatstonebridge
    #   U0_____
    #          |
    #          R0
    #   Uw_____|__
    #      |      |
    #      R2     R4
    #      |__dU__|
    #      |      |
    #      R1     R3
    #      |______|
    #  Gnd_____|_
    #
    # R1 = resistance of thermistor
    R0 = 0
    R2 = 5100 #(Ohm)
    R3 = 97600 #(Ohm)
    R4 = 5100 #(Ohm)
    U0 = 3 #(V)
    #steinhart-Hart Coefficients 10uA
    # NTC_A = 9.7142e-4;
    # NTC_B = 2.3268e-4;
    # NTC_C = 8.0591e-8;
    #steinhart-Hart Coefficients 100uA
    NTC_A = 9.6542e-4
    NTC_B = 2.3356e-4
    NTC_C = 7.7781e-8

    R1 = -(R0*R2*dU - R2*R3*U0 + R0*R3*dU + R0*R4*dU + R2*R3*dU + R2*R4*dU)/(R4*U0 + R0*dU + R3*dU + R4*dU)
    #calculate temperature
    try:
        T = 1/(NTC_A + NTC_B*math.log(float(R1)) + NTC_C*math.pow(math.log(float(R1)),3)) - 273.15
    except ValueError:
        T = 6666
    return T

#Thread for handling communication with spi devices
#def spithread(adc, dac,in_queue,out_queue):
def spithread(adc, dac):
    context = zmq.Context()
    server = context.socket(zmq.REP)
    server.bind("tcp://*:5555")

    stop = False
    while not globalvars.stopall and not stop:
        cmd_recv = server.recv()    #Blocking call, wait for a new message

        ans = 'NAK'
        msg = cmd_recv.decode().split('\t')
        #msg = in_queue.get()    #Blocking call, waits for an element
        try:
            msg[1] = int(msg[1])
            msg[2] = int(msg[2])
            msg[3] = int(msg[3])
        except (IndexError, ValueError):
            pass

        if msg[0] == 'ADC':
            if msg[1] <= 1:
                if msg[2] <= 1:
                    try:
                        T = adc2T(adc[msg[1]].read_differential())
                    except TimeoutError:
                        print("Conversion takes to long!")
                        T = 100
                    if msg[3] <= 5:
                        ans = str(T)
                        #out_queue[msg[3]].put(T)
                    else:
                        print('Error: Invalid output queue!')
                else:
                    print('Error: Invalid device channel!')
            else:
                print('Error: Invalid device number!')

        elif msg[0] == 'DAC':
            if msg[1] <= 1:
                if msg[2] <= 1:
                    if msg[2] == 1:
                        voltage = float(msg[4]) -  dac[msg[1]].nullVoltage
                        T = dac[msg[1]].write(voltage,msg[2])
                    else:
                        T = dac[msg[1]].write(float(msg[4]),msg[2])
                    if msg[3] <= 5:
                        #out_queue[msg[3]].put('ACK')
                        ans = 'ACK'
                    else:
                        print('Error: Invalid output queue!')
                else:
                    print('Error: Invalid device channel!')
            else:
                print('Error: Invalid device number!')
        elif msg[0] == 'END':
            ans = 'ACK'
            stop = True
        else:
            print('Error: Invalid device!')

        #zmq ensure that the answer is delivered to the right clientthread
        server.send(ans.encode())
