config_shutter.md 7.92 KB
Newer Older
1

2
# Shutter
3

4
5
This chapter describes the `bliss.common.shutter.Shutter` class, a generic base
class for shutter implementation.
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
Main kinds of shutters in BLISS are:

* [**IcePAP** shutter](config_shutter.md#icepap-shutter) for stepper motor controlled shutters
* [TangoShutter](config_shutter.md#tangoshutter) to manage:
    - Safety shutters
    - Beamline Frontend
    - Vacuum remote-valves

## Shutter API

Here are the common methods usable with shutters.

### Basic functions

* `open()`: to open the shutter (blocking)
* `close()`: to close the shutter (blocking)
* `state()`: return shutter state as a constant
    - one of `OPEN`, `CLOSED` or `UNKNOWN`
* `state_string()`: return the shutter state as a string
    - `"OPEN"`, `"CLOSED"` or `"UNKNOWN"`

### Advanced functions

* `.mode` property, to specify or tell in which mode the shutter operates
    - `MANUAL`: the shutter can be opened or closed manually with the `.open()`
      and `.close()` methods
    - `EXTERNAL`: the shutter is externally controlled - if the external control
      handler is known to the shutter object, it is used when calling `.open()`
      or `.close()`, otherwise commands will be refused;
    - `CONFIGURATION`: the shutter is in configuration (tuning) mode, it cannot
      be opened or closed

* `.set_external_control(set_open, set_closed, is_opened)`: set the shutter in
  `EXTERNAL` mode, and create an external control handler using the 3 callback
  functions passed in parameter (more details below)
* `.measure_open_close_time()`: put the shutter in `MANUAL` mode, then do
  open/close sequence to measure the time it takes
* `.opening_time`: return known opening time (see `.measure_open_close_time()`)
* `.closing_time`: return known closing time (see `.measure_open_close_time()`)


### External control

External control handler for the shutter can be specified in the configuration,
using the `external-control` key. The corresponding object musst derive from a
`bliss.common.shutter.ShutterSwitch` object.

As a convenience, external control handler for a shutter can also be specified
using the `.set_external_control` method. In this case, 3 callback functions
have to be passed:

* function that opens the shutter (e.g. activating **BTRIG** MUSST output)
* function that closes the shutter (e.g. setting **BTRIG** to 0 on MUSST object)
* function that returns `True` if shutter is opened

#### External control example from MX beamline

This code is part of the MD2S diffractometer controller. `fshutter` is an IcePAP
shutter configured in BLISS. The shutter is set in `EXTERNAL` mode, it moves
when a TTL signal is received on the IcePAP controller. The TTL signal is
triggered by the MD2S itself when doing the oscillation (continuous scan). It is
possible to generate a TTL pulse by sending commands to the MD2S controller:
this is how user can also operate the shutter on demand. The 3 Python lines
below show how to use `set_external_control` to achieve this configuration:

```python
fshutter = config.get("fshutter")

fshutter.set_external_control(functools.partial(self._exporter.writeProperty, "FastShutterIsOpen", "true"),
                              functools.partial(self._exporter.writeProperty, "FastShutterIsOpen", "false"),
                              lambda: self._exporter.readProperty("FastShutterIsOpen") == "true")
```




## IcePap shutter

An IcePAP controller can be used in *shutter control mode* (using IcePAP LIST
MODE), to operate the opening and closing of a shutter. This is done by moving
back and forth a stepper motor between two pre-defined positions. The change is
trigger by an external signal.

### Specific IcePAP shutter configuration

* **axis_name**: name of existing IcePAP axis to move as a shutter
* **closed_position**: position of the shutter when it is closed (in user position)
* **opened_position**: position of the shutter when it is open (in user position)

```python
DEMO [1]: fsh
 Out [1]: Shutter (fsh)
          ----------------  ------
          State:            CLOSED
          Mode:             MANUAL
          open position:    20
          closed position:  10
          ----------------  ------
```


In order to change the open/close positions,the icepap shutter must be put in
`CONFIGURATION` mode:
```python
DEMO [15]: fsh.mode = fsh.CONFIGURATION
DEMO [16]: fsh
 Out [16]: Shutter (fsh)
           ----------------  -------------
           State:            UNKNOWN
           Mode:             CONFIGURATION
           open position:    20
           closed position:  10
           ----------------  -------------
```

Then the open/closed positions can be changed:
```python

DEMO [20]: fsh.opened_position = 22

DEMO [21]: fsh.closed_position = 12

DEMO [22]: fsh
 Out [22]: Shutter (fsh)
           ----------------  -------------
           State:            UNKNOWN
           Mode:             CONFIGURATION
           open position:    22
           closed position:  12
           ----------------  -------------
```

And the shutter must be exited from CONFIGURATION mode to be usable:
```python
DEMO [23]: fsh.mode = fsh.MANUAL
```


### IcePap Shutter config

```YAML
controller:
   class: icepap
   host: iceid421
   axes:
       - name: fshut_mot
         address: 22
         ...
   shutters:
       - name: fshutter
         axis_name: fshut_mot             # no $ ???
         external_control: $wago_switch   # external control reference (not mandatory)
         closed_position: 0
         opened_position: 1
```

## TangoShutter

`TangoShutter` class is used to interface Tango Device Servers controlling:
166
167
168
169
170

* frontend
* safety shutter
* vaccum remote valves

171
172
173
174
175
176
177
`open()` and `close()` methods are blocking: the `TangoShutter` object waits the
end of the action before returning.

A timeout (60s by default) triggers a `RuntimeError` in case of failure during
the opening or the closing the shutter.

Some commands/attributes (like `automatic`/`manual`) are only implemented in the
178
179
180
front end device server, set by the `_frontend` variable.


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
### Usage examples

Example with a safety shutter:
```python
DEMO [1]: bsh1
 Out [1]: Pneumatic Beam Shutter is closed
           - PSS search broken in downstream hutch
           - Experiment interlock
           - RV4 not Open
           - RV6 not Open
```


Example with a vacuum remote valve:
```python
DEMO [6]: rv9.close()
rv9 was OPEN and is now CLOSED

DEMO [8]: rv9
 Out [8]: Pneumatic is closed

DEMO [10]: rv9.open()
rv9 was CLOSED and is now OPEN

DEMO [11]: rv9
 Out [11]: Pneumatic is open

DEMO [12]: rv9.open()
WARNING 2020-03-19 00:13:23,937 global.controllers.rv9: rv9 already open, command ignored
```


### Configuration examples
214

215
Safety shutter and FrontEnd:
216
```yaml
217
- name: safshut
218
  class: TangoShutter
219
  shutter_type: SafetyShutter
220
221
  uri: id42/bsh/1

222
- name: frontend
223
  class: TangoShutter
224
  shutter_type: FrontEnd
225
  uri: acs.esrf.fr:10000/fe/master/id42
226
227
228

```

229
Remote valves:
230
```yaml
231
- name: rv0
232
  class: TangoShutter
233
  shutter_type: Valve
234
  uri: id42/v-rv/0
235
236

- name: rv1
237
  class: TangoShutter
238
  shutter_type: Valve
239
  uri: id42/v-rv/1
240
241

- name: rv2
242
  class: TangoShutter
243
  shutter_type: Valve
244
245
  uri: id42/v-rv/2
```
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282


### FrontEnd mode

If a `TangoShutter` is a FrontEnd, a special attribute `mode` is usable to
activate or deactivate the automatic openning mode.

It can be : `MANUAL` `AUTOMATIC` or `UNKNOWN`

Example:
```python
DEMO [3]: fe
 Out [3]: State     : Fault on Front End
          Mode      : No mode is validated!
          Automatic : Automatic opening off
          Type      : UHV

          Module 1 Gate Valve 1: Open
          Module 2 Gate Valve 1: Close

          Fault, pending interlocks are:
           Beam permission loop was opened!
           Cooling fault on module1 fixed absorber
           Interlock from personal safety system
```

To change the opening mode of a `FrontEnd` shutter:
```python
DEMO [3]: fe.mode = "MANUAL"
fe mode was AUTOMATIC and is now MANUAL
```

Example (during a shutdown):
```python
DEMO [7]: fe.mode = "AUTOMATIC"
!!! === RuntimeError: Cannot set AUTOMATIC opening === !!!
```