Skip to content

Commit b7e0c8d

Browse files
committed
WIP
1 parent 6000568 commit b7e0c8d

File tree

11 files changed

+313
-139
lines changed

11 files changed

+313
-139
lines changed

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,6 @@ lint.select = [
119119
# See https://github.com/DiamondLightSource/python-copier-template/issues/154
120120
# Remove this line to forbid private member access in tests
121121
"tests/**/*" = ["SLF001"]
122+
# Ruff wants us to use `(|)` instead of `Union[,]` in types, but pyright warns against
123+
# it. For now we'll use `Union` and turn the ruff error off.
124+
"**" = ["UP007"]

src/fastcs_pandablocks/__init__.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from fastcs.backends.epics.backend import EpicsBackend
66
from fastcs.backends.epics.gui import EpicsGUIFormat
7-
from fastcs.backends.epics.ioc import EpicsIOCOptions, PvNamingConvention
7+
from fastcs.backends.epics.ioc import EpicsIOCOptions
8+
from fastcs.backends.epics.util import EpicsNameOptions, PvNamingConvention
89

910
from ._version import __version__
1011
from .gui import PandaGUIOptions
@@ -15,17 +16,23 @@
1516

1617

1718
def ioc(
18-
prefix: EpicsName,
19+
epics_prefix: EpicsName,
1920
hostname: str,
2021
screens_directory: Path | None = None,
21-
poll_period: float = DEFAULT_POLL_PERIOD,
2222
clear_bobfiles: bool = False,
23+
poll_period: float = DEFAULT_POLL_PERIOD,
24+
naming_convention: PvNamingConvention = PvNamingConvention.CAPITALIZED,
25+
pv_separator: str = ":",
2326
):
27+
name_options = EpicsNameOptions(
28+
pv_naming_convention=naming_convention, pv_separator=pv_separator
29+
)
30+
epics_ioc_options = EpicsIOCOptions(terminal=True, name_options=name_options)
31+
2432
controller = PandaController(hostname, poll_period)
25-
epics_ioc_options = EpicsIOCOptions(
26-
terminal=True, pv_naming_convention=PvNamingConvention.CAPITALIZED
33+
backend = EpicsBackend(
34+
controller, pv_prefix=str(epics_prefix), ioc_options=epics_ioc_options
2735
)
28-
backend = EpicsBackend(controller, pv_prefix=str(prefix), options=epics_ioc_options)
2936

3037
if clear_bobfiles and not screens_directory:
3138
raise ValueError("`clear_bobfiles` is True with no `screens_directory`")

src/fastcs_pandablocks/__main__.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import logging
55
from pathlib import Path
66

7+
from fastcs.backends.epics.ioc import PvNamingConvention
8+
79
from fastcs_pandablocks import DEFAULT_POLL_PERIOD, ioc
810
from fastcs_pandablocks.types import EpicsName
911

@@ -57,7 +59,19 @@ def main():
5759
"--poll-period",
5860
default=DEFAULT_POLL_PERIOD,
5961
type=float,
60-
help="Period to poll",
62+
help="Period in seconds with which to poll the panda.",
63+
)
64+
run_parser.add_argument(
65+
"--pv-naming-convention",
66+
default=PvNamingConvention.CAPITALIZED.name,
67+
choices=[choice.name for choice in PvNamingConvention],
68+
help="Naming convention of the EPICS PVs.",
69+
)
70+
run_parser.add_argument(
71+
"--pv-separator",
72+
default=":",
73+
type=str,
74+
help="Separator to use between EPICS PV sections.",
6175
)
6276

6377
parsed_args = parser.parse_args()
@@ -72,8 +86,10 @@ def main():
7286
EpicsName(prefix=parsed_args.prefix),
7387
parsed_args.hostname,
7488
screens_directory=Path(parsed_args.screens_dir),
75-
poll_period=parsed_args.poll_period,
7689
clear_bobfiles=parsed_args.clear_bobfiles,
90+
poll_period=parsed_args.poll_period,
91+
naming_convention=PvNamingConvention(parsed_args.pv_naming_convention),
92+
pv_separator=parsed_args.pv_separator,
7793
)
7894

7995

src/fastcs_pandablocks/handler.py

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/fastcs_pandablocks/handlers.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import Any
2+
3+
from fastcs.attributes import AttrW, Handler, Sender
4+
5+
from fastcs_pandablocks.types import AttrType, PandaName
6+
7+
8+
class DefaultFieldSender(Sender):
9+
def __init__(self, panda_name: PandaName):
10+
self.panda_name = panda_name
11+
12+
async def put(self, controller: Any, attr: AttrW, value: str) -> None:
13+
await controller.put_value_to_panda(self.panda_name, value)
14+
15+
16+
class UpdateEguSender(Sender):
17+
def __init__(self, attr_to_update: AttrType):
18+
"""Update the attr"""
19+
self.attr_to_update = attr_to_update
20+
21+
async def put(self, controller: Any, attr: AttrW, value: str) -> None:
22+
# TODO find out how to update attr_to_update's EGU with the value
23+
...

src/fastcs_pandablocks/panda/blocks.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@ def __init__(
3434
field_info, # type: ignore
3535
)
3636
self.fields[field_raw_name] = field
37-
if field.block_attribute:
38-
setattr(self, *field.block_attribute)
37+
38+
def initialise(self):
39+
for field_name, field in self.fields.items():
40+
if field.named_attribute:
41+
setattr(self, *field.named_attribute)
3942
if field.sub_field_controller:
4043
self.register_sub_controller(
41-
field_panda_name.attribute_name, field.sub_field_controller
44+
field_name, sub_controller=field.sub_field_controller
4245
)
4346

4447

@@ -106,8 +109,8 @@ def __getitem__(
106109
return block
107110
field = block.fields[name.field]
108111
if not name.sub_field:
109-
assert field.block_attribute
110-
return field.block_attribute.attribute
112+
assert field.named_attribute
113+
return field.named_attribute.attribute
111114

112115
sub_field = getattr(field.sub_field_controller, name.sub_field)
113116
return sub_field

src/fastcs_pandablocks/panda/controller.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,15 @@ async def connect(self) -> None:
2828
self._blocks.parse_introspected_data(
2929
self._raw_panda.blocks, self._raw_panda.fields
3030
)
31-
for attr_name, controller in self._blocks.flattened_attribute_tree():
32-
self.register_sub_controller(attr_name, controller)
33-
3431
self.is_connected = True
3532

3633
async def initialise(self) -> None:
37-
"""
38-
We connect in initialise since FastCS doesn't connect until
39-
it's already parsed sub controllers.
40-
"""
4134
await self.connect()
4235

36+
for attr_name, controller in self._blocks.flattened_attribute_tree():
37+
self.register_sub_controller(attr_name, controller)
38+
controller.initialise()
39+
4340
# TODO https://github.com/DiamondLightSource/FastCS/issues/62
4441
@scan(0.1)
4542
async def update(self):

0 commit comments

Comments
 (0)