|  | #!/usr/bin/env python
 | 
  
    |  | 
 | 
  
    |  | from leginon import conditioner
 | 
  
    |  | from leginon import leginondata
 | 
  
    |  | import leginon.gui.wx.LeginonAutoRefill
 | 
  
    |  | 
 | 
  
    |  | import sys
 | 
  
    |  | import re
 | 
  
    |  | import time
 | 
  
    |  | import math
 | 
  
    |  | import serial
 | 
  
    |  | 
 | 
  
    |  | class AutoRefill(conditioner.Conditioner):
 | 
  
    |  | 	# Define the class for gui panel
 | 
  
    |  | 	panelclass = leginon.gui.wx.LeginonAutoRefill.Panel
 | 
  
    |  | 
 | 
  
    |  | 	# Define the class for node settings
 | 
  
    |  | 	settingsclass = leginondata.AutoRefillSettingsData
 | 
  
    |  | 
 | 
  
    |  | 	# Inherit the default settings from the parent class, Conditioner
 | 
  
    |  | 
 | 
  
    |  | 	defaultsettings = conditioner.Conditioner.defaultsettings
 | 
  
    |  | 
 | 
  
    |  | 	# Inherit the eventinputs
 | 
  
    |  | 	eventinputs = conditioner.Conditioner.eventinputs
 | 
  
    |  | 
 | 
  
    |  |         port = None
 | 
  
    |  | 
 | 
  
    |  |         def onPlayer(self, state):
 | 
  
    |  |             infostr = ''
 | 
  
    |  |             if state == 'pause':
 | 
  
    |  |                 infostr += 'Pausing...'
 | 
  
    |  |             elif state == 'stop':
 | 
  
    |  |                 infostr += 'Continue'
 | 
  
    |  |             if infostr:
 | 
  
    |  |                 self.logger.info(infostr)
 | 
  
    |  |             self.panel.playerEvent(state)
 | 
  
    |  | 
 | 
  
    |  |         def checkPumping(self):
 | 
  
    |  |             self.port.write("rm 19" + '\r')
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             response = int(x[1],16)
 | 
  
    |  |             if response & 2:
 | 
  
    |  |                 self.logger.info("Pumping")
 | 
  
    |  |             else:
 | 
  
    |  |                 self.logger.error('Not pumping!')
 | 
  
    |  | 
 | 
  
    |  |         def checkSleeping(self):
 | 
  
    |  |             self.port.write("rm 19" + '\r')
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             response = int(x[1],16)
 | 
  
    |  |             if response & 32:
 | 
  
    |  |                 self.logger.info("Pump sleeping")
 | 
  
    |  |             else:
 | 
  
    |  |                 self.logger.error('Pump not sleeping!')
 | 
  
    |  | 
 | 
  
    |  | 
 | 
  
    |  |         def setPressure(self, pressure):
 | 
  
    |  |             # Takes an integer and converts it to hex, writes it to Norhof
 | 
  
    |  |             pressureString1 = "00"
 | 
  
    |  |             pressureString2 = "00"
 | 
  
    |  | 
 | 
  
    |  |             hex_re = re.compile('0x([a-fA-F0-9]{2})')
 | 
  
    |  |             byte1 = pressure % 256
 | 
  
    |  |             byte2 = pressure / 256
 | 
  
    |  | 
 | 
  
    |  |             byte1hex = hex(byte1)
 | 
  
    |  |             byte2hex = hex(byte2)
 | 
  
    |  |             m = hex_re.search(byte1hex)
 | 
  
    |  |             if m:
 | 
  
    |  |                 pressureString1 = m.group(1)
 | 
  
    |  |             else:
 | 
  
    |  |                 print byte1hex
 | 
  
    |  |             m = hex_re.search(byte2hex)
 | 
  
    |  |             if m:
 | 
  
    |  |                 pressureString2 = m.group(1)
 | 
  
    |  | 
 | 
  
    |  |             self.port.write("wm 112 "+pressureString1 + '\r')
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             self.port.write("wm 112 "+pressureString1 + '\r')
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             self.port.write("wm 113 "+pressureString2 + '\r')
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             self.port.write("wm 113 "+pressureString2 + '\r')
 | 
  
    |  |             x = self.getData()
 | 
  
    |  | 
 | 
  
    |  | 	def setCTypes(self):
 | 
  
    |  | 		'''
 | 
  
    |  | 		Define a unique condition type (CType) for database record.
 | 
  
    |  | 		'''
 | 
  
    |  | 		self.addCType('auto_refill')
 | 
  
    |  | 
 | 
  
    |  | 	def _fixCondition(self, condition_type):
 | 
  
    |  | 		'''
 | 
  
    |  | 		Define what to do
 | 
  
    |  | 		'''
 | 
  
    |  | 		self.runAutoRefill()
 | 
  
    |  | 
 | 
  
    |  | 	def runAutoRefill(self):
 | 
  
    |  | 		try:
 | 
  
    |  |                     self.logger.info('Auto refilling cryoholder...')
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("TO DO:")
 | 
  
    |  |                     self.logger.info(" - Close column valves on any error")
 | 
  
    |  |                     self.logger.info(" - Set pressure properly")
 | 
  
    |  |                     self.logger.info(" - Do error checking")
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("Initializing...")
 | 
  
    |  | 
 | 
  
    |  |                     portNum = getNorhofPort()
 | 
  
    |  |                     self.port    = serial.Serial(portNum,19200, timeout=0.2, parity='N', stopbits=1, bytesize=8)
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("Switching port to standby...")
 | 
  
    |  |                     self.pumpStandby()
 | 
  
    |  |                     self.logger.info("ok")
 | 
  
    |  | 
 | 
  
    |  |                     self.setPressure(2256)
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("Turning pump on...")
 | 
  
    |  |                     self.pumpOn()
 | 
  
    |  |                     self.logger.info("Pumping...")
 | 
  
    |  |                     self.checkPumping()
 | 
  
    |  |                     while (self.getExtraSensor() > 100 and self.getMainSensor() > 100):
 | 
  
    |  |                         self.logger.info("Filling...")
 | 
  
    |  |                         pressure  = self.getPressure()
 | 
  
    |  |                         mainTemp  = self.getMainSensor()
 | 
  
    |  |                         extraTemp = self.getExtraSensor()
 | 
  
    |  |                         self.logger.info("Pressure: "+str(pressure)+", Main sensor: "+str(mainTemp)+", Extra sensor: "+str(extraTemp))
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("Done")
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("Switching port to standby...")
 | 
  
    |  |                     self.pumpStandby()
 | 
  
    |  |                     self.logger.info("ok")
 | 
  
    |  | 
 | 
  
    |  |                     self.logger.info("Putting port to sleep...")
 | 
  
    |  |                     self.pumpSleep()
 | 
  
    |  |                     self.checkSleeping()
 | 
  
    |  |                     self.logger.info("ok")
 | 
  
    |  | 
 | 
  
    |  |                     self.port.close()
 | 
  
    |  | 
 | 
  
    |  | 		except AttributeError:
 | 
  
    |  | 			self.logger.warning('No buffer cycle for this instrument')
 | 
  
    |  | 		except Exception, e:
 | 
  
    |  | 			self.logger.error('Run buffer cycle failed: %s' % e)
 | 
  
    |  | 
 | 
  
    |  |         def hex2dec(self,inputString):
 | 
  
    |  |             """return the integer value of a two-byte hexadecimal string s"""
 | 
  
    |  |             inputHexString = inputString.rstrip()
 | 
  
    |  |             bytes          = inputHexString.split(" ")
 | 
  
    |  |             total          = 0
 | 
  
    |  |             for count in range(len(bytes)):
 | 
  
    |  |                 try:
 | 
  
    |  |                     total += int(bytes[count],16)*math.pow(256,count)
 | 
  
    |  |                 except:
 | 
  
    |  |                     self.pumpOff(self.port)
 | 
  
    |  |                     self.logger.error("ERROR CONVERTING '"+inputString+"'!\n")
 | 
  
    |  |             return total
 | 
  
    |  | 
 | 
  
    |  |         def getData(self):
 | 
  
    |  |             try:
 | 
  
    |  |                 x = self.port.readlines()
 | 
  
    |  |             except:
 | 
  
    |  |                 x = []
 | 
  
    |  |             return x 
 | 
  
    |  | 
 | 
  
    |  |         def getPressure(self):
 | 
  
    |  |             self.port.write("rm 088 2" + '\r')
 | 
  
    |  |             x = getData()
 | 
  
    |  |             return hex2dec(x[1])
 | 
  
    |  | 
 | 
  
    |  |         def pumpOn(self):
 | 
  
    |  |             self.port.write("wm 114 3" + '\r') 
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             self.port.write("wm 114 3" + '\r') 
 | 
  
    |  |             x = self.getData()
 | 
  
    |  | 
 | 
  
    |  |         def pumpStandby(self):
 | 
  
    |  |             self.port.write("wm 114 1" + '\r') 
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             self.port.write("wm 114 1" + '\r') 
 | 
  
    |  |             x = self.getData()
 | 
  
    |  | 
 | 
  
    |  |         def pumpSleep(self):
 | 
  
    |  |             self.port.write("wm 114 0" + '\r') 
 | 
  
    |  |             x = self.getData()
 | 
  
    |  |             self.port.write("wm 114 0" + '\r') 
 | 
  
    |  |             x = self.getData()
 | 
  
    |  | 
 | 
  
    |  |         def getExtraSensor(self):
 | 
  
    |  |             self.port.write("rm 084 2" + '\r') 
 | 
  
    |  |             reading = self.hex2dec(getData()[1])
 | 
  
    |  |             self.port.write("re 014 2" + '\r') 
 | 
  
    |  |             base    = self.hex2dec(getData()[1])
 | 
  
    |  |             temperature = reading - base
 | 
  
    |  |             return temperature
 | 
  
    |  | 
 | 
  
    |  |         def getMainSensor(self):
 | 
  
    |  |             self.port.write("rm 086 2" + '\r') 
 | 
  
    |  |             reading = self.hex2dec(getData()[1])
 | 
  
    |  |             self.port.write("re 016 2" + '\r') 
 | 
  
    |  |             base    = self.hex2dec(getData()[1])
 | 
  
    |  |             temperature = reading - base
 | 
  
    |  |             return temperature
 | 
  
    |  | 
 | 
  
    |  |         def getPorts(self):
 | 
  
    |  |            # scan for available ports. return a list of tuples (num, name)
 | 
  
    |  |            available = []
 | 
  
    |  |            for i in range(256):
 | 
  
    |  |                try:
 | 
  
    |  |                    s = serial.Serial(i)
 | 
  
    |  |                    available.append( (i, s.portstr))
 | 
  
    |  |                    s.close()
 | 
  
    |  |                except serial.SerialException:
 | 
  
    |  |                    pass
 | 
  
    |  |            return available
 | 
  
    |  | 
 | 
  
    |  |         def getNorhofPort(self):
 | 
  
    |  |             norhof_re = re.compile('[nN][oO][rR][hH][oO][fF]')
 | 
  
    |  |             thePort   = False
 | 
  
    |  | 
 | 
  
    |  |             for USBNumber in range(0,32):
 | 
  
    |  |                 name = "/dev/ttyUSB"+str(USBNumber)
 | 
  
    |  |                 try:
 | 
  
    |  |                     self.port = serial.Serial(name,19200, timeout=0.2, parity='N', stopbits=1, bytesize=8)
 | 
  
    |  |                     self.port.write("i" + '\r') 
 | 
  
    |  |                     response = self.getData()
 | 
  
    |  |                     for line in response:
 | 
  
    |  |                         m = norhof_re.search(line)
 | 
  
    |  |                         if m:
 | 
  
    |  |                             self.port.close()
 | 
  
    |  |                             return name
 | 
  
    |  |                     self.port.close()
 | 
  
    |  |                 except:
 | 
  
    |  |                     pass
 | 
  
    |  | 
 | 
  
    |  |             ports = self.getPorts()
 | 
  
    |  |             ports = []
 | 
  
    |  |             for portNum,name in ports:
 | 
  
    |  |                 self.port = serial.Serial(portNum,19200, timeout=0.2, parity='N', stopbits=1, bytesize=8)
 | 
  
    |  |                 self.port.write("i" + '\r') 
 | 
  
    |  |                 response = self.getData()
 | 
  
    |  |                 for line in response:
 | 
  
    |  |                     m = norhof_re.search(line)
 | 
  
    |  |                     if m:
 | 
  
    |  |                         self.port.close()
 | 
  
    |  |                         return portNum
 | 
  
    |  |                 self.port.close()
 | 
  
    |  | 
 | 
  
    |  |             self.logger.error("Could not find Norhof -- aborting. Are you a member of the dialout group?\n")
 | 
  
    |  |             self.logger.error("Try typing: sudo usermod -g dialout leginonuser\n")
 |