1
1
import asyncio
2
2
3
3
from fastcs .attributes import Attribute , AttrR , AttrRW , AttrW
4
- from fastcs .controller import Controller
4
+ from fastcs .controller import Controller , SubController
5
5
from fastcs .datatypes import Bool , Float , Int , String , T
6
6
from fastcs .wrappers import scan
7
7
11
11
RawFieldsType ,
12
12
RawInitialValuesType ,
13
13
)
14
+ from fastcs_pandablocks .types ._annotations import ResponseType
14
15
15
16
from .client_wrapper import RawPanda
16
- from .fields import FieldController
17
+ from .fields import make_attributes
18
+
19
+
20
+ class BlockController (SubController ):
21
+ def __init__ (self , panda_name : PandaName , label : str | None = None ):
22
+ self .description = label
23
+ self .panda_name = panda_name
24
+
25
+ self .attributes : dict [str , Attribute ] = {}
26
+ self .panda_name_to_attribute : dict [PandaName , Attribute ] = {}
27
+ super ().__init__ ()
28
+
29
+ def make_attributes (
30
+ self ,
31
+ field_info : dict [PandaName , ResponseType ],
32
+ initial_values : dict [PandaName , str ],
33
+ ):
34
+ if self .description is not None :
35
+ self .attributes ["LABEL" ] = AttrR (
36
+ String (),
37
+ description = "Label from metadata." ,
38
+ initial_value = self .description ,
39
+ )
40
+ self .panda_name_to_attribute = make_attributes (
41
+ self .panda_name , field_info , initial_values
42
+ )
43
+ attribute_name_to_attribute = {}
44
+ for panda_name , attribute in self .panda_name_to_attribute .items ():
45
+ assert panda_name .field
46
+ sub_field = f"_{ panda_name .sub_field } " if panda_name .sub_field else ""
47
+ attribute_name_to_attribute [f"{ panda_name .field } { sub_field } " ] = attribute
48
+
49
+ self .attributes .update (attribute_name_to_attribute )
17
50
18
51
19
52
def _parse_introspected_data (
@@ -22,7 +55,7 @@ def _parse_introspected_data(
22
55
raw_labels : RawInitialValuesType ,
23
56
raw_initial_values : RawInitialValuesType ,
24
57
):
25
- block_controllers : dict [PandaName , FieldController ] = {}
58
+ block_controllers : dict [PandaName , BlockController ] = {}
26
59
for (block_name , block_info ), field_info in zip (
27
60
raw_blocks .items (), raw_field_infos , strict = True
28
61
):
@@ -41,11 +74,11 @@ def _parse_introspected_data(
41
74
if key in numbered_block_name
42
75
}
43
76
label = raw_labels .get (numbered_block_name , None )
44
- block = FieldController (
77
+ block = BlockController (
45
78
numbered_block_name ,
46
79
label = block_info .description or label ,
47
80
)
48
- block .make_sub_fields (field_info , block_initial_values )
81
+ block .make_attributes (field_info , block_initial_values )
49
82
block_controllers [numbered_block_name ] = block
50
83
51
84
return block_controllers
@@ -64,7 +97,7 @@ def __init__(self, hostname: str, poll_period: float) -> None:
64
97
65
98
self .attributes : dict [str , Attribute ] = {}
66
99
self ._raw_panda = RawPanda (hostname )
67
- self ._blocks : dict [PandaName , FieldController ] = {}
100
+ self ._blocks : dict [PandaName , BlockController ] = {}
68
101
69
102
self .connected = False
70
103
@@ -83,27 +116,15 @@ async def connect(self) -> None:
83
116
async def initialise (self ) -> None :
84
117
await self .connect ()
85
118
for block_name , block in self ._blocks .items ():
86
- if block .top_level_attribute is not None :
87
- self .attributes [block_name .attribute_name ] = block .top_level_attribute
88
- if block .attributes or block .sub_fields :
89
- self .register_sub_controller (block_name .attribute_name .title (), block )
90
- await block .initialise ()
119
+ self .register_sub_controller (block_name .attribute_name .title (), block )
91
120
92
121
def get_attribute (self , panda_name : PandaName ) -> Attribute :
93
122
assert panda_name .block
94
123
block_controller = self ._blocks [panda_name .up_to_block ()]
95
124
if panda_name .field is None :
96
- assert block_controller .top_level_attribute is not None
97
- return block_controller .top_level_attribute
98
-
99
- field_controller = block_controller .sub_fields [panda_name .up_to_field ()]
100
- if panda_name .sub_field is None :
101
- assert field_controller .top_level_attribute is not None
102
- return field_controller .top_level_attribute
125
+ raise RuntimeError
103
126
104
- sub_field_controller = field_controller .sub_fields [panda_name ]
105
- assert sub_field_controller .top_level_attribute is not None
106
- return sub_field_controller .top_level_attribute
127
+ return block_controller .panda_name_to_attribute [panda_name ]
107
128
108
129
async def update_field_value (self , panda_name : PandaName , value : str ):
109
130
attribute = self .get_attribute (panda_name )
0 commit comments