From 2b7424acaaeddc22cbe54492bb386893a07b921a Mon Sep 17 00:00:00 2001 From: Elmir Jagudin Date: Thu, 1 Feb 2024 16:59:54 +0100 Subject: [PATCH] WIP: import TangoShutter fixes from #847 Import all changes from this PR: https://github.com/mxcube/mxcubecore/pull/847 TODO: drop this commit once the PR have been merged, or if rejected, deal with it --- mxcubecore/HardwareObjects/TangoShutter.py | 66 ++++++++++++---------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/mxcubecore/HardwareObjects/TangoShutter.py b/mxcubecore/HardwareObjects/TangoShutter.py index 1fc378d1da..cde2908fce 100644 --- a/mxcubecore/HardwareObjects/TangoShutter.py +++ b/mxcubecore/HardwareObjects/TangoShutter.py @@ -31,14 +31,24 @@ Open Close State - {"open": "OPEN", "cloded": "CLOSED", "DISABLE" : "DISABLE"} + {"OPEN": "MYOPEN", "NEWSTATE": ["MYSTATE", "BUSY"]} -In this example the tag contains a json dictionary that maps spectific tango shutter states to the -convantional states defined in the TangoShutter Class. This tag is not necessay in cases where the tango shutter states -are all covered by the TangoShuter class conventional states. +In the example the property contains a dictionary that redefines or +adds specific tango shutter states. +When redefining a known state, only the VALUES Enum will be updated. +When defining a new state (new key), the dictionary value should be a +list. The new state is added to both the VALUES and the SPECIFIC_STATES Enum. +Attention: + - do not use tuples or the python json parser will fail! + - make sure only double quotes are used inside the values dictionary. No single quotes (') are allowed ! + - the second element of the list should be a standard HardwareObjectState name + (UNKNOWN, WARNING, BUSY, READY, FAULT, OFF - see in BaseHardwareObjects.py)! +The property is optional. """ + import json +import logging from enum import ( Enum, unique, @@ -47,7 +57,7 @@ from mxcubecore.BaseHardwareObjects import HardwareObjectState from mxcubecore.HardwareObjects.abstract.AbstractShutter import AbstractShutter -__copyright__ = """ Copyright © 2023 by the MXCuBE collaboration """ +__copyright__ = """ Copyright © by the MXCuBE collaboration """ __license__ = "LGPLv3+" @@ -62,6 +72,7 @@ class TangoShutterStates(Enum): AUTOMATIC = HardwareObjectState.READY, "RUNNING" UNKNOWN = HardwareObjectState.UNKNOWN, "RUNNING" FAULT = HardwareObjectState.WARNING, "FAULT" + STANDBY = HardwareObjectState.WARNING, "STANDBY" class TangoShutter(AbstractShutter): @@ -85,26 +96,18 @@ def init(self): self.state_channel.connect_signal("update", self._update_value) self.update_state() - try: - self.config_values = json.loads(self.get_property("values")) - except: - self.config_values = None - def _update_value(self, value): """Update the value. Args: value(str): The value reported by the state channel. """ - if self.config_values: - value = self.config_values[str(value)] - else: - value = str(value) - - super().update_value(self.value_to_enum(value)) + super().update_value(self.value_to_enum(str(value))) def _initialise_values(self): - """Add the tango states to VALUES""" + """Add specific tango states to VALUES and, if configured + in the xml file, to SPECIFIC_STATES""" values_dict = {item.name: item.value for item in self.VALUES} + states_dict = {item.name: item.value for item in self.SPECIFIC_STATES} values_dict.update( { "MOVING": "MOVING", @@ -113,7 +116,19 @@ def _initialise_values(self): "FAULT": "FAULT", } ) + try: + config_values = json.loads(self.get_property("values")) + for key, val in config_values.items(): + if isinstance(val, (tuple, list)): + values_dict.update({key: val[1]}) + states_dict.update({key: (HardwareObjectState[val[1]], val[0])}) + else: + values_dict.update({key: val}) + except (ValueError, TypeError) as err: + logging.error(f"Exception in _initialise_values(): {err}") + self.VALUES = Enum("ValueEnum", values_dict) + self.SPECIFIC_STATES = Enum("TangoShutterStates", states_dict) def get_state(self): """Get the device state. @@ -121,25 +136,18 @@ def get_state(self): (enum 'HardwareObjectState'): Device state. """ try: - if self.config_values: - _state = self.config_values[str(self.state_channel.get_value())] - else: - _state = str(self.state_channel.get_value()) - - except (AttributeError, KeyError): + _state = self.get_value().name + return self.SPECIFIC_STATES[_state].value[0] + except (AttributeError, KeyError) as err: + logging.error(f"Exception in get_state(): {err}") return self.STATES.UNKNOWN - return self.SPECIFIC_STATES[_state].value[0] - def get_value(self): """Get the device value Returns: (Enum): Enum member, corresponding to the 'VALUE' or UNKNOWN. """ - if self.config_values: - _val = self.config_values[str(self.state_channel.get_value())] - else: - _val = str(self.state_channel.get_value()) + _val = str(self.state_channel.get_value()) return self.value_to_enum(_val) def _set_value(self, value):