11from collections .abc import Callable
22from dataclasses import dataclass
3- from enum import Enum
43from types import MethodType
54from typing import Any , Literal
65
1110from fastcs .attributes import AttrR , AttrRW , AttrW
1211from fastcs .backends .epics .util import (
1312 MBB_STATE_FIELDS ,
13+ EpicsNameOptions ,
14+ PvNamingConvention ,
1415 attr_is_enum ,
1516 enum_index_to_value ,
1617 enum_value_to_index ,
2324EPICS_MAX_NAME_LENGTH = 60
2425
2526
26- class PvNamingConvention (Enum ):
27- NO_CONVERSION = "NO_CONVERSION"
28- PASCAL = "PASCAL"
29- CAPITALIZED = "CAPITALIZED"
30-
31-
32- DEFAULT_PV_SEPARATOR = ":"
33-
34-
35- @dataclass
27+ @dataclass (frozen = True )
3628class EpicsIOCOptions :
3729 terminal : bool = True
38- pv_naming_convention : PvNamingConvention = PvNamingConvention .PASCAL
39- pv_separator : str = DEFAULT_PV_SEPARATOR
30+ name_options : EpicsNameOptions = EpicsNameOptions ()
4031
4132
4233def _convert_attr_name_to_pv_name (
@@ -53,8 +44,10 @@ class EpicsIOC:
5344 def __init__ (
5445 self , pv_prefix : str , mapping : Mapping , options : EpicsIOCOptions | None = None
5546 ):
56- self .options = options or EpicsIOCOptions ()
57- _add_pvi_info (f"{ pv_prefix } { self .options .pv_separator } PVI" )
47+ self ._options = options or EpicsIOCOptions ()
48+ self ._name_options = self ._options .name_options
49+
50+ _add_pvi_info (f"{ pv_prefix } { self ._name_options .pv_separator } PVI" )
5851 self ._add_sub_controller_pvi_info (pv_prefix , mapping .controller )
5952
6053 self ._create_and_link_attribute_pvs (pv_prefix , mapping )
@@ -68,7 +61,7 @@ def run(
6861 builder .LoadDatabase ()
6962 softioc .iocInit (dispatcher )
7063
71- if self .options .terminal :
64+ if self ._options .terminal :
7265 softioc .interactive_ioc (context )
7366
7467 def _add_sub_controller_pvi_info (self , pv_prefix : str , parent : BaseController ):
@@ -79,14 +72,16 @@ def _add_sub_controller_pvi_info(self, pv_prefix: str, parent: BaseController):
7972 parent: Controller to add PVI refs for
8073
8174 """
82- parent_pvi = self .options .pv_separator .join ([pv_prefix ] + parent .path + ["PVI" ])
75+ parent_pvi = self ._name_options .pv_separator .join (
76+ [pv_prefix ] + parent .path + ["PVI" ]
77+ )
8378
8479 for child in parent .get_sub_controllers ().values ():
85- child_pvi = self .options .pv_separator .join (
80+ child_pvi = self ._name_options .pv_separator .join (
8681 [pv_prefix ]
8782 + [
8883 _convert_attr_name_to_pv_name (
89- path , self .options .pv_naming_convention
84+ path , self ._name_options .pv_naming_convention
9085 )
9186 for path in child .path
9287 ]
@@ -101,18 +96,20 @@ def _add_sub_controller_pvi_info(self, pv_prefix: str, parent: BaseController):
10196 def _create_and_link_attribute_pvs (self , pv_prefix : str , mapping : Mapping ) -> None :
10297 for single_mapping in mapping .get_controller_mappings ():
10398 formatted_path = [
104- _convert_attr_name_to_pv_name (p , self .options .pv_naming_convention )
99+ _convert_attr_name_to_pv_name (
100+ p , self ._name_options .pv_naming_convention
101+ )
105102 for p in single_mapping .controller .path
106103 ]
107104 for attr_name , attribute in single_mapping .attributes .items ():
108105 pv_name = _convert_attr_name_to_pv_name (
109- attr_name , self .options .pv_naming_convention
106+ attr_name , self ._name_options .pv_naming_convention
110107 )
111- _pv_prefix = self .options .pv_separator .join (
108+ _pv_prefix = self ._name_options .pv_separator .join (
112109 [pv_prefix ] + formatted_path
113110 )
114111 full_pv_name_length = len (
115- f"{ _pv_prefix } { self .options .pv_separator } { pv_name } "
112+ f"{ _pv_prefix } { self ._name_options .pv_separator } { pv_name } "
116113 )
117114
118115 if full_pv_name_length > EPICS_MAX_NAME_LENGTH :
@@ -163,7 +160,7 @@ async def async_record_set(value: T):
163160 record .set (value )
164161
165162 record = _get_input_record (
166- f"{ pv_prefix } { self .options .pv_separator } { pv_name } " , attribute
163+ f"{ pv_prefix } { self ._name_options .pv_separator } { pv_name } " , attribute
167164 )
168165 self ._add_attr_pvi_info (record , pv_prefix , attr_name , "r" )
169166
@@ -172,18 +169,20 @@ async def async_record_set(value: T):
172169 def _create_and_link_command_pvs (self , pv_prefix : str , mapping : Mapping ) -> None :
173170 for single_mapping in mapping .get_controller_mappings ():
174171 formatted_path = [
175- _convert_attr_name_to_pv_name (p , self .options .pv_naming_convention )
172+ _convert_attr_name_to_pv_name (
173+ p , self ._name_options .pv_naming_convention
174+ )
176175 for p in single_mapping .controller .path
177176 ]
178177 for attr_name , method in single_mapping .command_methods .items ():
179178 pv_name = _convert_attr_name_to_pv_name (
180- attr_name , self .options .pv_naming_convention
179+ attr_name , self ._name_options .pv_naming_convention
181180 )
182- _pv_prefix = self .options .pv_separator .join (
181+ _pv_prefix = self ._name_options .pv_separator .join (
183182 [pv_prefix ] + formatted_path
184183 )
185184 if (
186- len (f"{ _pv_prefix } { self .options .pv_separator } { pv_name } " )
185+ len (f"{ _pv_prefix } { self ._name_options .pv_separator } { pv_name } " )
187186 > EPICS_MAX_NAME_LENGTH
188187 ):
189188 print (
@@ -221,7 +220,7 @@ async def async_write_display(value: T):
221220 record .set (value , process = False )
222221
223222 record = _get_output_record (
224- f"{ pv_prefix } { self .options .pv_separator } { pv_name } " ,
223+ f"{ pv_prefix } { self ._name_options .pv_separator } { pv_name } " ,
225224 attribute ,
226225 on_update = on_update ,
227226 )
@@ -237,7 +236,7 @@ async def wrapped_method(_: Any):
237236 await method ()
238237
239238 record = builder .aOut (
240- f"{ pv_prefix } { self .options .pv_separator } { pv_name } " ,
239+ f"{ pv_prefix } { self ._name_options .pv_separator } { pv_name } " ,
241240 initial_value = 0 ,
242241 always_update = True ,
243242 on_update = wrapped_method ,
@@ -264,7 +263,7 @@ def _add_attr_pvi_info(
264263 record .add_info (
265264 "Q:group" ,
266265 {
267- f"{ prefix } { self .options .pv_separator } PVI" : {
266+ f"{ prefix } { self ._name_options .pv_separator } PVI" : {
268267 f"value.{ name } .{ access_mode } " : {
269268 "+channel" : "NAME" ,
270269 "+type" : "plain" ,
0 commit comments