Project

General

Profile

RE: Creating a new Leginon node » leginonAutoRefill.py

Morgan Beeby, 10/11/2014 11:08 AM

 
#!/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")
(1-1/2)