Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/snippets/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}")

Expand Down
4 changes: 2 additions & 2 deletions docs/snippets/static10.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"))

Expand Down
4 changes: 2 additions & 2 deletions docs/snippets/static11.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"))
Expand Down
4 changes: 2 additions & 2 deletions docs/snippets/static12.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"))
Expand Down
4 changes: 2 additions & 2 deletions docs/snippets/static13.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"))
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
27 changes: 8 additions & 19 deletions src/fastcs/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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


Expand All @@ -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)
2 changes: 1 addition & 1 deletion src/fastcs/controller_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)"""
Expand Down
4 changes: 2 additions & 2 deletions src/fastcs/demo/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"))
Expand Down
6 changes: 3 additions & 3 deletions tests/assertable_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -34,7 +34,7 @@ class TestHandler(AttrHandlerRW, TestUpdater, TestSetter):
pass


class TestSubController(SubController):
class TestSubController(Controller):
read_int: AttrR = AttrR(Int(), handler=TestUpdater())


Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions tests/example_p4p_ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -37,7 +37,7 @@ class ParentController(Controller):
)


class ChildController(SubController):
class ChildController(Controller):
fail_on_next_e = True
c: AttrW = AttrW(Int(), handler=SimpleAttributeSetter())

Expand Down
4 changes: 2 additions & 2 deletions tests/example_softioc.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,7 +12,7 @@ class ParentController(Controller):
b: AttrRW = AttrRW(Int())


class ChildController(SubController):
class ChildController(Controller):
c: AttrW = AttrW(Int())

@command()
Expand Down
18 changes: 9 additions & 9 deletions tests/test_controller.py
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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__()

Expand All @@ -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())
Expand Down Expand Up @@ -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."
),
Expand Down
6 changes: 3 additions & 3 deletions tests/transport/epics/pva/test_p4p.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())

Expand Down
Loading