'''
expEYES program
Author  : Ajith Kumar B.P, bpajith@gmail.com
License : GNU GPL version 3
'''
import gettext
gettext.bindtextdomain("expeyes")
gettext.textdomain('expeyes')
_ = gettext.gettext

import time, math, sys
if sys.version_info.major==3:
        from tkinter import *
else:
        from Tkinter import *

sys.path=[".."] + sys.path

import expeyes.eyesj as eyes
import expeyes.eyeplot as eyeplot
import expeyes.eyemath as eyemath

WIDTH  = 600   # width of drawing canvas
HEIGHT = 400   # height    

class PT100:
	tv = [ [], [] ]			# Lists for Readings
	TIMER = 500				# Time interval between reads
	MINY = 0				# Temperature range
	MAXY = 100
	running = False
	current = 1.0		    # 1mA nominal
	gain = 1.0				
	calibrated = False
	bpdone = False
	fpdone = False

	def get_freezing(self):
		v = p.get_voltage(1)
		temp = self.v2t(v)
		#print temp
		if -10 < temp < 10:
			self.BPvoltage = v
			self.fpdone = True
			self.msg(_('Voltage at Freezing Point is %5.3f V')%v)
		else:
			self.msg(_('Something wrong. Check the connection & Rg'))

	def get_boiling(self):
		v = p.get_voltage(1)
		temp = self.v2t(v)
		#print temp
		if 90 < temp < 110:
			self.BPvoltage = v
			self.bpdone = True
			self.msg(_('Voltage at Boiling Point is %5.3f V')%v)
		else:
			self.msg(_('Something wrong. Check the connection & Rg'))

	def calibrate(self):
		if self.bpdone == True and self.fpdone == True:
			self.m = (100.0 - 0.0) / (self.BPvoltage - self.FPvoltage)
			self.c = self.FPvoltage
			self.calibrated = True
			self.msg(_('Calibration Done m = %5.3f, c = 5.3f')%(self.m, self.c))
		else:
			self.msg(_('Boiling & Freezing points to be measured first'))

	def v2t(self, v):			# Convert Voltage to Temperature for PT100
		r = v / self.gain / (self.current * 1.0e-3)  # mA to Ampere
		r0 = 100.0
		A = 3.9083e-3
		B = -5.7750e-7
		c = 1 - r/r0
		b4ac = math.sqrt( A*A - 4 * B * c)
		t = (-A + b4ac) / (2.0 * B)
		#print self.current, self.gain, v, r, t
		#print r,t
		return t

	def xmgrace(self):
		if self.running == True:
			return
		p.grace([self.tv])

	def start(self):
		self.running = True
		self.index = 0
		self.tv = [ [], [] ]
		try:
			self.MAXTIME = int(DURATION.get())
			self.MINY = int(TMIN.get())
			self.MAXY = int(TMAX.get())
			self.gain = float(Gval.get())
			self.current = float(CCval.get())
			#print self.gain, self.current
			g.setWorld(0, self.MINY, self.MAXTIME, self.MAXY,_('Time'),_('Volt'))
			self.TIMER = int(TGAP.get())
			Total.config(state=DISABLED)
			Dur.config(state=DISABLED)
			self.msg(_('Starting the Measurements'))
			root.after(self.TIMER, self.update)
		except:
			self.msg(_('Failed to Start'))

	def stop(self):
		self.running = False
		Total.config(state=NORMAL)
		Dur.config(state=NORMAL)
		self.msg(_('User Stopped the measurements'))

	def update(self):
		if self.running == False:
			return
		t,v = p.get_voltage_time(3)  # Read A1
		if len(self.tv[0]) == 0:
			self.start_time = t
			elapsed = 0
		else:
			elapsed = t - self.start_time
		self.tv[0].append(elapsed)
		if self.calibrated:
			temp = self.m * v + self.c		# Use the calibration 
		else:
			temp = self.v2t(v)
		#print v,temp
		self.tv[1].append(temp)
		if len(self.tv[0]) >= 2:
			g.delete_lines()
			g.line(self.tv[0], self.tv[1])
		if elapsed > self.MAXTIME:
			self.running = False
			Total.config(state=NORMAL)
			Dur.config(state=NORMAL)
			self.msg(_('Completed the Measurements'))
			return 
		root.after(self.TIMER, self.update)

	def calc_gain(self):
		vs = p.set_voltage(.1)
		va = p.get_voltage(1)
		#print va, vs, va/vs
		if va < -1:
			self.gain = va/vs
		else:
			self.gain = 1
			self.msg(_('Wrong connections or value of Rg'),'red')
		Gval.set('%5.1f'%(self.gain))

	def save(self):
		try:
			fn = filename.get()
		except:
			fn = 'pt100.dat'
		p.save([self.tv],fn)
		self.msg(_('Data saved to %s')%fn)

	def clear(self):
		if self.running == True:
			return
		self.nt = [ [], [] ]
		g.delete_lines()
		self.msg(_('Cleared Data and Trace'))

	def msg(self,s, col = 'blue'):
		msgwin.config(text=s, fg=col)

	def quit(self):
		p.set_state(11,0)
		sys.exit()

p = eyes.open()
p.disable_actions()
p.set_state(11,1)
root = Tk()
Canvas(root, width = WIDTH, height = 5).pack(side=TOP)  # Some space at the top
g = eyeplot.graph(root, width=WIDTH, height=HEIGHT, bip=False)	# make plot objects using draw.disp
pt = PT100()

cf = Frame(root, width = WIDTH, height = 10)
cf.pack(side=TOP,  fill = BOTH, expand = 1)

b3 = Label(cf, text = _('Read Every'))
b3.pack(side = LEFT, anchor = SW)
TGAP = StringVar()
Dur =Entry(cf, width=5, bg = 'white', textvariable = TGAP)
TGAP.set('500')
Dur.pack(side = LEFT, anchor = SW)
b3 = Label(cf, text = _('mS,'))
b3.pack(side = LEFT, anchor = SW)
b3 = Label(cf, text = _('for total'))
b3.pack(side = LEFT, anchor = SW)
DURATION = StringVar()
Total =Entry(cf, width=5, bg = 'white', textvariable = DURATION)
DURATION.set('100')
Total.pack(side = LEFT, anchor = SW)
b3 = Label(cf, text = _('Seconds.'))
b3.pack(side = LEFT, anchor = SW)

b3 = Label(cf, text = _('Range'))
b3.pack(side = LEFT, anchor = SW)
TMIN = StringVar()
TMIN.set('0')
Tmin =Entry(cf, width=5, bg = 'white', textvariable = TMIN)
Tmin.pack(side = LEFT, anchor = SW)
b3 = Label(cf, text = _('to,'))
b3.pack(side = LEFT, anchor = SW)
TMAX = StringVar()
TMAX.set('200')
Tmax =Entry(cf, width=5, bg = 'white', textvariable = TMAX)
Tmax.pack(side = LEFT, anchor = SW)
b3 = Label(cf, text = _('C. '))
b3.pack(side = LEFT, anchor = SW)
b1 = Button(cf, text = _('START'), command = pt.start)
b1.pack(side = LEFT, anchor = N)
b1 = Button(cf, text = _('STOP'), command = pt.stop)
b1.pack(side = LEFT, anchor = N)
b4 = Button(cf, text = _('CLEAR'), command = pt.clear)
b4.pack(side = LEFT, anchor = N)

cf = Frame(root, width = WIDTH, height = 10)
cf.pack(side=TOP,  fill = BOTH, expand = 1)

b1 = Label(cf, text = _('Gain='))
b1.pack(side = LEFT, anchor = N)
Gval = StringVar()
Gval.set('1')
Gain =Entry(cf, width=5, bg = 'white', textvariable = Gval)
Gain.pack(side = LEFT, anchor = SW)

b3 = Label(cf, text = _('Current ='))
b3.pack(side = LEFT, anchor = SW)
CCval = StringVar()
CCval.set('1.0')
Ccs =Entry(cf, width=4, bg = 'white', textvariable = CCval)
Ccs.pack(side = LEFT, anchor = SW)
Label(cf, text = _('mA')).pack(side = LEFT, anchor = SW)
b1 = Button(cf, text = _('Xmgrace'), command = pt.xmgrace)
b1.pack(side = LEFT, anchor = N)
b3 = Button(cf, text = _('SAVE to'), command = pt.save)
b3.pack(side = LEFT, anchor = N)
filename = StringVar()
e1 =Entry(cf, width=15, bg = 'white', textvariable = filename)
filename.set('pt100.dat')

cf = Frame(root, width = WIDTH, height = 10)
cf.pack(side=TOP,  fill = BOTH, expand = 1)
b1 = Button(cf, text = _('Freezing Point'), command = pt.get_freezing)
b1.pack(side = LEFT, anchor = N)
b1 = Button(cf, text = _('Boiling Point'), command = pt.get_boiling)
b1.pack(side = LEFT, anchor = N)
b1 = Button(cf, text = _('Calibrate'), command = pt.calibrate)
b1.pack(side = LEFT, anchor = N)
e1.pack(side = LEFT)
b5 = Button(cf, text = _('QUIT'), command = pt.quit)
b5.pack(side = RIGHT, anchor = N)

mf = Frame(root, width = WIDTH, height = 10)
mf.pack(side=TOP)
msgwin = Label(mf,text=_('Message'), fg = 'blue')
msgwin.pack(side=LEFT, anchor = S, fill=BOTH, expand=1)

eyeplot.pop_image('pics/pt100.png', _('Temperatue by PT100'))
root.title(_('Temperature measuements using PT100'))
root.mainloop()

