2
2
from enum import Enum
3
3
from pathlib import Path
4
4
5
- from pvi ._format .base import Formatter
6
- from pvi ._yaml_utils import deserialize_yaml
5
+ from pvi ._format .dls import DLSFormatter
7
6
from pvi .device import (
8
7
LED ,
9
8
CheckBox ,
16
15
SignalRW ,
17
16
SignalW ,
18
17
SignalX ,
18
+ SubScreen ,
19
19
TextFormat ,
20
20
TextRead ,
21
21
TextWrite ,
24
24
)
25
25
26
26
from fastcs .attributes import Attribute , AttrR , AttrRW , AttrW
27
+ from fastcs .cs_methods import Command
27
28
from fastcs .datatypes import Bool , DataType , Float , Int , String
28
29
from fastcs .exceptions import FastCSException
29
- from fastcs .mapping import Mapping
30
-
31
- FORMATTER_YAML = Path .cwd () / ".." / "pvi" / "formatters" / "dls.bob.pvi.formatter.yaml"
30
+ from fastcs .mapping import Mapping , SingleMapping
32
31
33
32
34
33
class EpicsGUIFormat (Enum ):
@@ -83,26 +82,32 @@ def _get_write_widget(datatype: DataType) -> WriteWidget:
83
82
@classmethod
84
83
def _get_attribute_component (cls , attr_path : str , name : str , attribute : Attribute ):
85
84
pv = cls ._get_pv (attr_path , name )
86
- name = name .title ().replace ("_" , " " )
85
+ name = name .title ().replace ("_" , "" )
87
86
88
87
match attribute :
89
88
case AttrRW ():
90
89
read_widget = cls ._get_read_widget (attribute .datatype )
91
90
write_widget = cls ._get_write_widget (attribute .datatype )
92
- return SignalRW (name , pv , write_widget , pv + "_RBV" , read_widget )
91
+ return SignalRW (
92
+ name = name ,
93
+ pv = pv ,
94
+ widget = write_widget ,
95
+ read_pv = pv + "_RBV" ,
96
+ read_widget = read_widget ,
97
+ )
93
98
case AttrR ():
94
99
read_widget = cls ._get_read_widget (attribute .datatype )
95
- return SignalR (name , pv , read_widget )
100
+ return SignalR (name = name , pv = pv , widget = read_widget )
96
101
case AttrW ():
97
102
write_widget = cls ._get_write_widget (attribute .datatype )
98
- return SignalW (name , pv , TextWrite ())
103
+ return SignalW (name = name , pv = pv , widget = TextWrite ())
99
104
100
105
@classmethod
101
106
def _get_command_component (cls , attr_path : str , name : str ):
102
107
pv = cls ._get_pv (attr_path , name )
103
- name = name .title ().replace ("_" , " " )
108
+ name = name .title ().replace ("_" , "" )
104
109
105
- return SignalX (name , pv , value = 1 )
110
+ return SignalX (name = name , pv = pv , value = "1" )
106
111
107
112
def create_gui (self , options : EpicsGUIOptions | None = None ) -> None :
108
113
if options is None :
@@ -113,29 +118,60 @@ def create_gui(self, options: EpicsGUIOptions | None = None) -> None:
113
118
114
119
assert options .output_path .suffix == options .file_format .value
115
120
116
- formatter = deserialize_yaml ( Formatter , FORMATTER_YAML )
121
+ formatter = DLSFormatter ( )
117
122
118
- components : Tree [Component ] = []
119
- for single_mapping in self ._mapping .get_controller_mappings ():
120
- attr_path = single_mapping .controller .path
121
-
122
- group_name = type (single_mapping .controller ).__name__ + " " + attr_path
123
- group_children : list [Component ] = []
124
-
125
- for attr_name , attribute in single_mapping .attributes .items ():
126
- group_children .append (
127
- self ._get_attribute_component (
128
- attr_path ,
129
- attr_name ,
130
- attribute ,
131
- )
132
- )
123
+ controller_mapping = self ._mapping .get_controller_mappings ()[0 ]
124
+ sub_controller_mappings = self ._mapping .get_controller_mappings ()[1 :]
133
125
134
- for name in single_mapping .command_methods :
135
- group_children .append (self ._get_command_component (attr_path , name ))
126
+ components = self .extract_mapping_components (controller_mapping )
136
127
137
- components .append (Group (group_name , Grid (), group_children ))
128
+ for sub_controller_mapping in sub_controller_mappings :
129
+ components .append (
130
+ Group (
131
+ name = sub_controller_mapping .controller .path ,
132
+ layout = SubScreen (),
133
+ children = self .extract_mapping_components (sub_controller_mapping ),
134
+ )
135
+ )
138
136
139
- device = Device ("Simple Device" , children = components )
137
+ device = Device (label = "Simple Device" , children = components )
140
138
141
139
formatter .format (device , "MY-DEVICE-PREFIX" , options .output_path )
140
+
141
+ def extract_mapping_components (self , mapping : SingleMapping ) -> list [Component ]:
142
+ components : Tree [Component ] = []
143
+ attr_path = mapping .controller .path
144
+
145
+ groups : dict [str , list [Component ]] = {}
146
+ for attr_name , attribute in mapping .attributes .items ():
147
+ signal = self ._get_attribute_component (
148
+ attr_path ,
149
+ attr_name ,
150
+ attribute ,
151
+ )
152
+
153
+ match attribute :
154
+ case Attribute (group = group ) if group is not None :
155
+ if group not in groups :
156
+ groups [group ] = []
157
+
158
+ groups [group ].append (signal )
159
+ case _:
160
+ components .append (signal )
161
+
162
+ for name , command in mapping .command_methods .items ():
163
+ signal = self ._get_command_component (attr_path , name )
164
+
165
+ match command :
166
+ case Command (group = group ) if group is not None :
167
+ if group not in groups :
168
+ groups [group ] = []
169
+
170
+ groups [group ].append (signal )
171
+ case _:
172
+ components .append (signal )
173
+
174
+ for name , children in groups .items ():
175
+ components .append (Group (name = name , layout = Grid (), children = children ))
176
+
177
+ return components
0 commit comments