Skip to content

Commit

Permalink
Merge pull request #88 from evalott100/adjust_to_use_new_pvi_0.7.1
Browse files Browse the repository at this point in the history
Adjusted to use the new pydantic pvi
  • Loading branch information
evalott100 authored Jan 22, 2024
2 parents f9efa39 + 506460a commit d949bd6
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 63 deletions.
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.5.3",
"pvi>=0.6",
"pvi~=0.7.0",
] # Add project dependencies here, e.g. ["click", "numpy"]
dynamic = ["version"]
license.file = "LICENSE"
Expand Down
105 changes: 73 additions & 32 deletions src/pandablocks_ioc/_pvi.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from softioc import builder
from softioc.pythonSoftIoc import RecordWrapper

from ._types import OUT_RECORD_FUNCTIONS, EpicsName
from ._types import OUT_RECORD_FUNCTIONS, EpicsName, epics_to_pvi_name


class PviGroup(Enum):
Expand Down Expand Up @@ -64,18 +64,20 @@ def add_pvi_info(
writeable: bool = record_creation_func in OUT_RECORD_FUNCTIONS
useComboBox: bool = record_creation_func == builder.mbbOut

pvi_name = epics_to_pvi_name(record_name)

if record_creation_func == builder.Action:
if record_name == "PCAP:ARM":
component = SignalRW(
record_name,
record_name,
widget=ButtonPanel(actions=dict(Arm=1, Disarm=0)),
name=pvi_name,
pv=record_name,
widget=ButtonPanel(actions=dict(Arm="1", Disarm="0")),
read_widget=LED(),
)
access = "rw"

else:
component = SignalX(record_name, record_name, value="")
component = SignalX(name=pvi_name, pv=record_name, value="")
access = "x"
elif writeable:
if useComboBox:
Expand All @@ -86,10 +88,10 @@ def add_pvi_info(
else:
widget = TextWrite(format=None)

component = SignalRW(record_name, record_name, widget)
component = SignalRW(name=pvi_name, pv=record_name, widget=widget)
access = "rw"
else:
component = SignalR(record_name, record_name, TextRead())
component = SignalR(name=pvi_name, pv=record_name, widget=TextRead())
access = "r"
block, field = record_name.split(":", maxsplit=1)
block_name_suffixed = f"pvi.{field.lower().replace(':', '_')}.{access}"
Expand All @@ -108,39 +110,67 @@ def add_pvi_info(
Pvi.add_pvi_info(record_name=record_name, group=group, component=component)


_positions_table_group = Group("POSITIONS_TABLE", Grid(labelled=True), children=[])
_positions_table_group = Group(
name="PositionsTable", layout=Grid(labelled=True), children=[]
)
_positions_table_headers = ["VALUE", "UNITS", "SCALE", "OFFSET", "CAPTURE"]


# TODO: Replicate this for the BITS table
def add_positions_table_row(
record_name: str,
value_record_name: str,
units_record_name: str,
scale_record_name: str,
offset_record_name: str,
capture_record_name: str,
record_name: EpicsName,
value_record_name: EpicsName,
units_record_name: EpicsName,
scale_record_name: EpicsName,
offset_record_name: EpicsName,
capture_record_name: EpicsName,
) -> None:
"""Add a Row to the Positions table"""
# TODO: Use the Components defined in _positions_columns_defs to
# create the children, which will make it more obvious which
# component is for which column
children = [
SignalR(value_record_name, value_record_name, TextWrite()),
SignalRW(units_record_name, units_record_name, TextWrite()),
SignalRW(scale_record_name, scale_record_name, TextWrite()),
SignalRW(offset_record_name, offset_record_name, TextWrite()),
SignalRW(capture_record_name, capture_record_name, TextWrite()),
SignalR(
name=epics_to_pvi_name(value_record_name),
label=value_record_name,
pv=value_record_name,
widget=TextRead(),
),
SignalRW(
name=epics_to_pvi_name(units_record_name),
label=units_record_name,
pv=units_record_name,
widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(scale_record_name),
label=scale_record_name,
pv=scale_record_name,
widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(offset_record_name),
label=offset_record_name,
pv=offset_record_name,
widget=TextWrite(),
),
SignalRW(
name=epics_to_pvi_name(capture_record_name),
label=capture_record_name,
pv=capture_record_name,
widget=TextWrite(),
),
]

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

row_group = Group(
record_name,
row,
children,
name=epics_to_pvi_name(record_name),
label=record_name,
layout=row,
children=children,
)

_positions_table_group.children.append(row_group)
Expand All @@ -156,9 +186,9 @@ class Pvi:
# to the positions table
_general_device_refs = {
"CAPTURE": DeviceRef(
"AllPostionCaptureParameters",
"CAPTURE",
"PandA_POSITIONS_TABLE",
name="AllPostionCaptureParameters",
pv="CAPTURE",
ui="PandA_PositionsTable",
)
}

Expand Down Expand Up @@ -205,9 +235,11 @@ def create_pvi_records(record_prefix: str):
if PviGroup.NONE in v:
children.extend(v.pop(PviGroup.NONE))
for group, components in v.items():
children.append(Group(group.name, Grid(), components))
children.append(
Group(name=group.name, layout=Grid(), children=components)
)

device = Device(block_name, children=children)
device = Device(label=block_name, children=children)
devices.append(device)

# Add PVI structure. Unfortunately we need something in the database
Expand Down Expand Up @@ -238,16 +270,25 @@ def create_pvi_records(record_prefix: str):
# TODO: Properly add this to list of screens, add a PV, maybe roll into
# the "PLACEHOLDER" Device?
# Add Tables to a new top level screen
top_device = Device("PandA", children=[_positions_table_group])
top_device = Device(label="PandA", children=[_positions_table_group])
devices.append(top_device)

# Create top level Device, with references to all child Devices
index_device_refs = [
DeviceRef(x, x, x.replace(":PVI", "")) for x in pvi_records
]
index_device_refs = []
for pvi_record in pvi_records:
record_with_no_suffix = EpicsName(pvi_record.replace(":PVI", ""))
name = epics_to_pvi_name(record_with_no_suffix)
index_device_refs.append(
DeviceRef(
name=name,
label=record_with_no_suffix,
pv=pvi_record,
ui=record_with_no_suffix,
)
)

# # TODO: What should the label be?
device = Device("index", children=index_device_refs)
device = Device(label="index", children=index_device_refs)
devices.append(device)

# TODO: label widths need some tweaking - some are pretty long right now
Expand Down
10 changes: 7 additions & 3 deletions src/pandablocks_ioc/_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
RecordInfo,
RecordValue,
epics_to_panda_name,
epics_to_pvi_name,
trim_description,
)

Expand Down Expand Up @@ -56,7 +57,7 @@ class TableFieldRecordContainer:


def make_bit_order(
table_field_records: Dict[str, TableFieldRecordContainer]
table_field_records: Dict[str, TableFieldRecordContainer],
) -> Dict[str, TableFieldRecordContainer]:
return dict(
sorted(table_field_records.items(), key=lambda item: item[1].field.bit_low)
Expand Down Expand Up @@ -144,12 +145,14 @@ def __init__(
)
self.all_values_dict = all_values_dict

pvi_table_name = epics_to_pvi_name(table_name)

# The PVI group to put all records into
pvi_group = PviGroup.PARAMETERS
Pvi.add_pvi_info(
table_name,
pvi_group,
SignalRW(table_name, table_name, TableWrite([])),
SignalRW(name=pvi_table_name, pv=table_name, widget=TableWrite(widgets=[])),
)

# Note that the table_updater's table_fields are guaranteed sorted in bit order,
Expand Down Expand Up @@ -216,10 +219,11 @@ def __init__(
initial_value=TableModeEnum.VIEW.value,
on_update=self.update_mode,
)
pvi_name = epics_to_pvi_name(mode_record_name)
Pvi.add_pvi_info(
mode_record_name,
pvi_group,
SignalRW(mode_record_name, mode_record_name, ComboBox()),
SignalRW(name=pvi_name, pv=mode_record_name, widget=ComboBox()),
)

self.mode_record_info = RecordInfo(lambda x: x, labels, False)
Expand Down
17 changes: 17 additions & 0 deletions src/pandablocks_ioc/_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Various new or derived types/classes and helper functions for the IOC module
import logging
import re
from dataclasses import dataclass, field
from typing import Any, Awaitable, Callable, List, NewType, Optional, Union

Expand All @@ -20,6 +21,8 @@ class InErrorException(Exception):
EpicsName = NewType("EpicsName", str)
# PandA format, i.e. "." dividers
PandAName = NewType("PandAName", str)
# No dividers and PascalCase
PviName = NewType("PviName", str)


def panda_to_epics_name(field_name: PandAName) -> EpicsName:
Expand All @@ -34,6 +37,20 @@ def epics_to_panda_name(field_name: EpicsName) -> PandAName:
return PandAName(field_name.replace(":", "."))


def epics_to_pvi_name(field_name: EpicsName) -> PviName:
"""Converts EPICS naming convention to PVI naming convention.
For example PANDA:PCAP:TRIG_EDGE -> TrigEdge."""
relevant_section = field_name.split(":")[-1]
words = relevant_section.replace("-", "_").split("_")
capitalised_word = "".join(word.capitalize() for word in words)

# We don't want to allow any non-alphanumeric characters.
formatted_word = re.search(r"[A-Za-z0-9]+", capitalised_word)
assert formatted_word

return PviName(formatted_word.group())


def device_and_record_to_panda_name(field_name: EpicsName) -> PandAName:
"""Convert an EPICS naming convention (including Device prefix) to PandA
convention."""
Expand Down
14 changes: 7 additions & 7 deletions tests/test-bobfiles/HDF5.bob
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<transparent>true</transparent>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: File Path</text>
<text>Filepath</text>
<x>0</x>
<y>0</y>
<width>250</width>
Expand All @@ -52,7 +52,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: File Name</text>
<text>Filename</text>
<x>0</x>
<y>25</y>
<width>250</width>
Expand All @@ -70,7 +70,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: Num Capture</text>
<text>Numcapture</text>
<x>0</x>
<y>50</y>
<width>250</width>
Expand All @@ -87,7 +87,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: Flush Period</text>
<text>Flushperiod</text>
<x>0</x>
<y>75</y>
<width>250</width>
Expand All @@ -104,7 +104,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: Capture</text>
<text>Capture</text>
<x>0</x>
<y>100</y>
<width>250</width>
Expand All @@ -129,7 +129,7 @@
<transparent>true</transparent>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: Status</text>
<text>Status</text>
<x>0</x>
<y>0</y>
<width>250</width>
Expand All @@ -150,7 +150,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>HDF5: Capturing</text>
<text>Capturing</text>
<x>0</x>
<y>25</y>
<width>250</width>
Expand Down
12 changes: 6 additions & 6 deletions tests/test-bobfiles/PCAP.bob
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<transparent>true</transparent>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>PCAP: LABEL</text>
<text>Label</text>
<x>0</x>
<y>0</y>
<width>250</width>
Expand All @@ -52,7 +52,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>PCAP: ARM</text>
<text>Arm</text>
<x>0</x>
<y>25</y>
<width>250</width>
Expand Down Expand Up @@ -94,15 +94,15 @@
</widget>
<widget type="led" version="2.0.0">
<name>LED</name>
<pv_name>TEST_PREFIX:</pv_name>
<pv_name>TEST_PREFIX:PCAP:ARM</pv_name>
<x>350</x>
<y>25</y>
<width>20</width>
<height>20</height>
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>PCAP: GATE</text>
<text>Gate</text>
<x>0</x>
<y>50</y>
<width>250</width>
Expand All @@ -120,7 +120,7 @@
</widget>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>PCAP: GATE: DELAY</text>
<text>Delay</text>
<x>0</x>
<y>75</y>
<width>250</width>
Expand All @@ -145,7 +145,7 @@
<transparent>true</transparent>
<widget type="label" version="2.0.0">
<name>Label</name>
<text>PCAP: TRIG_ EDGE</text>
<text>Trig Edge</text>
<x>0</x>
<y>0</y>
<width>250</width>
Expand Down
Loading

0 comments on commit d949bd6

Please sign in to comment.