#! /bin/env python
#-------------------------------------------------------------------
#
#  File:     RmMotorFrame.py
#  Purpose:  Motor Display Frame
#  Created:  June 22, 2000
#  Author:   Lionel PEYRICHOUX
#
#-------------------------------------------------------------------

from Tkinter import *
from CaChannel import *
from Dialog import Dialog
from ConfigMotor import *
from Canvas import *
from Data import *
 

#===============================================================
#
# Description of each Rack Monitor :
# 	* Name

RackMonitor =  ('CTL_RM_02-01',  
		'CTL_RM_02-02', 
		'CTL_RM_02-03', 
		'CTL_RM_02-04', 
		'CTL_RM_02-11', 
		'CTL_RM_02-12', 
		'CTL_RM_02-13', 
		'CTL_RM_02-14', 
		'CTL_RM_02-05', # Smoke Detector to the Dipoles
		'CTL_RM_02-15') # Smoke Detector to P1

# End of the description of each Rack Monitor
#
#=============================================================== 



#===============================================================
#
# Drawing Pot

DrPot = ((67,380, 87,390),	# D2 Inside
	(139,344,159,354),	# D1 Inside
	(226,223,236,243),	# A2 Top
	(226,323,236,343),	# A2 Bottom
	(171,278,191,288),	# A2 Outside
	(271,278,291,288),	# A2 Inside
	(322,175,332,195),	# A1 Top
	(322,275,332,295),	# A1 Bottom
	(267,230,287,240),	# A1 Outside
	(367,230,387,240),	# A1 Inside
	(490, 91,500,111),	# P1 Top
	(490,191,500,211),	# P1 Bottom
	(435,146,455,156),	# P1 Outside
	(535,146,555,156),	# P1 Inside
	(586, 43,596, 63),	# P2 Top
	(586,143,596,163),	# P2 Bottom
	(531, 98,551,108),	# P2 Outside
	(631, 98,651,108))	# P2 Inside

# End of Drawing Pot 
#
#=============================================================== 



#===============================================================
#
# ErrorInput :
#	* size = 18 (motors) * 3 (errors/motors)
#	* ErrorInput[i][0]=1 => Mechanical failure
#	* ErrorInput[i][1]=1 => Cable Failure
#	* ErrorInput[i][2]=1 => Driver Failure

ErrorInput=[]

# End of ErrorInput
#
#=============================================================== 



#===============================================================
#
# TestOneMotor :
#	* size = 18
#	* TestOneMotor[i]=1 => The datas (position and speed) 
#		can be send to the motor i when the user press
#		the button 'RUN' 
#	* TestOneMotor[i]=0 => The datas (Position and Speed)
#		can't be send to the motor

TestOneMotor=[]

# End of TestOneMotor
#
#=============================================================== 



#===============================================================
#
# OutputRM :
#	* size = Number of Rack Monitor x 2
#	* This array has the words sent to each motor
#
# Example:
#	OutputRM[2][0] = 111  -> put the word 111 to the Channel P08 of the Rack Monitor CTL_RM_02-03
#	OutputRM[2][1] = 101  -> put the word 101 to the Channel P02 of the Rack Monitor CTL_RM_02-03

OutputRM=[]

# End of OutputRM
#
#=============================================================== 



#===============================================================
#
# InputRM :
#	* size = Number of Rack Monitor x 2
#
# Example:
#	InputRM[2][0] = 111  -> get the word 111 to the Channel P03 of the Rack Monitor CTL_RM_02-03
#	InputRM[2][1] = 101  -> get the word 101 to the Channel P07 of the Rack Monitor CTL_RM_02-03

InputRM = []

# End of InputRM
#
#=============================================================== 



#===============================================================
#
# LVDTRM :
#	* size = Number of Rack Monitor x 4
#
# Example:
#	InputRM[2][0] = 111  -> get the word 111 to the Channel 32 of the Rack Monitor CTL_RM_02-03
#	InputRM[2][1] = 703  -> get the word 703 to the Channel 33 of the Rack Monitor CTL_RM_02-03
#	InputRM[2][3] = 354  -> get the word 354 to the Channel 34 of the Rack Monitor CTL_RM_02-03
#	InputRM[2][4] = 265  -> get the word 265 to the Channel 35 of the Rack Monitor CTL_RM_02-03

LVDTRM = []				# Initialisation LVDTRM (P10 channel 32 to 35)

# End of LVDTRM
#
#=============================================================== 



#===============================================================
#
# HomeLVDT :
#	* size = 18
#	* LVDT value when the motors are in Home Position

HomeLVDT=[]

# End of HomeLVDT
#
#=============================================================== 





tempo_mechanical_error = []



#===============================================================
#
# Canvas Class
#

class CanvasDisplay:


	def __init__(self,parent):
			
		self.display=Canvas(parent,width=640,height=480,relief=GROOVE,bd=4)
		
		self.item=[]
		self.beam=[]
		
		for i in range(len(DrPot)):
		
			self.item.insert(i,self.display.create_rectangle(DrPot[i][0],DrPot[i][1],DrPot[i][2],DrPot[i][3],fill='red',outline='black'))
		
		for i in range(30):
			self.beam.insert(i*2,self.display.create_polygon(7+i*12,389-i*6,13+i*12,386-i*6,16+i*12,392-i*6,14+i*12,398-i*6,8+i*12,401-i*6,10+i*12,395-i*6,fill='blue'))
			self.beam.insert(i*2+1,self.display.create_polygon(13+i*12,386-i*6,19+i*12,383-i*6,22+i*12,389-i*6,20+i*12,395-i*6,14+i*12,398-i*6,16+i*12,392-i*6,fill='black'))

		for j in range(30,45):
			i=j-30
			self.beam.insert(i*2,self.display.create_polygon(631-i*12,77+i*6,637-i*12,74+i*6,634-i*12,80+i*6,636-i*12,86+i*6,630-i*12,89+i*6,628-i*12,83+i*6,fill='brown'))
			self.beam.insert(i*2+1,self.display.create_polygon(625-i*12,80+i*6,631-i*12,77+i*6,628-i*12,83+i*6,630-i*12,89+i*6,624-i*12,92+i*6,622-i*12,86+i*6,fill='black'))
		
		self.display.create_text(410,195,text='D0')
			
		self.display.bind("<Button-1>",self.ChoicePot)
		
		self.display.pack(side=TOP)
		self.NumInput = 0
		self.beam_color=0

		return
			
	def update(self):

#		for i in range(20):
#			if self.beam_color == 0:
#				self.display.itemconfigure(self.beam[i*2],fill='blue')
#				self.display.itemconfigure(self.beam[i*2+1],fill='black')
#				self.display.itemconfigure(self.beam[20+i*2],fill='brown')
#7				self.display.itemconfigure(self.beam[20+i*2+1],fill='black')
#			else:
#				self.display.itemconfigure(self.beam[i*2],fill='black')
#				self.display.itemconfigure(self.beam[i*2+1],fill='blue')
#				self.display.itemconfigure(self.beam[20+i*2],fill='black')
#				self.display.itemconfigure(self.beam[20+i*2+1],fill='brown')

#		if self.beam_color==0:
#			self.beam_color=1
#		else:
#			self.beam_color=0
		
		
		for i in range(len(Pot)):
			
			if Pot[i][7]>10:
				NumRM = Pot[i][7] - 7
			else:
				NumRM = Pot[i][7] - 1

			if ErrorRM[NumRM] == 0:
				val=float(LVDTRM[NumRM][Pot[i][8]-32])
			else:
				val=0

			if (Pot[i][1]=='Top'):
				x=0
				y=(0.0048828125*val + 10)*1.5
			elif (Pot[i][1]=='Bottom'):
				x=0
				y=-(0.0048828125*val + 10)*1.5
			elif (Pot[i][1]=='Inside'):
				x=-(0.0048828125*val + 10)*1.5
				y=0
			else:
				x=(0.0048828125*val + 10)*1.5
				y=0

			self.display.coords(self.item[i],DrPot[i][0]+x,DrPot[i][1]+y,DrPot[i][2]+x,DrPot[i][3]+y)
		
			if ErrorInput[i] != [0,0,0]:
				color='red'
			else:
				if TestOneMotor[i].get() == 1:
					color='green'
				else:
					color='orange'
								
			self.display.itemconfigure(self.item[i],fill=color,outline='black')

		return self.NumInput
		
	def ChoicePot(self,event):

		try:
			tag=self.display.find_withtag('current')[0]-1
		except:
			return
		
		if tag<len(Pot):
			self.NumInput = Pot[tag][9]
		
		return
 
#===============================================================
#
# ErrorFrame Class
#

class ErrorFrame(Frame):

	def __init__(self,
		     parent):

		Frame.__init__(self,parent,relief=GROOVE,bd=4)

		self.parent=parent

		for i in range(len(Pot)):
			ErrorInput.insert(i,[0,0,0])
			HomeLVDT.insert(i,0)
			tempo_mechanical_error.insert(i,0)
			
		HomeLVDT[0]=1.42
		HomeLVDT[1]=0.7
		
		self.__CreateFrame()
		
	def __CreateFrame(self):

		self.text=StringVar()

		top=self.top=Toplevel(self.parent)

 		Label(self.top,textvariable=self.text,anchor=W,font=("Times",12)).pack(side=TOP)
							
	def update(self):
	
		self.Dialog_Failure_text=''

		for i in range(len(RackMonitor)):

			if (ErrorRM[i] == 1):
				self.Dialog_Failure_text=self.Dialog_Failure_text + 'Error accessing Rack Monitor : ' + RackMonitor[i] + chr(13)

		for i in range(len(Pot)):
		
			if int(Pot[i][4]) < 10:
				NumRM = int(Pot[i][4])-1
			else:
				NumRM = int(Pot[i][4])-7
			
			if ErrorRM[NumRM] == 0:
			
				self.Dialog_Failure_Pot_text = ''

				if Pot[i][6] == 0:
					InputData=InputRM[NumRM][Pot[i][5]] & 0x007f
				else:
					InputData=(InputRM[NumRM][Pot[i][5]] & 0x3f80) / 0x0080
		
				if ((InputData & 0x0010) == 16):
					ErrorInput[i][1]=1
					self.Dialog_Failure_Pot_text = self.Dialog_Failure_Pot_text + '   Mechanical Failure' + chr(13)
					
					if int(Pot[i][4]) < 10:
						NumRM = int(Pot[i][4])-1
					else:
						NumRM = int(Pot[i][4])-7
				
					if (OutputRM[NumRM][Pot[i][3]] & 16384) == 16384:
						OutputRM[NumRM][Pot[i][3]]=OutputRM[NumRM][Pot[i][3]]-16384
						tempo_mechanical_error[i] = 0
						print 'Mechanical Failure for the Motor', Pot[i][0], Pot[i][1],': Speed is automatically changed by the software.'						
					else:
						tempo_mechanical_error[i] = tempo_mechanical_error[i] +1
						if tempo_mechanical_error[i] == 5:
							OutputRM[NumRM][Pot[i][3]]=0
				else:
					ErrorInput[i][1] = 0
					tempo_mechanical_error[i] = 0
		
				if ((InputData & 0x0001) == 1):
					ErrorInput[i][0]=1
					self.Dialog_Failure_Pot_text = self.Dialog_Failure_Pot_text + '   Cable Failure' + chr(13)
					OutputRM[NumRM][Pot[i][3]]=0
				else:
					ErrorInput[i][0]=0

				if ((InputData & 0x0020) != 32):
					ErrorInput[i][2]=1
					self.Dialog_Failure_Pot_text = self.Dialog_Failure_Pot_text + '   Driver Failure' + chr(13)
					OutputRM[NumRM][Pot[i][3]]=0
				else:
					ErrorInput[i][2]=0
		
				if ((InputData & 0x0002) == 2):
					if int(Pot[i][7]) < 10:
						NumRMLVDT = int(Pot[i][7])-1
					else:
						NumRMLVDT = int(Pot[i][7])-7
#					HomeLVDT[i]=(0.0048828125*float(LVDTRM[NumRMLVDT][Pot[i][8]-32])+10)*2
					
				if (self.Dialog_Failure_Pot_text != ''):
					self.Dialog_Failure_text = self.Dialog_Failure_text + Pot[i][0] + ' ' + Pot[i][1] + chr(13) + self.Dialog_Failure_Pot_text
				 
			else:
				ErrorInput[i][0]=1
				ErrorInput[i][1]=1
				ErrorInput[i][2]=1
				OutputRM[NumRM][Pot[i][3]]=0

		self.text.set(self.Dialog_Failure_text + chr(13))

		return
 
class InputFrame(Frame):

	def __init__(self,
		     parent):
		     
		Frame.__init__(self,parent,relief=GROOVE,bd=4)
		
		self.__NameLabel=StringVar()
		self.__OrientationLabel=StringVar()
		self.__StatusLabel=StringVar()
		self.__WantedPositionLabel=StringVar()
		self.__PositionLabel=StringVar()
		self.__HomePosLabel=StringVar()
		self.__InPos=StringVar()
		self.__CabFailure=StringVar()
		self.__DrFailure=StringVar()
		self.__MecFailure=StringVar()
		self.failure = 0
		
		self.__CreateFrame()	
		
		return
			
	def __CreateFrame(self):
	
		f = Frame(self)
		
		l = Label(f, text='Name',font=("Times",12)).grid(row=0, column=0, sticky=W)
		Label(f,textvariable=self.__NameLabel,relief=GROOVE,width=11,font=("Times",12)).grid(row=0, column=1, sticky=W)

		l = Label(f, text='Orientation',font=("Times",12)).grid(row=1, column=0, sticky=W)
		Label(f,textvariable=self.__OrientationLabel,relief=GROOVE,width=11,font=("Times",12)).grid(row=1, column=1, sticky=W)

		l = Label(f, text='Status',font=("Times",12)).grid(row=2, column=0, sticky=W)
		Label(f,textvariable=self.__StatusLabel,relief=GROOVE,width=11,font=("Times",12)).grid(row=2, column=1, sticky=W)

		l = Label(f, text='POSITION',font=("Times",12)).grid(row=3, column=0, sticky=W)

		l = Label(f, text='  Wanted',font=("Times",12)).grid(row=4, column=0, sticky=W)
		Label(f,textvariable=self.__WantedPositionLabel,relief=GROOVE,width=11,font=("Times",12)).grid(row=4, column=1, sticky=W)
		
		l = Label(f, text='  Current',font=("Times",12)).grid(row=5, column=0, sticky=W)
		Label(f,textvariable=self.__PositionLabel,relief=GROOVE,width=11,font=("Times",12)).grid(row=5, column=1, sticky=W)		

		l = Label(f, text='  Home',font=("Times",12)).grid(row=6, column=0, sticky=W)
		Label(f,textvariable=self.__HomePosLabel,relief=GROOVE,width=11,font=("Times",12)).grid(row=6, column=1, sticky=W)

		l = Label(f, text='  In',font=("Times",12)).grid(row=7, column=0, sticky=W)
		Label(f,textvariable=self.__InPos,relief=GROOVE,width=11,font=("Times",12)).grid(row=7, column=1, sticky=W)

		l = Label(f, text='FAILURES',font=("Times",12)).grid(row=8, column=0, sticky=W)
		
		l = Label(f, text='  Cable',font=("Times",12)).grid(row=9, column=0, sticky=W)
		Label(f,textvariable=self.__CabFailure,relief=GROOVE,width=11,font=("Times",12)).grid(row=9, column=1, sticky=W)

		l = Label(f, text='  Driver',font=("Times",12)).grid(row=10, column=0, sticky=W)
		Label(f,textvariable=self.__DrFailure,relief=GROOVE,width=11,font=("Times",12)).grid(row=10, column=1, sticky=W)

		l = Label(f, text='  Mechanical',font=("Times",12)).grid(row=11, column=0, sticky=W)
		Label(f,textvariable=self.__MecFailure,relief=GROOVE,width=11,font=("Times",12)).grid(row=11, column=1, sticky=W)

		f.pack()

		return
	
	def update(self,
		   NumInput = None):
		
		if int(Pot[NumInput][2]) < 10:
			NumRM = int(Pot[NumInput][2])-1
		else:
			NumRM = int(Pot[NumInput][2])-7

				
		self.__WantedPositionLabel.set(str('%6.2f' %(float((OutputRM[NumRM][Pot[NumInput][3]] & 8191)*25/3000))))

		if Pot[NumInput][6] == 0:
			InputData=InputRM[NumRM][Pot[NumInput][5]] & 0x007f
		else:
			InputData=(InputRM[NumRM][Pot[NumInput][5]] & 0x3f80) / 0x0080
			
		self.__NameLabel.set(Pot[NumInput][0])
		self.__OrientationLabel.set(Pot[NumInput][1])


		if ((InputData & 0x0001) == 1):
			self.__CabFailure.set('YES')
		else:
			self.__CabFailure.set('NO')
		
		if ((InputData & 0x0002) == 2):
			self.__HomePosLabel.set('YES')
		else:
			self.__HomePosLabel.set('NO')
		
		if ((InputData & 0x0004) == 4):
			self.__InPos.set('YES')
		else:
			self.__InPos.set('NO')
		
		if ((InputData & 0x0008) == 8):
			self.__StatusLabel.set('RUN')
		else:
			self.__StatusLabel.set('STOP')
		
		if ((InputData & 0x0010) == 16):
			self.__MecFailure.set('YES')
		else:
			self.__MecFailure.set('NO')
		
		if ((InputData & 0x0020) != 32):
			self.__DrFailure.set('YES')
		else:
			self.__DrFailure.set('NO')
		
		val=((0.0048828125*float(LVDTRM[NumRM][Pot[NumInput][8]-32])+10)*2)*33.5/24-HomeLVDT[NumInput]
		
		self.__PositionLabel.set(str('%6.2f' %val))
		

		
#		import shelve
#		
#		dbase=shelve.open('databaseMotor','c')
#		
#		print ctime(time())
							
		return	
		
	def destroy(self):
		
		Frame.destroy(self)
		
		return
 
class OutputFrame(Frame):

	__SpeedParams = ('Low ','High')

	def __init__(self,
		     parent,NumInput=None):
		     				
		Frame.__init__(self,parent,relief=GROOVE,bd=4)
				
		self.__CreateFrame()
		self.NewPosition = '0'
		self.HomePosition = 0
		self.__SpeedChoice.set(self.__SpeedParams[0])
		self.NumInput=NumInput
		 
		for i in range(len(Pot)):
			TestOneMotor.insert(i,IntVar())
			TestOneMotor[i].set(0)
		
		return
	
	def __NewValue(self,event):
	
		self.NewPosition = event.widget.get()
				
		self.__UnlockValue(event)
		
		return
		
	def __LockValue(self, event):
	
		self.__NewPos.lock = 1
		self.__NewPos.config(bg = 'lightgoldenrod1')
		
		return
		
	def __UnlockValue(self, event):
	
		self.__NewPos.lock = 0
		self.__NewPos.config(bg = 'lightgray')
	
		return
	
	def __CreateFrame(self):
	
		f = Frame(self)
		
		l = Label(f,text='New Position :',font=("Times",12)).grid(row=0, column=0, sticky=W)
		self.__NewPos = Entry(f,relief=GROOVE,width=11)
		self.__NewPos.lock=0
#		self.__NewPos.bind("<Double-Button-1>",self.__b1Callback)
		self.__NewPos.bind('<FocusIn>', self.__LockValue)
		self.__NewPos.bind('<FocusOut>', self.__UnlockValue)
		self.__NewPos.bind('<Return>',self.__NewValue)
		self.__NewPos.grid(row=0, column=1, sticky=W)
		
		l = Label(f,text='Speed :',font=("Times",12)).grid(row=1, column=0, sticky=W)
		self.__SpeedIndex=IntVar()
		self.__SpeedChoice=StringVar()
		b=OptionMenu(f,self.__SpeedChoice, "0")
		b.config(relief=GROOVE,font=("Times",12))
		b.grid(row=1, column=1, sticky=W)
		m = Menu(b)
		m.add_radiobutton(label=self.__SpeedParams[0],variable=self.__SpeedIndex,
				  value=0,command=self.__SpeedSet,font=("Times",12))
		m.add_radiobutton(label=self.__SpeedParams[1],variable=self.__SpeedIndex,
				  value=1,command=self.__SpeedSet,font=("Times",12))
		self.__SpeedLabel = b
		self.__SpeedMenu = m
		b['menu'] = m
	
		f.pack()
	
		f = Frame(self,relief=GROOVE)
	
		b = Button(f,text='Run',command=self.Run,font=("Times",12))
		b.pack(side=LEFT,expand=YES)

		b = Button(f,text='Stop',command=self.StopMotor,font=("Times",12))
		b.pack(side=RIGHT,expand=YES)

		f.pack(side=TOP,expand=YES,fill=X)
		f = Frame(self,relief=GROOVE)

		b = Button(f,text='Home',command=self.Home,font=("Times",12))
		b.pack()
		self.__HomeButton=b
	
		f.pack(side=TOP,expand=YES,fill=X)

		return	
		
	def __SpeedSet(self):
	
		MenuChoice = self.__SpeedIndex.get()
		self.__SpeedChoice.set(self.__SpeedParams[MenuChoice])
		
		return

	def StopMotor(self):

		word = 0
		val = word & 0xffff
		
		for i in range(len(Pot)):

			if int(Pot[i][4]) < 10:
				NumRM = int(Pot[i][4])-1
			else:
				NumRM = int(Pot[i][4])-7
					
			OutputRM[NumRM][Pot[i][3]]= val 
			print Pot[i][4]
		
		self.HomePosition = 0

		return

	def Run(self):
		
		try:
			float(self.NewPosition)
		except:
			if (self.NewPosition == ''):
 				text = 'You must enter a position'
			else:
				text = 'The new position must be a number.'
			Dialog(self,
			       title = 'Error',
			       text = text,
			       bitmap = 'error',
			       strings=  ('OK',),
			       default = 0)
			self.NewPosition = ''
			self.__NewPos.delete(0,'end')
			return

		if (float(self.NewPosition)*120 > 8160):
		
			Dialog(self,
			       title = 'Error',
			       text = 'New position > 68 mm',
			       bitmap = 'error',
			       strings=  ('OK',),
			       default = 0)
			       
			return
		
		if (float(self.NewPosition) < 0):
		
			Dialog(self,
			       title = 'Error',
			       text = 'New position < 0',
			       bitmap = 'error',
			       strings=  ('OK',),
			       default = 0)
			       
			return
				
			
		if self.HomePosition == 1:
			word=int(self.HomePosition * 32768 + self.__SpeedIndex.get()*16384)
		else:
			word =int ( self.__SpeedIndex.get()*16384  + 8192 + float(self.NewPosition)*1000*3/25)
			
		if (self.NewPosition == '0'):
			text = 'Home Position'
		else:
			text = 'New Position : ' + chr(13) + '   %d half turns' %(float(self.NewPosition)*120) + chr(13) + '   %6.2f mm' %(float(self.NewPosition)) + chr(13)
		
		for i in range(len(Pot)):
			if TestOneMotor[i].get() == 1:
			
				text=text + chr(13) + '   ' + Pot[i][0] + ' ' + Pot[i][1]
			
		ans = Dialog(self,
			     title = 'New Position',
			     text = text,anchor=W,
			     bitmap = 'question',
			     strings=('YES','NO'),default=0)
			
		if ans.num == 0:

			for i in range(len(Pot)):
				if TestOneMotor[i].get() == 1:
			
					val=word & 0xffff
					if ErrorInput[i] == [0,0,0]:

						if int(Pot[i][4]) < 10:
							NumRM = int(Pot[i][4])-1
						else:
							NumRM = int(Pot[i][4])-7
					
						OutputRM[NumRM][Pot[i][3]]= val 
					print val
				
			self.HomePosition = 0
		return

	def Home(self):
        
		self.HomePosition=1
		self.NewPosition = '0'
		self.Run()
		return

	def destroy(self):

		Frame.destroy(self)
		return

	def update(self):
	
		for i in range(len(Pot)):
			
			if int(Pot[i][4]) < 10:
				NumRM = int(Pot[i][4])-1
			else:
				NumRM = int(Pot[i][4])-7
				
			wanted=(OutputRM[NumRM][Pot[i][3]] & 8191)*25/3000
			val=((0.0048828125*float(LVDTRM[NumRM][Pot[i][8]-32])+10)*2-HomeLVDT[i])*33.5/24
			
			if ((abs(wanted-val) < 0.5) & ((OutputRM[NumRM][Pot[i][3]] & 16384) == 16384)) == 1:
				OutputRM[NumRM][Pot[i][3]]=OutputRM[NumRM][Pot[i][3]]-16384
		

class ChoiceMotorFrame(Frame):
	
	
	def __init__(self,parent):
	
		Frame.__init__(self,parent,relief=GROOVE,bd=4)
		
		self.textButton=StringVar()
		self.textButton.set("Run")
		
		self.__CreateFrame()

		return
		
	def __CreateFrame(self):
	
		f = Frame(self)
		f.pack(side=TOP,fill=X)
		
		Label(f,text='D2 :',font=("Times",12)).grid(row=0, column=0, sticky=W)
		Label(f,text='Inside :',font=("Times",12)).grid(row=0, column=1, sticky=W)
		self.D1I= Checkbutton(f,variable=TestOneMotor[0],
					selectcolor='green').grid(row=0, column=2, sticky=W)

		Label(f,text='D1 :',font=("Times",12)).grid(row=1, column=0, sticky=W)
		Label(f,text='Inside :',font=("Times",12)).grid(row=1, column=1, sticky=W)
		self.D2I= Checkbutton(f,variable=TestOneMotor[1],
					selectcolor='green').grid(row=1, column=2, sticky=W)

		
		Label(f,text='A2 :',font=("Times",12)).grid(row=2, column=0, sticky=W)

		Label(f,text='Top :',font=("Times",12)).grid(row=2, column=1, sticky=W)
		self.A2T= Checkbutton(f,variable=TestOneMotor[2],
					selectcolor='green').grid(row=2, column=2, sticky=W)
		Label(f,text='Bottom :',font=("Times",12)).grid(row=3, column=1, sticky=W)
		self.A2B= Checkbutton(f,variable=TestOneMotor[3],
					selectcolor='green').grid(row=3, column=2, sticky=W)
		Label(f,text='Outside :',font=("Times",12)).grid(row=4, column=1, sticky=W)
		self.A2O= Checkbutton(f,variable=TestOneMotor[4],
					selectcolor='green').grid(row=4, column=2, sticky=W)
		Label(f,text='Inside :',font=("Times",12)).grid(row=5, column=1, sticky=W)
		self.A2I= Checkbutton(f,variable=TestOneMotor[5],
					selectcolor='green').grid(row=5, column=2, sticky=W)


		Label(f,text='A1 :',font=("Times",12)).grid(row=6, column=0, sticky=W)

		Label(f,text='Top :',font=("Times",12)).grid(row=6, column=1, sticky=W)
		self.A1T= Checkbutton(f,variable=TestOneMotor[6],
					selectcolor='green').grid(row=6, column=2, sticky=W)
		Label(f,text='Bottom :',font=("Times",12)).grid(row=7, column=1, sticky=W)
		self.A1B= Checkbutton(f,variable=TestOneMotor[7],
					selectcolor='green').grid(row=7, column=2, sticky=W)
		Label(f,text='Outside :',font=("Times",12)).grid(row=8, column=1, sticky=W)
		self.A1O= Checkbutton(f,variable=TestOneMotor[8],
					selectcolor='green').grid(row=8, column=2, sticky=W)
		Label(f,text='Inside :',font=("Times",12)).grid(row=9, column=1, sticky=W)
		self.A1I= Checkbutton(f,variable=TestOneMotor[9],
					selectcolor='green').grid(row=9, column=2, sticky=W)

		
		Label(f,text='P1 :',font=("Times",12)).grid(row=10, column=0, sticky=W)

		Label(f,text='Top :',font=("Times",12)).grid(row=10, column=1, sticky=W)
		self.D1T= Checkbutton(f,variable=TestOneMotor[10],
					selectcolor='green').grid(row=10, column=2, sticky=W)
		Label(f,text='Bottom :',font=("Times",12)).grid(row=11, column=1, sticky=W)
		self.D1B= Checkbutton(f,variable=TestOneMotor[11],
					selectcolor='green').grid(row=11, column=2, sticky=W)
		Label(f,text='Outside :',font=("Times",12)).grid(row=12, column=1, sticky=W)
		self.D1O= Checkbutton(f,variable=TestOneMotor[12],
					selectcolor='green').grid(row=12, column=2, sticky=W)
		Label(f,text='Inside :',font=("Times",12)).grid(row=13, column=1, sticky=W)
		self.D1I= Checkbutton(f,variable=TestOneMotor[13],
					selectcolor='green').grid(row=13, column=2, sticky=W)


		Label(f,text='P2 :',font=("Times",12)).grid(row=14, column=0, sticky=W)

		Label(f,text='Top :',font=("Times",12)).grid(row=14, column=1, sticky=W)
		self.D2T= Checkbutton(f,variable=TestOneMotor[14],
					selectcolor='green').grid(row=14, column=2, sticky=W)
		Label(f,text='Bottom :',font=("Times",12)).grid(row=15, column=1, sticky=W)
		self.D2B= Checkbutton(f,variable=TestOneMotor[15],
					selectcolor='green').grid(row=15, column=2, sticky=W)
		Label(f,text='Outside :',font=("Times",12)).grid(row=16, column=1, sticky=W)
		self.D2O= Checkbutton(f,variable=TestOneMotor[16],
					selectcolor='green').grid(row=16, column=2, sticky=W)
		Label(f,text='Inside :',font=("Times",12)).grid(row=17, column=1, sticky=W)
		self.D2I= Checkbutton(f,variable=TestOneMotor[17],
					selectcolor='green').grid(row=17, column=2, sticky=W)
		
		return
		
class MenuFrame(Frame):

	def __init__(self, parent,quitCallback=None):
	
		Frame.__init__(self,parent,relief=GROOVE,bd=4)
		
		self.__CreateFrame(quitCallback)

		return

	def __CreateFrame(self,quitCallback):
	
		f = Frame(self)
		f.pack(side=TOP,fill=X)

		m = self.__actionMenu(self,quitCallback)
    		m.pack(side=LEFT)

    		m = self.__helpMenu(self)
    		m.pack(side=RIGHT)

		return	

  	def destroy(self):
    
    		Frame.destroy(self)
    		
		return

  	def __actionMenu(self,
		   parent,
		   quitCallback):

    		b = Menubutton(parent, text='Actions', underline=0, relief=GROOVE)
    		m = Menu(b)
   		m.add_command(label='Configuration',command= self.__configmotor,font=("Times",12))
   		m.add_command(label='Quit', command=quit,font=("Times",12))
    		b['menu'] = m
    		return b

	def __configmotor(self):
			
		ConfigMotorFrame(self)
	
		return

  	def __helpMenu(self,
		 	parent):

    		b = Menubutton(parent, text='Help', underline=0, relief=GROOVE)
    		m = Menu(b)        
    		m.add_command(label='Help', command=self.__help,font=("Times",12))
    		b['menu'] = m
    		return b
         
  	def __help(self):

    		Dialog(self, title = 'FPD V4.0',
	   		text  = '"The Gods help those who help themselves"',
	   		bitmap= 'error', default=0, strings=('OK',))
    		return


class InfoMotorFrame(Frame):

	def __init__(self,parent):
	
		Frame.__init__(self,parent)

		self.__CreateFrame()

		return

	def __CreateFrame(self):
	
		f = Frame(self)
		f.pack(side=TOP,expand=YES,fill=X)
		
		self.__inputFrame = InputFrame(self)
    		self.__inputFrame.pack(side=TOP, fill=X, expand=YES)
		 		
	def update(self,
		   NumInput = None):
	
		self.__inputFrame.update(NumInput)

class StatusRackMonitor:

	def __init__(self,parent):
	
		for i in range(len(RackMonitor)):
			OutputRM.insert(i,[0,0])		# Initialisation OutputRM (P08, P02)
			InputRM.insert(i,[0,0])			# Initialisation InputRM (P03, P07)
			LVDTRM.insert(i,[0,0,0,0])		# Initialisation LVDTRM (P10 channel 32 to 35)
			ErrorRM.insert(i,0)			# Initialisation ErrorRM
	
	
	def update(self):
	
			
		self.__DSTAT=CaChannel()
		self.__BIN00=CaChannel()
		self.__BIN01=CaChannel()
		self.__BIN02=CaChannel()
		self.__BIN03=CaChannel()
		self.__AD=CaChannel()
				
		for i in range(len(RackMonitor)):
				
			try:
				self.__DSTAT.searchw(RackMonitor[i] + '.DSTAT')
				d=self.__DSTAT.getw()
			except:
				d=9999

			if (d != 0):
				ErrorRM[i]=1
			else:
				ErrorRM[i]=0

				try:	
					self.__BIN00.searchw(RackMonitor[i] + '.BIN00')
					InputRM[i][0]=self.__BIN00.getw()
				except:
					pass

				try:	
					self.__BIN03.searchw(RackMonitor[i] + '.BIN03')
					InputRM[i][1]=self.__BIN03.getw()
				except:
					pass
				
				try:
					self.__BIN01.searchw(RackMonitor[i] + '.BIN01')
					self.__BIN01.putw(OutputRM[i][0])
				except:
					pass
								
				try:
					self.__BIN02.searchw(RackMonitor[i] + '.BIN02')
					self.__BIN02.putw(OutputRM[i][1])
				except:
					pass

				try:
					self.__AD.searchw(RackMonitor[i] + '.AD')
					LVDTRM[i]=[self.__AD.getw()[32],self.__self.__AD.getw()[33],self.__AD.getw()[34],self.__AD.getw()[35]]
				except:
					pass
		
		del self.__BIN00
		del self.__BIN01
		del self.__BIN02
		del self.__BIN03
		del self.__AD
		del self.__DSTAT
		del d
		
class IOFrame(Frame):

	def __init__(self,parent):
	
		Frame.__init__(self,parent)

		self.__CreateFrame()

		return

	def __CreateFrame(self):
	
		f = Frame(self)
		f.pack(side=TOP,expand=YES,fill=X)

		self.__outputFrame = OutputFrame(self)
	    	self.__outputFrame.pack(side=TOP, fill=X, expand=YES)
		
		self.__choicemotorFrame = ChoiceMotorFrame(self)
		self.__choicemotorFrame.pack(side=TOP, fill=X, expand=YES)
		

 		
	def update(self,
		   NumInput = None):
	
		self.__outputFrame.update()
		
		
class RmMotorFrame(Frame): 


  def __init__(self,
	       parent):

    	Frame.__init__(self, parent)        # Initialize the base class
	
	title = 'FPD V4.0 - CTL_RM_02'
	self.master.title(title)

    	try:
		self.__createFrames(self) # Create component frames
    	except:
      		self.destroy()
      		raise
    	
	return
        
  def destroy(self):

	Frame.destroy(self)
	
	return

  def __createFrames(self,
		     parent):

	self.__statusRackMonitor = StatusRackMonitor(self)

	self.__errorFrame = ErrorFrame(self)

	self.__MenuFrame = MenuFrame(parent)
	self.__MenuFrame.pack(side=TOP, fill=X)

	self.__ioframe = IOFrame(parent)
    	self.__ioframe.pack(side=LEFT, fill=X)

	self.__infomotorframe = InfoMotorFrame(parent)
	self.__infomotorframe.pack(side=RIGHT, fill=X)
	
	self.__canvasdisplay = CanvasDisplay(parent)	

	return

  def update(self):

	self.__statusRackMonitor.update()
	self.__errorFrame.update()
	Num_Input = self.__canvasdisplay.update()
	self.__ioframe.update(Num_Input)
	self.__infomotorframe.update(Num_Input)

    	return



def quit():

  	global rmFrame, menuBar
		

	text='Are you sure you want to quit?' + chr(13)

	for i in range(len(Pot)):

		if int(Pot[i][4]) < 10:
			NumRM = int(Pot[i][4])-1
		else:
			NumRM = int(Pot[i][4])-7
	
		if Pot[i][6] == 0:
			InputData=InputRM[NumRM][Pot[i][5]] & 0x007f
		else:
			InputData=(InputRM[NumRM][Pot[i][5]] & 0x3f80) / 0x007f
			
		if ((InputData & 0x0002) != 2):
			text=text+'The Detector '+ Pot[i][0]+ ' ' + Pot[i][1]  + ' is not in Home Position.' + chr(13)
			
	ans = Dialog(title = 'Exit',
		     text = text,font=("Times",12),
		     bitmap = 'question',
		     strings = ('Yes','No',),default = 0)
		    
	if ans.num == 0:
	  	frame.destroy()
	
		exit()
		
	return

# Integrated test procedure

if (__name__== '__main__'): 


  	from sys import *

  	UpdatePeriod = 1000  # 1 second

  	def update():

    		global frame

    		frame.update()
    		frame.after(UpdatePeriod, update)
		
		return


	global frame
   	base = Tk()
	    	
	try:
		frame = RmMotorFrame(base)
	except:
		print 'Error Accessing Power PC: CTL_RM_02 (D0OLCTL02)'
		exit()

	frame.pack(fill=X, expand=YES,ipadx=0,ipady=0)       # Pack into topmost widget

	text= 'Last Version : FPD V 3.5, October, 12 2000' + chr(13) + chr(13)
	text= text + 'Modifications :' + chr(13)
	text= text +	'	* Now, you must enter the distance in millimiters between the home position and the wanted position' + chr(13)
	text= text +	'	* One label "Position Wanted" is added' + chr(13)
	text= text +	'	* The Current Position indicates the distance in millimeters between the Home Position and the current position' + chr(13) + chr(13)
	text= text +	' All comments are welcome' + chr(13)
	text= text +	' Lionel Peyrichoux (peyricli@fnal.gov)'
		

    	Dialog(base, title = 'FPD V 4.0',
	   	text  = text,font=("Times",12),
	   	bitmap= 'warning', default=0, strings=('OK',))
 	
	update()
	base.mainloop()