Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

76 pass backend options on init and provide pv name formatting options #77

Closed
wants to merge 10 commits into from
3 changes: 2 additions & 1 deletion src/fastcs/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ async def put(self, controller: Any, attr: AttrW, value: Any) -> None:
class Updater(Protocol):
"""Protocol for updating the cached readback value of an ``Attribute``."""

update_period: float
# If update period is None then the attribute will not be updated as a task.
update_period: float | None

async def update(self, controller: Any, attr: AttrR) -> None:
pass
Expand Down
2 changes: 2 additions & 0 deletions src/fastcs/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@
for attribute in single_mapping.attributes.values():
match attribute:
case AttrR(updater=Updater(update_period=update_period)) as attribute:
if update_period is None:
continue

Check warning on line 138 in src/fastcs/backend.py

View check run for this annotation

Codecov / codecov/patch

src/fastcs/backend.py#L138

Added line #L138 was not covered by tests
callback = _create_updater_callback(
attribute, single_mapping.controller
)
Expand Down
25 changes: 17 additions & 8 deletions src/fastcs/backends/epics/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,26 @@


class EpicsBackend(Backend):
def __init__(self, controller: Controller, pv_prefix: str = "MY-DEVICE-PREFIX"):
def __init__(
self,
controller: Controller,
pv_prefix: str = "MY-DEVICE-PREFIX",
ioc_options: EpicsIOCOptions | None = None,
):
super().__init__(controller)

self._pv_prefix = pv_prefix
self._ioc = EpicsIOC(pv_prefix, self._mapping)
self.ioc_options = ioc_options or EpicsIOCOptions()
self._ioc = EpicsIOC(pv_prefix, self._mapping, options=ioc_options)

def create_docs(self, options: EpicsDocsOptions | None = None) -> None:
EpicsDocs(self._mapping).create_docs(options)
def create_docs(self, docs_options: EpicsDocsOptions | None = None) -> None:
EpicsDocs(self._mapping).create_docs(docs_options)

Check warning on line 23 in src/fastcs/backends/epics/backend.py

View check run for this annotation

Codecov / codecov/patch

src/fastcs/backends/epics/backend.py#L23

Added line #L23 was not covered by tests

def create_gui(self, options: EpicsGUIOptions | None = None) -> None:
EpicsGUI(self._mapping, self._pv_prefix).create_gui(options)
def create_gui(self, gui_options: EpicsGUIOptions | None = None) -> None:
assert self.ioc_options.name_options is not None
EpicsGUI(

Check warning on line 27 in src/fastcs/backends/epics/backend.py

View check run for this annotation

Codecov / codecov/patch

src/fastcs/backends/epics/backend.py#L26-L27

Added lines #L26 - L27 were not covered by tests
self._mapping, self._pv_prefix, self.ioc_options.name_options
).create_gui(gui_options)

def _run(self, options: EpicsIOCOptions | None = None):
self._ioc.run(self._dispatcher, self._context, options)
def _run(self):
self._ioc.run(self._dispatcher, self._context)
36 changes: 32 additions & 4 deletions src/fastcs/backends/epics/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
from pydantic import ValidationError

from fastcs.attributes import Attribute, AttrR, AttrRW, AttrW
from fastcs.backends.epics.util import (
EpicsNameOptions,
_convert_attribute_name_to_pv_name,
)
from fastcs.cs_methods import Command
from fastcs.datatypes import Bool, Float, Int, String
from fastcs.exceptions import FastCSException
Expand All @@ -39,21 +43,45 @@ class EpicsGUIFormat(Enum):
edl = ".edl"


@dataclass
@dataclass(frozen=True)
class EpicsGUIOptions:
output_path: Path = Path.cwd() / "output.bob"
file_format: EpicsGUIFormat = EpicsGUIFormat.bob
title: str = "Simple Device"


class EpicsGUI:
def __init__(self, mapping: Mapping, pv_prefix: str) -> None:
def __init__(
self,
mapping: Mapping,
pv_prefix: str,
epics_name_options: EpicsNameOptions | None = None,
) -> None:
self._mapping = mapping
self._pv_prefix = pv_prefix
self.epics_name_options = epics_name_options or EpicsNameOptions()

def _get_pv(self, attr_path: list[str], name: str):
attr_prefix = ":".join([self._pv_prefix] + attr_path)
return f"{attr_prefix}:{name.title().replace('_', '')}"
return self.epics_name_options.pv_separator.join(
[
self._pv_prefix,
]
+ [
_convert_attribute_name_to_pv_name(
attr_name,
self.epics_name_options.pv_naming_convention,
is_attribute=False,
)
for attr_name in attr_path
]
+ [
_convert_attribute_name_to_pv_name(
name,
self.epics_name_options.pv_naming_convention,
is_attribute=True,
),
],
)

@staticmethod
def _get_read_widget(attribute: AttrR) -> ReadWidgetUnion:
Expand Down
Loading
Loading