From 82130abbebcfc6604b9209b4bacba86d9248466b Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Fri, 1 Sep 2023 09:26:53 +0100 Subject: [PATCH 1/8] Added necessary PVI information for PCAP:ARM --- src/pandablocks_ioc/_pvi.py | 15 ++++++++-- src/pandablocks_ioc/ioc.py | 15 ++++++---- tests/test-bobfiles/PCAP.bob | 53 +++++++++++++++++++++++++++++------- tests/test_ioc_system.py | 16 +++++++---- 4 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/pandablocks_ioc/_pvi.py b/src/pandablocks_ioc/_pvi.py index 3a3d8cbc..7cb5657b 100644 --- a/src/pandablocks_ioc/_pvi.py +++ b/src/pandablocks_ioc/_pvi.py @@ -7,6 +7,8 @@ from epicsdbbuilder import RecordName from pvi._format.dls import DLSFormatter from pvi.device import ( + LED, + ButtonPanel, ComboBox, Component, Device, @@ -61,9 +63,16 @@ def add_pvi_info( useComboBox: bool = record_creation_func == builder.mbbOut if record_creation_func == builder.Action: - # TODO: What value do I write? PandA uses an empty string - component = SignalX(record_name, record_name, value="") - access = "x" + if record_name == "PCAP:ARM": + component = SignalRW( + record_name, record_name, widget=ButtonPanel(), read_widget=LED() + ) + access = "rw" + + else: + # TODO: What value do I write? PandA uses an empty string + component = SignalX(record_name, record_name, value="") + access = "x" elif writeable: if useComboBox: widget = ComboBox() diff --git a/src/pandablocks_ioc/ioc.py b/src/pandablocks_ioc/ioc.py index 3fe8ab68..ba670067 100644 --- a/src/pandablocks_ioc/ioc.py +++ b/src/pandablocks_ioc/ioc.py @@ -1402,8 +1402,8 @@ def _make_action_write( builder.Action, int, # not bool, as that'll treat string "0" as true PviGroup.OUTPUTS, # TODO: Not sure what group to use - ZNAM=ZNAM_STR, - ONAM=ONAM_STR, + ZNAM="", + ONAM="", on_update=lambda v: updater.update(v), ) @@ -1707,14 +1707,19 @@ def create_block_records( if block == "PCAP": # TODO: Need to add PVI Info here. Just use create_record_info? # And why isn't this record in the record_dict? - builder.Action( + + pcap_arm_record = builder.Action( "PCAP:ARM", - ZNAM=ZNAM_STR, - ONAM=ONAM_STR, + ZNAM="Disarm", + ONAM="Arm", on_update=self._arm_on_update, DESC="Arm/Disarm the PandA", ) + add_pvi_info( + PviGroup.INPUTS, pcap_arm_record, EpicsName("PCAP:ARM"), builder.Action + ) + HDF5RecordController(self._client, self._record_prefix) return record_dict diff --git a/tests/test-bobfiles/PCAP.bob b/tests/test-bobfiles/PCAP.bob index 6d554980..3e109c18 100644 --- a/tests/test-bobfiles/PCAP.bob +++ b/tests/test-bobfiles/PCAP.bob @@ -2,8 +2,8 @@ Display 0 0 - 361 - 202 + 426 + 227 4 4 @@ -12,7 +12,7 @@ PCAP - TEST-PREFIX: 0 0 - 361 + 426 25 @@ -29,8 +29,8 @@ INPUTS 5 30 - 351 - 106 + 416 + 131 true Label @@ -51,17 +51,50 @@ Label - PCAP: GATE + PCAP: ARM 0 25 250 20 + + ActionButton + TEST-PREFIX:PCAP:ARM + + + $(pv_name) + 1 + WritePV + + + o + 255 + 25 + 60 + 20 + $(actions) + + + LED + TEST-PREFIX: + 340 + 25 + 20 + 20 + + + Label + PCAP: GATE + 0 + 50 + 250 + 20 + TextEntry TEST-PREFIX:PCAP:GATE 255 - 25 + 50 60 20 1 @@ -70,7 +103,7 @@ Label PCAP: GATE: DELAY 0 - 50 + 75 250 20 @@ -78,7 +111,7 @@ TextEntry TEST-PREFIX:PCAP:GATE:DELAY 255 - 50 + 75 60 20 1 @@ -87,7 +120,7 @@ PARAMETERS 5 - 141 + 166 351 56 true diff --git a/tests/test_ioc_system.py b/tests/test_ioc_system.py index bf9e8c57..66211e1c 100644 --- a/tests/test_ioc_system.py +++ b/tests/test_ioc_system.py @@ -279,11 +279,11 @@ async def test_softioc_records_block(mocked_panda_standard_responses): try: arm_queue = asyncio.Queue() m1 = camonitor(TEST_PREFIX + ":PCAP:ARM", arm_queue.put, datatype=str) - assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "0" + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Disarm" await caput(TEST_PREFIX + ":PCAP:ARM", 1, wait=True, timeout=TIMEOUT) - assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "1" + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Arm" finally: m1.close() @@ -360,13 +360,19 @@ async def test_create_softioc_arm_disarm( try: arm_queue = asyncio.Queue() m1 = camonitor(TEST_PREFIX + ":PCAP:ARM", arm_queue.put, datatype=str) - assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "0" + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Disarm" # Put PVs and check the ioc sets the values await caput(TEST_PREFIX + ":PCAP:ARM", "1", wait=True, timeout=TIMEOUT) - assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "1" + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Arm" await caput(TEST_PREFIX + ":PCAP:ARM", "0", wait=True, timeout=TIMEOUT) - assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "0" + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Disarm" + + # Test you can also use "Arm" and "Disarm" instead of "1" and "0" + await caput(TEST_PREFIX + ":PCAP:ARM", "Arm", wait=True, timeout=TIMEOUT) + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Arm" + await caput(TEST_PREFIX + ":PCAP:ARM", "Disarm", wait=True, timeout=TIMEOUT) + assert await asyncio.wait_for(arm_queue.get(), TIMEOUT) == "Disarm" finally: m1.close() From 5874fd33c63ec2ce98e57ffc1765edb85a76db3a Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Fri, 1 Sep 2023 13:58:05 +0100 Subject: [PATCH 2/8] added pvi fields using `add_pvi_info` --- src/pandablocks_ioc/_hdf_ioc.py | 60 +++++++++-- tests/test-bobfiles/HDF5.bob | 171 ++++++++++++++++++++++++++++++++ tests/test-bobfiles/TOP.bob | 14 ++- 3 files changed, 234 insertions(+), 11 deletions(-) create mode 100644 tests/test-bobfiles/HDF5.bob diff --git a/src/pandablocks_ioc/_hdf_ioc.py b/src/pandablocks_ioc/_hdf_ioc.py index 27bf8ddf..e42cc7d5 100644 --- a/src/pandablocks_ioc/_hdf_ioc.py +++ b/src/pandablocks_ioc/_hdf_ioc.py @@ -18,7 +18,8 @@ from softioc import alarm, builder from softioc.pythonSoftIoc import RecordWrapper -from ._types import ONAM_STR, ZNAM_STR +from ._pvi import PviGroup, add_pvi_info +from ._types import ONAM_STR, ZNAM_STR, EpicsName class HDF5RecordController: @@ -52,51 +53,76 @@ def __init__(self, client: AsyncioClient, record_prefix: str): # Create the records, including an uppercase alias for each # Naming convention and settings (mostly) copied from FSCN2 HDF5 records - file_path_record_name = self._HDF5_PREFIX + ":FilePath" + file_path_record_name = EpicsName(self._HDF5_PREFIX + ":FilePath") self._file_path_record = builder.longStringOut( file_path_record_name, length=path_length, DESC="File path for HDF5 files", validate=self._parameter_validate, ) + add_pvi_info( + PviGroup.INPUTS, + self._file_path_record, + file_path_record_name, + builder.longStringOut, + ) self._file_path_record.add_alias( record_prefix + ":" + file_path_record_name.upper() ) - file_name_record_name = self._HDF5_PREFIX + ":FileName" + file_name_record_name = EpicsName(self._HDF5_PREFIX + ":FileName") self._file_name_record = builder.longStringOut( file_name_record_name, length=filename_length, DESC="File name prefix for HDF5 files", validate=self._parameter_validate, ) + add_pvi_info( + PviGroup.INPUTS, + self._file_name_record, + file_name_record_name, + builder.longStringOut, + ) self._file_name_record.add_alias( record_prefix + ":" + file_name_record_name.upper() ) - num_capture_record_name = self._HDF5_PREFIX + ":NumCapture" + num_capture_record_name = EpicsName(self._HDF5_PREFIX + ":NumCapture") self._num_capture_record = builder.longOut( num_capture_record_name, initial_value=0, # Infinite capture DESC="Number of frames to capture. 0=infinite", DRVL=0, ) + + add_pvi_info( + PviGroup.INPUTS, + self._num_capture_record, + num_capture_record_name, + builder.longOut, + ) # No validate - users are allowed to change this at any time self._num_capture_record.add_alias( record_prefix + ":" + num_capture_record_name.upper() ) - flush_period_record_name = self._HDF5_PREFIX + ":FlushPeriod" + flush_period_record_name = EpicsName(self._HDF5_PREFIX + ":FlushPeriod") self._flush_period_record = builder.aOut( flush_period_record_name, initial_value=1.0, DESC="Frequency that data is flushed (seconds)", ) + add_pvi_info( + PviGroup.INPUTS, + self._flush_period_record, + flush_period_record_name, + builder.aOut, + ) self._flush_period_record.add_alias( record_prefix + ":" + flush_period_record_name.upper() ) - capture_control_record_name = self._HDF5_PREFIX + ":Capture" + capture_control_record_name = EpicsName(self._HDF5_PREFIX + ":Capture") self._capture_control_record = builder.boolOut( capture_control_record_name, ZNAM=ZNAM_STR, @@ -105,27 +131,45 @@ def __init__(self, client: AsyncioClient, record_prefix: str): validate=self._capture_validate, DESC="Start/stop HDF5 capture", ) + add_pvi_info( + PviGroup.INPUTS, + self._capture_control_record, + capture_control_record_name, + builder.boolOut, + ) self._capture_control_record.add_alias( record_prefix + ":" + capture_control_record_name.upper() ) - status_message_record_name = self._HDF5_PREFIX + ":Status" + status_message_record_name = EpicsName(self._HDF5_PREFIX + ":Status") self._status_message_record = builder.stringIn( status_message_record_name, initial_value="OK", DESC="Reports current status of HDF5 capture", ) + add_pvi_info( + PviGroup.OUTPUTS, + self._status_message_record, + status_message_record_name, + builder.stringIn, + ) self._status_message_record.add_alias( record_prefix + ":" + status_message_record_name.upper() ) - currently_capturing_record_name = self._HDF5_PREFIX + ":Capturing" + currently_capturing_record_name = EpicsName(self._HDF5_PREFIX + ":Capturing") self._currently_capturing_record = builder.boolIn( currently_capturing_record_name, ZNAM=ZNAM_STR, ONAM=ONAM_STR, DESC="If HDF5 file is currently being written", ) + add_pvi_info( + PviGroup.OUTPUTS, + self._currently_capturing_record, + currently_capturing_record_name, + builder.boolIn, + ) self._currently_capturing_record.add_alias( record_prefix + ":" + currently_capturing_record_name.upper() ) diff --git a/tests/test-bobfiles/HDF5.bob b/tests/test-bobfiles/HDF5.bob new file mode 100644 index 00000000..5a973d2d --- /dev/null +++ b/tests/test-bobfiles/HDF5.bob @@ -0,0 +1,171 @@ + + Display + 0 + 0 + 426 + 277 + 4 + 4 + + Title + TITLE + HDF5 - TEST-PREFIX: + 0 + 0 + 426 + 25 + + + + + + + + + true + 1 + + + INPUTS + 5 + 30 + 351 + 156 + true + + Label + HDF5: File Path + 0 + 0 + 250 + 20 + + + TextEntry + TEST-PREFIX:HDF5:FilePath + 255 + 0 + 60 + 20 + 1 + + + Label + HDF5: File Name + 0 + 25 + 250 + 20 + + + TextEntry + TEST-PREFIX:HDF5:FileName + 255 + 25 + 60 + 20 + 1 + + + Label + HDF5: Num Capture + 0 + 50 + 250 + 20 + + + TextEntry + TEST-PREFIX:HDF5:NumCapture + 255 + 50 + 60 + 20 + 1 + + + Label + HDF5: Flush Period + 0 + 75 + 250 + 20 + + + TextEntry + TEST-PREFIX:HDF5:FlushPeriod + 255 + 75 + 60 + 20 + 1 + + + Label + HDF5: Capture + 0 + 100 + 250 + 20 + + + TextEntry + TEST-PREFIX:HDF5:Capture + 255 + 100 + 60 + 20 + 1 + + + + OUTPUTS + 5 + 191 + 416 + 81 + true + + Label + HDF5: Status + 0 + 0 + 250 + 20 + + + TextUpdate + TEST-PREFIX:HDF5:Status + 255 + 0 + 125 + 20 + + + + + 1 + + + Label + HDF5: Capturing + 0 + 25 + 250 + 20 + + + TextUpdate + TEST-PREFIX:HDF5:Capturing + 255 + 25 + 125 + 20 + + + + + 1 + + + diff --git a/tests/test-bobfiles/TOP.bob b/tests/test-bobfiles/TOP.bob index 5b36375d..15413d75 100644 --- a/tests/test-bobfiles/TOP.bob +++ b/tests/test-bobfiles/TOP.bob @@ -3,7 +3,7 @@ 0 0 278 - 105 + 130 4 4 @@ -35,7 +35,7 @@ Label - SEQ: PVI + HDF5: PVI 23 55 250 @@ -43,10 +43,18 @@ Label - PULSE: PVI + SEQ: PVI 23 80 250 20 + + Label + PULSE: PVI + 23 + 105 + 250 + 20 + From 102e1aa6d7a4ac01b2c035f33679cfd2c99a6abb Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Fri, 1 Sep 2023 09:26:53 +0100 Subject: [PATCH 3/8] Added necessary PVI information for PCAP:ARM --- src/pandablocks_ioc/_pvi.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pandablocks_ioc/_pvi.py b/src/pandablocks_ioc/_pvi.py index 7cb5657b..43c4b68a 100644 --- a/src/pandablocks_ioc/_pvi.py +++ b/src/pandablocks_ioc/_pvi.py @@ -7,7 +7,6 @@ from epicsdbbuilder import RecordName from pvi._format.dls import DLSFormatter from pvi.device import ( - LED, ButtonPanel, ComboBox, Component, @@ -15,6 +14,7 @@ DeviceRef, Grid, Group, + LED, Row, SignalR, SignalRW, @@ -65,7 +65,10 @@ def add_pvi_info( if record_creation_func == builder.Action: if record_name == "PCAP:ARM": component = SignalRW( - record_name, record_name, widget=ButtonPanel(), read_widget=LED() + record_name, + record_name, + widget=ButtonPanel(actions=dict(Arm=1, Disarm=0)), + read_widget=LED(), ) access = "rw" From 35446c8f287f2e0aba0006d57598ae0098555c16 Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Fri, 1 Sep 2023 14:11:13 +0100 Subject: [PATCH 4/8] Fixed incorrect .bob --- src/pandablocks_ioc/_pvi.py | 2 +- tests/test-bobfiles/PCAP.bob | 29 +++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/pandablocks_ioc/_pvi.py b/src/pandablocks_ioc/_pvi.py index 43c4b68a..e6f0f7e3 100644 --- a/src/pandablocks_ioc/_pvi.py +++ b/src/pandablocks_ioc/_pvi.py @@ -7,6 +7,7 @@ from epicsdbbuilder import RecordName from pvi._format.dls import DLSFormatter from pvi.device import ( + LED, ButtonPanel, ComboBox, Component, @@ -14,7 +15,6 @@ DeviceRef, Grid, Group, - LED, Row, SignalR, SignalRW, diff --git a/tests/test-bobfiles/PCAP.bob b/tests/test-bobfiles/PCAP.bob index 3e109c18..430919ad 100644 --- a/tests/test-bobfiles/PCAP.bob +++ b/tests/test-bobfiles/PCAP.bob @@ -2,7 +2,7 @@ Display 0 0 - 426 + 425 227 4 4 @@ -12,7 +12,7 @@ PCAP - TEST-PREFIX: 0 0 - 426 + 425 25 @@ -29,7 +29,7 @@ INPUTS 5 30 - 416 + 415 131 true @@ -67,17 +67,34 @@ WritePV - o + Arm 255 25 - 60 + 38 + 20 + $(actions) + + + ActionButton + TEST-PREFIX:PCAP:ARM + + + $(pv_name) + 0 + WritePV + + + Disarm + 298 + 25 + 38 20 $(actions) LED TEST-PREFIX: - 340 + 350 25 20 20 From cffb9582cbe6523647896e930b71340228d9f2bc Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Mon, 4 Sep 2023 09:36:19 +0100 Subject: [PATCH 5/8] Fixed error in metadata parsing --- src/pandablocks_ioc/ioc.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pandablocks_ioc/ioc.py b/src/pandablocks_ioc/ioc.py index ba670067..cd2c3f39 100644 --- a/src/pandablocks_ioc/ioc.py +++ b/src/pandablocks_ioc/ioc.py @@ -6,6 +6,7 @@ from string import digits from typing import Any, Callable, Dict, List, Optional, Tuple +import re import numpy as np from pandablocks.asyncio import AsyncioClient from pandablocks.commands import ( @@ -222,18 +223,19 @@ def _store_values( "LABEL_" ): _, block_name_number = field_name.split("_", maxsplit=1) - if block_name_number in block_info: - number_of_blocks = block_info[block_name_number].number - else: - number_of_blocks = block_info[block_name_number[:-1]].number - # The block is fixed with metadata + # The block is fixed with metadata, it should end with a number # "*METADATA.LABEL_SEQ2": "NewSeqMetadataLabel", if not block_name_number[-1].isdigit(): raise ValueError( f"Recieved metadata for a block name {block_name_number} that " "didn't contain a number" ) + + parts = re.findall(r"\d+|[^\d]+", block_name_number) + block_name_no_number = "".join(parts[:-1]) + number_of_blocks = block_info[block_name_no_number].number + if number_of_blocks == 1: if block_name_number[-1] != "1" or block_name_number[-2].isdigit(): raise ValueError( From 6e952e766cd50f941992e5e8380fd99f035a2465 Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Fri, 1 Sep 2023 10:12:02 +0100 Subject: [PATCH 6/8] Various fixes from the PR --- src/pandablocks_ioc/_tables.py | 16 ++++++++-------- src/pandablocks_ioc/_types.py | 3 ++- src/pandablocks_ioc/ioc.py | 21 ++++++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/pandablocks_ioc/_tables.py b/src/pandablocks_ioc/_tables.py index 38e56a12..8f01797e 100644 --- a/src/pandablocks_ioc/_tables.py +++ b/src/pandablocks_ioc/_tables.py @@ -308,9 +308,9 @@ def __init__( value, ) - putorder_index = 1 - - for field_name, field_record_container in self.table_fields_records.items(): + for i, (field_name, field_record_container) in enumerate( + self.table_fields_records.items() + ): field_details = field_record_container.field full_name = table_name + ":" + field_name @@ -333,14 +333,14 @@ def __init__( field_pva_info = { "+type": "plain", "+channel": "VAL", - "+putorder": putorder_index, + "+putorder": i + 1, "+trigger": "", } pva_info = {f"value.{field_name.lower()}": field_pva_info} # For the last column in the table - if putorder_index == len(self.table_fields_records): + if i == len(self.table_fields_records) - 1: # Trigger a monitor update field_pva_info["+trigger"] = "*" # Add metadata @@ -351,8 +351,6 @@ def __init__( {pva_table_name: pva_info}, ) - putorder_index += 1 - field_record_container.record_info = RecordInfo(lambda x: x, None, False) field_record_container.record_info.add_record(field_record) @@ -456,7 +454,9 @@ def __init__( OUT=PP(mode_record), ) # Edit mode done first, Submit mode done last - putorder = 0 if action == TableModeEnum.EDIT else putorder_index + putorder = ( + 0 if action == TableModeEnum.EDIT else len(self.table_fields_records) + ) action_record.add_info( "Q:group", { diff --git a/src/pandablocks_ioc/_types.py b/src/pandablocks_ioc/_types.py index c90b87d9..7ae02c36 100644 --- a/src/pandablocks_ioc/_types.py +++ b/src/pandablocks_ioc/_types.py @@ -39,7 +39,8 @@ def device_and_record_to_panda_name(field_name: EpicsName) -> PandAName: convention.""" if field_name.endswith(":LABEL"): - # Device is a metadata_label field + # Field is the label for the block, which is stored in the special + # *METADATA area block_name = field_name.split(":")[-2] if not block_name[-1].isdigit(): diff --git a/src/pandablocks_ioc/ioc.py b/src/pandablocks_ioc/ioc.py index cd2c3f39..e4cd3c83 100644 --- a/src/pandablocks_ioc/ioc.py +++ b/src/pandablocks_ioc/ioc.py @@ -96,7 +96,7 @@ async def _create_softioc( except OSError: logging.exception("Unable to connect to PandA") raise - (all_records, all_values_dict, panda_dict) = await create_records( + (all_records, all_values_dict, block_info_dict) = await create_records( client, dispatcher, record_prefix ) @@ -105,7 +105,7 @@ async def _create_softioc( raise RuntimeError("Unexpected state - softioc task already exists") create_softioc_task = asyncio.create_task( - update(client, all_records, 0.1, all_values_dict, panda_dict) + update(client, all_records, 0.1, all_values_dict, block_info_dict) ) create_softioc_task.add_done_callback(_when_finished) @@ -189,13 +189,13 @@ async def introspect_panda( def _create_dicts_from_changes( - changes: Changes, block_info: Dict[str, BlockInfo] + changes: Changes, block_info_dict: Dict[str, BlockInfo] ) -> Tuple[Dict[str, Dict[EpicsName, RecordValue]], Dict[EpicsName, RecordValue]]: """Take the `Changes` object and convert it into two dictionaries. Args: changes: The `Changes` object as returned by `GetChanges` - block_info: Information from the initial `GetBlockInfo` request, + block_info_dict: Information from the initial `GetBlockInfo` request, used to check the `number` of blocks for parsing metadata Returns: @@ -1696,7 +1696,7 @@ def create_block_records( # The record uses the default _RecordUpdater.update to update the value # on the panda - record_dict[key] = self._create_record_info( + record_dict[EpicsName(key)] = self._create_record_info( key, None, builder.longStringOut, @@ -1748,7 +1748,7 @@ async def create_records( EpicsName, RecordValue, ], - Dict[str, _BlockAndFieldInfo], + Dict[str, BlockInfo], ]: """Query the PandA and create the relevant records based on the information returned""" @@ -1823,7 +1823,8 @@ async def create_records( record_factory.initialise(dispatcher) - return (all_records, all_values_dict, panda_dict) + block_info_dict = {key: value.block_info for key, value in panda_dict.items()} + return (all_records, all_values_dict, block_info_dict) async def update( @@ -1831,7 +1832,7 @@ async def update( all_records: Dict[EpicsName, RecordInfo], poll_period: float, all_values_dict: Dict[EpicsName, RecordValue], - block_info: Dict[str, BlockInfo], + block_info_dict: Dict[str, BlockInfo], ): """Query the PandA at regular intervals for any changed fields, and update the records accordingly @@ -1874,7 +1875,9 @@ async def update( # Clear any alarm state as we've received a new update from PandA set_all_records_severity(all_records, alarm.NO_ALARM, alarm.UDF_ALARM) - _, new_all_values_dict = _create_dicts_from_changes(changes, block_info) + _, new_all_values_dict = _create_dicts_from_changes( + changes, block_info_dict + ) # Apply the new values to the existing dict, so various updater classes # will have access to the latest values. From b1fd12ca930990fbea9ceb4500b4a7f026f7a205 Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Mon, 4 Sep 2023 09:43:26 +0100 Subject: [PATCH 7/8] Fixed merge problem --- src/pandablocks_ioc/ioc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pandablocks_ioc/ioc.py b/src/pandablocks_ioc/ioc.py index e4cd3c83..c875eea7 100644 --- a/src/pandablocks_ioc/ioc.py +++ b/src/pandablocks_ioc/ioc.py @@ -2,11 +2,11 @@ import asyncio import inspect import logging +import re from dataclasses import dataclass from string import digits from typing import Any, Callable, Dict, List, Optional, Tuple -import re import numpy as np from pandablocks.asyncio import AsyncioClient from pandablocks.commands import ( @@ -234,7 +234,7 @@ def _store_values( parts = re.findall(r"\d+|[^\d]+", block_name_number) block_name_no_number = "".join(parts[:-1]) - number_of_blocks = block_info[block_name_no_number].number + number_of_blocks = block_info_dict[block_name_no_number].number if number_of_blocks == 1: if block_name_number[-1] != "1" or block_name_number[-2].isdigit(): From 846bad55be38453a2fff771860e68e057564e8b0 Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Mon, 4 Sep 2023 13:39:00 +0100 Subject: [PATCH 8/8] Removed uneccesary TODO --- src/pandablocks_ioc/_pvi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pandablocks_ioc/_pvi.py b/src/pandablocks_ioc/_pvi.py index e6f0f7e3..27cadf75 100644 --- a/src/pandablocks_ioc/_pvi.py +++ b/src/pandablocks_ioc/_pvi.py @@ -73,7 +73,6 @@ def add_pvi_info( access = "rw" else: - # TODO: What value do I write? PandA uses an empty string component = SignalX(record_name, record_name, value="") access = "x" elif writeable: