Skip to content

Commit

Permalink
WIP: import TangoShutter fixes from mxcube#847
Browse files Browse the repository at this point in the history
Import all changes from this PR:
mxcube#847

TODO: drop this commit once the PR have been merged, or
      if rejected, deal with it
  • Loading branch information
elmjag committed Oct 30, 2024
1 parent 78b3719 commit 40f8b06
Showing 1 changed file with 37 additions and 29 deletions.
66 changes: 37 additions & 29 deletions mxcubecore/HardwareObjects/TangoShutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,23 @@
<command type="tango" name="Open">Open</command>
<command type="tango" name="Close">Close</command>
<channel type="tango" name="State" polling="1000">State</channel>
<values>{"open": "OPEN", "cloded": "CLOSED", "DISABLE" : "DISABLE"}</values>
<values>{"OPEN": "MYOPEN", "NEWSTATE": ["MYSTATE", "BUSY"]}</values>
</object>
In this example the <values> 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 <values> 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 <values> property is optional.
"""

import logging
import json
from enum import (
Enum,
Expand All @@ -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+"


Expand All @@ -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):
Expand All @@ -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",
Expand All @@ -113,33 +116,38 @@ 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.
Returns:
(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):
Expand Down

0 comments on commit 40f8b06

Please sign in to comment.