|
1 | 1 | from collections.abc import Callable |
2 | 2 | from dataclasses import dataclass |
| 3 | +from enum import Enum |
3 | 4 | from types import MethodType |
4 | 5 | from typing import Any, Literal |
5 | 6 |
|
|
22 | 23 | EPICS_MAX_NAME_LENGTH = 60 |
23 | 24 |
|
24 | 25 |
|
| 26 | +class PvNamingConvention(Enum): |
| 27 | + NO_CONVERSION = 0 |
| 28 | + PASCAL = 1 |
| 29 | + CAPITALIZED = 2 |
| 30 | + |
| 31 | + |
25 | 32 | @dataclass |
26 | 33 | class EpicsIOCOptions: |
27 | 34 | terminal: bool = True |
| 35 | + pv_naming_convention: PvNamingConvention = PvNamingConvention.PASCAL |
28 | 36 |
|
29 | 37 |
|
30 | 38 | class EpicsIOC: |
31 | | - def __init__(self, pv_prefix: str, mapping: Mapping): |
| 39 | + def __init__( |
| 40 | + self, pv_prefix: str, mapping: Mapping, options: EpicsIOCOptions | None = None |
| 41 | + ): |
| 42 | + self.options = options or EpicsIOCOptions() |
32 | 43 | _add_pvi_info(f"{pv_prefix}:PVI") |
33 | 44 | _add_sub_controller_pvi_info(pv_prefix, mapping.controller) |
34 | 45 |
|
35 | 46 | _create_and_link_attribute_pvs(pv_prefix, mapping) |
36 | | - _create_and_link_command_pvs(pv_prefix, mapping) |
| 47 | + _create_and_link_command_pvs( |
| 48 | + pv_prefix, mapping, self.options.pv_naming_convention |
| 49 | + ) |
37 | 50 |
|
38 | 51 | def run( |
39 | 52 | self, |
40 | 53 | dispatcher: AsyncioDispatcher, |
41 | 54 | context: dict[str, Any], |
42 | | - options: EpicsIOCOptions | None = None, |
43 | 55 | ) -> None: |
44 | | - if options is None: |
45 | | - options = EpicsIOCOptions() |
46 | | - |
47 | 56 | builder.LoadDatabase() |
48 | 57 | softioc.iocInit(dispatcher) |
49 | 58 |
|
50 | | - softioc.interactive_ioc(context) |
| 59 | + if self.options.terminal: |
| 60 | + softioc.interactive_ioc(context) |
51 | 61 |
|
52 | 62 |
|
53 | 63 | def _add_pvi_info( |
@@ -222,9 +232,6 @@ async def async_write_display(value: T): |
222 | 232 | record = _get_output_record( |
223 | 233 | f"{pv_prefix}:{pv_name}", attribute, on_update=on_update |
224 | 234 | ) |
225 | | - pascal_case_pv_name = pv_name.title() |
226 | | - if pascal_case_pv_name != pv_name: |
227 | | - record.add_alias(f"{pv_prefix}:{pascal_case_pv_name}") |
228 | 235 |
|
229 | 236 | _add_attr_pvi_info(record, pv_prefix, attr_name, "w") |
230 | 237 |
|
@@ -279,11 +286,23 @@ def _get_output_record(pv: str, attribute: AttrW, on_update: Callable) -> Any: |
279 | 286 | ) |
280 | 287 |
|
281 | 288 |
|
282 | | -def _create_and_link_command_pvs(pv_prefix: str, mapping: Mapping) -> None: |
| 289 | +def _convert_attr_name_to_pv_name( |
| 290 | + attr_name: str, naming_convention: PvNamingConvention |
| 291 | +) -> str: |
| 292 | + if naming_convention == PvNamingConvention.PASCAL: |
| 293 | + return attr_name.title().replace("_", "") |
| 294 | + elif naming_convention == PvNamingConvention.CAPITALIZED: |
| 295 | + return attr_name.upper().replace("_", "-") |
| 296 | + return attr_name |
| 297 | + |
| 298 | + |
| 299 | +def _create_and_link_command_pvs( |
| 300 | + pv_prefix: str, mapping: Mapping, naming_convention: PvNamingConvention |
| 301 | +) -> None: |
283 | 302 | for single_mapping in mapping.get_controller_mappings(): |
284 | 303 | path = single_mapping.controller.path |
285 | 304 | for attr_name, method in single_mapping.command_methods.items(): |
286 | | - pv_name = attr_name.title().replace("_", "") |
| 305 | + pv_name = _convert_attr_name_to_pv_name(attr_name, naming_convention) |
287 | 306 | _pv_prefix = ":".join([pv_prefix] + path) |
288 | 307 | if len(f"{_pv_prefix}:{pv_name}") > EPICS_MAX_NAME_LENGTH: |
289 | 308 | print( |
|
0 commit comments