Coverage for /opt/conda/envs/apienv/lib/python3.10/site-packages/daiquiri/core/hardware/bliss/shutter.py: 98%
49 statements
« prev ^ index » next coverage.py v7.6.5, created at 2024-11-15 02:12 +0000
« prev ^ index » next coverage.py v7.6.5, created at 2024-11-15 02:12 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3import enum
4from daiquiri.core.hardware.abstract import HardwareProperty
5from daiquiri.core.hardware.abstract.shutter import Shutter as AbstractShutter
6from daiquiri.core.hardware.bliss.object import BlissObject
7from bliss.common.shutter import BaseShutterState
8from bliss.controllers.tango_shutter import TangoShutterState
9from daiquiri.core.utils import loggingutils
11import logging
13logger = logging.getLogger(__name__)
16_states_mapping = {
17 BaseShutterState.OPEN: "OPEN",
18 BaseShutterState.CLOSED: "CLOSED",
19 BaseShutterState.FAULT: "FAULT",
20 BaseShutterState.UNKNOWN: "UNKNOWN",
21 # Duplication is needed cause TangoShutterState have totally different states
22 # Even if it uses the same names
23 TangoShutterState.OPEN: "OPEN",
24 TangoShutterState.CLOSED: "CLOSED",
25 TangoShutterState.FAULT: "FAULT",
26 TangoShutterState.UNKNOWN: "UNKNOWN",
27 TangoShutterState.MOVING: "MOVING",
28 TangoShutterState.DISABLE: "DISABLED",
29 TangoShutterState.RUNNING: "OPEN", # Was automatically open by the machine
30 TangoShutterState.STANDBY: "STANDBY",
31}
34class ShutterStateProperty(HardwareProperty):
35 """Attribute mapping BLISS shutter state into Daiquiri names"""
37 def __init__(self, name: str, getter: callable = None):
38 HardwareProperty.__init__(self, name, getter=getter)
40 def string_to_state(self, value):
41 for state_class in (BaseShutterState, TangoShutterState):
42 # Check with enum names
43 v = getattr(state_class, value, None)
44 if v is not None:
45 return v
46 # Check with enum values
47 try:
48 return state_class(value)
49 except ValueError:
50 pass
52 loggingutils.log_once(
53 logger,
54 logging.WARNING,
55 "BLISS shutter is exposing state as an unexpected value '%s' (%s).",
56 value,
57 type(value),
58 )
59 return BaseShutterState.UNKNOWN
61 def translate_from(self, value):
62 # TODO: Some shutters use their own state enums, so do a hacky string conversion
63 # See https://gitlab.esrf.fr/bcu-vercors/ID26/id26/-/blob/master/id26/controllers/fast_shutter.py#L21
64 # For this particular case we need to add AUTO to the Bliss BaseShutterState
65 # https://gitlab.esrf.fr/bliss/bliss/-/blob/master/bliss/common/shutter.py#L51
66 if isinstance(value, enum.Enum):
67 for extra_value in ["AUTO", "CLOSED", "OPEN"]:
68 if value.name == extra_value:
69 return extra_value
71 if isinstance(value, str):
72 value = self.string_to_state(value)
73 try:
74 state = _states_mapping[value]
75 except KeyError:
76 state = "UNKNOWN"
78 return state
81class Shutter(BlissObject, AbstractShutter):
83 CALLABLE_MAP = {"open": "open", "close": "close", "toggle": "toggle"}
85 def _get_status(self):
86 if hasattr(self._object, "_tango_status"):
87 return self._object._tango_status
88 else:
89 return ""
91 def _get_open_text(self):
92 return "Open"
94 def _get_closed_text(self):
95 return "Closed"
97 def _get_valid(self):
98 return True
100 PROPERTY_MAP = {
101 # TODO:ideally this would have a channel
102 # Now has a channel, but doesnt work?
103 "state": ShutterStateProperty("state"),
104 "status": HardwareProperty("status", getter=_get_status),
105 "open_text": HardwareProperty("open_text", getter=_get_open_text),
106 "closed_text": HardwareProperty("closed_text", getter=_get_closed_text),
107 "valid": HardwareProperty("valid", getter=_get_valid),
108 }