Skip to content

Commit

Permalink
review comments, fix ioc entrypoint and config fan out
Browse files Browse the repository at this point in the history
  • Loading branch information
jsouter committed Dec 9, 2024
1 parent 0104af8 commit 67d5154
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 34 deletions.
16 changes: 11 additions & 5 deletions src/fastcs_odin/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import typer
from fastcs.connections.ip_connection import IPConnectionSettings
from fastcs.launch import FastCS
from fastcs.transport.epics.options import EpicsGUIOptions, EpicsOptions
from fastcs.transport.epics.options import (
EpicsGUIOptions,
EpicsIOCOptions,
EpicsOptions,
)

from fastcs_odin.odin_controller import OdinController

Expand Down Expand Up @@ -43,15 +47,17 @@ def main(

@app.command()
def ioc(pv_prefix: str = typer.Argument(), ip: str = OdinIp, port: int = OdinPort):
# from fastcs.backends.epics.backend import EpicsBackend

controller = OdinController(IPConnectionSettings(ip, port))
options = EpicsOptions(
ioc=EpicsIOCOptions(pv_prefix=pv_prefix),
gui=EpicsGUIOptions(
output_path=Path.cwd() / "odin.bob", title=f"Odin - {pv_prefix}"
)
),
)
FastCS(controller, options)
launcher = FastCS(controller, options)
launcher.create_docs()
launcher.create_gui()
launcher.run()


# test with: python -m fastcs_odin
Expand Down
17 changes: 7 additions & 10 deletions src/fastcs_odin/odin_adapter_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import re
from collections.abc import Callable, Iterable, Sequence
from dataclasses import dataclass
from typing import Any, Generic, TypeVar
from typing import Any

from fastcs.attributes import AttrR, AttrRW, AttrW, Handler, Sender, Updater
from fastcs.controller import BaseController, SubController
Expand Down Expand Up @@ -59,11 +59,8 @@ async def update(
logging.error("Update loop failed for %s:\n%s", self.path, e)


T = TypeVar("T")


@dataclass
class StatusSummaryUpdater(Updater, Generic[T]):
class StatusSummaryUpdater(Updater):
"""Updater to accumulate underlying attributes into a high-level summary.
Args:
Expand All @@ -79,13 +76,13 @@ class StatusSummaryUpdater(Updater, Generic[T]):

path_filter: list[str | tuple[str] | re.Pattern]
attribute_name: str
accumulator: Callable[[Iterable[T]], T]
accumulator: Callable[[Iterable[Any]], float | int | bool | str]
update_period: float | None = 0.2

async def update(self, controller: "OdinAdapterController", attr: AttrR):
values = []
for sub_controller in _filter_sub_controllers(controller, self.path_filter):
sub_attribute: AttrR = getattr(sub_controller, self.attribute_name)
sub_attribute: AttrR = sub_controller.attributes[self.attribute_name]
values.append(sub_attribute.get())

await attr.set(self.accumulator(values))
Expand All @@ -101,7 +98,7 @@ class ConfigFanSender(Sender):

attributes: list[AttrW]

async def put(self, _: "OdinAdapterController", attr: AttrW, value: Any): # pyright: ignore[reportIncompatibleMethodOverride]
async def put(self, controller: "OdinAdapterController", attr: AttrW, value: Any):
for attribute in self.attributes:
await attribute.process(value)

Expand All @@ -111,7 +108,7 @@ async def put(self, _: "OdinAdapterController", attr: AttrW, value: Any): # pyr

def _filter_sub_controllers(
controller: BaseController, path_filter: Sequence[str | tuple[str] | re.Pattern]
) -> Iterable[BaseController]:
) -> Iterable[SubController]:
sub_controller_map = controller.get_sub_controllers()

if len(path_filter) == 1:
Expand Down Expand Up @@ -213,4 +210,4 @@ def _create_attributes(self):
),
group=group,
)
self.attributes[parameter.name.replace(".", "")] = attr
self.attributes[parameter.name] = attr
23 changes: 7 additions & 16 deletions src/fastcs_odin/odin_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def _create_config_fan_attributes(self):
mode, key = parameter.uri[0], parameter.uri[-1]
if mode == "config" and key not in self._unique_config:
try:
attr = getattr(sub_controller, parameter.name)
attr = sub_controller.attributes[parameter.name]
if parameter.name not in parameter_attribute_map:
parameter_attribute_map[parameter.name] = (
parameter,
Expand All @@ -83,7 +83,7 @@ def _create_config_fan_attributes(self):
parameter_attribute_map[parameter.name][1].append(
attr
)
except AttributeError:
except KeyError:
logging.warning(
f"Controller has parameter {parameter}, "
f"but no corresponding attribute {parameter.name}"
Expand All @@ -94,14 +94,10 @@ def _create_config_fan_attributes(self):
)

for parameter, sub_attributes in parameter_attribute_map.values():
setattr(
self,
parameter.name,
sub_attributes[0].__class__(
sub_attributes[0].datatype,
group=sub_attributes[0].group,
handler=ConfigFanSender(sub_attributes),
),
self.attributes[parameter.name] = sub_attributes[0].__class__(
sub_attributes[0].datatype,
group=sub_attributes[0].group,
handler=ConfigFanSender(sub_attributes),
)


Expand Down Expand Up @@ -179,12 +175,7 @@ def __parameter_in_plugin(
class FrameProcessorAdapterController(OdinDataAdapterController):
frames_written: AttrR = AttrR(
Int(),
handler=StatusSummaryUpdater(
[re.compile("FP*"), "HDF"],
"frames_written",
sum, # type: ignore
# sum does not fit accumulator type signature, casts bools to ints
),
handler=StatusSummaryUpdater([re.compile("FP*"), "HDF"], "frames_written", sum),
)
writing: AttrR = AttrR(
Bool(),
Expand Down
4 changes: 1 addition & 3 deletions tests/test_controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,7 @@ async def test_status_summary_updater(mocker: MockerFixture):
hdf_controller.frames_written.get.return_value = 50

handler = StatusSummaryUpdater(
["OD", ("FP",), re.compile("FP*"), "HDF"],
"frames_written",
sum, # type: ignore
["OD", ("FP",), re.compile("FP*"), "HDF"], "frames_written", sum
)
hdf_controller.frames_written.get.return_value = 50
await handler.update(controller, attr)
Expand Down

0 comments on commit 67d5154

Please sign in to comment.