From a795e2e3098cfdabedbda5f99d413d66cb2dc675 Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Thu, 19 Oct 2023 09:43:47 +0100 Subject: [PATCH] Made the following changes: Added :VAL field to positions table, added button on counters to go to positions table; Altered code to work with recent pvi changes; Added a label field for the Capture table Updating pvi version in pyproject.toml Changed test bobfiles to work with pvi changes --- pyproject.toml | 2 +- src/pandablocks_ioc/_pvi.py | 52 +++++++++----- src/pandablocks_ioc/ioc.py | 17 +++-- tests/test-bobfiles/HDF5.bob | 2 + tests/test-bobfiles/PCAP.bob | 10 +-- tests/test-bobfiles/PandA.bob | 14 +++- tests/test-bobfiles/TOP.bob | 60 ---------------- tests/test-bobfiles/index.bob | 124 ++++++++++++++++++++++++++++++++++ tests/test_ioc_system.py | 2 +- 9 files changed, 189 insertions(+), 94 deletions(-) delete mode 100644 tests/test-bobfiles/TOP.bob create mode 100644 tests/test-bobfiles/index.bob diff --git a/pyproject.toml b/pyproject.toml index 3d3faf05..e7d43fc8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ "h5py", "softioc>=4.4.0", "pandablocks>=0.5.3", - "pvi==0.5", + "pvi>=0.6", ] # Add project dependencies here, e.g. ["click", "numpy"] dynamic = ["version"] license.file = "LICENSE" diff --git a/src/pandablocks_ioc/_pvi.py b/src/pandablocks_ioc/_pvi.py index 3ebe5282..0d7686cc 100644 --- a/src/pandablocks_ioc/_pvi.py +++ b/src/pandablocks_ioc/_pvi.py @@ -19,6 +19,7 @@ SignalR, SignalRW, SignalX, + TextFormat, TextRead, TextWrite, Tree, @@ -37,6 +38,7 @@ class PviGroup(Enum): PARAMETERS = "Parameters" READBACKS = "Readbacks" OUTPUTS = "Outputs" + CAPTURE = "Capture" TABLE = "Table" # TODO: May not need this anymore @@ -79,7 +81,11 @@ def add_pvi_info( if useComboBox: widget = ComboBox() else: - widget = TextWrite() + if record_creation_func in (builder.longStringOut, builder.stringOut): + widget = TextWrite(format=TextFormat.string) + else: + widget = TextWrite(format=None) + component = SignalRW(record_name, record_name, widget) access = "rw" else: @@ -103,21 +109,13 @@ def add_pvi_info( _positions_table_group = Group("POSITIONS_TABLE", Grid(labelled=True), children=[]) -_positions_columns_defs = [ - # TODO: To exactly copy the PandA Table web GUI, we'll need a new widget - # type that displays a static string in the same space as a PV - # ("NAME", record_name), - ("VALUE", SignalR), - ("UNITS", SignalRW), - ("SCALE", SignalRW), - ("OFFSET", SignalRW), - ("CAPTURE", SignalRW), -] +_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, @@ -128,7 +126,7 @@ def add_positions_table_row( # create the children, which will make it more obvious which # component is for which column children = [ - SignalR(record_name, record_name, TextRead()), + 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()), @@ -137,10 +135,10 @@ def add_positions_table_row( row = Row() if len(_positions_table_group.children) == 0: - row.header = [k[0] for k in _positions_columns_defs] + row.header = _positions_table_headers row_group = Group( - record_name + "_row", + record_name, row, children, ) @@ -153,6 +151,17 @@ class Pvi: _screens_dir: Optional[Path] = None _clear_bobfiles: bool = False + + # We may want general device refs, e.g every CAPTURE group having a reference + # to the positions table + _general_device_refs = { + "CAPTURE": DeviceRef( + "AllPostionCaptureParameters", + "CAPTURE", + "PandA_POSITIONS_TABLE", + ) + } + pvi_info_dict: Dict[str, Dict[PviGroup, List[Component]]] = {} @staticmethod @@ -177,6 +186,12 @@ def add_pvi_info(record_name: EpicsName, group: PviGroup, component: Component): else: Pvi.pvi_info_dict[record_base] = {group: [component]} + @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]) + @staticmethod def create_pvi_records(record_prefix: str): """Create the :PVI records, one for each block and one at the top level""" @@ -227,10 +242,12 @@ def create_pvi_records(record_prefix: str): devices.append(top_device) # Create top level Device, with references to all child Devices - device_refs = [DeviceRef(x, x) for x in pvi_records] + index_device_refs = [ + DeviceRef(x, x, x.replace(":PVI", "")) for x in pvi_records + ] # # TODO: What should the label be? - device = Device("TOP", children=device_refs) + device = Device("index", children=index_device_refs) devices.append(device) # TODO: label widths need some tweaking - some are pretty long right now @@ -256,4 +273,7 @@ def create_pvi_records(record_prefix: str): for device in devices: bobfile_path = Pvi._screens_dir / Path(f"{device.label}.bob") + + Pvi.add_general_device_refs_to_groups(device) + formatter.format(device, record_prefix + ":", bobfile_path) diff --git a/src/pandablocks_ioc/ioc.py b/src/pandablocks_ioc/ioc.py index bd22b851..148488f5 100644 --- a/src/pandablocks_ioc/ioc.py +++ b/src/pandablocks_ioc/ioc.py @@ -596,7 +596,6 @@ def _create_record_info( updating the record. """ extra_kwargs: Dict[str, Any] = {} - assert ( record_creation_func in self._builder_methods ), "Unrecognised record creation function passed to _create_record_info" @@ -824,7 +823,6 @@ def _make_pos_out( record_dict: Dict[EpicsName, RecordInfo] = {} units_record_name = EpicsName(record_name + ":UNITS") - record_dict[record_name] = self._create_record_info( record_name, field_info.description, @@ -844,7 +842,7 @@ def _make_pos_out( "Capture options", builder.mbbOut, int, - PviGroup.PARAMETERS, + PviGroup.CAPTURE, labels=labels, initial_value=capture_index, ) @@ -855,7 +853,7 @@ def _make_pos_out( "Offset", builder.aOut, float, - PviGroup.PARAMETERS, + PviGroup.CAPTURE, initial_value=values[offset_record_name], ) @@ -865,7 +863,7 @@ def _make_pos_out( "Scale factor", builder.aOut, float, - PviGroup.PARAMETERS, + PviGroup.CAPTURE, initial_value=values[scale_record_name], ) @@ -874,7 +872,7 @@ def _make_pos_out( "Units string", builder.stringOut, str, - PviGroup.PARAMETERS, + PviGroup.CAPTURE, initial_value=values[units_record_name], ) @@ -899,9 +897,8 @@ def _make_pos_out( DESC="Table of configured positional outputs", ) - scaled_calc_record.add_alias( - self._record_prefix + ":" + positions_record_name + ":VAL" - ) + value_record_name = EpicsName(positions_record_name + ":VAL") + scaled_calc_record.add_alias(self._record_prefix + ":" + value_record_name) record_dict[capture_record_name].record.add_alias( self._record_prefix @@ -935,6 +932,7 @@ def _make_pos_out( self._pos_out_row_counter += 1 add_positions_table_row( record_name, + value_record_name, units_record_name, scale_record_name, offset_record_name, @@ -1809,6 +1807,7 @@ async def create_records( # unrelated fields. e.g. for record_name "INENC1:CLK", # values for keys "INENC1:CLK" "INENC1:CLK:DELAY" should match # but "INENC1:CLK_PERIOD" should not + field_values = { field: value for field, value in values.items() diff --git a/tests/test-bobfiles/HDF5.bob b/tests/test-bobfiles/HDF5.bob index a384b0dc..65860a16 100644 --- a/tests/test-bobfiles/HDF5.bob +++ b/tests/test-bobfiles/HDF5.bob @@ -48,6 +48,7 @@ 60 20 1 + 6 Label @@ -65,6 +66,7 @@ 60 20 1 + 6 Label diff --git a/tests/test-bobfiles/PCAP.bob b/tests/test-bobfiles/PCAP.bob index 4a047ee3..80555971 100644 --- a/tests/test-bobfiles/PCAP.bob +++ b/tests/test-bobfiles/PCAP.bob @@ -48,6 +48,7 @@ 60 20 1 + 6 Label @@ -58,13 +59,13 @@ 20 - ActionButton + WritePV TEST_PREFIX:PCAP:ARM $(pv_name) 1 - WritePV + $(name) Arm @@ -75,13 +76,13 @@ $(actions) - ActionButton + WritePV TEST_PREFIX:PCAP:ARM $(pv_name) 0 - WritePV + $(name) Disarm @@ -115,6 +116,7 @@ 60 20 1 + 6 Label diff --git a/tests/test-bobfiles/PandA.bob b/tests/test-bobfiles/PandA.bob index 09d14f85..4a8da246 100644 --- a/tests/test-bobfiles/PandA.bob +++ b/tests/test-bobfiles/PandA.bob @@ -2,8 +2,8 @@ Display 0 0 - 10 - 35 + 46 + 71 4 4 @@ -12,7 +12,7 @@ PandA - TEST_PREFIX: 0 0 - 10 + 46 25 @@ -25,4 +25,12 @@ true 1 + + POSITIONS_ TABLE + 5 + 30 + 36 + 36 + true + diff --git a/tests/test-bobfiles/TOP.bob b/tests/test-bobfiles/TOP.bob deleted file mode 100644 index 61914707..00000000 --- a/tests/test-bobfiles/TOP.bob +++ /dev/null @@ -1,60 +0,0 @@ - - Display - 0 - 0 - 278 - 130 - 4 - 4 - - Title - TITLE - TOP - TEST_PREFIX: - 0 - 0 - 278 - 25 - - - - - - - - - true - 1 - - - Label - PCAP: PVI - 23 - 30 - 250 - 20 - - - Label - HDF5: PVI - 23 - 55 - 250 - 20 - - - Label - SEQ: PVI - 23 - 80 - 250 - 20 - - - Label - PULSE: PVI - 23 - 105 - 250 - 20 - - diff --git a/tests/test-bobfiles/index.bob b/tests/test-bobfiles/index.bob new file mode 100644 index 00000000..7a6b2418 --- /dev/null +++ b/tests/test-bobfiles/index.bob @@ -0,0 +1,124 @@ + + Display + 0 + 0 + 408 + 130 + 4 + 4 + + Title + TITLE + index - TEST_PREFIX: + 0 + 0 + 408 + 25 + + + + + + + + + true + 1 + + + Label + PCAP: PVI + 23 + 30 + 250 + 20 + + + OpenDisplay + + + PCAP.bob + tab + Open Display + + + PCAP: PVI + 278 + 30 + 125 + 20 + $(actions) + + + Label + HDF5: PVI + 23 + 55 + 250 + 20 + + + OpenDisplay + + + HDF5.bob + tab + Open Display + + + HDF5: PVI + 278 + 55 + 125 + 20 + $(actions) + + + Label + SEQ: PVI + 23 + 80 + 250 + 20 + + + OpenDisplay + + + SEQ.bob + tab + Open Display + + + SEQ: PVI + 278 + 80 + 125 + 20 + $(actions) + + + Label + PULSE: PVI + 23 + 105 + 250 + 20 + + + OpenDisplay + + + PULSE.bob + tab + Open Display + + + PULSE: PVI + 278 + 105 + 125 + 20 + $(actions) + + diff --git a/tests/test_ioc_system.py b/tests/test_ioc_system.py index 0c3fbeef..0634a005 100644 --- a/tests/test_ioc_system.py +++ b/tests/test_ioc_system.py @@ -375,7 +375,7 @@ async def test_create_bobfiles_deletes_existing_files_with_clear_bobfiles( new_random_test_prefix, clear_records, ): - generated_bobfile = Path(tmp_path / "TOP.bob") + generated_bobfile = Path(tmp_path / "index.bob") non_generated_bobfile = Path(tmp_path / "Blahblah.bob") non_bobfile = Path(tmp_path / "Blahblah.txt")