bec-widgets 1.0.1__py3-none-any.whl → 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +26 -24
- PKG-INFO +1 -1
- bec_widgets/applications/alignment/alignment_1d/alignment_1d.ui +60 -84
- bec_widgets/cli/client.py +56 -0
- bec_widgets/tests/__init__.py +0 -0
- bec_widgets/tests/utils.py +226 -0
- bec_widgets/utils/filter_io.py +156 -0
- bec_widgets/utils/widget_io.py +12 -9
- bec_widgets/widgets/base_classes/device_input_base.py +331 -62
- bec_widgets/widgets/base_classes/device_signal_input_base.py +280 -0
- bec_widgets/widgets/dap_combo_box/dap_combo_box_plugin.py +1 -1
- bec_widgets/widgets/device_combobox/device_combo_box_plugin.py +1 -1
- bec_widgets/widgets/device_combobox/device_combobox.py +118 -41
- bec_widgets/widgets/device_line_edit/device_line_edit.py +122 -59
- bec_widgets/widgets/device_line_edit/device_line_edit_plugin.py +1 -1
- bec_widgets/widgets/image/image_widget.py +7 -1
- bec_widgets/widgets/motor_map/motor_map_widget.py +4 -2
- bec_widgets/widgets/positioner_box/positioner_box.py +4 -1
- bec_widgets/widgets/scan_control/scan_control.py +2 -3
- bec_widgets/widgets/scan_control/scan_group_box.py +3 -1
- bec_widgets/widgets/signal_combobox/__init__.py +0 -0
- bec_widgets/widgets/signal_combobox/register_signal_combobox.py +15 -0
- bec_widgets/widgets/signal_combobox/signal_combobox.py +115 -0
- bec_widgets/widgets/signal_combobox/signal_combobox.pyproject +1 -0
- bec_widgets/widgets/signal_combobox/signal_combobox_plugin.py +54 -0
- bec_widgets/widgets/signal_line_edit/__init__.py +0 -0
- bec_widgets/widgets/signal_line_edit/register_signal_line_edit.py +15 -0
- bec_widgets/widgets/signal_line_edit/signal_line_edit.py +140 -0
- bec_widgets/widgets/signal_line_edit/signal_line_edit.pyproject +1 -0
- bec_widgets/widgets/signal_line_edit/signal_line_edit_plugin.py +54 -0
- {bec_widgets-1.0.1.dist-info → bec_widgets-1.1.0.dist-info}/METADATA +1 -1
- {bec_widgets-1.0.1.dist-info → bec_widgets-1.1.0.dist-info}/RECORD +36 -22
- pyproject.toml +1 -1
- {bec_widgets-1.0.1.dist-info → bec_widgets-1.1.0.dist-info}/WHEEL +0 -0
- {bec_widgets-1.0.1.dist-info → bec_widgets-1.1.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-1.0.1.dist-info → bec_widgets-1.1.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
CHANGED
@@ -1,6 +1,32 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
3
|
|
4
|
+
## v1.1.0 (2024-10-25)
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* feat: add filter i/o utility class ([`0350833`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0350833f36e0a7cadce4173f9b1d1fbfdf985375))
|
9
|
+
|
10
|
+
### Refactoring
|
11
|
+
|
12
|
+
* refactor: do not flush selection upon receiving config update; allow widgetIO to receive kwargs to be able to use get_value to receive string instead of int for QComboBox ([`91959e8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/91959e82de8586934af3ebb5aaa0923930effc51))
|
13
|
+
|
14
|
+
* refactor: allow to set selection in DeviceInput; automatic update of selection on device config update; cleanup ([`5eb15b7`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5eb15b785f12e30eb8ccbc56d4ad9e759a4cf5eb))
|
15
|
+
|
16
|
+
* refactor: cleanup, added device_signal for signal inputs ([`6fb2055`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6fb20552ff57978f4aeb79fd7f062f8d6b5581e7))
|
17
|
+
|
18
|
+
### Testing
|
19
|
+
|
20
|
+
* test(scan_control): tests added for grid_scan to ensure scan_args signal validity ([`acb7902`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/acb79020d4be546efc001ff47b6f5cdba2ee9375))
|
21
|
+
|
22
|
+
|
23
|
+
## v1.0.2 (2024-10-22)
|
24
|
+
|
25
|
+
### Bug Fixes
|
26
|
+
|
27
|
+
* fix(scan_control): scan args signal fixed to emit list instead of hardcoded structure ([`4f5448c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4f5448cf51a204e077af162c7f0aed1f1a60e57a))
|
28
|
+
|
29
|
+
|
4
30
|
## v1.0.1 (2024-10-22)
|
5
31
|
|
6
32
|
### Bug Fixes
|
@@ -144,30 +170,6 @@ is emitted multiple times. ([`f084e25`](https://gitlab.psi.ch/bec/bec_widgets/-/
|
|
144
170
|
|
145
171
|
## v0.113.0 (2024-10-02)
|
146
172
|
|
147
|
-
### Bug Fixes
|
148
|
-
|
149
|
-
* fix: add is_log checks and functionality to plot_indicator_items ([`0f9953e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0f9953e8fdcf3f9b5a09f994c69edb6b34756df9))
|
150
|
-
|
151
|
-
### Features
|
152
|
-
|
153
|
-
* feat: add first draft for alignment_1d GUI ([`63c24f9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/63c24f97a355edaa928b6e222909252b276bcada))
|
154
|
-
|
155
|
-
* feat: add move to position button to lmfit dialog ([`281cb27`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/281cb27d8b5433e27a7ba0ca0a19e4b45b9c544f))
|
156
|
-
|
157
|
-
### Refactoring
|
158
|
-
|
159
|
-
* refactor: various minor improvements for the alignment gui ([`f554f3c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f554f3c1672c4fe32968a5991dc98802556a6f3b))
|
160
|
-
|
161
|
-
* refactor: allow hiding of arg/kwarg boxes ([`efe90eb`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/efe90eb163e2123a5b4d0bb59f66025a569336ad))
|
162
|
-
|
163
|
-
* refactor: add proxy to waveform to limit the dap_request frequency ([`5c74037`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5c740371d86d9b1b341bc3c4d8bdf62027aa089b))
|
164
|
-
|
165
|
-
* refactor: update dap_model also if x and y axis are selected ([`28ee385`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/28ee3856be2c47a63182b16454ece37a0ec04811))
|
166
|
-
|
167
173
|
### Testing
|
168
174
|
|
169
175
|
* test: add tests for scan_status_callback ([`dc0c825`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/dc0c825fd594c093a24543ff803d6c6564010e92))
|
170
|
-
|
171
|
-
### Unknown
|
172
|
-
|
173
|
-
* feat : Add bec_signal_proxy to handle signals with option to unblock them manually. ([`1dcfeb6`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1dcfeb6cfce3c69f0c5401731d4d3f9a1981b22e))
|
PKG-INFO
CHANGED
@@ -215,42 +215,18 @@
|
|
215
215
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
216
216
|
<item>
|
217
217
|
<widget class="ScanControl" name="scan_control">
|
218
|
-
<property name="sizePolicy">
|
219
|
-
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
220
|
-
<horstretch>1</horstretch>
|
221
|
-
<verstretch>0</verstretch>
|
222
|
-
</sizepolicy>
|
223
|
-
</property>
|
224
|
-
<property name="minimumSize">
|
225
|
-
<size>
|
226
|
-
<width>0</width>
|
227
|
-
<height>0</height>
|
228
|
-
</size>
|
229
|
-
</property>
|
230
218
|
<property name="current_scan" stdset="0">
|
231
219
|
<string>line_scan</string>
|
232
220
|
</property>
|
233
221
|
<property name="hide_arg_box" stdset="0">
|
234
222
|
<bool>false</bool>
|
235
223
|
</property>
|
236
|
-
<property name="hide_kwarg_boxes" stdset="0">
|
237
|
-
<bool>false</bool>
|
238
|
-
</property>
|
239
|
-
<property name="hide_scan_control_buttons" stdset="0">
|
240
|
-
<bool>false</bool>
|
241
|
-
</property>
|
242
224
|
<property name="hide_scan_selection_combobox" stdset="0">
|
243
225
|
<bool>true</bool>
|
244
226
|
</property>
|
245
227
|
<property name="hide_add_remove_buttons" stdset="0">
|
246
228
|
<bool>true</bool>
|
247
229
|
</property>
|
248
|
-
<property name="hide_args_group" stdset="0">
|
249
|
-
<bool>false</bool>
|
250
|
-
</property>
|
251
|
-
<property name="hide_kwargs_group" stdset="0">
|
252
|
-
<bool>false</bool>
|
253
|
-
</property>
|
254
230
|
</widget>
|
255
231
|
</item>
|
256
232
|
<item>
|
@@ -440,54 +416,54 @@
|
|
440
416
|
</widget>
|
441
417
|
<customwidgets>
|
442
418
|
<customwidget>
|
443
|
-
<class>
|
419
|
+
<class>DapComboBox</class>
|
444
420
|
<extends>QWidget</extends>
|
445
|
-
<header>
|
421
|
+
<header>dap_combo_box</header>
|
446
422
|
</customwidget>
|
447
423
|
<customwidget>
|
448
|
-
<class>
|
424
|
+
<class>StopButton</class>
|
449
425
|
<extends>QWidget</extends>
|
450
|
-
<header>
|
426
|
+
<header>stop_button</header>
|
451
427
|
</customwidget>
|
452
428
|
<customwidget>
|
453
|
-
<class>
|
429
|
+
<class>WebsiteWidget</class>
|
454
430
|
<extends>QWidget</extends>
|
455
|
-
<header>
|
431
|
+
<header>website_widget</header>
|
456
432
|
</customwidget>
|
457
433
|
<customwidget>
|
458
|
-
<class>
|
434
|
+
<class>BECQueue</class>
|
459
435
|
<extends>QWidget</extends>
|
460
|
-
<header>
|
436
|
+
<header>bec_queue</header>
|
461
437
|
</customwidget>
|
462
438
|
<customwidget>
|
463
|
-
<class>
|
439
|
+
<class>ScanControl</class>
|
464
440
|
<extends>QWidget</extends>
|
465
|
-
<header>
|
441
|
+
<header>scan_control</header>
|
466
442
|
</customwidget>
|
467
443
|
<customwidget>
|
468
|
-
<class>
|
444
|
+
<class>ToggleSwitch</class>
|
469
445
|
<extends>QWidget</extends>
|
470
|
-
<header>
|
446
|
+
<header>toggle_switch</header>
|
471
447
|
</customwidget>
|
472
448
|
<customwidget>
|
473
|
-
<class>
|
449
|
+
<class>BECProgressBar</class>
|
474
450
|
<extends>QWidget</extends>
|
475
|
-
<header>
|
451
|
+
<header>bec_progress_bar</header>
|
476
452
|
</customwidget>
|
477
453
|
<customwidget>
|
478
|
-
<class>
|
454
|
+
<class>DarkModeButton</class>
|
479
455
|
<extends>QWidget</extends>
|
480
|
-
<header>
|
456
|
+
<header>dark_mode_button</header>
|
481
457
|
</customwidget>
|
482
458
|
<customwidget>
|
483
|
-
<class>
|
459
|
+
<class>PositionerGroup</class>
|
484
460
|
<extends>QWidget</extends>
|
485
|
-
<header>
|
461
|
+
<header>positioner_group</header>
|
486
462
|
</customwidget>
|
487
463
|
<customwidget>
|
488
|
-
<class>
|
464
|
+
<class>BECWaveformWidget</class>
|
489
465
|
<extends>QWidget</extends>
|
490
|
-
<header>
|
466
|
+
<header>bec_waveform_widget</header>
|
491
467
|
</customwidget>
|
492
468
|
<customwidget>
|
493
469
|
<class>DeviceComboBox</class>
|
@@ -495,14 +471,14 @@
|
|
495
471
|
<header>device_combobox</header>
|
496
472
|
</customwidget>
|
497
473
|
<customwidget>
|
498
|
-
<class>
|
474
|
+
<class>LMFitDialog</class>
|
499
475
|
<extends>QWidget</extends>
|
500
|
-
<header>
|
476
|
+
<header>lm_fit_dialog</header>
|
501
477
|
</customwidget>
|
502
478
|
<customwidget>
|
503
|
-
<class>
|
479
|
+
<class>BECStatusBox</class>
|
504
480
|
<extends>QWidget</extends>
|
505
|
-
<header>
|
481
|
+
<header>bec_status_box</header>
|
506
482
|
</customwidget>
|
507
483
|
</customwidgets>
|
508
484
|
<resources/>
|
@@ -514,12 +490,12 @@
|
|
514
490
|
<slot>toogle_roi_select(bool)</slot>
|
515
491
|
<hints>
|
516
492
|
<hint type="sourcelabel">
|
517
|
-
<x>
|
518
|
-
<y>
|
493
|
+
<x>1042</x>
|
494
|
+
<y>212</y>
|
519
495
|
</hint>
|
520
496
|
<hint type="destinationlabel">
|
521
|
-
<x>
|
522
|
-
<y>
|
497
|
+
<x>1416</x>
|
498
|
+
<y>322</y>
|
523
499
|
</hint>
|
524
500
|
</hints>
|
525
501
|
</connection>
|
@@ -546,12 +522,12 @@
|
|
546
522
|
<slot>plot(QString)</slot>
|
547
523
|
<hints>
|
548
524
|
<hint type="sourcelabel">
|
549
|
-
<x>
|
550
|
-
<y>
|
525
|
+
<x>577</x>
|
526
|
+
<y>215</y>
|
551
527
|
</hint>
|
552
528
|
<hint type="destinationlabel">
|
553
|
-
<x>
|
554
|
-
<y>
|
529
|
+
<x>1416</x>
|
530
|
+
<y>427</y>
|
555
531
|
</hint>
|
556
532
|
</hints>
|
557
533
|
</connection>
|
@@ -562,12 +538,12 @@
|
|
562
538
|
<slot>select_y_axis(QString)</slot>
|
563
539
|
<hints>
|
564
540
|
<hint type="sourcelabel">
|
565
|
-
<x>
|
566
|
-
<y>
|
541
|
+
<x>577</x>
|
542
|
+
<y>215</y>
|
567
543
|
</hint>
|
568
544
|
<hint type="destinationlabel">
|
569
|
-
<x>
|
570
|
-
<y>
|
545
|
+
<x>909</x>
|
546
|
+
<y>215</y>
|
571
547
|
</hint>
|
572
548
|
</hints>
|
573
549
|
</connection>
|
@@ -578,60 +554,60 @@
|
|
578
554
|
<slot>add_dap(QString,QString,QString)</slot>
|
579
555
|
<hints>
|
580
556
|
<hint type="sourcelabel">
|
581
|
-
<x>
|
582
|
-
<y>
|
557
|
+
<x>909</x>
|
558
|
+
<y>215</y>
|
583
559
|
</hint>
|
584
560
|
<hint type="destinationlabel">
|
585
|
-
<x>
|
586
|
-
<y>
|
561
|
+
<x>1416</x>
|
562
|
+
<y>447</y>
|
587
563
|
</hint>
|
588
564
|
</hints>
|
589
565
|
</connection>
|
590
566
|
<connection>
|
591
567
|
<sender>scan_control</sender>
|
592
|
-
<signal>
|
593
|
-
<receiver>
|
594
|
-
<slot>
|
568
|
+
<signal>device_selected(QString)</signal>
|
569
|
+
<receiver>positioner_group</receiver>
|
570
|
+
<slot>set_positioners(QString)</slot>
|
595
571
|
<hints>
|
596
572
|
<hint type="sourcelabel">
|
597
|
-
<x>
|
598
|
-
<y>
|
573
|
+
<x>230</x>
|
574
|
+
<y>306</y>
|
599
575
|
</hint>
|
600
576
|
<hint type="destinationlabel">
|
601
|
-
<x>
|
602
|
-
<y>
|
577
|
+
<x>187</x>
|
578
|
+
<y>926</y>
|
603
579
|
</hint>
|
604
580
|
</hints>
|
605
581
|
</connection>
|
606
582
|
<connection>
|
607
583
|
<sender>scan_control</sender>
|
608
|
-
<signal>
|
609
|
-
<receiver>
|
610
|
-
<slot>
|
584
|
+
<signal>device_selected(QString)</signal>
|
585
|
+
<receiver>bec_waveform_widget</receiver>
|
586
|
+
<slot>set_x(QString)</slot>
|
611
587
|
<hints>
|
612
588
|
<hint type="sourcelabel">
|
613
|
-
<x>
|
614
|
-
<y>
|
589
|
+
<x>187</x>
|
590
|
+
<y>356</y>
|
615
591
|
</hint>
|
616
592
|
<hint type="destinationlabel">
|
617
|
-
<x>
|
618
|
-
<y>
|
593
|
+
<x>972</x>
|
594
|
+
<y>509</y>
|
619
595
|
</hint>
|
620
596
|
</hints>
|
621
597
|
</connection>
|
622
598
|
<connection>
|
623
599
|
<sender>scan_control</sender>
|
624
600
|
<signal>device_selected(QString)</signal>
|
625
|
-
<receiver>
|
626
|
-
<slot>
|
601
|
+
<receiver>dap_combo_box</receiver>
|
602
|
+
<slot>select_x_axis(QString)</slot>
|
627
603
|
<hints>
|
628
604
|
<hint type="sourcelabel">
|
629
|
-
<x>
|
630
|
-
<y>
|
605
|
+
<x>187</x>
|
606
|
+
<y>356</y>
|
631
607
|
</hint>
|
632
608
|
<hint type="destinationlabel">
|
633
|
-
<x>
|
634
|
-
<y>
|
609
|
+
<x>794</x>
|
610
|
+
<y>202</y>
|
635
611
|
</hint>
|
636
612
|
</hints>
|
637
613
|
</connection>
|
bec_widgets/cli/client.py
CHANGED
@@ -38,6 +38,8 @@ class Widgets(str, enum.Enum):
|
|
38
38
|
ResumeButton = "ResumeButton"
|
39
39
|
RingProgressBar = "RingProgressBar"
|
40
40
|
ScanControl = "ScanControl"
|
41
|
+
SignalComboBox = "SignalComboBox"
|
42
|
+
SignalLineEdit = "SignalLineEdit"
|
41
43
|
StopButton = "StopButton"
|
42
44
|
TextBox = "TextBox"
|
43
45
|
VSCodeEditor = "VSCodeEditor"
|
@@ -2591,6 +2593,24 @@ class DeviceLineEdit(RPCBase):
|
|
2591
2593
|
"""
|
2592
2594
|
|
2593
2595
|
|
2596
|
+
class DeviceSignalInputBase(RPCBase):
|
2597
|
+
@property
|
2598
|
+
@rpc_call
|
2599
|
+
def _config_dict(self) -> "dict":
|
2600
|
+
"""
|
2601
|
+
Get the configuration of the widget.
|
2602
|
+
|
2603
|
+
Returns:
|
2604
|
+
dict: The configuration of the widget.
|
2605
|
+
"""
|
2606
|
+
|
2607
|
+
@rpc_call
|
2608
|
+
def _get_all_rpc(self) -> "dict":
|
2609
|
+
"""
|
2610
|
+
Get all registered RPC objects.
|
2611
|
+
"""
|
2612
|
+
|
2613
|
+
|
2594
2614
|
class LMFitDialog(RPCBase):
|
2595
2615
|
@property
|
2596
2616
|
@rpc_call
|
@@ -3003,6 +3023,42 @@ class ScanControl(RPCBase):
|
|
3003
3023
|
"""
|
3004
3024
|
|
3005
3025
|
|
3026
|
+
class SignalComboBox(RPCBase):
|
3027
|
+
@property
|
3028
|
+
@rpc_call
|
3029
|
+
def _config_dict(self) -> "dict":
|
3030
|
+
"""
|
3031
|
+
Get the configuration of the widget.
|
3032
|
+
|
3033
|
+
Returns:
|
3034
|
+
dict: The configuration of the widget.
|
3035
|
+
"""
|
3036
|
+
|
3037
|
+
@rpc_call
|
3038
|
+
def _get_all_rpc(self) -> "dict":
|
3039
|
+
"""
|
3040
|
+
Get all registered RPC objects.
|
3041
|
+
"""
|
3042
|
+
|
3043
|
+
|
3044
|
+
class SignalLineEdit(RPCBase):
|
3045
|
+
@property
|
3046
|
+
@rpc_call
|
3047
|
+
def _config_dict(self) -> "dict":
|
3048
|
+
"""
|
3049
|
+
Get the configuration of the widget.
|
3050
|
+
|
3051
|
+
Returns:
|
3052
|
+
dict: The configuration of the widget.
|
3053
|
+
"""
|
3054
|
+
|
3055
|
+
@rpc_call
|
3056
|
+
def _get_all_rpc(self) -> "dict":
|
3057
|
+
"""
|
3058
|
+
Get all registered RPC objects.
|
3059
|
+
"""
|
3060
|
+
|
3061
|
+
|
3006
3062
|
class StopButton(RPCBase):
|
3007
3063
|
@property
|
3008
3064
|
@rpc_call
|
File without changes
|
@@ -0,0 +1,226 @@
|
|
1
|
+
from unittest.mock import MagicMock
|
2
|
+
|
3
|
+
from bec_lib.device import Device as BECDevice
|
4
|
+
from bec_lib.device import Positioner as BECPositioner
|
5
|
+
from bec_lib.device import ReadoutPriority
|
6
|
+
from bec_lib.devicemanager import DeviceContainer
|
7
|
+
|
8
|
+
|
9
|
+
class FakeDevice(BECDevice):
|
10
|
+
"""Fake minimal positioner class for testing."""
|
11
|
+
|
12
|
+
def __init__(self, name, enabled=True, readout_priority=ReadoutPriority.MONITORED):
|
13
|
+
super().__init__(name=name)
|
14
|
+
self._enabled = enabled
|
15
|
+
self.signals = {self.name: {"value": 1.0}}
|
16
|
+
self.description = {self.name: {"source": self.name, "dtype": "number", "shape": []}}
|
17
|
+
self._readout_priority = readout_priority
|
18
|
+
self._config = {
|
19
|
+
"readoutPriority": "baseline",
|
20
|
+
"deviceClass": "ophyd.Device",
|
21
|
+
"deviceConfig": {},
|
22
|
+
"deviceTags": ["user device"],
|
23
|
+
"enabled": enabled,
|
24
|
+
"readOnly": False,
|
25
|
+
"name": self.name,
|
26
|
+
}
|
27
|
+
|
28
|
+
@property
|
29
|
+
def readout_priority(self):
|
30
|
+
return self._readout_priority
|
31
|
+
|
32
|
+
@readout_priority.setter
|
33
|
+
def readout_priority(self, value):
|
34
|
+
self._readout_priority = value
|
35
|
+
|
36
|
+
@property
|
37
|
+
def limits(self) -> tuple[float, float]:
|
38
|
+
return self._limits
|
39
|
+
|
40
|
+
@limits.setter
|
41
|
+
def limits(self, value: tuple[float, float]):
|
42
|
+
self._limits = value
|
43
|
+
|
44
|
+
def __contains__(self, item):
|
45
|
+
return item == self.name
|
46
|
+
|
47
|
+
@property
|
48
|
+
def _hints(self):
|
49
|
+
return [self.name]
|
50
|
+
|
51
|
+
def set_value(self, fake_value: float = 1.0) -> None:
|
52
|
+
"""
|
53
|
+
Setup fake value for device readout
|
54
|
+
Args:
|
55
|
+
fake_value(float): Desired fake value
|
56
|
+
"""
|
57
|
+
self.signals[self.name]["value"] = fake_value
|
58
|
+
|
59
|
+
def describe(self) -> dict:
|
60
|
+
"""
|
61
|
+
Get the description of the device
|
62
|
+
Returns:
|
63
|
+
dict: Description of the device
|
64
|
+
"""
|
65
|
+
return self.description
|
66
|
+
|
67
|
+
|
68
|
+
class FakePositioner(BECPositioner):
|
69
|
+
|
70
|
+
def __init__(
|
71
|
+
self,
|
72
|
+
name,
|
73
|
+
enabled=True,
|
74
|
+
limits=None,
|
75
|
+
read_value=1.0,
|
76
|
+
readout_priority=ReadoutPriority.MONITORED,
|
77
|
+
):
|
78
|
+
super().__init__(name=name)
|
79
|
+
# self.limits = limits if limits is not None else [0.0, 0.0]
|
80
|
+
self.read_value = read_value
|
81
|
+
self.setpoint_value = read_value
|
82
|
+
self.motor_is_moving_value = 0
|
83
|
+
self._enabled = enabled
|
84
|
+
self._limits = limits
|
85
|
+
self._readout_priority = readout_priority
|
86
|
+
self.signals = {self.name: {"value": 1.0}}
|
87
|
+
self.description = {self.name: {"source": self.name, "dtype": "number", "shape": []}}
|
88
|
+
self._config = {
|
89
|
+
"readoutPriority": "baseline",
|
90
|
+
"deviceClass": "ophyd_devices.SimPositioner",
|
91
|
+
"deviceConfig": {"delay": 1, "tolerance": 0.01, "update_frequency": 400},
|
92
|
+
"deviceTags": ["user motors"],
|
93
|
+
"enabled": enabled,
|
94
|
+
"readOnly": False,
|
95
|
+
"name": self.name,
|
96
|
+
}
|
97
|
+
self._info = {
|
98
|
+
"signals": {
|
99
|
+
"readback": {"kind_str": "5"}, # hinted
|
100
|
+
"setpoint": {"kind_str": "1"}, # normal
|
101
|
+
"velocity": {"kind_str": "2"}, # config
|
102
|
+
}
|
103
|
+
}
|
104
|
+
self.signals = {
|
105
|
+
self.name: {"value": self.read_value},
|
106
|
+
f"{self.name}_setpoint": {"value": self.setpoint_value},
|
107
|
+
f"{self.name}_motor_is_moving": {"value": self.motor_is_moving_value},
|
108
|
+
}
|
109
|
+
|
110
|
+
@property
|
111
|
+
def readout_priority(self):
|
112
|
+
return self._readout_priority
|
113
|
+
|
114
|
+
@readout_priority.setter
|
115
|
+
def readout_priority(self, value):
|
116
|
+
self._readout_priority = value
|
117
|
+
|
118
|
+
@property
|
119
|
+
def enabled(self) -> bool:
|
120
|
+
return self._enabled
|
121
|
+
|
122
|
+
@enabled.setter
|
123
|
+
def enabled(self, value: bool):
|
124
|
+
self._enabled = value
|
125
|
+
|
126
|
+
@property
|
127
|
+
def limits(self) -> tuple[float, float]:
|
128
|
+
return self._limits
|
129
|
+
|
130
|
+
@limits.setter
|
131
|
+
def limits(self, value: tuple[float, float]):
|
132
|
+
self._limits = value
|
133
|
+
|
134
|
+
def __contains__(self, item):
|
135
|
+
return item == self.name
|
136
|
+
|
137
|
+
@property
|
138
|
+
def _hints(self):
|
139
|
+
return [self.name]
|
140
|
+
|
141
|
+
def set_value(self, fake_value: float = 1.0) -> None:
|
142
|
+
"""
|
143
|
+
Setup fake value for device readout
|
144
|
+
Args:
|
145
|
+
fake_value(float): Desired fake value
|
146
|
+
"""
|
147
|
+
self.read_value = fake_value
|
148
|
+
|
149
|
+
def describe(self) -> dict:
|
150
|
+
"""
|
151
|
+
Get the description of the device
|
152
|
+
Returns:
|
153
|
+
dict: Description of the device
|
154
|
+
"""
|
155
|
+
return self.description
|
156
|
+
|
157
|
+
@property
|
158
|
+
def precision(self):
|
159
|
+
return 3
|
160
|
+
|
161
|
+
def set_read_value(self, value):
|
162
|
+
self.read_value = value
|
163
|
+
|
164
|
+
def read(self):
|
165
|
+
return self.signals
|
166
|
+
|
167
|
+
def set_limits(self, limits):
|
168
|
+
self.limits = limits
|
169
|
+
|
170
|
+
def move(self, value, relative=False):
|
171
|
+
"""Simulates moving the device to a new position."""
|
172
|
+
if relative:
|
173
|
+
self.read_value += value
|
174
|
+
else:
|
175
|
+
self.read_value = value
|
176
|
+
# Respect the limits
|
177
|
+
self.read_value = max(min(self.read_value, self.limits[1]), self.limits[0])
|
178
|
+
|
179
|
+
@property
|
180
|
+
def readback(self):
|
181
|
+
return MagicMock(get=MagicMock(return_value=self.read_value))
|
182
|
+
|
183
|
+
|
184
|
+
class Positioner(FakePositioner):
|
185
|
+
"""just placeholder for testing embedded isinstance check in DeviceCombobox"""
|
186
|
+
|
187
|
+
def __init__(self, name="test", limits=None, read_value=1.0):
|
188
|
+
super().__init__(name, limits, read_value)
|
189
|
+
|
190
|
+
|
191
|
+
class Device(FakeDevice):
|
192
|
+
"""just placeholder for testing embedded isinstance check in DeviceCombobox"""
|
193
|
+
|
194
|
+
def __init__(self, name, enabled=True):
|
195
|
+
super().__init__(name, enabled)
|
196
|
+
|
197
|
+
|
198
|
+
class DMMock:
|
199
|
+
def __init__(self):
|
200
|
+
self.devices = DeviceContainer()
|
201
|
+
self.enabled_devices = [device for device in self.devices if device.enabled]
|
202
|
+
|
203
|
+
def add_devives(self, devices: list):
|
204
|
+
for device in devices:
|
205
|
+
self.devices[device.name] = device
|
206
|
+
|
207
|
+
|
208
|
+
DEVICES = [
|
209
|
+
FakePositioner("samx", limits=[-10, 10], read_value=2.0),
|
210
|
+
FakePositioner("samy", limits=[-5, 5], read_value=3.0),
|
211
|
+
FakePositioner("samz", limits=[-8, 8], read_value=4.0),
|
212
|
+
FakePositioner("aptrx", limits=None, read_value=4.0),
|
213
|
+
FakePositioner("aptry", limits=None, read_value=5.0),
|
214
|
+
FakeDevice("gauss_bpm"),
|
215
|
+
FakeDevice("gauss_adc1"),
|
216
|
+
FakeDevice("gauss_adc2"),
|
217
|
+
FakeDevice("gauss_adc3"),
|
218
|
+
FakeDevice("bpm4i"),
|
219
|
+
FakeDevice("bpm3a"),
|
220
|
+
FakeDevice("bpm3i"),
|
221
|
+
FakeDevice("eiger", readout_priority=ReadoutPriority.ASYNC),
|
222
|
+
FakeDevice("waveform1d"),
|
223
|
+
FakeDevice("async_device", readout_priority=ReadoutPriority.ASYNC),
|
224
|
+
Positioner("test", limits=[-10, 10], read_value=2.0),
|
225
|
+
Device("test_device"),
|
226
|
+
]
|