diff --git a/csaxs_bec/device_configs/omny_config.yaml b/csaxs_bec/device_configs/omny_config.yaml index f48aeea..0fab939 100644 --- a/csaxs_bec/device_configs/omny_config.yaml +++ b/csaxs_bec/device_configs/omny_config.yaml @@ -10,6 +10,18 @@ omny_samples: readOnly: false readoutPriority: baseline +############################################################ +##################### OMNY temperatures #################### +############################################################ +omny_temperatures: + description: OMNY Temperatures and pressures + deviceClass: csaxs_bec.devices.omny.omny_temperatures.OMNYTemperatures + deviceConfig: {} + enabled: true + onFailure: buffer + readOnly: false + readoutPriority: baseline + ############################################################ ##################### OMNY Galil motors #################### ############################################################ diff --git a/csaxs_bec/devices/omny/omny_temperatures.py b/csaxs_bec/devices/omny/omny_temperatures.py new file mode 100644 index 0000000..b3379cc --- /dev/null +++ b/csaxs_bec/devices/omny/omny_temperatures.py @@ -0,0 +1,121 @@ +import time + +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 + +class OMNYTemperaturesError(Exception): + pass + + +class OMNYTemperatures(Device): + USER_ACCESS = [ + "if_temperature_controller_used_get_name_and_values", + "show_all", + "help", + ] + 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) + + 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 if_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) + 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()) + return (True, controller_name, temperature, setpoint, unit, alarmstate) + + def show_all(self): + # t = PrettyTable() + # red = "\x1b[91m" + # green = "\x1b[92m" + # white = "\x1b[0m" + # for ch in ["A", "B", "C"]: + # t.clear() + # shuttle_in_slot = self.search_shuttle_in_slot(ch) + # if shuttle_in_slot > 0: + # t.title = green + "Shuttle " + ch + " in OMNY slot " + str(shuttle_in_slot) + white + # else: + # t.title = red + "Shuttle " + ch + white + # field_names = [""] + # for ax in [1, 3, 5]: + # row = [] + # row.extend([self.get_sample_name(ch, ax)]) + # row.extend(str(ax)) + # row.extend(str(ax + 1)) + # row.extend([self.get_sample_name(ch, ax + 1)]) + # t.add_row(row) + # t.header = False + # t.vrules = FRAME + # print(t) + t = PrettyTable() + t.clear() + t.title = "OMNY Temperature Controllers" + t.field_names = ["Controller Nr.","Name","Temperature","Setpoint","Unit","AlarmState"] + for i in range (1,49): + controller_status = self.if_temperature_controller_used_get_name_and_values("TEMP", i) + if controller_status[0]: + row = [] + row.extend([f"Controller {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) + + print("Use dev.omny_temperatures.help() for assistance.") + + def help(self): + print("Help for OMNY temperatures:")