import GPIBPrologix
import bme280
import smbus2
from requests import post

## Initialize GPIB adapter
GPIB = GPIBPrologix.ResourceManager("/dev/ttyACM0")
# Connect equipment
inst1 = GPIB.open_resource(7)
inst2 = GPIB.open_resource(3)
inst3 = GPIB.open_resource(16)
# Initialize BME280 temperature/humidity sensor
bus = smbus2.SMBus(1)
## Configure equipment
# BME280 temperature/humidity sensor
calibration_params = bme280.load_calibration_params(bus, 0x76)
# Prema 3040 thermometer readout
inst1.query("R3")     #Resistance mode 3, PT100 1mA
inst1.query("F2")     #Auto filter
inst1.query("T7")     #Set integration time 4S
inst1.query("CN0")    #Only data on query
inst1.query("O4")     #4 Wire
inst1.query("U1")     #Basic unit ON
inst1.query("AZA1")   #Auto zero on
inst1.query("AZT0300")#Auto zero every 300seconds
inst1.query("MAR")    #Front, Channel A, RTD
# EOI temp controller
inst2.query("S2")
inst2.query("LLA 15")
inst2.query("LHA 35")
inst2.query("R3")
# Advantest R6581T
inst3.query("*RST")
inst3.query(":CONF:FRES")
inst3.query(":SENS:FRES:POW HI")
inst3.query(":SENS:FRES:DIG MAX")
inst3.query(":SENS:FRES:NPLC 100")
inst3.query(":SENS:ZERO:AUTO ON")
inst3.query(":INPut:GUARd LOW")

# Measurement functions
def readValue(instObj):
    value = instObj.query("FETch?")
    return value
def readTemperature(instObj):
    value = instObj.query("RD?") #Query a measurement
    value = round((float(value[:10])-100)/0.385,4)
    return value
def setTemperature(instObj, inputVar):
    instObj.query("D"+str(inputVar))
    return inputVar
def getEnvironment(instObj, i2cbus):
    value = instObj.sample(i2cbus, 0x76, calibration_params)
    return value

def findparabolaVertex(a,b,c):
   print ("Vertex: (",(-b/(2*a)),",",(((4*a*c)-(b*b))/(4*a)),")")
   return -(-b/(2*a))

## Have gitpython pull in the repository
import os
import git
import shutil
username = input("Your 0xC6 git username: ")
password = input("Your 0xC6 git password: ")
remote = f"https://{username}:{password}@git.0xc6.com/xans/ResistorDatabase.git"
if not os.path.exists(os.getcwd()+"/ResistorDatabase"):
    git.Repo.clone_from(remote, os.getcwd()+"/ResistorDatabase/")
else:
    shutil.rmtree(os.getcwd()+"/ResistorDatabase/", ignore_errors=True)
    git.Repo.clone_from(remote, os.getcwd()+"/ResistorDatabase/")

## Get needed info to properly label everything
manufacturer = input("Manufacturer: ").lower()
restype      = input("Resistor Type: ").upper()
nomValue     = input("Nominal resistor value: ").upper() # Use R instead of dot
resdate      = input("Manufactury date: ").upper()
resid        = input("Personally assigned ID: ").upper()
shellyIp        = input("If you use shelly for protection, enter the IP: ").upper()
if shellyIp and os.system("ping -c 1 " + shellyIp):
    print("shelly not found")
    quit()
if shellyIp:
    url = "{}://{}:{}/relay/0?turn=on".format("http", "192.168.0.101", "80")
    post(url)

## Create proper directory structure
basePath = os.getcwd() + "/ResistorDatabase/"
if not os.path.exists(basePath+manufacturer):
    os.makedirs(basePath+manufacturer)
if not os.path.exists(basePath+manufacturer+'/'+restype):
    os.makedirs(basePath+manufacturer+'/'+restype)
if not os.path.exists(basePath+manufacturer+'/'+restype+"/data/"):
    os.makedirs(basePath+manufacturer+'/'+restype+"/data/")
basePath = basePath+manufacturer+'/'+restype
print(basePath+"/data/")

import csv  
import time
import datetime
import numpy as np
import pandas as pd
from math import sin
## Create logfile
logFileName = restype+'-'+nomValue+'-'+resdate+'-'+resid+'.csv'
with open(basePath+"/data/"+logFileName, 'a') as f:
    writer = csv.writer(f)
    writer.writerow(["DateTime","Resistance","Box Temperature", "Set Temperature","Env Pressure","Env Temperature", "Env Humidity"])
print(basePath+"/data/"+logFileName)

sweep = np.append([23] * 25, np.arange(23,28,0.1))
sweep = np.append(sweep, [28] * 25)
sweep = np.append(sweep, np.arange(28,23,-0.1))
sweep = np.append(sweep, [23] * 25)
sweep = np.append(sweep, np.arange(23,18,-0.1))
sweep = np.append(sweep, [18] * 25)
sweep = np.append(sweep, np.arange(18,23,0.1))
sweep = np.append(sweep, [23] * 25)

cntr = 0
## Collect data
setPoint = setTemperature(inst2,round(sweep[0],3))
time.sleep(600)
for x in sweep:
    cntr = cntr + 1
    try:
        #Set temp and let accimatize
        setPoint = setTemperature(inst2,round(x,3))
        print(str(cntr)+'/'+str(len(sweep)))
        time.sleep(15)
        for i in range(3):
            try:
                time.sleep(5)
                #Get DUT value
                readout = readValue(inst3)
                #Read the temperature
                temperature = readTemperature(inst1)
                #Get envirnmental values
                data = getEnvironment(bme280, bus)
                #Write to file
                d = datetime.datetime.now()
                dx = d - datetime.timedelta(microseconds=d.microsecond)
                fields=[dx.strftime("%d-%m-%y %H:%M:%S"),float(readout),float(temperature),setPoint,round(data.humidity,2),round(data.temperature,2),round(data.pressure,2)]
                print(fields)
                with open(basePath+"/data/"+logFileName, 'a') as f:
                    writer = csv.writer(f)
                    writer.writerow(fields)
                if shellyIp and float(temperature) > 30 or float(temperature) < 16:
                    url = "{}://{}:{}/relay/0?turn=off".format("http", "192.168.0.101", "80")
                    post(url)
            except Exception as e: 
                print(e)
                inst1.query("*RST")
                time.sleep(3)
                inst1.query("R3")     #Resistance mode 3, PT100 1mA
                inst1.query("F2")     #Auto filter
                inst1.query("T7")     #Set integration time 4S
                inst1.query("CN0")    #Only data on query
                inst1.query("O4")     #4 Wire
                inst1.query("U1")     #Basic unit ON
                inst1.query("AZA1")   #Auto zero on
                inst1.query("AZT0300")#Auto zero every 300seconds
                inst1.query("MAR")    #Front, Channel A, RTD
                time.sleep(3)
                inst1.query("U1")
                time.sleep(33)
                i = i-1
    except Exception as e: 
        print(e)
        time.sleep(1)

## Calculate TCR
df = pd.read_csv(basePath+"/data/"+logFileName)
abCoef = np.polyfit(df["Box Temperature"], df["Resistance"], 2)
zeroTC = findparabolaVertex(abCoef[0],abCoef[1],0)
zeroTC = round(zeroTC,3)
if abs(zeroTC) >= 500:
    zeroTC = '/'
alpha = (abCoef[1]*1000000)/float(nomValue)
beta  = (abCoef[0]*1000000)/float(nomValue)
if abs(alpha) >= 50000:
    alpha = '/'
else:
    alpha = round(alpha,3)
if abs(beta) >= 50000:
    beta = '/'
else:
    beta  = round(beta,3)

## Make plot and save
from matplotlib import pyplot as plt
plt.plot(df["Box Temperature"], df["Resistance"])
plt.plot(df["Box Temperature"], ((abCoef[0]*pow(df["Box Temperature"],2))+abCoef[1]*df["Box Temperature"]+abCoef[2]))
plt.xlabel('Temperature DUT (PT100, °C)')
plt.ylabel('Resistance DUT (Ohms)')
plt.title ('TCR sweep '+ logFileName[:-4])
plt.savefig(basePath+"/data/"+logFileName[:-4]+".jpg", bbox_inches='tight')

## Write away values to result overview
if not os.path.exists(basePath+'/README.md'):
    with open(basePath+'/README.md', 'a') as f:
        f.write("| Manufacturer | Type | Nominal Value | Manufacturing Date | Alpha(ppm) | Beta(ppm) | Zero-Tempco | File | ID | User |\n")
        f.write("|--------------|------|---------------|--------------------|------------|-----------|-------------|------|----|------|\n")
        f.close()
with open(basePath+'/README.md', 'a') as f:
    linkToImg = "/data/"+logFileName[:-4]+".jpg"
    print("|"+manufacturer+"|"+restype+"|"+nomValue+"|"+resdate+"|"+str(alpha)+"|"+str(beta)+"|"+str(-zeroTC)+"|"+linkToImg+"|"+resid+"|"+username+"|\n")
    f.write("|"+manufacturer+"|"+restype+"|"+nomValue+"|"+resdate+"|"+str(alpha)+"|"+str(beta)+"|"+str(-zeroTC)+"|"+linkToImg+"|"+resid+"|"+username+"|\n")
    f.close()
    repo = git.Repo(os.getcwd() + "/ResistorDatabase/")
    repo.git.add(basePath)
    repo.index.commit("Add resistor "+ logFileName)
    repo.remotes[0].push()

