import time
import datetime
from ophyd import Component as Cpt
from ophyd import Device
from ophyd import DynamicDeviceComponent as Dcpt
from ophyd import EpicsSignal
from prettytable import FRAME, PrettyTable
import numpy as np
[docs]
class OMNYTemperaturesError(Exception):
pass
[docs]
class OMNYTemperatures(Device):
USER_ACCESS = [
"temperature_controller_used_get_name_and_values",
"set_setpoint",
"show_all",
"help",
"_set_TEMP_default_setpoints",
"temperature_controller_TEMP_running",
"temperature_controller_CRYO_running",
]
SUB_VALUE = "value"
_default_sub = SUB_VALUE
temperature = {
f"temperature{i}": (EpicsSignal, f"XOMNY-TEMP{i}:GET", {}) for i in range(1, 49)
}
temperature = Dcpt(temperature)
temperature_setpoint = {
f"temperature_setpoint{i}": (EpicsSignal, f"XOMNY-TEMP{i}:SET", {}) for i in range(1, 49)
}
temperature_setpoint = Dcpt(temperature_setpoint)
temperature_unit = {
f"temperature_unit{i}": (EpicsSignal, f"XOMNY-TEMP{i}:GET.EGU", {}) for i in range(1, 49)
}
temperature_unit = Dcpt(temperature_unit)
temperature_alarmstate = {
f"temperature_alarmstate{i}": (EpicsSignal, f"XOMNY-TEMP{i}:ALARM", {}) for i in range(1, 49)
}
temperature_alarmstate = Dcpt(temperature_alarmstate)
temperature_names = {
f"temperature_name{i}": (EpicsSignal, f"XOMNY-TEMP{i}:GET.DESC", {"string": True})
for i in range(1, 49)
}
temperature_names = Dcpt(temperature_names)
temperature_update_time = Cpt(
EpicsSignal, name="temperature_update_time", read_pv="XOMNY-TEMP:UPDATED.VAL"
)
cryo_temperature = {
f"cryo_temperature{i}": (EpicsSignal, f"XOMNY-TEMP-CRYO-{chr(i+ord('A')-1)}:GET.VAL", {}) for i in range(1,5)
}
cryo_temperature = Dcpt(cryo_temperature)
cryo_temperature_setpoint = {
f"cryo_temperature_setpoint{i}": (EpicsSignal, f"XOMNY-TEMP-CRYO-{chr(i+ord('A')-1)}:SET.VAL", {}) for i in range(1,5)
}
cryo_temperature_setpoint = Dcpt(cryo_temperature_setpoint)
cryo_temperature_name = {
f"cryo_temperature_name{i}": (EpicsSignal, f"XOMNY-TEMP-CRYO-{chr(i+ord('A')-1)}:GET.DESC", {}) for i in range(1,5)
}
cryo_temperature_name = Dcpt(cryo_temperature_name)
cryo_temperature_update_time = Cpt(
EpicsSignal, name="cryo_temperature_update_time", read_pv="XOMNY-TEMP-CRYO:UPDATED.VAL"
)
cryo_temperature_closed_loop = Cpt(
EpicsSignal, name="cryo_temperature_closed_loop", read_pv="XOMNY-TEMP-CRYO:CLOSEDLOOP.VAL"
)
def __init__(self, prefix="", *, name, **kwargs):
super().__init__(prefix, name=name, **kwargs)
self.temperature.temperature1.subscribe(self._emit_value)
def _emit_value(self, **kwargs):
timestamp = kwargs.pop("timestamp", time.time())
self.wait_for_connection()
self._run_subs(sub_type=self.SUB_VALUE, timestamp=timestamp, obj=self)
def set_setpoint(self, type: str, controller_nr: int, temperature: float):
if type == "TEMP":
getattr(self.temperature_setpoint, f"temperature_setpoint{controller_nr}").set(temperature)
elif type == "CRYO":
getattr(self.cryo_temperature_setpoint, f"cryo_temperature_setpoint{controller_nr}").set(temperature)
else:
raise OMNYTemperaturesError("invalid type")
def _set_TEMP_default_setpoints(self):
self.set_setpoint("TEMP",8,-199.9)
time.sleep(0.1)
self.set_setpoint("TEMP",9,23)
time.sleep(0.1)
self.set_setpoint("TEMP",10,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",16,-199.9)
time.sleep(0.1)
self.set_setpoint("TEMP",17,23)
time.sleep(0.1)
self.set_setpoint("TEMP",18,26)
time.sleep(0.1)
self.set_setpoint("TEMP",19,26)
time.sleep(0.1)
self.set_setpoint("TEMP",20,26)
time.sleep(0.1)
self.set_setpoint("TEMP",21,23)
time.sleep(0.1)
self.set_setpoint("TEMP",22,-199.9)
time.sleep(0.1)
self.set_setpoint("TEMP",23,-199.9)
time.sleep(0.1)
self.set_setpoint("TEMP",24,-199.9)
time.sleep(0.1)
self.set_setpoint("TEMP",25,25)
time.sleep(0.1)
self.set_setpoint("TEMP",27,25)
time.sleep(0.1)
self.set_setpoint("TEMP",28,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",29,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",30,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",31,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",35,25)
time.sleep(0.1)
self.set_setpoint("TEMP",36,25)
time.sleep(0.1)
self.set_setpoint("TEMP",37,25)
time.sleep(0.1)
self.set_setpoint("TEMP",38,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",39,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",41,30)
time.sleep(0.1)
self.set_setpoint("TEMP",42,25)
time.sleep(0.1)
self.set_setpoint("TEMP",44,25)
time.sleep(0.1)
self.set_setpoint("TEMP",45,-199.9)
time.sleep(0.1)
self.set_setpoint("TEMP",46,73.2)
time.sleep(0.1)
self.set_setpoint("TEMP",47,73.2)
time.sleep(0.1)
def temperature_controller_TEMP_running(self):
time_diff = np.fabs(float(self.temperature_update_time.get()) - time.time())
if time_diff > 600:
return False
else:
return True
def temperature_controller_CRYO_running(self):
time_diff = np.fabs(float(self.cryo_temperature_update_time.get()) - time.time())
if time_diff > 600:
return False
else:
return True
def temperature_controller_used_get_name_and_values(self, type: str, controller_nr: int) -> bool:
if type == "TEMP":
controller_name = str(getattr(self.temperature_names, f"temperature_name{controller_nr}").get())
if controller_name == '-' or controller_name == 'NOT INITIALIZED':
return (False, "none", 0, 0, "none", False, False)
else:
temperature = float(getattr(self.temperature, f"temperature{controller_nr}").get())
setpoint = float(getattr(self.temperature_setpoint, f"temperature_setpoint{controller_nr}").get())
unit = str(getattr(self.temperature_unit, f"temperature_unit{controller_nr}").get())
alarmstate = bool(getattr(self.temperature_alarmstate, f"temperature_alarmstate{controller_nr}").get())
controller_running = self.temperature_controller_TEMP_running()
return (True, controller_name, temperature, setpoint, unit, alarmstate,controller_running)
elif type == "CRYO":
controller_name = str(getattr(self.cryo_temperature_name, f"cryo_temperature_name{controller_nr}").get())
temperature = float(getattr(self.cryo_temperature, f"cryo_temperature{controller_nr}").get())
setpoint = float(getattr(self.cryo_temperature_setpoint, f"cryo_temperature_setpoint{controller_nr}").get())
unit = 'K'
alarmstate = False
controller_running = self.temperature_controller_CRYO_running()
return (True, controller_name, temperature, setpoint, unit, alarmstate,controller_running)
else:
raise OMNYTemperaturesError("invalid type")
def show_all(self):
red = "\x1b[91m"
white = "\x1b[0m"
t = PrettyTable()
t.clear()
t.title = "OMNY Temperature Controllers"
t.field_names = ["Channel","Name","Temperature","Setpoint","Unit","AlarmState"]
for i in range (1,49):
controller_status = self.temperature_controller_used_get_name_and_values("TEMP", i)
if controller_status[0]:
row = []
row.extend([f"{i}"])
row.extend([controller_status[1]])
row.extend([f"{controller_status[2]:.2f}"])
if (controller_status[3] < -199 and controller_status[4] == "degC") or (np.fabs(controller_status[3]-73.25) < 0.1 and controller_status[4] == "K"):
row.extend([" "])
else:
row.extend([f"{controller_status[3]:.2f}"])
row.extend([f"{controller_status[4]}"])
if controller_status[5]:
row.extend(["Alarm"])
else:
row.extend([" "])
t.add_row(row)
t.header = True
t.vrules = FRAME
print(t)
if not self.temperature_controller_TEMP_running():
print (red + "Warning: the temperature controller communication is not running" + white)
print (f"The last update was {datetime.datetime.fromtimestamp(float(self.temperature_update_time.get())).strftime('%c')}\n")
t.clear()
t.title = "OMNY Cryo Temperature Controller"
t.field_names = ["Channel","Name","Temperature","Setpoint","Unit"]
for i in range (1,5):
controller_status = self.temperature_controller_used_get_name_and_values("CRYO", i)
if controller_status[0]:
row = []
row.extend([f"{i}"])
row.extend([controller_status[1]])
row.extend([f"{controller_status[2]:.2f}"])
row.extend([f"{controller_status[3]:.2f}"])
row.extend([f"{controller_status[4]}"])
t.add_row(row)
t.header = True
t.vrules = FRAME
print(t)
if bool(self.cryo_temperature_closed_loop.get()):
print ("Cryo controller is running in closed loop.")
else:
print ("Cryo controller is running in " + red + "open" + white + " loop.")
if not self.temperature_controller_CRYO_running():
print (red + "Warning: the temperature controller communication is not running" + white)
print (f"The last update was {datetime.datetime.fromtimestamp(float(self.cryo_temperature_update_time.get())).strftime('%c')}\n")
print("Use dev.omny_temperatures.help() for assistance.")
def help(self):
print("Help for OMNY temperatures:")