from labcontrol.ea import EA_PS8080,EA_EL9080,EA_interface
from labcontrol.meter import MeterConfig,K2100Multimeter
import time
import i2c.i2c2 as pit
import signal

# Setup
maxpower    = 1000   #maximum powerdraw for complete system in W
psvolt      = [48.0] #supplied voltage in V
steps       = 20     # number of steps to measure between 0 and 100% power
settletime  = 8.     # time to wait between setting current to draw and measurements in s
measures    = 8      # number of measurements per setting
measuretime = .6     # time between measures in s

# defines
# stepwidth = maxpower/psvolt/steps
starttime = time.time()

def identify(devlist, mm=False):
    outdict = {}
    for dev in devlist:
        devid = EA_interface(dev).write(12, 0, [])
        if "PS" in devid[1]:
            devtype = "ps"
        else:
            devtype = "el"

        outdict[devtype] = {"id":devid[1][:-1], "address":dev, "type":devtype}

    if mm == True:
        outdict['mm']['dev']    = K2100Multimeter(mm_config)
        outdict['mm']['type']   = "mm"
        outdict['mm']['config'] = MeterConfig()
    
    return outdict

def init(tree):
    for dev, dat in tree.iteritems():
        if dat['type'] == "el":
            devobj = EA_EL9080(tree[dev]['address'])
            devobj.remote(True)
        elif dat['type'] == "ps":
            devobj = EA_PS8080(tree[dev]['address'])
            devobj.remote(True)
        elif dat['type'] == "mm":
            devobj = K2100Multimeter(tree[dev]['config'])
        
        devobj.interface.debug_output = False
        
        tree[dev]['dev'] = devobj


def setRanges(tree, volts):
    for dev, dat in tree.iteritems():
        if dat['type'] == "el":
            dat['dev'].set_current(0)
            dat['dev'].enable(True)
        elif dat['type'] == "ps":
            dat['dev'].set_current(maxpower/volts+1)
            dat['dev'].set_power(maxpower+1)
            dat['dev'].set_voltage(volts)
            dat['dev'].output(True)
        

def deinit(signum, frame):
    for dev, dat in devicetree.iteritems():
        if devicetree[dev]['type'] == "el":
            devicetree[dev]['dev'].enable(False)
        #else:
            #tree[dev]['dev'].output(False)
        devicetree[dev]['dev'].remote(False)
        devicetree[dev]['dev'].close()

    #signal.signal(signal.SIGINT, original_sigint)

def measurement(devicetree, volts):

    devicetree['ps']['dev'].set_current(maxpower/volts*1.1)
    for i in range(1, steps+1):
        steppercent = 100 * i/float(steps)
        adcdata = {'T':0, 'V48':0, 'I48':0}
        try:
            act_el = devicetree['el']['dev'].get_actual_values()
            act_ps = devicetree['ps']['dev'].get_actual_values()
            devicetree['el']['dev'].set_current(steppercent /100 *maxpower/act_el['v'])
            time.sleep(settletime)
            act_el['i'] = 0
            act_ps['i'] = 0
            for m in range(0, measures):
                act_el['i'] += devicetree['el']['dev'].get_actual_values()['i']
                act_ps['i'] += devicetree['ps']['dev'].get_actual_values()['i']
                #act_mm += devicetree['mm']['dev'].get_voltage()
                adc = pit.rxtx_em()
                for k in adcdata:
                    adcdata[k] += adc[k]

                time.sleep(measuretime)

            act_ps['i'] /= measures
            act_el['i'] /= measures
            for k in adcdata:
                adcdata[k] /= measures


            #$act_mm = act_mm/measures
            log_new= "{:.2f},{:d},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f}\n".format(
                time.time()-starttime, 
                int(steppercent),
                act_ps['v'], 
                act_ps['i'],
                act_ps['p'],
                act_el['v'],                
                act_el['i'],
                act_el['p'],
                adcdata['T'],
                adcdata['V48'],
                adcdata['I48']
            )
            log += log_new
        except Exception as e:
            print type(e)
            print e

    print(log)

if __name__ == "__main__":
    #original_sigint = signal.getsignal(signal.SIGINT)
    #signal.signal(signal.SIGINT, deinit)
    devicetree = identify(["/dev/ttyUSB0","/dev/ttyUSB1"])

    # manually start measurement by enabling 8V OUT
    init(devicetree)
    setRanges(devicetree, 48.0)
    print("waiting for enable")
    print(devicetree)
    while (devicetree['el']['dev'].get_actual_values()['v'] < 5):
        time.sleep(measuretime)

    # prep log 
    time.sleep(settletime)
    print("starting Measurement (approx {}s)".format(steps*(settletime + measures*measuretime)*len(psvolt)))
    log = "time,perc_power,act_volt_ps,act_curr_ps,act_pow_ps,act_volt_el,act_curr_el,act_pow_el,pit_t,pit_v48,pit_i48\n"
    for volts in psvolt:
        #init(devicetree, volts)
        #init(devicetree, volts)
        setRanges(devicetree, volts)
        measurement(devicetree, volts)
    with open('./log.csv', 'w') as f:
        f.write(log)
    deinit(devicetree)
