diff --git a/docs/snippets/dynamic.py b/docs/snippets/dynamic.py index dac6894b7..9dad42e7a 100644 --- a/docs/snippets/dynamic.py +++ b/docs/snippets/dynamic.py @@ -8,7 +8,7 @@ from fastcs.attributes import AttrHandlerRW, Attribute, AttrR, AttrRW, AttrW from fastcs.connections import IPConnection, IPConnectionSettings -from fastcs.controller import Controller, SubController +from fastcs.controller import Controller from fastcs.datatypes import Bool, DataType, Float, Int, String from fastcs.launch import FastCS from fastcs.transport.epics.ca.options import EpicsCAOptions @@ -76,7 +76,7 @@ async def put(self, attr: AttrW, value: Any): ) -class TemperatureRampController(SubController): +class TemperatureRampController(Controller): def __init__(self, index: int, connection: IPConnection): super().__init__(f"Ramp {index}") diff --git a/docs/snippets/static10.py b/docs/snippets/static10.py index 919254547..44f569f6d 100644 --- a/docs/snippets/static10.py +++ b/docs/snippets/static10.py @@ -6,7 +6,7 @@ from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW from fastcs.connections import IPConnection, IPConnectionSettings -from fastcs.controller import BaseController, Controller, SubController +from fastcs.controller import BaseController, Controller from fastcs.datatypes import Float, Int, String from fastcs.launch import FastCS from fastcs.transport.epics.ca.options import EpicsCAOptions @@ -44,7 +44,7 @@ async def put(self, attr: AttrW, value: Any): ) -class TemperatureRampController(SubController): +class TemperatureRampController(Controller): start = AttrRW(Int(), handler=TemperatureControllerHandler("S")) end = AttrRW(Int(), handler=TemperatureControllerHandler("E")) diff --git a/docs/snippets/static11.py b/docs/snippets/static11.py index fb56b129a..55d3ab29f 100644 --- a/docs/snippets/static11.py +++ b/docs/snippets/static11.py @@ -7,7 +7,7 @@ from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW from fastcs.connections import IPConnection, IPConnectionSettings -from fastcs.controller import BaseController, Controller, SubController +from fastcs.controller import BaseController, Controller from fastcs.datatypes import Enum, Float, Int, String from fastcs.launch import FastCS from fastcs.transport.epics.ca.options import EpicsCAOptions @@ -50,7 +50,7 @@ class OnOffEnum(enum.StrEnum): On = "1" -class TemperatureRampController(SubController): +class TemperatureRampController(Controller): start = AttrRW(Int(), handler=TemperatureControllerHandler("S")) end = AttrRW(Int(), handler=TemperatureControllerHandler("E")) enabled = AttrRW(Enum(OnOffEnum), handler=TemperatureControllerHandler("N")) diff --git a/docs/snippets/static12.py b/docs/snippets/static12.py index b14b1d198..1613c1d7c 100644 --- a/docs/snippets/static12.py +++ b/docs/snippets/static12.py @@ -8,7 +8,7 @@ from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW from fastcs.connections import IPConnection, IPConnectionSettings -from fastcs.controller import BaseController, Controller, SubController +from fastcs.controller import BaseController, Controller from fastcs.datatypes import Enum, Float, Int, String from fastcs.launch import FastCS from fastcs.transport.epics.ca.options import EpicsCAOptions @@ -52,7 +52,7 @@ class OnOffEnum(enum.StrEnum): On = "1" -class TemperatureRampController(SubController): +class TemperatureRampController(Controller): start = AttrRW(Int(), handler=TemperatureControllerHandler("S")) end = AttrRW(Int(), handler=TemperatureControllerHandler("E")) enabled = AttrRW(Enum(OnOffEnum), handler=TemperatureControllerHandler("N")) diff --git a/docs/snippets/static13.py b/docs/snippets/static13.py index 74e2e1a64..aa5abaef2 100644 --- a/docs/snippets/static13.py +++ b/docs/snippets/static13.py @@ -9,7 +9,7 @@ from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW from fastcs.connections import IPConnection, IPConnectionSettings -from fastcs.controller import BaseController, Controller, SubController +from fastcs.controller import BaseController, Controller from fastcs.datatypes import Enum, Float, Int, String from fastcs.launch import FastCS from fastcs.transport.epics.ca.options import EpicsCAOptions @@ -53,7 +53,7 @@ class OnOffEnum(enum.StrEnum): On = "1" -class TemperatureRampController(SubController): +class TemperatureRampController(Controller): start = AttrRW(Int(), handler=TemperatureControllerHandler("S")) end = AttrRW(Int(), handler=TemperatureControllerHandler("E")) enabled = AttrRW(Enum(OnOffEnum), handler=TemperatureControllerHandler("N")) diff --git a/pyproject.toml b/pyproject.toml index 53cbec9f8..cb2d5a40f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ requires-python = ">=3.11" demo = ["tickit~=0.4.3"] epicsca = ["pvi~=0.11.0", "softioc>=4.5.0"] epicspva = ["p4p", "pvi~=0.11.0"] -epics = ["fastcs[epicsca]", "fastcs[epicspca]"] +epics = ["fastcs[epicsca]", "fastcs[epicspva]"] tango = ["pytango"] graphql = ["strawberry-graphql", "uvicorn[standard]>=0.12.0"] rest = ["fastapi[standard]", "numpy", "uvicorn[standard]>=0.12.0"] diff --git a/src/fastcs/controller.py b/src/fastcs/controller.py index c01380003..d74b3c1d8 100755 --- a/src/fastcs/controller.py +++ b/src/fastcs/controller.py @@ -26,7 +26,7 @@ def __init__( if not hasattr(self, "attributes"): self.attributes = {} self._path: list[str] = path or [] - self.__sub_controller_tree: dict[str, SubController] = {} + self.__sub_controller_tree: dict[str, Controller] = {} self._bind_attrs() @@ -51,7 +51,7 @@ def path(self) -> list[str]: def set_path(self, path: list[str]): if self._path: - raise ValueError(f"SubController is already registered under {self.path}") + raise ValueError(f"sub controller is already registered under {self.path}") self._path = path @@ -98,10 +98,10 @@ class method and a controller instance, so that it can be called from any elif isinstance(attr, UnboundPut | UnboundScan | UnboundCommand): setattr(self, attr_name, attr.bind(self)) - def register_sub_controller(self, name: str, sub_controller: SubController): + def register_sub_controller(self, name: str, sub_controller: Controller): if name in self.__sub_controller_tree.keys(): raise ValueError( - f"Controller {self} already has a SubController registered as {name}" + f"Controller {self} already has a sub controller registered as {name}" ) self.__sub_controller_tree[name] = sub_controller @@ -110,13 +110,13 @@ def register_sub_controller(self, name: str, sub_controller: SubController): if isinstance(sub_controller.root_attribute, Attribute): if name in self.attributes: raise TypeError( - f"Cannot set SubController `{name}` root attribute " + f"Cannot set sub controller `{name}` root attribute " f"on the parent controller `{type(self).__name__}` " f"as it already has an attribute of that name." ) self.attributes[name] = sub_controller.root_attribute - def get_sub_controllers(self) -> dict[str, SubController]: + def get_sub_controllers(self) -> dict[str, Controller]: return self.__sub_controller_tree @@ -129,21 +129,10 @@ class Controller(BaseController): generating a UI or creating parameters for a control system. """ + root_attribute: Attribute | None = None + def __init__(self, description: str | None = None) -> None: super().__init__(description=description) async def connect(self) -> None: pass - - -class SubController(BaseController): - """A subordinate to a ``Controller`` for managing a subset of a device. - - An instance of this class can be registered with a parent ``Controller`` to include - it as part of a larger device. - """ - - root_attribute: Attribute | None = None - - def __init__(self, description: str | None = None) -> None: - super().__init__(description=description) diff --git a/src/fastcs/controller_api.py b/src/fastcs/controller_api.py index ac5d1af31..c5724000b 100644 --- a/src/fastcs/controller_api.py +++ b/src/fastcs/controller_api.py @@ -7,7 +7,7 @@ @dataclass class ControllerAPI: - """Attributes, bound methods and sub APIs of a `Controller` / `SubController`""" + """Attributes, bound methods and sub APIs of a `Controller`""" path: list[str] = field(default_factory=list) """Path within controller tree (empty if this is the root)""" diff --git a/src/fastcs/demo/controllers.py b/src/fastcs/demo/controllers.py index 8b2c761a9..953f78980 100755 --- a/src/fastcs/demo/controllers.py +++ b/src/fastcs/demo/controllers.py @@ -8,7 +8,7 @@ from fastcs.attributes import AttrHandlerRW, AttrR, AttrRW, AttrW from fastcs.connections import IPConnection, IPConnectionSettings -from fastcs.controller import BaseController, Controller, SubController +from fastcs.controller import BaseController, Controller from fastcs.datatypes import Enum, Float, Int from fastcs.wrappers import command, scan @@ -94,7 +94,7 @@ async def update_voltages(self): await controller.voltage.set(float(voltages[index])) -class TemperatureRampController(SubController): +class TemperatureRampController(Controller): start = AttrRW(Int(), handler=TemperatureControllerHandler("S")) end = AttrRW(Int(), handler=TemperatureControllerHandler("E")) enabled = AttrRW(Enum(OnOffEnum), handler=TemperatureControllerHandler("N")) diff --git a/tests/assertable_controller.py b/tests/assertable_controller.py index 5f9aa55b4..586fa5823 100644 --- a/tests/assertable_controller.py +++ b/tests/assertable_controller.py @@ -6,7 +6,7 @@ from fastcs.attributes import AttrHandlerR, AttrHandlerRW, AttrHandlerW, AttrR from fastcs.backend import build_controller_api -from fastcs.controller import Controller, SubController +from fastcs.controller import Controller from fastcs.controller_api import ControllerAPI from fastcs.datatypes import Int from fastcs.wrappers import command, scan @@ -34,7 +34,7 @@ class TestHandler(AttrHandlerRW, TestUpdater, TestSetter): pass -class TestSubController(SubController): +class TestSubController(Controller): read_int: AttrR = AttrR(Int(), handler=TestUpdater()) @@ -110,7 +110,7 @@ def _assert_method(self, path: list[str], method: Literal["get", "process", ""]) """ queue = copy.deepcopy(path) - # Navigate to subcontroller + # Navigate to sub controller controller_api = self item_name = queue.pop(-1) for item in queue: diff --git a/tests/example_p4p_ioc.py b/tests/example_p4p_ioc.py index 7b75918d7..e4498cc23 100644 --- a/tests/example_p4p_ioc.py +++ b/tests/example_p4p_ioc.py @@ -4,7 +4,7 @@ import numpy as np from fastcs.attributes import AttrHandlerW, AttrR, AttrRW, AttrW -from fastcs.controller import Controller, SubController +from fastcs.controller import Controller from fastcs.datatypes import Bool, Enum, Float, Int, Table, Waveform from fastcs.launch import FastCS from fastcs.transport.epics.options import ( @@ -37,7 +37,7 @@ class ParentController(Controller): ) -class ChildController(SubController): +class ChildController(Controller): fail_on_next_e = True c: AttrW = AttrW(Int(), handler=SimpleAttributeSetter()) diff --git a/tests/example_softioc.py b/tests/example_softioc.py index 65c33e7bb..85e8ca9f8 100644 --- a/tests/example_softioc.py +++ b/tests/example_softioc.py @@ -1,5 +1,5 @@ from fastcs.attributes import AttrR, AttrRW, AttrW -from fastcs.controller import Controller, SubController +from fastcs.controller import Controller from fastcs.datatypes import Int from fastcs.launch import FastCS from fastcs.transport.epics.ca.transport import EpicsCATransport @@ -12,7 +12,7 @@ class ParentController(Controller): b: AttrRW = AttrRW(Int()) -class ChildController(SubController): +class ChildController(Controller): c: AttrW = AttrW(Int()) @command() diff --git a/tests/test_controller.py b/tests/test_controller.py index b0e87fd07..d77bd1bc2 100644 --- a/tests/test_controller.py +++ b/tests/test_controller.py @@ -1,14 +1,14 @@ import pytest from fastcs.attributes import AttrR -from fastcs.controller import Controller, SubController +from fastcs.controller import Controller from fastcs.datatypes import Int def test_controller_nesting(): controller = Controller() - sub_controller = SubController() - sub_sub_controller = SubController() + sub_controller = Controller() + sub_sub_controller = Controller() controller.register_sub_controller("a", sub_controller) sub_controller.register_sub_controller("b", sub_sub_controller) @@ -19,17 +19,17 @@ def test_controller_nesting(): assert sub_controller.get_sub_controllers() == {"b": sub_sub_controller} with pytest.raises( - ValueError, match=r"Controller .* already has a SubController registered as .*" + ValueError, match=r"Controller .* already has a sub controller registered as .*" ): - controller.register_sub_controller("a", SubController()) + controller.register_sub_controller("a", Controller()) with pytest.raises( - ValueError, match=r"SubController is already registered under .*" + ValueError, match=r"sub controller is already registered under .*" ): controller.register_sub_controller("c", sub_controller) -class SomeSubController(SubController): +class SomeSubController(Controller): def __init__(self): super().__init__() @@ -44,7 +44,7 @@ class SomeController(Controller): equal_attr = AttrR(Int()) annotated_and_equal_attr: AttrR[int] = AttrR(Int()) - def __init__(self, sub_controller: SubController): + def __init__(self, sub_controller: Controller): self.attributes = {} self.annotated_attr = AttrR(Int()) @@ -106,7 +106,7 @@ class FailingController(SomeController): with pytest.raises( TypeError, match=( - "Cannot set SubController `sub_controller` root attribute " + "Cannot set sub controller `sub_controller` root attribute " "on the parent controller `FailingController` as it already " "has an attribute of that name." ), diff --git a/tests/transport/epics/pva/test_p4p.py b/tests/transport/epics/pva/test_p4p.py index 7670c871f..5d470a7d8 100644 --- a/tests/transport/epics/pva/test_p4p.py +++ b/tests/transport/epics/pva/test_p4p.py @@ -14,7 +14,7 @@ from p4p.nt import NTTable from fastcs.attributes import AttrR, AttrRW, AttrW -from fastcs.controller import Controller, SubController +from fastcs.controller import Controller from fastcs.datatypes import Bool, Enum, Float, Int, String, Table, Waveform from fastcs.launch import FastCS from fastcs.transport.epics.options import EpicsIOCOptions @@ -272,11 +272,11 @@ async def _wait_and_set_attr_r(): def test_pvi_grouping(): - class ChildChildController(SubController): + class ChildChildController(Controller): attr_e: AttrRW = AttrRW(Int()) attr_f: AttrR = AttrR(String()) - class ChildController(SubController): + class ChildController(Controller): attr_c: AttrW = AttrW(Bool(), description="Some bool") attr_d: AttrW = AttrW(String())