#! /usr/local/bin/python
# Kitt Peak National Observatory
# 4 meter Telescope Facility
#
# Oil and Floor Temperature Control GUI
#
# Bill Gillespie
# November, 2002
#
#
#
# This program provides graphical user interface interaction with the 4meter
# telescope facility "Oil and Floor - Temperature Control Device". The device
# is located on the ** floor in the ******* **** of the **************** at
# Kitt Peak.
#
# The method of interaction is communication via serial line with the oil and
# floor temperature control device. The serial line is accessed by reaching
# /*****/**** on the machine ***********.
#
# This program relies on the serial line program commands written by Scott
# Bulau, engineering dept at NOAO, Tucson. Those commands are written in
# Forth and allow ascii commands to be sent to the OFTC control box on the **
# floor. The device responds with reports of sensor temperatures, and setpoint
# values.
#
# The main purpose of this program is to allow easy changes of the two
# setpoint values that control the amount of cooling the dome floor and the
# telescope oil support receive. For an overview of the complete system click
# the "DIAGRAM" button on the GUI.
#---------Fetch needed modules ---------------------------------------------#
#------------the serial module may have to be installed separately----------#
import serial, os, sys, string
#---------Set up the serial line for R/W -----------------------------------#
#(secured)
dev=serial.Serial('****/dev/*******', (****buad rate), (***num of data bits),( ***num of stop bits) , timeout= ****x)
#------- Read the "osetpoint?" value into varialbe OSP --------------------#
def GetOilSetpointValue():
dev.flush()
dev.write('osetpoint?')
dev.write('\r')
OSP = dev.readlines()
global startingOSP
stringOSP = OSP[0]
splitupOSP = stringOSP.split()
finalOSP = splitupOSP[1]
startingOSP = int(finalOSP)
GetOilSetpointValue() # returns the integer value of "Oil Setpoint" from the serial line.
#------- Read the "fsetpoint?" value into variable FSP ---------------------#
def GetFloorSetpointValue():
dev.flush()
dev.write('fsetpoint?')
dev.write('\r')
FSP = dev.readlines()
global startingFSP
stringFSP = FSP[0]
splitupFSP = stringFSP.split()
finalFSP = splitupFSP[1]
startingFSP = int(finalFSP)
GetFloorSetpointValue() # returns the integer value of "Floor Setpoint" from the serial device.
# GUI SECTION
from Tkinter import *
from tkMessageBox import *
root = Tk()
root.title("OFTC Gui")
labelfont = ('helvetica', 13)
guiTitle = Label(root, relief=GROOVE, borderwidth=3,
text="4 meter Oil and Floor Temperature Control")
guiTitle.config(font= labelfont)
guiTitle.grid(row= 4, column=2, columnspan=40, rowspan=1,
sticky=W+E+N+S)
noaoImage= PhotoImage(file="noao.gif")
def programInforamtion():
showinfo("OFTC Info", "OFTC GUI\r4 meter Telescope\nKitt Peak\nNovemeber, 2002\nBill
Gillespie\n")
noaoButton= Button(root, image=noaoImage, command= programInforamtion)
noaoButton.grid(row= 4, column=60, columnspan=1, rowspan=1,
sticky=W+E+N+S)
NOAOimageSpacer1 = Label(root, text=" ")
NOAOimageSpacer1.grid(row=4, column=59)
TopGuiSpacer0 = Label(root, text="")
TopGuiSpacer0.grid(row=0, column=0, columnspan= 70)
BelowTitleGuiSpacer0 = Label(root, text="")
BelowTitleGuiSpacer0.grid(row=5, column=0, columnspan= 70)
RightSideSpacer1 = Label(root, text=" ")
RightSideSpacer1.grid(row=0, column=70, rowspan= 70)
# Oil Temperature - Program Section
oilCurrentLabel = Label(root, text="THE CURRENT OIL SETPOINT =")
oilCurrentLabel.grid(row=10, column=10, sticky=W)
oilValueLabel = Label(root, text= startingOSP)
oilValueLabel.grid(row= 10, column=11, columnspan=1, rowspan=1, sticky=W)
oilLabel = Label(root, text="SELECT NEW OIL SETPOINT:")
oilLabel.grid(row=20, column=10, sticky=W)
oilSlider = Scale(root, from_= 2, to=8,
tickinterval=1, resolution=1, showvalue=YES, orient="horizontal")
oilSlider.grid(row= 20, column=11, columnspan=10, rowspan=1,
sticky=W+E+N+S, padx=5, pady=5 )
oilSlider.set(startingOSP)
# When answer YES to dialogue popup question "reset the oil temp?" this function called
# it sends the value of the oil current slider to the serial line.
# It redraws the label "oilValueLabel" with the new setpoint value from the slider.
# It resets the global variable startingOSP to the newly commanded value for Oil Set Point.
def SendInNewOilSetpoint():
newOSP = oilSlider.get()
global startingOSP
startingOSP = newOSP
dev.flush()
dev.write('osetpoint='+ " " +`newOSP`)
dev.write('\r')
oilValueLabel = Label(root, text= newOSP)
oilValueLabel.grid(row= 10, column=11, columnspan=1, rowspan=1,
sticky=W)
# When answer NO to dialogue popup question "reset the oil temp?" this function called
# it resets the slider value to the original oil setpoint value,
#
#
def NoSendInNewOilSetpoint():
global startingOSP
oilSlider.set(startingOSP) # repositions slider back to current setpoint value.
oilValueLabel = Label(root, text= startingOSP)
oilValueLabel.grid(row= 10, column=11, columnspan=1, rowspan=1,
sticky=W)
# This function is called with the CHANGE button at the end of the
# slider on the GUI. It calls up a "verification dialogue" to ask the
# user if they do indeed want to issue the new value of the slider to
# the device.
def SendNewOilTempCheckPopup():
if askyesno("Verify Change", "Change oil setpoint?"):
showwarning("Yes", "Oil setpoint changed.")
SendInNewOilSetpoint()
else:
showinfo("No", "No change.")
NoSendInNewOilSetpoint()
oilChange = Button(root, text="Change", command = SendNewOilTempCheckPopup)
oilChange.grid(row= 20, column=22, columnspan=1, rowspan=1)
CenterDivider0 = Label(root, text="")
CenterDivider0.grid(row=22, column=0)
CenterDivider0 = Label(root, text="")
CenterDivider0.grid(row=29, column=0)
# Floor Temperature - Program Section
floorCurrentLabel = Label(root, text="THE CURRENT FLOOR SETPOINT =")
floorCurrentLabel.grid(row=50, column=10, sticky=W)
floorValueLabel = Label(root, text= startingFSP)
floorValueLabel.grid(row= 50, column= 11, columnspan=1, rowspan=1,
sticky=W)
floorLabel = Label(root, text= "SELECT NEW FLOOR SETPOINT:")
floorLabel.grid(row=60, column=10, sticky=W)
floorSlider = Scale(root, from_= -8, to= 2, tickinterval= 1, resolution= 1,
showvalue= YES, orient= "horizontal")
floorSlider.grid(row= 60, column=11, columnspan=10, rowspan=1, sticky=E+W, padx=5, pady=5 )
floorSlider.set(startingFSP) # set slider value to serial
value on start
# when answer YES to dialogue popup question "reset the floor temp?" this function called
# it sends the value of the floor slider to the serial line.
# and it redraws the label (it's value) for "current floor setpoint".
def SendInNewFloorSetpoint():
newFSP = floorSlider.get()
global startingFSP
startingFSP = newFSP
dev.flush()
dev.write('fsetpoint='+ " " +`newFSP`)
dev.write('\r')
floorValueLabel = Label(root, text= newFSP)
floorValueLabel.grid(row= 50, column=11, columnspan=1, rowspan=1,
sticky=W)
# when answeer NO to dialogue popup question "reset the floor temp?" this function called
# it resets the slider value to the the serial line value of floor setpoint.
# and it redraws the label (it's value) for "current floor setpoint".
def NoSendInNewFloorSetpoint():
global startingFSP
floorSlider.set(startingFSP) # repositions slider back to current setpoint value.
floorValueLabel = Label(root, text= startingFSP)
floorValueLabel.grid(row= 50, column=11, columnspan=1, rowspan=1,
sticky=W)
#### Dialogue box popup function (Calls on the two functions above)
#### This dialgoue asks user if they "really" want to command the change in setpoint"
#### As there are two choices - YES or NO - the are two functions that the two choices call.
#### They are: Yes = SendInNewFloorSetpoint and No = NoSendInNewFloorSetpoint
def SendNewFloorTempCheckPopup():
if askyesno("Verify Change", "Change floor setpoint?"):
showwarning("Yes", "Floor setpoint changed")
SendInNewFloorSetpoint()
else:
showinfo("No", "No change.")
NoSendInNewFloorSetpoint()
# change the temp by clicking "change" button - which calls function SendNewFloorTempCheckPopup
to verify change.
floorChange = Button(root, text="Change", command= SendNewFloorTempCheckPopup)
floorChange.grid(row= 60, column=22, columnspan=1, rowspan=1)
CenterDivider0 = Label(root, text="")
CenterDivider0.grid(row=63, column=0)
CenterDivider1 = Label(root, text=" ")
CenterDivider1.grid(row=75, column=0)
# Additional Buttons Section
def HelpWindowPopup():
HelpWindow= Toplevel()
Button(HelpWindow, text="Quit this window", command= HelpWindow.destroy).pack()
HelpWindow.mainloop()
Helpbutton = Button(root, text="HELP", command= HelpWindowPopup)
Helpbutton.grid(row= 90, column=11)
def DiagramWindowPopup():
DiagramWindow= Toplevel()
gifdir = "../oftc/"
diagramImage = PhotoImage(file=gifdir+"diagram.gif")
Button(DiagramWindow, image=diagramImage).pack()
Button(DiagramWindow, text="Quit this window", command= DiagramWindow.destroy).pack()
DiagramWindow.mainloop()
Diagrambutton = Button(root, text="DIAGRAM", command= DiagramWindowPopup)
Diagrambutton.grid(row= 90, column=12)
def GraphsWindowPopup():
GraphsWindow= Toplevel()
Button(GraphsWindow, text="Quit this window", command= GraphsWindow.destroy).pack()
GraphsWindow.mainloop()
Graphsbutton = Button(root, text="GRAPHS", command= GraphsWindowPopup)
Graphsbutton.grid(row= 90, column=13)
def LogsWindowPopup():
LogsWindow= Toplevel()
Button(LogsWindow, text="Quit this window", command= LogsWindow.destroy).pack()
LogsWindow.mainloop()
Logsbutton = Button(root, text="LOGS", command= LogsWindowPopup)
Logsbutton.grid(row= 90, column=14)
def URLWindowPopup():
URLWindow= Toplevel()
Button(URLWindow, text="Quit this window", command= URLWindow.destroy).pack()
URLWindow.mainloop()
URLbutton = Button(root, text="URL", command= URLWindowPopup)
URLbutton.grid(row= 90, column=15)
def LegendWindowPopup():
LegendWindow= Toplevel()
Button(LegendWindow, text="Quit this window", command= LegendWindow.destroy).pack()
LegendWindow.mainloop()
Legendbutton = Button(root, text="LEGEND", command= LegendWindowPopup)
Legendbutton.grid(row= 90, column=16)
import sys # for sys.exit
def quitVerify():
ans = askyesno('Verify exit', "Exit now?")
if ans: sys.exit()
Quitbutton = Button(root, text=" QUIT ",activebackground="darkgray",command= quitVerify)
Quitbutton.grid(row= 90, column=10, sticky=W,padx=5, pady=5 )
CenterDivider2 = Label(root, text="")
CenterDivider2.grid(row=100, column=0)
mainloop()