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

Updated PandABlocks to interface with PVI 0.10.0 #132

Merged
merged 22 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies = [
"h5py",
"softioc>=4.4.0",
"pandablocks~=0.10.0",
"pvi~=0.7.0",
"pvi~=0.10.0",
"typing-extensions;python_version<'3.8'",
] # Add project dependencies here, e.g. ["click", "numpy"]
dynamic = ["version"]
Expand Down
2 changes: 1 addition & 1 deletion src/pandablocks_ioc/_hdf_ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def __init__(
["Name", "Type"], [[], []], length=300, default_data_type=str
)

def hdf_writer_names(self):
def hdf_writer_names(self) -> Dict[str, Dict[str, str]]:
"""Formats the current dataset names for use in the HDFWriter"""

hdf_names: Dict[str, Dict[str, str]] = {}
Expand Down
108 changes: 66 additions & 42 deletions src/pandablocks_ioc/_pvi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from enum import Enum
from os import remove
from pathlib import Path
from typing import Callable, Dict, List, Optional
from typing import Callable, Dict, List, Optional, Union

from epicsdbbuilder import RecordName
from pvi._format.dls import DLSFormatter
Expand All @@ -11,6 +11,7 @@
ButtonPanel,
ComboBox,
Component,
ComponentUnion,
Device,
DeviceRef,
Grid,
Expand All @@ -22,7 +23,6 @@
TextFormat,
TextRead,
TextWrite,
Tree,
)
from softioc import builder
from softioc.pythonSoftIoc import RecordWrapper
Expand Down Expand Up @@ -82,8 +82,9 @@
):
component = SignalRW(
name=epics_to_pvi_name(data_capture_record_name),
pv=data_capture_record_name,
widget=ButtonPanel(actions={"Start": "1", "Stop": "0"}),
read_pv=f"{Pvi.record_prefix}:{data_capture_record_name}",
write_pv=f"{Pvi.record_prefix}:{data_capture_record_name}",
write_widget=ButtonPanel(actions={"Start": "1", "Stop": "0"}),
read_widget=LED(),
)
add_pvi_info_to_record(data_capture_pvi_record, data_capture_record_name, "rw")
Expand All @@ -96,8 +97,9 @@
pcap_arm_record_name = EpicsName("PCAP:ARM")
component = SignalRW(
name=epics_to_pvi_name(pcap_arm_record_name),
pv=pcap_arm_record_name,
widget=ButtonPanel(actions={"Arm": "1", "Disarm": "0"}),
read_pv=f"{Pvi.record_prefix}:{pcap_arm_record_name}",
write_pv=f"{Pvi.record_prefix}:{pcap_arm_record_name}",
write_widget=ButtonPanel(actions={"Arm": "1", "Disarm": "0"}),
read_widget=LED(),
)
add_pvi_info_to_record(pcap_arm_pvi_record, pcap_arm_record_name, "rw")
Expand All @@ -112,7 +114,7 @@
) -> None:
"""Create the most common forms of the `PviInfo` structure.
Generates generic components from"""
component: Component
component: ComponentUnion
writeable: bool = record_creation_func in OUT_RECORD_FUNCTIONS
useComboBox: bool = record_creation_func == builder.mbbOut

Expand All @@ -122,39 +124,50 @@
if record_name == "PCAP:ARM":
component = SignalRW(
name=pvi_name,
pv=record_name,
widget=ButtonPanel(actions={"Arm": "1", "Disarm": "0"}),
write_pv=f"{Pvi.record_prefix}:{record_name}",
write_widget=ButtonPanel(actions={"Arm": "1", "Disarm": "0"}),
read_widget=LED(),
)
access = "rw"

else:
component = SignalX(name=pvi_name, pv=record_name, value="")
component = SignalX(
name=pvi_name, write_pv=f"{Pvi.record_prefix}:{record_name}", value=""
)
access = "x"
elif writeable:
text_read_widget: Union[ComboBox, TextWrite]
if useComboBox:
widget = ComboBox()
text_read_widget = ComboBox()
else:
if record_creation_func in (
builder.longStringOut,
builder.stringOut,
):
widget = TextWrite(format=TextFormat.string)
text_read_widget = TextWrite(format=TextFormat.string)
else:
widget = TextWrite(format=None)

component = SignalRW(name=pvi_name, pv=record_name, widget=widget)
text_read_widget = TextWrite(format=None)
component = SignalRW(
name=pvi_name,
write_pv=f"{Pvi.record_prefix}:{record_name}",
write_widget=text_read_widget,
)
access = "rw"
else:
readable_widget: TextRead
if record_creation_func in (
builder.longStringIn,
builder.stringIn,
):
widget = TextRead(format=TextFormat.string)
readable_widget = TextRead(format=TextFormat.string)
else:
widget = TextRead(format=None)
readable_widget = TextRead(format=None)

component = SignalR(name=pvi_name, pv=record_name, widget=widget)
component = SignalR(
name=pvi_name,
read_pv=f"{Pvi.record_prefix}:{record_name}",
read_widget=readable_widget,
)
access = "r"

add_pvi_info_to_record(record, record_name, access)
Expand Down Expand Up @@ -185,60 +198,62 @@
SignalR(
name=epics_to_pvi_name(value_record_name),
label=value_record_name,
pv=value_record_name,
widget=TextRead(),
read_pv=f"{Pvi.record_prefix}:{value_record_name}",
read_widget=TextRead(),
),
SignalRW(
name=epics_to_pvi_name(units_record_name),
label=units_record_name,
pv=units_record_name,
widget=TextWrite(),
write_pv=f"{Pvi.record_prefix}:{value_record_name}",
write_widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(scale_record_name),
label=scale_record_name,
pv=scale_record_name,
widget=TextWrite(),
write_pv=f"{Pvi.record_prefix}:{scale_record_name}",
write_widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(offset_record_name),
label=offset_record_name,
pv=offset_record_name,
widget=TextWrite(),
write_pv=f"{Pvi.record_prefix}:{offset_record_name}",
write_widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(dataset_record_name),
label=dataset_record_name,
pv=dataset_record_name,
widget=TextWrite(),
write_pv=f"{Pvi.record_prefix}:{dataset_record_name}",
write_widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(capture_record_name),
label=capture_record_name,
pv=capture_record_name,
widget=ComboBox(),
write_pv=f"{Pvi.record_prefix}:{capture_record_name}",
write_widget=ComboBox(),
),
]

row = Row()
if len(_positions_table_group.children) == 0:
row.header = _positions_table_headers

row = (
Row(header=None)
if _positions_table_group.children
else Row(header=_positions_table_headers)
)
row_group = Group(
name=epics_to_pvi_name(record_name),
label=record_name,
layout=row,
children=children,
)

_positions_table_group.children.append(row_group)
_positions_table_group.children.append(row_group) # type: ignore


class Pvi:
"""TODO: Docs"""

_screens_dir: Optional[Path] = None
_clear_bobfiles: bool = False
record_prefix: Optional[str] = None

# We may want general device refs, e.g every CAPTURE group having a reference
# to the positions table
Expand All @@ -250,7 +265,8 @@
)
}

pvi_info_dict: Dict[str, Dict[PviGroup, List[Component]]] = {}
# pvi_info_dict: Dict[str, Dict[PviGroup, List[Component]]] = {}
DiamondRC marked this conversation as resolved.
Show resolved Hide resolved
pvi_info_dict: Dict[str, Dict[PviGroup, List[ComponentUnion]]] = {}
DiamondRC marked this conversation as resolved.
Show resolved Hide resolved

@staticmethod
def configure_pvi(screens_dir: Optional[str], clear_bobfiles: bool):
Expand All @@ -261,7 +277,9 @@
Pvi._clear_bobfiles = clear_bobfiles

@staticmethod
def add_pvi_info(record_name: EpicsName, group: PviGroup, component: Component):
def add_pvi_info(
record_name: EpicsName, group: PviGroup, component: ComponentUnion
):
"""Add PVI Info to the global collection"""

record_base, _ = record_name.split(":", 1)
Expand All @@ -276,9 +294,15 @@

@staticmethod
def add_general_device_refs_to_groups(device: Device):
for group in device.children:
if group.name in Pvi._general_device_refs:
group.children.append(Pvi._general_device_refs[group.name])
for device_child in device.children:
if device_child.name in Pvi._general_device_refs:
if not isinstance(device_child, Group):
raise RuntimeError(

Check warning on line 300 in src/pandablocks_ioc/_pvi.py

View check run for this annotation

Codecov / codecov/patch

src/pandablocks_ioc/_pvi.py#L300

Added line #L300 was not covered by tests
"Tried to add a .... to a " f"widget group {device_child} ... "
DiamondRC marked this conversation as resolved.
Show resolved Hide resolved
)
device_child.children = list(device_child.children) + [
Pvi._general_device_refs[device_child.name]
]

@staticmethod
def create_pvi_records(record_prefix: str):
Expand All @@ -287,7 +311,7 @@
devices: List[Device] = []
pvi_records: List[str] = []
for block_name, v in Pvi.pvi_info_dict.items():
children: Tree = []
children: List[ComponentUnion] = []

# Item in the NONE group should be rendered outside of any Group box
if PviGroup.NONE in v:
Expand Down Expand Up @@ -375,4 +399,4 @@

Pvi.add_general_device_refs_to_groups(device)

formatter.format(device, record_prefix + ":", bobfile_path)
formatter.format(device, bobfile_path)
DiamondRC marked this conversation as resolved.
Show resolved Hide resolved
12 changes: 10 additions & 2 deletions src/pandablocks_ioc/_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,11 @@ def __init__(
Pvi.add_pvi_info(
table_name,
pvi_group,
SignalRW(name=pvi_table_name, pv=table_name, widget=TableWrite(widgets=[])),
SignalRW(
name=pvi_table_name,
write_pv=f"{Pvi.record_prefix}:{table_name}",
write_widget=TableWrite(widgets=[]),
),
)

# Note that the table_updater's table_fields are guaranteed sorted in bit order,
Expand Down Expand Up @@ -308,7 +312,11 @@ def __init__(
Pvi.add_pvi_info(
mode_record_name,
pvi_group,
SignalRW(name=pvi_name, pv=mode_record_name, widget=ComboBox()),
SignalRW(
name=pvi_name,
write_pv=f"{Pvi.record_prefix}:{mode_record_name}",
write_widget=ComboBox(),
),
)

self.mode_record_info = RecordInfo(lambda x: x, labels, False)
Expand Down
1 change: 1 addition & 0 deletions src/pandablocks_ioc/ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ def __init__(

# Set the record prefix
builder.SetDeviceName(self._record_prefix)
Pvi.record_prefix = self._record_prefix

# All records should be blocking
builder.SetBlocking(True)
Expand Down
Loading
Loading