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

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 

10 

11import logging 

12 

13logger = logging.getLogger(__name__) 

14 

15 

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} 

32 

33 

34class ShutterStateProperty(HardwareProperty): 

35 """Attribute mapping BLISS shutter state into Daiquiri names""" 

36 

37 def __init__(self, name: str, getter: callable = None): 

38 HardwareProperty.__init__(self, name, getter=getter) 

39 

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 

51 

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 

60 

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 

70 

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" 

77 

78 return state 

79 

80 

81class Shutter(BlissObject, AbstractShutter): 

82 

83 CALLABLE_MAP = {"open": "open", "close": "close", "toggle": "toggle"} 

84 

85 def _get_status(self): 

86 if hasattr(self._object, "_tango_status"): 

87 return self._object._tango_status 

88 else: 

89 return "" 

90 

91 def _get_open_text(self): 

92 return "Open" 

93 

94 def _get_closed_text(self): 

95 return "Closed" 

96 

97 def _get_valid(self): 

98 return True 

99 

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 }