From dfebd66241ec82c74eefe21a8223d5044b9a237c Mon Sep 17 00:00:00 2001 From: Eva Lott Date: Fri, 13 Dec 2024 14:58:55 +0000 Subject: [PATCH] allowed parsing of `*METADATA_LABEL` post introspection --- src/pandablocks_ioc/ioc.py | 61 +++++++++++++++++++++++----------- tests/fixtures/mocked_panda.py | 1 + 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/pandablocks_ioc/ioc.py b/src/pandablocks_ioc/ioc.py index 452ceb80..581a2d3e 100644 --- a/src/pandablocks_ioc/ioc.py +++ b/src/pandablocks_ioc/ioc.py @@ -258,17 +258,34 @@ async def introspect_panda( values, all_values_dict = _create_dicts_from_changes(changes, block_dict) - panda_dict = {} - for (block_name, block_info), field_info in zip( - block_dict.items(), field_infos, strict=False - ): - panda_dict[block_name] = _BlockAndFieldInfo( - block_info=block_info, fields=field_info, values=values[block_name] + panda_dict = { + block_name: _BlockAndFieldInfo(block_info, field_info, values[block_name]) + for (block_name, block_info), field_info in zip( + block_dict.items(), field_infos, strict=False ) + } return (panda_dict, all_values_dict) +def extract_label_from_metadata(block_name_number, field_name: str): + # Parse *METADATA.LABEL_ into "" key and + # ":LABEL" value + if block_name_number.startswith("*METADATA") and field_name.startswith("LABEL_"): + _, block_name_number = field_name.split("_", maxsplit=1) + + # 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" + ) + + return block_name_number + return None + + def _create_dicts_from_changes( changes: Changes, block_info_dict: dict[str, BlockInfo] ) -> tuple[dict[str, dict[EpicsName, RecordValue]], dict[EpicsName, RecordValue]]: @@ -298,22 +315,12 @@ def _store_values( block_name_number, field_name = block_and_field_name.split(".", maxsplit=1) - # Parse *METADATA.LABEL_ into "" key and - # ":LABEL" value - if block_name_number.startswith("*METADATA") and field_name.startswith( - "LABEL_" + if label_block_name_number := extract_label_from_metadata( + block_name_number, field_name ): - _, block_name_number = field_name.split("_", maxsplit=1) - - # 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" - ) + block_name_number = label_block_name_number + block_name_no_number = re.sub(r"\d*$", "", label_block_name_number) - block_name_no_number = re.sub(r"\d*$", "", block_name_number) number_of_blocks = block_info_dict[block_name_no_number].number if number_of_blocks == 1: @@ -2095,6 +2102,20 @@ async def update( field = PandAName(field) field = panda_to_epics_name(field) + if block_label := extract_label_from_metadata( + *field.split(":", maxsplit=1) + ): + no_trailing_number_regex = r"\d*$" + block_label_no_number = ( + f"{re.sub(no_trailing_number_regex, '', block_label)}:LABEL" + ) + block_label = f"{block_label}:LABEL" + + if block_label_no_number in all_records: + field = block_label_no_number + elif block_label in all_records: + field = block_label + if field not in all_records: logging.error( f"Unknown field {field} returned from GetChanges values" diff --git a/tests/fixtures/mocked_panda.py b/tests/fixtures/mocked_panda.py index 533ed76b..be08b37d 100644 --- a/tests/fixtures/mocked_panda.py +++ b/tests/fixtures/mocked_panda.py @@ -871,6 +871,7 @@ def standard_responses(table_field_info, table_data_1, table_data_2): values={ "PCAP.TRIG_EDGE": "Either", "PULSE.DELAY.UNITS": "s", + "*METADATA.LABEL_PULSE1": "ANewLabel", }, multiline_values={"SEQ.TABLE": table_data_2}, ),